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) && (defined(__GNUC__) && !defined(__clang__)) 
 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 |       template <typename SignedType> 
 00277 |       inline std::string to_str_impl(SignedType i) 
 00278 |       { 
 00279 |          if (0 == i) 
 00280 |             return std::string("0"); 
 00281 |  
 00282 |          std::string result; 
 00283 |  
 00284 |          const int sign = (i < 0) ? -1 : 1; 
 00285 |  
 00286 |          for ( ; i; i /= 10) 
 00287 |          { 
 00288 |             result += '0' + static_cast<char_t>(sign * (i % 10)); 
 00289 |          } 
 00290 |  
 00291 |          if (sign < 0) 
 00292 |          { 
 00293 |             result += '-'; 
 00294 |          } 
 00295 |  
 00296 |          std::reverse(result.begin(), result.end()); 
 00297 |  
 00298 |          return result; 
 00299 |       } 
 00300 |  
 00301 |       inline std::string to_str(int i) 
 00302 |       { 
 00303 |          return to_str_impl(i); 
 00304 |       } 
 00305 |  
 00306 |       inline std::string to_str(std::size_t i) 
 00307 |       { 
 00308 |          return to_str_impl(static_cast<long long int>(i)); 
 00309 |       } 
 00310 |  
 00311 |       inline bool is_hex_digit(const uchar_t digit) 
 00312 |       { 
 00313 |          return (('0' <= digit) && (digit <= '9')) || 
 00314 |                 (('A' <= digit) && (digit <= 'F')) || 
 00315 |                 (('a' <= digit) && (digit <= 'f')) ; 
 00316 |       } 
 00317 |  
 00318 |       inline uchar_t hex_to_bin(uchar_t h) 
 00319 |       { 
 00320 |          if (('0' <= h) && (h <= '9')) 
 00321 |             return (h - '0'); 
 00322 |          else 
 00323 |             return static_cast<uchar_t>(std::toupper(h) - 'A' + 10); 
 00324 |       } 
 00325 |  
 00326 |       template <typename Iterator> 
 00327 |       inline bool parse_hex(Iterator& itr, Iterator end, 
 00328 |                             char_t& result) 
 00329 |       { 
 00330 |          if ( 
 00331 |               (end ==  (itr    ))               || 
 00332 |               (end ==  (itr + 1))               || 
 00333 |               (end ==  (itr + 2))               || 
 00334 |               (end ==  (itr + 3))               || 
 00335 |               ('0' != *(itr    ))               || 
 00336 |               ('X' != std::toupper(*(itr + 1))) || 
 00337 |               (!is_hex_digit(*(itr + 2)))       || 
 00338 |               (!is_hex_digit(*(itr + 3))) 
 00339 |             ) 
 00340 |          { 
 00341 |             return false; 
 00342 |          } 
 00343 |  
 00344 |          result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 | 
 00345 |                   hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ; 
 00346 |  
 00347 |          return true; 
 00348 |       } 
 00349 |  
 00350 |       inline bool cleanup_escapes(std::string& s) 
 00351 |       { 
 00352 |          typedef std::string::iterator str_itr_t; 
 00353 |  
 00354 |          str_itr_t itr1 = s.begin(); 
 00355 |          str_itr_t itr2 = s.begin(); 
 00356 |          str_itr_t end  = s.end  (); 
 00357 |  
 00358 |          std::size_t removal_count  = 0; 
 00359 |  
 00360 |          while (end != itr1) 
 00361 |          { 
 00362 |             if ('\\' == (*itr1)) 
 00363 |             { 
 00364 |                if (end == ++itr1) 
 00365 |                { 
 00366 |                   return false; 
 00367 |                } 
 00368 |                else if (parse_hex(itr1, end, *itr2)) 
 00369 |                { 
 00370 |                   itr1 += 4; 
 00371 |                   itr2 += 1; 
 00372 |                   removal_count += 4; 
 00373 |                } 
 00374 |                else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; } 
 00375 |                else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; } 
 00376 |                else if ('f' == (*itr1)) { (*itr2++) = '\f'; ++itr1; ++removal_count; } 
 00377 |                else if ('n' == (*itr1)) { (*itr2++) = '\n'; ++itr1; ++removal_count; } 
 00378 |                else if ('r' == (*itr1)) { (*itr2++) = '\r'; ++itr1; ++removal_count; } 
 00379 |                else if ('t' == (*itr1)) { (*itr2++) = '\t'; ++itr1; ++removal_count; } 
 00380 |                else if ('v' == (*itr1)) { (*itr2++) = '\v'; ++itr1; ++removal_count; } 
 00381 |                else if ('0' == (*itr1)) { (*itr2++) = '\0'; ++itr1; ++removal_count; } 
 00382 |                else 
 00383 |                { 
 00384 |                   (*itr2++) = (*itr1++); 
 00385 |                   ++removal_count; 
 00386 |                } 
 00387 |  
 00388 |                continue; 
 00389 |             } 
 00390 |             else 
 00391 |                (*itr2++) = (*itr1++); 
 00392 |          } 
 00393 |  
 00394 |          if ((removal_count > s.size()) || (0 == removal_count)) 
 00395 |             return false; 
 00396 |  
 00397 |          s.resize(s.size() - removal_count); 
 00398 |  
 00399 |          return true; 
 00400 |       } 
 00401 |  
 00402 |       class build_string 
 00403 |       { 
 00404 |       public: 
 00405 |  
 00406 |          explicit build_string(const std::size_t& initial_size = 64) 
 00407 |          { 
 00408 |             data_.reserve(initial_size); 
 00409 |          } 
 00410 |  
 00411 |          inline build_string& operator << (const std::string& s) 
 00412 |          { 
 00413 |             data_ += s; 
 00414 |             return (*this); 
 00415 |          } 
 00416 |  
 00417 |          inline build_string& operator << (char_cptr s) 
 00418 |          { 
 00419 |             data_ += std::string(s); 
 00420 |             return (*this); 
 00421 |          } 
 00422 |  
 00423 |          inline operator std::string () const 
 00424 |          { 
 00425 |             return data_; 
 00426 |          } 
 00427 |  
 00428 |          inline std::string as_string() const 
 00429 |          { 
 00430 |             return data_; 
 00431 |          } 
 00432 |  
 00433 |       private: 
 00434 |  
 00435 |          std::string data_; 
 00436 |       }; 
 00437 |  
 00438 |       static const std::string reserved_words[] = 
 00439 |       { 
 00440 |          "assert",  "break", "case", "continue", "const",  "default", 
 00441 |          "false", "for", "if", "else", "ilike", "in", "like",  "and", 
 00442 |          "nand",  "nor",  "not",  "null",  "or",  "repeat", "return", 
 00443 |          "shl",  "shr",  "swap",  "switch",  "true",  "until", "var", 
 00444 |          "while", "xnor", "xor", "&", "|" 
 00445 |       }; 
 00446 |  
 00447 |       static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string); 
 00448 |  
 00449 |       static const std::string reserved_symbols[] = 
 00450 |       { 
 00451 |          "abs", "acos",  "acosh", "and",  "asin", "asinh",  "assert", 
 00452 |          "atan", "atanh",  "atan2", "avg",  "break", "case",  "ceil", 
 00453 |          "clamp", "continue", "const",  "cos", "cosh", "cot",  "csc", 
 00454 |          "default",  "deg2grad", "deg2rad",  "equal", "erf",  "erfc", 
 00455 |          "exp", "expm1", "false", "floor", "for", "frac", "grad2deg", 
 00456 |          "hypot", "iclamp", "if",  "else", "ilike", "in",  "inrange", 
 00457 |          "like",  "log",  "log10", "log2",  "logn",  "log1p", "mand", 
 00458 |          "max", "min",  "mod", "mor",  "mul", "ncdf",  "nand", "nor", 
 00459 |          "not",   "not_equal",   "null",   "or",   "pow",  "rad2deg", 
 00460 |          "repeat", "return", "root", "round", "roundn", "sec", "sgn", 
 00461 |          "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum",  "swap", 
 00462 |          "switch", "tan",  "tanh", "true",  "trunc", "until",  "var", 
 00463 |          "while", "xnor", "xor", "&", "|" 
 00464 |       }; 
 00465 |  
 00466 |       static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string); 
 00467 |  
 00468 |       static const std::string base_function_list[] = 
 00469 |       { 
 00470 |          "abs", "acos",  "acosh", "asin",  "asinh", "atan",  "atanh", 
 00471 |          "atan2",  "avg",  "ceil",  "clamp",  "cos",  "cosh",  "cot", 
 00472 |          "csc",  "equal",  "erf",  "erfc",  "exp",  "expm1", "floor", 
 00473 |          "frac", "hypot", "iclamp",  "like", "log", "log10",  "log2", 
 00474 |          "logn", "log1p", "mand", "max", "min", "mod", "mor",  "mul", 
 00475 |          "ncdf",  "pow",  "root",  "round",  "roundn",  "sec", "sgn", 
 00476 |          "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh", 
 00477 |          "trunc",  "not_equal",  "inrange",  "deg2grad",   "deg2rad", 
 00478 |          "rad2deg", "grad2deg" 
 00479 |       }; 
 00480 |  
 00481 |       static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string); 
 00482 |  
 00483 |       static const std::string logic_ops_list[] = 
 00484 |       { 
 00485 |          "and", "nand", "nor", "not", "or",  "xnor", "xor", "&", "|" 
 00486 |       }; 
 00487 |  
 00488 |       static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string); 
 00489 |  
 00490 |       static const std::string cntrl_struct_list[] = 
 00491 |       { 
 00492 |          "if", "switch", "for", "while", "repeat", "return" 
 00493 |       }; 
 00494 |  
 00495 |       static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string); 
 00496 |  
 00497 |       static const std::string arithmetic_ops_list[] = 
 00498 |       { 
 00499 |          "+", "-", "*", "/", "%", "^" 
 00500 |       }; 
 00501 |  
 00502 |       static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string); 
 00503 |  
 00504 |       static const std::string assignment_ops_list[] = 
 00505 |       { 
 00506 |          ":=", "+=", "-=", 
 00507 |          "*=", "/=", "%=" 
 00508 |       }; 
 00509 |  
 00510 |       static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string); 
 00511 |  
 00512 |       static const std::string inequality_ops_list[] = 
 00513 |       { 
 00514 |          "<",  "<=", "==", 
 00515 |          "=",  "!=", "<>", 
 00516 |          ">=",  ">" 
 00517 |       }; 
 00518 |  
 00519 |       static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string); 
 00520 |  
 00521 |       inline bool is_reserved_word(const std::string& symbol) 
 00522 |       { 
 00523 |          for (std::size_t i = 0; i < reserved_words_size; ++i) 
 00524 |          { 
 00525 |             if (imatch(symbol, reserved_words[i])) 
 00526 |             { 
 00527 |                return true; 
 00528 |             } 
 00529 |          } 
 00530 |  
 00531 |          return false; 
 00532 |       } 
 00533 |  
 00534 |       inline bool is_reserved_symbol(const std::string& symbol) 
 00535 |       { 
 00536 |          for (std::size_t i = 0; i < reserved_symbols_size; ++i) 
 00537 |          { 
 00538 |             if (imatch(symbol, reserved_symbols[i])) 
 00539 |             { 
 00540 |                return true; 
 00541 |             } 
 00542 |          } 
 00543 |  
 00544 |          return false; 
 00545 |       } 
 00546 |  
 00547 |       inline bool is_base_function(const std::string& function_name) 
 00548 |       { 
 00549 |          for (std::size_t i = 0; i < base_function_list_size; ++i) 
 00550 |          { 
 00551 |             if (imatch(function_name, base_function_list[i])) 
 00552 |             { 
 00553 |                return true; 
 00554 |             } 
 00555 |          } 
 00556 |  
 00557 |          return false; 
 00558 |       } 
 00559 |  
 00560 |       inline bool is_control_struct(const std::string& cntrl_strct) 
 00561 |       { 
 00562 |          for (std::size_t i = 0; i < cntrl_struct_list_size; ++i) 
 00563 |          { 
 00564 |             if (imatch(cntrl_strct, cntrl_struct_list[i])) 
 00565 |             { 
 00566 |                return true; 
 00567 |             } 
 00568 |          } 
 00569 |  
 00570 |          return false; 
 00571 |       } 
 00572 |  
 00573 |       inline bool is_logic_opr(const std::string& lgc_opr) 
 00574 |       { 
 00575 |          for (std::size_t i = 0; i < logic_ops_list_size; ++i) 
 00576 |          { 
 00577 |             if (imatch(lgc_opr, logic_ops_list[i])) 
 00578 |             { 
 00579 |                return true; 
 00580 |             } 
 00581 |          } 
 00582 |  
 00583 |          return false; 
 00584 |       } 
 00585 |  
 00586 |       struct cs_match 
 00587 |       { 
 00588 |          static inline bool cmp(const char_t c0, const char_t c1) 
 00589 |          { 
 00590 |             return (c0 == c1); 
 00591 |          } 
 00592 |       }; 
 00593 |  
 00594 |       struct cis_match 
 00595 |       { 
 00596 |          static inline bool cmp(const char_t c0, const char_t c1) 
 00597 |          { 
 00598 |             return (std::tolower(c0) == std::tolower(c1)); 
 00599 |          } 
 00600 |       }; 
 00601 |  
 00602 |       template <typename Iterator, typename Compare> 
 00603 |       inline bool match_impl(const Iterator pattern_begin, 
 00604 |                              const Iterator pattern_end  , 
 00605 |                              const Iterator data_begin   , 
 00606 |                              const Iterator data_end     , 
 00607 |                              const typename std::iterator_traits<Iterator>::value_type& zero_or_more, 
 00608 |                              const typename std::iterator_traits<Iterator>::value_type& exactly_one ) 
 00609 |       { 
 00610 |          typedef typename std::iterator_traits<Iterator>::value_type type; 
 00611 |  
 00612 |          const Iterator null_itr(0); 
 00613 |  
 00614 |          Iterator p_itr  = pattern_begin; 
 00615 |          Iterator d_itr  = data_begin; 
 00616 |          Iterator np_itr = null_itr; 
 00617 |          Iterator nd_itr = null_itr; 
 00618 |  
 00619 |          for ( ; ; ) 
 00620 |          { 
 00621 |             if (p_itr != pattern_end) 
 00622 |             { 
 00623 |                const type c = *(p_itr); 
 00624 |  
 00625 |                if ((data_end != d_itr) && (Compare::cmp(c,*(d_itr)) || (exactly_one == c))) 
 00626 |                { 
 00627 |                   ++d_itr; 
 00628 |                   ++p_itr; 
 00629 |                   continue; 
 00630 |                } 
 00631 |                else if (zero_or_more == c) 
 00632 |                { 
 00633 |                   while ((pattern_end != p_itr) && (zero_or_more == *(p_itr))) 
 00634 |                   { 
 00635 |                      ++p_itr; 
 00636 |                   } 
 00637 |  
 00638 |                   const type d = *(p_itr); 
 00639 |  
 00640 |                   while ((data_end != d_itr) && !(Compare::cmp(d,*(d_itr)) || (exactly_one == d))) 
 00641 |                   { 
 00642 |                      ++d_itr; 
 00643 |                   } 
 00644 |  
 00645 |                   // set backtrack iterators 
 00646 |                   np_itr = p_itr - 1; 
 00647 |                   nd_itr = d_itr + 1; 
 00648 |  
 00649 |                   continue; 
 00650 |                } 
 00651 |             } 
 00652 |             else if (data_end == d_itr) 
 00653 |                break; 
 00654 |  
 00655 |             if ((data_end == d_itr) || (null_itr == nd_itr)) 
 00656 |                 return false; 
 00657 |  
 00658 |             p_itr = np_itr; 
 00659 |             d_itr = nd_itr; 
 00660 |          } 
 00661 |  
 00662 |          return true; 
 00663 |       } 
 00664 |  
 00665 |       inline bool wc_match(const std::string& wild_card, 
 00666 |                            const std::string& str) 
 00667 |       { 
 00668 |          return match_impl<char_cptr,cs_match> 
 00669 |                 ( 
 00670 |                    wild_card.data(), 
 00671 |                    wild_card.data() + wild_card.size(), 
 00672 |                    str.data(), 
 00673 |                    str.data() + str.size(), 
 00674 |                    '*', '?' 
 00675 |                 ); 
 00676 |       } 
 00677 |  
 00678 |       inline bool wc_imatch(const std::string& wild_card, 
 00679 |                             const std::string& str) 
 00680 |       { 
 00681 |          return match_impl<char_cptr,cis_match> 
 00682 |                 ( 
 00683 |                    wild_card.data(), 
 00684 |                    wild_card.data() + wild_card.size(), 
 00685 |                    str.data(), 
 00686 |                    str.data() + str.size(), 
 00687 |                    '*', '?' 
 00688 |                 ); 
 00689 |       } 
 00690 |  
 00691 |       inline bool sequence_match(const std::string& pattern, 
 00692 |                                  const std::string& str, 
 00693 |                                  std::size_t&       diff_index, 
 00694 |                                  char_t&            diff_value) 
 00695 |       { 
 00696 |          if (str.empty()) 
 00697 |          { 
 00698 |             return ("Z" == pattern); 
 00699 |          } 
 00700 |          else if ('*' == pattern[0]) 
 00701 |             return false; 
 00702 |  
 00703 |          typedef std::string::const_iterator itr_t; 
 00704 |  
 00705 |          itr_t p_itr = pattern.begin(); 
 00706 |          itr_t s_itr = str    .begin(); 
 00707 |  
 00708 |          const itr_t p_end = pattern.end(); 
 00709 |          const itr_t s_end = str    .end(); 
 00710 |  
 00711 |          while ((s_end != s_itr) && (p_end != p_itr)) 
 00712 |          { 
 00713 |             if ('*' == (*p_itr)) 
 00714 |             { 
 00715 |                const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1))); 
 00716 |  
 00717 |                if ('*' == target) 
 00718 |                { 
 00719 |                   diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr)); 
 00720 |                   diff_value = static_cast<char_t>(std::toupper(*p_itr)); 
 00721 |  
 00722 |                   return false; 
 00723 |                } 
 00724 |                else 
 00725 |                   ++p_itr; 
 00726 |  
 00727 |                while (s_itr != s_end) 
 00728 |                { 
 00729 |                   if (target != std::toupper(*s_itr)) 
 00730 |                      break; 
 00731 |                   else 
 00732 |                      ++s_itr; 
 00733 |                } 
 00734 |  
 00735 |                continue; 
 00736 |             } 
 00737 |             else if ( 
 00738 |                       ('?' != *p_itr) && 
 00739 |                       std::toupper(*p_itr) != std::toupper(*s_itr) 
 00740 |                     ) 
 00741 |             { 
 00742 |                diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr)); 
 00743 |                diff_value = static_cast<char_t>(std::toupper(*p_itr)); 
 00744 |  
 00745 |                return false; 
 00746 |             } 
 00747 |  
 00748 |             ++p_itr; 
 00749 |             ++s_itr; 
 00750 |          } 
 00751 |  
 00752 |          return ( 
 00753 |                   (s_end == s_itr) && 
 00754 |                   ( 
 00755 |                     (p_end ==  p_itr) || 
 00756 |                     ('*'   == *p_itr) 
 00757 |                   ) 
 00758 |                 ); 
 00759 |       } 
 00760 |  
 00761 |       template<typename T> 
 00762 |       struct set_zero_value_impl 
 00763 |       { 
 00764 |          static inline void process(T* base_ptr, const std::size_t size) 
 00765 |          { 
 00766 |             const T zero = T(0); 
 00767 |             for (std::size_t i = 0; i < size; ++i) 
 00768 |             { 
 00769 |                base_ptr[i] = zero; 
 00770 |             } 
 00771 |          } 
 00772 |       }; 
 00773 |  
 00774 |       #define pod_set_zero_value(T)                                      \ 
 00775 |       template <>                                                        \ 
 00776 |       struct set_zero_value_impl<T>                                      \ 
 00777 |       {                                                                  \ 
 00778 |          static inline void process(T* base_ptr, const std::size_t size) \ 
 00779 |          { std::memset(base_ptr, 0x00, size * sizeof(T)); }              \ 
 00780 |       };                                                                 \ 
 00781 |  
 00782 |       pod_set_zero_value(float      ) 
 00783 |       pod_set_zero_value(double     ) 
 00784 |       pod_set_zero_value(long double) 
 00785 |  
 00786 |       #ifdef pod_set_zero_value 
 00787 |       #undef pod_set_zero_value 
 00788 |       #endif 
 00789 |  
 00790 |       template<typename T> 
 00791 |       inline void set_zero_value(T* data, const std::size_t size) 
 00792 |       { 
 00793 |          set_zero_value_impl<T>::process(data,size); 
 00794 |       } 
 00795 |  
 00796 |       template<typename T> 
 00797 |       inline void set_zero_value(std::vector<T>& v) 
 00798 |       { 
 00799 |          set_zero_value(v.data(),v.size()); 
 00800 |       } 
 00801 |  
 00802 |       static const double pow10[] = 
 00803 |       { 
 00804 |          1.0, 
 00805 |          1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 
 00806 |          1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 
 00807 |          1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012, 
 00808 |          1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016 
 00809 |       }; 
 00810 |  
 00811 |       static const std::size_t pow10_size = sizeof(pow10) / sizeof(double); 
 00812 |  
 00813 |       namespace numeric 
 00814 |       { 
 00815 |          namespace constant 
 00816 |          { 
 00817 |             static const double e       =  2.71828182845904523536028747135266249775724709369996; 
 00818 |             static const double pi      =  3.14159265358979323846264338327950288419716939937510; 
 00819 |             static const double pi_2    =  1.57079632679489661923132169163975144209858469968755; 
 00820 |             static const double pi_4    =  0.78539816339744830961566084581987572104929234984378; 
 00821 |             static const double pi_180  =  0.01745329251994329576923690768488612713442871888542; 
 00822 |             static const double _1_pi   =  0.31830988618379067153776752674502872406891929148091; 
 00823 |             static const double _2_pi   =  0.63661977236758134307553505349005744813783858296183; 
 00824 |             static const double _180_pi = 57.29577951308232087679815481410517033240547246656443; 
 00825 |             static const double log2    =  0.69314718055994530941723212145817656807550013436026; 
 00826 |             static const double sqrt2   =  1.41421356237309504880168872420969807856967187537695; 
 00827 |          } 
 00828 |  
 00829 |          namespace details 
 00830 |          { 
 00831 |             struct unknown_type_tag { unknown_type_tag() {} }; 
 00832 |             struct real_type_tag    { real_type_tag   () {} }; 
 00833 |             struct int_type_tag     { int_type_tag    () {} }; 
 00834 |  
 00835 |             template <typename T> 
 00836 |             struct number_type 
 00837 |             { 
 00838 |                typedef unknown_type_tag type; 
 00839 |                number_type() {} 
 00840 |             }; 
 00841 |  
 00842 |             #define exprtk_register_real_type_tag(T)          \ 
 00843 |             template <> struct number_type<T>                 \ 
 00844 |             { typedef real_type_tag type; number_type() {} }; \ 
 00845 |  
 00846 |             #define exprtk_register_int_type_tag(T)           \ 
 00847 |             template <> struct number_type<T>                 \ 
 00848 |             { typedef int_type_tag type; number_type() {} };  \ 
 00849 |  
 00850 |             exprtk_register_real_type_tag(float      ) 
 00851 |             exprtk_register_real_type_tag(double     ) 
 00852 |             exprtk_register_real_type_tag(long double) 
 00853 |  
 00854 |             exprtk_register_int_type_tag(short         ) 
 00855 |             exprtk_register_int_type_tag(int           ) 
 00856 |             exprtk_register_int_type_tag(_int64_t      ) 
 00857 |             exprtk_register_int_type_tag(unsigned short) 
 00858 |             exprtk_register_int_type_tag(unsigned int  ) 
 00859 |             exprtk_register_int_type_tag(_uint64_t     ) 
 00860 |  
 00861 |             #undef exprtk_register_real_type_tag 
 00862 |             #undef exprtk_register_int_type_tag 
 00863 |  
 00864 |             template <typename T> 
 00865 |             struct epsilon_type {}; 
 00866 |  
 00867 |             #define exprtk_define_epsilon_type(Type, Epsilon)      \ 
 00868 |             template <> struct epsilon_type<Type>                  \ 
 00869 |             {                                                      \ 
 00870 |                static inline Type value()                          \ 
 00871 |                {                                                   \ 
 00872 |                   const Type epsilon = static_cast<Type>(Epsilon); \ 
 00873 |                   return epsilon;                                  \ 
 00874 |                }                                                   \ 
 00875 |             };                                                     \ 
 00876 |  
 00877 |             exprtk_define_epsilon_type(float      , 0.00000100000f) 
 00878 |             exprtk_define_epsilon_type(double     , 0.000000000100) 
 00879 |             exprtk_define_epsilon_type(long double, 0.000000000001) 
 00880 |  
 00881 |             #undef exprtk_define_epsilon_type 
 00882 |  
 00883 |             template <typename T> 
 00884 |             inline bool is_nan_impl(const T v, real_type_tag) 
 00885 |             { 
 00886 |                return std::not_equal_to<T>()(v,v); 
 00887 |             } 
 00888 |  
 00889 |             template <typename T> 
 00890 |             inline int to_int32_impl(const T v, real_type_tag) 
 00891 |             { 
 00892 |                return static_cast<int>(v); 
 00893 |             } 
 00894 |  
 00895 |             template <typename T> 
 00896 |             inline _int64_t to_int64_impl(const T v, real_type_tag) 
 00897 |             { 
 00898 |                return static_cast<_int64_t>(v); 
 00899 |             } 
 00900 |  
 00901 |             template <typename T> 
 00902 |             inline _uint64_t to_uint64_impl(const T v, real_type_tag) 
 00903 |             { 
 00904 |                return static_cast<_uint64_t>(v); 
 00905 |             } 
 00906 |  
 00907 |             template <typename T> 
 00908 |             inline bool is_true_impl(const T v) 
 00909 |             { 
 00910 |                return std::not_equal_to<T>()(T(0),v); 
 00911 |             } 
 00912 |  
 00913 |             template <typename T> 
 00914 |             inline bool is_false_impl(const T v) 
 00915 |             { 
 00916 |                return std::equal_to<T>()(T(0),v); 
 00917 |             } 
 00918 |  
 00919 |             template <typename T> 
 00920 |             inline T abs_impl(const T v, real_type_tag) 
 00921 |             { 
 00922 |                return ((v < T(0)) ? -v : v); 
 00923 |             } 
 00924 |  
 00925 |             template <typename T> 
 00926 |             inline T min_impl(const T v0, const T v1, real_type_tag) 
 00927 |             { 
 00928 |                return std::min<T>(v0,v1); 
 00929 |             } 
 00930 |  
 00931 |             template <typename T> 
 00932 |             inline T max_impl(const T v0, const T v1, real_type_tag) 
 00933 |             { 
 00934 |                return std::max<T>(v0,v1); 
 00935 |             } 
 00936 |  
 00937 |             template <typename T> 
 00938 |             inline T equal_impl(const T v0, const T v1, real_type_tag) 
 00939 |             { 
 00940 |                const T epsilon = epsilon_type<T>::value(); 
 00941 |                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); 
 00942 |             } 
 00943 |  
 00944 |             inline float equal_impl(const float v0, const float v1, real_type_tag) 
 00945 |             { 
 00946 |                const float epsilon = epsilon_type<float>::value(); 
 00947 |                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; 
 00948 |             } 
 00949 |  
 00950 |             template <typename T> 
 00951 |             inline T equal_impl(const T v0, const T v1, int_type_tag) 
 00952 |             { 
 00953 |                return (v0 == v1) ? 1 : 0; 
 00954 |             } 
 00955 |  
 00956 |             template <typename T> 
 00957 |             inline T expm1_impl(const T v, real_type_tag) 
 00958 |             { 
 00959 |                // return std::expm1<T>(v); 
 00960 |                if (abs_impl(v,real_type_tag()) < T(0.00001)) 
 00961 |                   return v + (T(0.5) * v * v); 
 00962 |                else 
 00963 |                   return std::exp(v) - T(1); 
 00964 |             } 
 00965 |  
 00966 |             template <typename T> 
 00967 |             inline T expm1_impl(const T v, int_type_tag) 
 00968 |             { 
 00969 |                return T(std::exp<double>(v)) - T(1); 
 00970 |             } 
 00971 |  
 00972 |             template <typename T> 
 00973 |             inline T nequal_impl(const T v0, const T v1, real_type_tag) 
 00974 |             { 
 00975 |                typedef real_type_tag rtg; 
 00976 |                const T epsilon = epsilon_type<T>::value(); 
 00977 |                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); 
 00978 |             } 
 00979 |  
 00980 |             inline float nequal_impl(const float v0, const float v1, real_type_tag) 
 00981 |             { 
 00982 |                typedef real_type_tag rtg; 
 00983 |                const float epsilon = epsilon_type<float>::value(); 
 00984 |                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; 
 00985 |             } 
 00986 |  
 00987 |             template <typename T> 
 00988 |             inline T nequal_impl(const T v0, const T v1, int_type_tag) 
 00989 |             { 
 00990 |                return (v0 != v1) ? 1 : 0; 
 00991 |             } 
 00992 |  
 00993 |             template <typename T> 
 00994 |             inline T modulus_impl(const T v0, const T v1, real_type_tag) 
 00995 |             { 
 00996 |                return std::fmod(v0,v1); 
 00997 |             } 
 00998 |  
 00999 |             template <typename T> 
 01000 |             inline T modulus_impl(const T v0, const T v1, int_type_tag) 
 01001 |             { 
 01002 |                return v0 % v1; 
 01003 |             } 
 01004 |  
 01005 |             template <typename T> 
 01006 |             inline T pow_impl(const T v0, const T v1, real_type_tag) 
 01007 |             { 
 01008 |                return std::pow(v0,v1); 
 01009 |             } 
 01010 |  
 01011 |             template <typename T> 
 01012 |             inline T pow_impl(const T v0, const T v1, int_type_tag) 
 01013 |             { 
 01014 |                return std::pow(static_cast<double>(v0),static_cast<double>(v1)); 
 01015 |             } 
 01016 |  
 01017 |             template <typename T> 
 01018 |             inline T logn_impl(const T v0, const T v1, real_type_tag) 
 01019 |             { 
 01020 |                return std::log(v0) / std::log(v1); 
 01021 |             } 
 01022 |  
 01023 |             template <typename T> 
 01024 |             inline T logn_impl(const T v0, const T v1, int_type_tag) 
 01025 |             { 
 01026 |                return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag())); 
 01027 |             } 
 01028 |  
 01029 |             template <typename T> 
 01030 |             inline T log1p_impl(const T v, real_type_tag) 
 01031 |             { 
 01032 |                if (v > T(-1)) 
 01033 |                { 
 01034 |                   if (abs_impl(v,real_type_tag()) > T(0.0001)) 
 01035 |                   { 
 01036 |                      return std::log(T(1) + v); 
 01037 |                   } 
 01038 |                   else 
 01039 |                      return (T(-0.5) * v + T(1)) * v; 
 01040 |                } 
 01041 |  
 01042 |                return std::numeric_limits<T>::quiet_NaN(); 
 01043 |             } 
 01044 |  
 01045 |             template <typename T> 
 01046 |             inline T log1p_impl(const T v, int_type_tag) 
 01047 |             { 
 01048 |                if (v > T(-1)) 
 01049 |                { 
 01050 |                   return std::log(T(1) + v); 
 01051 |                } 
 01052 |  
 01053 |                return std::numeric_limits<T>::quiet_NaN(); 
 01054 |             } 
 01055 |  
 01056 |             template <typename T> 
 01057 |             inline T root_impl(const T v0, const T v1, real_type_tag) 
 01058 |             { 
 01059 |                if (v0 < T(0)) 
 01060 |                { 
 01061 |                   return (v1 == trunc_impl(v1, real_type_tag())) && 
 01062 |                          (modulus_impl(v1, T(2), real_type_tag()) != T(0)) ? 
 01063 |                          -std::pow(abs_impl(v0, real_type_tag()), T(1) / v1) : 
 01064 |                           std::numeric_limits<double>::quiet_NaN(); 
 01065 |                } 
 01066 |  
 01067 |                return std::pow(v0, T(1) / v1); 
 01068 |             } 
 01069 |  
 01070 |             template <typename T> 
 01071 |             inline T root_impl(const T v0, const T v1, int_type_tag) 
 01072 |             { 
 01073 |                return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()); 
 01074 |             } 
 01075 |  
 01076 |             template <typename T> 
 01077 |             inline T round_impl(const T v, real_type_tag) 
 01078 |             { 
 01079 |                return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5))); 
 01080 |             } 
 01081 |  
 01082 |             template <typename T> 
 01083 |             inline T roundn_impl(const T v0, const T v1, real_type_tag) 
 01084 |             { 
 01085 |                const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1)))); 
 01086 |                const T p10 = T(pow10[index]); 
 01087 |  
 01088 |                if (v0 < T(0)) 
 01089 |                   return T(std::ceil ((v0 * p10) - T(0.5)) / p10); 
 01090 |                else 
 01091 |                   return T(std::floor((v0 * p10) + T(0.5)) / p10); 
 01092 |             } 
 01093 |  
 01094 |             template <typename T> 
 01095 |             inline T roundn_impl(const T v0, const T, int_type_tag) 
 01096 |             { 
 01097 |                return v0; 
 01098 |             } 
 01099 |  
 01100 |             template <typename T> 
 01101 |             inline T hypot_impl(const T v0, const T v1, real_type_tag) 
 01102 |             { 
 01103 |                return std::sqrt((v0 * v0) + (v1 * v1)); 
 01104 |             } 
 01105 |  
 01106 |             template <typename T> 
 01107 |             inline T hypot_impl(const T v0, const T v1, int_type_tag) 
 01108 |             { 
 01109 |                return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1)))); 
 01110 |             } 
 01111 |  
 01112 |             template <typename T> 
 01113 |             inline T atan2_impl(const T v0, const T v1, real_type_tag) 
 01114 |             { 
 01115 |                return std::atan2(v0,v1); 
 01116 |             } 
 01117 |  
 01118 |             template <typename T> 
 01119 |             inline T atan2_impl(const T, const T, int_type_tag) 
 01120 |             { 
 01121 |                return 0; 
 01122 |             } 
 01123 |  
 01124 |             template <typename T> 
 01125 |             inline T shr_impl(const T v0, const T v1, real_type_tag) 
 01126 |             { 
 01127 |                return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1)))); 
 01128 |             } 
 01129 |  
 01130 |             template <typename T> 
 01131 |             inline T shr_impl(const T v0, const T v1, int_type_tag) 
 01132 |             { 
 01133 |                return v0 >> v1; 
 01134 |             } 
 01135 |  
 01136 |             template <typename T> 
 01137 |             inline T shl_impl(const T v0, const T v1, real_type_tag) 
 01138 |             { 
 01139 |                return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1))); 
 01140 |             } 
 01141 |  
 01142 |             template <typename T> 
 01143 |             inline T shl_impl(const T v0, const T v1, int_type_tag) 
 01144 |             { 
 01145 |                return v0 << v1; 
 01146 |             } 
 01147 |  
 01148 |             template <typename T> 
 01149 |             inline T sgn_impl(const T v, real_type_tag) 
 01150 |             { 
 01151 |                if      (v > T(0)) return T(+1); 
 01152 |                else if (v < T(0)) return T(-1); 
 01153 |                else               return T( 0); 
 01154 |             } 
 01155 |  
 01156 |             template <typename T> 
 01157 |             inline T sgn_impl(const T v, int_type_tag) 
 01158 |             { 
 01159 |                if      (v > T(0)) return T(+1); 
 01160 |                else if (v < T(0)) return T(-1); 
 01161 |                else               return T( 0); 
 01162 |             } 
 01163 |  
 01164 |             template <typename T> 
 01165 |             inline T and_impl(const T v0, const T v1, real_type_tag) 
 01166 |             { 
 01167 |                return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0); 
 01168 |             } 
 01169 |  
 01170 |             template <typename T> 
 01171 |             inline T and_impl(const T v0, const T v1, int_type_tag) 
 01172 |             { 
 01173 |                return v0 && v1; 
 01174 |             } 
 01175 |  
 01176 |             template <typename T> 
 01177 |             inline T nand_impl(const T v0, const T v1, real_type_tag) 
 01178 |             { 
 01179 |                return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0); 
 01180 |             } 
 01181 |  
 01182 |             template <typename T> 
 01183 |             inline T nand_impl(const T v0, const T v1, int_type_tag) 
 01184 |             { 
 01185 |                return !(v0 && v1); 
 01186 |             } 
 01187 |  
 01188 |             template <typename T> 
 01189 |             inline T or_impl(const T v0, const T v1, real_type_tag) 
 01190 |             { 
 01191 |                return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0); 
 01192 |             } 
 01193 |  
 01194 |             template <typename T> 
 01195 |             inline T or_impl(const T v0, const T v1, int_type_tag) 
 01196 |             { 
 01197 |                return (v0 || v1); 
 01198 |             } 
 01199 |  
 01200 |             template <typename T> 
 01201 |             inline T nor_impl(const T v0, const T v1, real_type_tag) 
 01202 |             { 
 01203 |                return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0); 
 01204 |             } 
 01205 |  
 01206 |             template <typename T> 
 01207 |             inline T nor_impl(const T v0, const T v1, int_type_tag) 
 01208 |             { 
 01209 |                return !(v0 || v1); 
 01210 |             } 
 01211 |  
 01212 |             template <typename T> 
 01213 |             inline T xor_impl(const T v0, const T v1, real_type_tag) 
 01214 |             { 
 01215 |                return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0); 
 01216 |             } 
 01217 |  
 01218 |             template <typename T> 
 01219 |             inline T xor_impl(const T v0, const T v1, int_type_tag) 
 01220 |             { 
 01221 |                return v0 ^ v1; 
 01222 |             } 
 01223 |  
 01224 |             template <typename T> 
 01225 |             inline T xnor_impl(const T v0, const T v1, real_type_tag) 
 01226 |             { 
 01227 |                const bool v0_true = is_true_impl(v0); 
 01228 |                const bool v1_true = is_true_impl(v1); 
 01229 |  
 01230 |                if ((v0_true &&  v1_true) || (!v0_true && !v1_true)) 
 01231 |                   return T(1); 
 01232 |                else 
 01233 |                   return T(0); 
 01234 |             } 
 01235 |  
 01236 |             template <typename T> 
 01237 |             inline T xnor_impl(const T v0, const T v1, int_type_tag) 
 01238 |             { 
 01239 |                const bool v0_true = is_true_impl(v0); 
 01240 |                const bool v1_true = is_true_impl(v1); 
 01241 |  
 01242 |                if ((v0_true &&  v1_true) || (!v0_true && !v1_true)) 
 01243 |                   return T(1); 
 01244 |                else 
 01245 |                   return T(0); 
 01246 |             } 
 01247 |  
 01248 |             #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER) 
 01249 |             #define exprtk_define_erf(TT, impl)                \ 
 01250 |             inline TT erf_impl(const TT v) { return impl(v); } \ 
 01251 |  
 01252 |             exprtk_define_erf(float      , ::erff) 
 01253 |             exprtk_define_erf(double     , ::erf ) 
 01254 |             exprtk_define_erf(long double, ::erfl) 
 01255 |             #undef exprtk_define_erf 
 01256 |             #endif 
 01257 |  
 01258 |             template <typename T> 
 01259 |             inline T erf_impl(const T v, real_type_tag) 
 01260 |             { 
 01261 |                #if defined(_MSC_VER) && (_MSC_VER < 1900) 
 01262 |                // Credits: Abramowitz & Stegun Equations 7.1.25-28 
 01263 |                static const T c[] = 
 01264 |                { 
 01265 |                   T( 1.26551223), T(1.00002368), 
 01266 |                   T( 0.37409196), T(0.09678418), 
 01267 |                   T(-0.18628806), T(0.27886807), 
 01268 |                   T(-1.13520398), T(1.48851587), 
 01269 |                   T(-0.82215223), T(0.17087277) 
 01270 |                }; 
 01271 |  
 01272 |                const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag())); 
 01273 |  
 01274 |                const T result = T(1) - t * std::exp((-v * v) - 
 01275 |                                             c[0] + t * (c[1] + t * 
 01276 |                                            (c[2] + t * (c[3] + t * 
 01277 |                                            (c[4] + t * (c[5] + t * 
 01278 |                                            (c[6] + t * (c[7] + t * 
 01279 |                                            (c[8] + t * (c[9])))))))))); 
 01280 |  
 01281 |                return (v >= T(0)) ? result : -result; 
 01282 |                #else 
 01283 |                return erf_impl(v); 
 01284 |                #endif 
 01285 |             } 
 01286 |  
 01287 |             template <typename T> 
 01288 |             inline T erf_impl(const T v, int_type_tag) 
 01289 |             { 
 01290 |                return erf_impl(static_cast<double>(v),real_type_tag()); 
 01291 |             } 
 01292 |  
 01293 |             #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER) 
 01294 |             #define exprtk_define_erfc(TT, impl)                \ 
 01295 |             inline TT erfc_impl(const TT v) { return impl(v); } \ 
 01296 |  
 01297 |             exprtk_define_erfc(float      ,::erfcf) 
 01298 |             exprtk_define_erfc(double     ,::erfc ) 
 01299 |             exprtk_define_erfc(long double,::erfcl) 
 01300 |             #undef exprtk_define_erfc 
 01301 |             #endif 
 01302 |  
 01303 |             template <typename T> 
 01304 |             inline T erfc_impl(const T v, real_type_tag) 
 01305 |             { 
 01306 |                #if defined(_MSC_VER) && (_MSC_VER < 1900) 
 01307 |                return T(1) - erf_impl(v,real_type_tag()); 
 01308 |                #else 
 01309 |                return erfc_impl(v); 
 01310 |                #endif 
 01311 |             } 
 01312 |  
 01313 |             template <typename T> 
 01314 |             inline T erfc_impl(const T v, int_type_tag) 
 01315 |             { 
 01316 |                return erfc_impl(static_cast<double>(v),real_type_tag()); 
 01317 |             } 
 01318 |  
 01319 |             template <typename T> 
 01320 |             inline T ncdf_impl(const T v, real_type_tag) 
 01321 |             { 
 01322 |                return T(0.5) * erfc_impl(-(v / T(numeric::constant::sqrt2)),real_type_tag()); 
 01323 |             } 
 01324 |  
 01325 |             template <typename T> 
 01326 |             inline T ncdf_impl(const T v, int_type_tag) 
 01327 |             { 
 01328 |                return ncdf_impl(static_cast<double>(v),real_type_tag()); 
 01329 |             } 
 01330 |  
 01331 |             template <typename T> 
 01332 |             inline T sinc_impl(const T v, real_type_tag) 
 01333 |             { 
 01334 |                if (std::abs(v) >= std::numeric_limits<T>::epsilon()) 
 01335 |                    return(std::sin(v) / v); 
 01336 |                else 
 01337 |                   return T(1); 
 01338 |             } 
 01339 |  
 01340 |             template <typename T> 
 01341 |             inline T sinc_impl(const T v, int_type_tag) 
 01342 |             { 
 01343 |                return sinc_impl(static_cast<double>(v),real_type_tag()); 
 01344 |             } 
 01345 |  
 01346 |             #if __cplusplus >= 201103L 
 01347 |             template <typename T> 
 01348 |             inline T acosh_impl(const T v, real_type_tag) 
 01349 |             { 
 01350 |                return std::acosh(v); 
 01351 |             } 
 01352 |  
 01353 |             template <typename T> 
 01354 |             inline T asinh_impl(const T v, real_type_tag) 
 01355 |             { 
 01356 |                return std::asinh(v); 
 01357 |             } 
 01358 |  
 01359 |             template <typename T> 
 01360 |             inline T atanh_impl(const T v, real_type_tag) 
 01361 |             { 
 01362 |                return std::atanh(v); 
 01363 |             } 
 01364 |  
 01365 |             template <typename T> 
 01366 |             inline T trunc_impl(const T v, real_type_tag) 
 01367 |             { 
 01368 |                return std::trunc(v); 
 01369 |             } 
 01370 |             #else 
 01371 |             template <typename T> 
 01372 |             inline T acosh_impl(const T v, real_type_tag) 
 01373 |             { 
 01374 |                return std::log(v + std::sqrt((v * v) - T(1))); 
 01375 |             } 
 01376 |  
 01377 |             template <typename T> 
 01378 |             inline T asinh_impl(const T v, real_type_tag) 
 01379 |             { 
 01380 |                return std::log(v + std::sqrt((v * v) + T(1))); 
 01381 |             } 
 01382 |  
 01383 |             template <typename T> 
 01384 |             inline T atanh_impl(const T v, real_type_tag) 
 01385 |             { 
 01386 |                return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); 
 01387 |             } 
 01388 |  
 01389 |             template <typename T> 
 01390 |             inline T trunc_impl(const T v, real_type_tag) 
 01391 |             { 
 01392 |                return T(static_cast<long long>(v)); 
 01393 |             } 
 01394 |             #endif 
 01395 |  
 01396 |             template <typename T> inline T  acos_impl(const T v, real_type_tag) { return std::acos (v); } 
 01397 |             template <typename T> inline T  asin_impl(const T v, real_type_tag) { return std::asin (v); } 
 01398 |             template <typename T> inline T  atan_impl(const T v, real_type_tag) { return std::atan (v); } 
 01399 |             template <typename T> inline T  ceil_impl(const T v, real_type_tag) { return std::ceil (v); } 
 01400 |             template <typename T> inline T   cos_impl(const T v, real_type_tag) { return std::cos  (v); } 
 01401 |             template <typename T> inline T  cosh_impl(const T v, real_type_tag) { return std::cosh (v); } 
 01402 |             template <typename T> inline T   exp_impl(const T v, real_type_tag) { return std::exp  (v); } 
 01403 |             template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); } 
 01404 |             template <typename T> inline T   log_impl(const T v, real_type_tag) { return std::log  (v); } 
 01405 |             template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); } 
 01406 |             template <typename T> inline T  log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); } 
 01407 |             template <typename T> inline T   neg_impl(const T v, real_type_tag) { return -v;            } 
 01408 |             template <typename T> inline T   pos_impl(const T v, real_type_tag) { return +v;            } 
 01409 |             template <typename T> inline T   sin_impl(const T v, real_type_tag) { return std::sin  (v); } 
 01410 |             template <typename T> inline T  sinh_impl(const T v, real_type_tag) { return std::sinh (v); } 
 01411 |             template <typename T> inline T  sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); } 
 01412 |             template <typename T> inline T   tan_impl(const T v, real_type_tag) { return std::tan  (v); } 
 01413 |             template <typename T> inline T  tanh_impl(const T v, real_type_tag) { return std::tanh (v); } 
 01414 |             template <typename T> inline T   cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); } 
 01415 |             template <typename T> inline T   sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); } 
 01416 |             template <typename T> inline T   csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); } 
 01417 |             template <typename T> inline T   r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); } 
 01418 |             template <typename T> inline T   d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180));  } 
 01419 |             template <typename T> inline T   d2g_impl(const T v, real_type_tag) { return (v * T(10.0/9.0)); } 
 01420 |             template <typename T> inline T   g2d_impl(const T v, real_type_tag) { return (v * T(9.0/10.0)); } 
 01421 |             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)); } 
 01422 |             template <typename T> inline T  frac_impl(const T v, real_type_tag) { return (v - trunc_impl(v,real_type_tag())); } 
 01423 |  
 01424 |             template <typename T> inline T   const_pi_impl(real_type_tag) { return T(numeric::constant::pi);            } 
 01425 |             template <typename T> inline T    const_e_impl(real_type_tag) { return T(numeric::constant::e);             } 
 01426 |             template <typename T> inline T const_qnan_impl(real_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01427 |  
 01428 |             template <typename T> inline T   abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); } 
 01429 |             template <typename T> inline T   exp_impl(const T v, int_type_tag) { return std::exp  (v); } 
 01430 |             template <typename T> inline T   log_impl(const T v, int_type_tag) { return std::log  (v); } 
 01431 |             template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); } 
 01432 |             template <typename T> inline T  log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); } 
 01433 |             template <typename T> inline T   neg_impl(const T v, int_type_tag) { return -v;            } 
 01434 |             template <typename T> inline T   pos_impl(const T v, int_type_tag) { return +v;            } 
 01435 |             template <typename T> inline T  ceil_impl(const T v, int_type_tag) { return v;             } 
 01436 |             template <typename T> inline T floor_impl(const T v, int_type_tag) { return v;             } 
 01437 |             template <typename T> inline T round_impl(const T v, int_type_tag) { return v;             } 
 01438 |             template <typename T> inline T  notl_impl(const T v, int_type_tag) { return !v;            } 
 01439 |             template <typename T> inline T  sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); } 
 01440 |             template <typename T> inline T  frac_impl(const T  , int_type_tag) { return T(0);          } 
 01441 |             template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v;             } 
 01442 |             template <typename T> inline T  acos_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01443 |             template <typename T> inline T acosh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01444 |             template <typename T> inline T  asin_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01445 |             template <typename T> inline T asinh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01446 |             template <typename T> inline T  atan_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01447 |             template <typename T> inline T atanh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01448 |             template <typename T> inline T   cos_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01449 |             template <typename T> inline T  cosh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01450 |             template <typename T> inline T   sin_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01451 |             template <typename T> inline T  sinh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01452 |             template <typename T> inline T   tan_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01453 |             template <typename T> inline T  tanh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01454 |             template <typename T> inline T   cot_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01455 |             template <typename T> inline T   sec_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01456 |             template <typename T> inline T   csc_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01457 |  
 01458 |             template <typename T> 
 01459 |             inline bool is_integer_impl(const T& v, real_type_tag) 
 01460 |             { 
 01461 |                return std::equal_to<T>()(T(0),std::fmod(v,T(1))); 
 01462 |             } 
 01463 |  
 01464 |             template <typename T> 
 01465 |             inline bool is_integer_impl(const T&, int_type_tag) 
 01466 |             { 
 01467 |                return true; 
 01468 |             } 
 01469 |          } 
 01470 |  
 01471 |          template <typename Type> 
 01472 |          struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; }; 
 01473 |  
 01474 |          template <> struct numeric_info<int        > { enum { length = 10, size = 16, bound_length = 9 }; }; 
 01475 |          template <> struct numeric_info<float      > { enum { min_exp =  -38, max_exp =  +38 }; }; 
 01476 |          template <> struct numeric_info<double     > { enum { min_exp = -308, max_exp = +308 }; }; 
 01477 |          template <> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308 }; }; 
 01478 |  
 01479 |          template <typename T> 
 01480 |          inline int to_int32(const T v) 
 01481 |          { 
 01482 |             const typename details::number_type<T>::type num_type; 
 01483 |             return to_int32_impl(v, num_type); 
 01484 |          } 
 01485 |  
 01486 |          template <typename T> 
 01487 |          inline _int64_t to_int64(const T v) 
 01488 |          { 
 01489 |             const typename details::number_type<T>::type num_type; 
 01490 |             return to_int64_impl(v, num_type); 
 01491 |          } 
 01492 |  
 01493 |          template <typename T> 
 01494 |          inline _uint64_t to_uint64(const T v) 
 01495 |          { 
 01496 |             const typename details::number_type<T>::type num_type; 
 01497 |             return to_uint64_impl(v, num_type); 
 01498 |          } 
 01499 |  
 01500 |          template <typename T> 
 01501 |          inline bool is_nan(const T v) 
 01502 |          { 
 01503 |             const typename details::number_type<T>::type num_type; 
 01504 |             return is_nan_impl(v, num_type); 
 01505 |          } 
 01506 |  
 01507 |          template <typename T> 
 01508 |          inline T min(const T v0, const T v1) 
 01509 |          { 
 01510 |             const typename details::number_type<T>::type num_type; 
 01511 |             return min_impl(v0, v1, num_type); 
 01512 |          } 
 01513 |  
 01514 |          template <typename T> 
 01515 |          inline T max(const T v0, const T v1) 
 01516 |          { 
 01517 |             const typename details::number_type<T>::type num_type; 
 01518 |             return max_impl(v0, v1, num_type); 
 01519 |          } 
 01520 |  
 01521 |          template <typename T> 
 01522 |          inline T equal(const T v0, const T v1) 
 01523 |          { 
 01524 |             const typename details::number_type<T>::type num_type; 
 01525 |             return equal_impl(v0, v1, num_type); 
 01526 |          } 
 01527 |  
 01528 |          template <typename T> 
 01529 |          inline T nequal(const T v0, const T v1) 
 01530 |          { 
 01531 |             const typename details::number_type<T>::type num_type; 
 01532 |             return nequal_impl(v0, v1, num_type); 
 01533 |          } 
 01534 |  
 01535 |          template <typename T> 
 01536 |          inline T modulus(const T v0, const T v1) 
 01537 |          { 
 01538 |             const typename details::number_type<T>::type num_type; 
 01539 |             return modulus_impl(v0, v1, num_type); 
 01540 |          } 
 01541 |  
 01542 |          template <typename T> 
 01543 |          inline T pow(const T v0, const T v1) 
 01544 |          { 
 01545 |             const typename details::number_type<T>::type num_type; 
 01546 |             return pow_impl(v0, v1, num_type); 
 01547 |          } 
 01548 |  
 01549 |          template <typename T> 
 01550 |          inline T logn(const T v0, const T v1) 
 01551 |          { 
 01552 |             const typename details::number_type<T>::type num_type; 
 01553 |             return logn_impl(v0, v1, num_type); 
 01554 |          } 
 01555 |  
 01556 |          template <typename T> 
 01557 |          inline T root(const T v0, const T v1) 
 01558 |          { 
 01559 |             const typename details::number_type<T>::type num_type; 
 01560 |             return root_impl(v0, v1, num_type); 
 01561 |          } 
 01562 |  
 01563 |          template <typename T> 
 01564 |          inline T roundn(const T v0, const T v1) 
 01565 |          { 
 01566 |             const typename details::number_type<T>::type num_type; 
 01567 |             return roundn_impl(v0, v1, num_type); 
 01568 |          } 
 01569 |  
 01570 |          template <typename T> 
 01571 |          inline T hypot(const T v0, const T v1) 
 01572 |          { 
 01573 |             const typename details::number_type<T>::type num_type; 
 01574 |             return hypot_impl(v0, v1, num_type); 
 01575 |          } 
 01576 |  
 01577 |          template <typename T> 
 01578 |          inline T atan2(const T v0, const T v1) 
 01579 |          { 
 01580 |             const typename details::number_type<T>::type num_type; 
 01581 |             return atan2_impl(v0, v1, num_type); 
 01582 |          } 
 01583 |  
 01584 |          template <typename T> 
 01585 |          inline T shr(const T v0, const T v1) 
 01586 |          { 
 01587 |             const typename details::number_type<T>::type num_type; 
 01588 |             return shr_impl(v0, v1, num_type); 
 01589 |          } 
 01590 |  
 01591 |          template <typename T> 
 01592 |          inline T shl(const T v0, const T v1) 
 01593 |          { 
 01594 |             const typename details::number_type<T>::type num_type; 
 01595 |             return shl_impl(v0, v1, num_type); 
 01596 |          } 
 01597 |  
 01598 |          template <typename T> 
 01599 |          inline T and_opr(const T v0, const T v1) 
 01600 |          { 
 01601 |             const typename details::number_type<T>::type num_type; 
 01602 |             return and_impl(v0, v1, num_type); 
 01603 |          } 
 01604 |  
 01605 |          template <typename T> 
 01606 |          inline T nand_opr(const T v0, const T v1) 
 01607 |          { 
 01608 |             const typename details::number_type<T>::type num_type; 
 01609 |             return nand_impl(v0, v1, num_type); 
 01610 |          } 
 01611 |  
 01612 |          template <typename T> 
 01613 |          inline T or_opr(const T v0, const T v1) 
 01614 |          { 
 01615 |             const typename details::number_type<T>::type num_type; 
 01616 |             return or_impl(v0, v1, num_type); 
 01617 |          } 
 01618 |  
 01619 |          template <typename T> 
 01620 |          inline T nor_opr(const T v0, const T v1) 
 01621 |          { 
 01622 |             const typename details::number_type<T>::type num_type; 
 01623 |             return nor_impl(v0, v1, num_type); 
 01624 |          } 
 01625 |  
 01626 |          template <typename T> 
 01627 |          inline T xor_opr(const T v0, const T v1) 
 01628 |          { 
 01629 |             const typename details::number_type<T>::type num_type; 
 01630 |             return xor_impl(v0, v1, num_type); 
 01631 |          } 
 01632 |  
 01633 |          template <typename T> 
 01634 |          inline T xnor_opr(const T v0, const T v1) 
 01635 |          { 
 01636 |             const typename details::number_type<T>::type num_type; 
 01637 |             return xnor_impl(v0, v1, num_type); 
 01638 |          } 
 01639 |  
 01640 |          template <typename T> 
 01641 |          inline bool is_integer(const T v) 
 01642 |          { 
 01643 |             const typename details::number_type<T>::type num_type; 
 01644 |             return is_integer_impl(v, num_type); 
 01645 |          } 
 01646 |  
 01647 |          template <typename T, unsigned int N> 
 01648 |          struct fast_exp 
 01649 |          { 
 01650 |             static inline T result(T v) 
 01651 |             { 
 01652 |                unsigned int k = N; 
 01653 |                T l = T(1); 
 01654 |  
 01655 |                while (k) 
 01656 |                { 
 01657 |                   if (1 == (k % 2)) 
 01658 |                   { 
 01659 |                      l *= v; 
 01660 |                      --k; 
 01661 |                   } 
 01662 |  
 01663 |                   v *= v; 
 01664 |                   k /= 2; 
 01665 |                } 
 01666 |  
 01667 |                return l; 
 01668 |             } 
 01669 |          }; 
 01670 |  
 01671 |          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; } }; 
 01672 |          template <typename T> struct fast_exp<T, 9> { static inline T result(const T v) { return fast_exp<T,8>::result(v) * v; } }; 
 01673 |          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; } }; 
 01674 |          template <typename T> struct fast_exp<T, 7> { static inline T result(const T v) { return fast_exp<T,6>::result(v) * v; } }; 
 01675 |          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; } }; 
 01676 |          template <typename T> struct fast_exp<T, 5> { static inline T result(const T v) { return fast_exp<T,4>::result(v) * v; } }; 
 01677 |          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; } }; 
 01678 |          template <typename T> struct fast_exp<T, 3> { static inline T result(const T v) { return v * v * v; } }; 
 01679 |          template <typename T> struct fast_exp<T, 2> { static inline T result(const T v) { return v * v;     } }; 
 01680 |          template <typename T> struct fast_exp<T, 1> { static inline T result(const T v) { return v;         } }; 
 01681 |          template <typename T> struct fast_exp<T, 0> { static inline T result(const T  ) { return T(1);      } }; 
 01682 |  
 01683 |          #define exprtk_define_unary_function(FunctionName)        \ 
 01684 |          template <typename T>                                     \ 
 01685 |          inline T FunctionName (const T v)                         \ 
 01686 |          {                                                         \ 
 01687 |             const typename details::number_type<T>::type num_type; \ 
 01688 |             return  FunctionName##_impl(v,num_type);               \ 
 01689 |          }                                                         \ 
 01690 |  
 01691 |          exprtk_define_unary_function(abs  ) 
 01692 |          exprtk_define_unary_function(acos ) 
 01693 |          exprtk_define_unary_function(acosh) 
 01694 |          exprtk_define_unary_function(asin ) 
 01695 |          exprtk_define_unary_function(asinh) 
 01696 |          exprtk_define_unary_function(atan ) 
 01697 |          exprtk_define_unary_function(atanh) 
 01698 |          exprtk_define_unary_function(ceil ) 
 01699 |          exprtk_define_unary_function(cos  ) 
 01700 |          exprtk_define_unary_function(cosh ) 
 01701 |          exprtk_define_unary_function(exp  ) 
 01702 |          exprtk_define_unary_function(expm1) 
 01703 |          exprtk_define_unary_function(floor) 
 01704 |          exprtk_define_unary_function(log  ) 
 01705 |          exprtk_define_unary_function(log10) 
 01706 |          exprtk_define_unary_function(log2 ) 
 01707 |          exprtk_define_unary_function(log1p) 
 01708 |          exprtk_define_unary_function(neg  ) 
 01709 |          exprtk_define_unary_function(pos  ) 
 01710 |          exprtk_define_unary_function(round) 
 01711 |          exprtk_define_unary_function(sin  ) 
 01712 |          exprtk_define_unary_function(sinc ) 
 01713 |          exprtk_define_unary_function(sinh ) 
 01714 |          exprtk_define_unary_function(sqrt ) 
 01715 |          exprtk_define_unary_function(tan  ) 
 01716 |          exprtk_define_unary_function(tanh ) 
 01717 |          exprtk_define_unary_function(cot  ) 
 01718 |          exprtk_define_unary_function(sec  ) 
 01719 |          exprtk_define_unary_function(csc  ) 
 01720 |          exprtk_define_unary_function(r2d  ) 
 01721 |          exprtk_define_unary_function(d2r  ) 
 01722 |          exprtk_define_unary_function(d2g  ) 
 01723 |          exprtk_define_unary_function(g2d  ) 
 01724 |          exprtk_define_unary_function(notl ) 
 01725 |          exprtk_define_unary_function(sgn  ) 
 01726 |          exprtk_define_unary_function(erf  ) 
 01727 |          exprtk_define_unary_function(erfc ) 
 01728 |          exprtk_define_unary_function(ncdf ) 
 01729 |          exprtk_define_unary_function(frac ) 
 01730 |          exprtk_define_unary_function(trunc) 
 01731 |          #undef exprtk_define_unary_function 
 01732 |       } 
 01733 |  
 01734 |       template <typename T> 
 01735 |       inline T compute_pow10(T d, const int exponent) 
 01736 |       { 
 01737 |          static const double fract10[] = 
 01738 |          { 
 01739 |             0.0, 
 01740 |             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, 
 01741 |             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, 
 01742 |             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, 
 01743 |             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, 
 01744 |             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, 
 01745 |             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, 
 01746 |             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, 
 01747 |             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, 
 01748 |             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, 
 01749 |             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, 
 01750 |             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, 
 01751 |             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, 
 01752 |             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, 
 01753 |             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, 
 01754 |             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, 
 01755 |             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, 
 01756 |             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, 
 01757 |             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, 
 01758 |             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, 
 01759 |             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, 
 01760 |             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, 
 01761 |             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, 
 01762 |             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, 
 01763 |             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, 
 01764 |             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, 
 01765 |             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, 
 01766 |             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, 
 01767 |             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, 
 01768 |             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, 
 01769 |             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, 
 01770 |             1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308 
 01771 |          }; 
 01772 |  
 01773 |          static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double)); 
 01774 |  
 01775 |          const int e = std::abs(exponent); 
 01776 |  
 01777 |          if (exponent >= std::numeric_limits<T>::min_exponent10) 
 01778 |          { 
 01779 |             if (e < fract10_size) 
 01780 |             { 
 01781 |                if (exponent > 0) 
 01782 |                   return T(d * fract10[e]); 
 01783 |                else 
 01784 |                   return T(d / fract10[e]); 
 01785 |             } 
 01786 |             else 
 01787 |                return T(d * std::pow(10.0, 10.0 * exponent)); 
 01788 |          } 
 01789 |          else 
 01790 |          { 
 01791 |                      d /= T(fract10[           -std::numeric_limits<T>::min_exponent10]); 
 01792 |             return T(d /    fract10[-exponent + std::numeric_limits<T>::min_exponent10]); 
 01793 |          } 
 01794 |       } 
 01795 |  
 01796 |       template <typename Iterator, typename T> 
 01797 |       inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result) 
 01798 |       { 
 01799 |          if (itr == end) 
 01800 |             return false; 
 01801 |  
 01802 |          const bool negative = ('-' == (*itr)); 
 01803 |  
 01804 |          if (negative || ('+' == (*itr))) 
 01805 |          { 
 01806 |             if (end == ++itr) 
 01807 |                return false; 
 01808 |          } 
 01809 |  
 01810 |          static const uchar_t zero = static_cast<uchar_t>('0'); 
 01811 |  
 01812 |          while ((end != itr) && (zero == (*itr))) ++itr; 
 01813 |  
 01814 |          bool return_result = true; 
 01815 |          unsigned int digit = 0; 
 01816 |          const std::size_t length = static_cast<std::size_t>(std::distance(itr,end)); 
 01817 |  
 01818 |          if (length <= 4) 
 01819 |          { 
 01820 |             switch (length) 
 01821 |             { 
 01822 |                #ifdef exprtk_use_lut 
 01823 |  
 01824 |                #define exprtk_process_digit                          \ 
 01825 |                if ((digit = details::digit_table[(int)*itr++]) < 10) \ 
 01826 |                   result = result * 10 + (digit);                    \ 
 01827 |                else                                                  \ 
 01828 |                {                                                     \ 
 01829 |                   return_result = false;                             \ 
 01830 |                   break;                                             \ 
 01831 |                }                                                     \ 
 01832 |                exprtk_fallthrough                                    \ 
 01833 |  
 01834 |                #else 
 01835 |  
 01836 |                #define exprtk_process_digit        \ 
 01837 |                if ((digit = (*itr++ - zero)) < 10) \ 
 01838 |                   result = result * T(10) + digit; \ 
 01839 |                else                                \ 
 01840 |                {                                   \ 
 01841 |                   return_result = false;           \ 
 01842 |                   break;                           \ 
 01843 |                }                                   \ 
 01844 |                exprtk_fallthrough                  \ 
 01845 |  
 01846 |                #endif 
 01847 |  
 01848 |                case 4 : exprtk_process_digit 
 01849 |                case 3 : exprtk_process_digit 
 01850 |                case 2 : exprtk_process_digit 
 01851 |                case 1 : if ((digit = (*itr - zero))>= 10) 
 01852 |                         { 
 01853 |                            digit = 0; 
 01854 |                            return_result = false; 
 01855 |                         } 
 01856 |  
 01857 |                #undef exprtk_process_digit 
 01858 |             } 
 01859 |          } 
 01860 |          else 
 01861 |             return_result = false; 
 01862 |  
 01863 |          if (length && return_result) 
 01864 |          { 
 01865 |             result = result * 10 + static_cast<T>(digit); 
 01866 |             ++itr; 
 01867 |          } 
 01868 |  
 01869 |          result = negative ? -result : result; 
 01870 |          return return_result; 
 01871 |       } 
 01872 |  
 01873 |       template <typename Iterator, typename T> 
 01874 |       static inline bool parse_nan(Iterator& itr, const Iterator end, T& t) 
 01875 |       { 
 01876 |          typedef typename std::iterator_traits<Iterator>::value_type type; 
 01877 |  
 01878 |          static const std::size_t nan_length = 3; 
 01879 |  
 01880 |          if (std::distance(itr,end) != static_cast<int>(nan_length)) 
 01881 |             return false; 
 01882 |  
 01883 |          if (static_cast<type>('n') == (*itr)) 
 01884 |          { 
 01885 |             if ( 
 01886 |                  (static_cast<type>('a') != *(itr + 1)) || 
 01887 |                  (static_cast<type>('n') != *(itr + 2)) 
 01888 |                ) 
 01889 |             { 
 01890 |                return false; 
 01891 |             } 
 01892 |          } 
 01893 |          else if ( 
 01894 |                    (static_cast<type>('A') != *(itr + 1)) || 
 01895 |                    (static_cast<type>('N') != *(itr + 2)) 
 01896 |                  ) 
 01897 |          { 
 01898 |             return false; 
 01899 |          } 
 01900 |  
 01901 |          t = std::numeric_limits<T>::quiet_NaN(); 
 01902 |  
 01903 |          return true; 
 01904 |       } 
 01905 |  
 01906 |       template <typename Iterator, typename T> 
 01907 |       static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, const bool negative) 
 01908 |       { 
 01909 |          static const char_t inf_uc[] = "INFINITY" 
 01910 |          static const char_t inf_lc[] = "infinity" 
 01911 |          static const std::size_t inf_length = 8; 
 01912 |  
 01913 |          const std::size_t length = static_cast<std::size_t>(std::distance(itr,end)); 
 01914 |  
 01915 |          if ((3 != length) && (inf_length != length)) 
 01916 |             return false; 
 01917 |  
 01918 |          char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc; 
 01919 |  
 01920 |          while (end != itr) 
 01921 |          { 
 01922 |             if (*inf_itr == static_cast<char_t>(*itr)) 
 01923 |             { 
 01924 |                ++itr; 
 01925 |                ++inf_itr; 
 01926 |                continue; 
 01927 |             } 
 01928 |             else 
 01929 |                return false; 
 01930 |          } 
 01931 |  
 01932 |          if (negative) 
 01933 |             t = -std::numeric_limits<T>::infinity(); 
 01934 |          else 
 01935 |             t =  std::numeric_limits<T>::infinity(); 
 01936 |  
 01937 |          return true; 
 01938 |       } 
 01939 |  
 01940 |       template <typename T> 
 01941 |       inline bool valid_exponent(const int exponent, numeric::details::real_type_tag) 
 01942 |       { 
 01943 |          using namespace details::numeric; 
 01944 |          return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp); 
 01945 |       } 
 01946 |  
 01947 |       template <typename Iterator, typename T> 
 01948 |       inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t, numeric::details::real_type_tag) 
 01949 |       { 
 01950 |          if (end == itr_external) return false; 
 01951 |  
 01952 |          Iterator itr = itr_external; 
 01953 |  
 01954 |          T d = T(0); 
 01955 |  
 01956 |          const bool negative = ('-' == (*itr)); 
 01957 |  
 01958 |          if (negative || '+' == (*itr)) 
 01959 |          { 
 01960 |             if (end == ++itr) 
 01961 |                return false; 
 01962 |          } 
 01963 |  
 01964 |          bool instate = false; 
 01965 |  
 01966 |          static const char_t zero = static_cast<uchar_t>('0'); 
 01967 |  
 01968 |          #define parse_digit_1(d)          \ 
 01969 |          if ((digit = (*itr - zero)) < 10) \ 
 01970 |             { d = d * T(10) + digit; }     \ 
 01971 |          else                              \ 
 01972 |             { break; }                     \ 
 01973 |          if (end == ++itr) break;          \ 
 01974 |  
 01975 |          #define parse_digit_2(d)          \ 
 01976 |          if ((digit = (*itr - zero)) < 10) \ 
 01977 |             { d = d * T(10) + digit; }     \ 
 01978 |          else                              \ 
 01979 |             { break; }                     \ 
 01980 |             ++itr;                         \ 
 01981 |  
 01982 |          if ('.' != (*itr)) 
 01983 |          { 
 01984 |             const Iterator curr = itr; 
 01985 |  
 01986 |             while ((end != itr) && (zero == (*itr))) ++itr; 
 01987 |  
 01988 |             while (end != itr) 
 01989 |             { 
 01990 |                unsigned int digit; 
 01991 |                parse_digit_1(d) 
 01992 |                parse_digit_1(d) 
 01993 |                parse_digit_2(d) 
 01994 |             } 
 01995 |  
 01996 |             if (curr != itr) instate = true; 
 01997 |          } 
 01998 |  
 01999 |          int exponent = 0; 
 02000 |  
 02001 |          if (end != itr) 
 02002 |          { 
 02003 |             if ('.' == (*itr)) 
 02004 |             { 
 02005 |                const Iterator curr = ++itr; 
 02006 |                T tmp_d = T(0); 
 02007 |  
 02008 |                while (end != itr) 
 02009 |                { 
 02010 |                   unsigned int digit; 
 02011 |                   parse_digit_1(tmp_d) 
 02012 |                   parse_digit_1(tmp_d) 
 02013 |                   parse_digit_2(tmp_d) 
 02014 |                } 
 02015 |  
 02016 |                if (curr != itr) 
 02017 |                { 
 02018 |                   instate = true; 
 02019 |  
 02020 |                   const int frac_exponent = static_cast<int>(-std::distance(curr, itr)); 
 02021 |  
 02022 |                   if (!valid_exponent<T>(frac_exponent, numeric::details::real_type_tag())) 
 02023 |                      return false; 
 02024 |  
 02025 |                   d += compute_pow10(tmp_d, frac_exponent); 
 02026 |                } 
 02027 |  
 02028 |                #undef parse_digit_1 
 02029 |                #undef parse_digit_2 
 02030 |             } 
 02031 |  
 02032 |             if (end != itr) 
 02033 |             { 
 02034 |                typename std::iterator_traits<Iterator>::value_type c = (*itr); 
 02035 |  
 02036 |                if (('e' == c) || ('E' == c)) 
 02037 |                { 
 02038 |                   int exp = 0; 
 02039 |  
 02040 |                   if (!details::string_to_type_converter_impl_ref(++itr, end, exp)) 
 02041 |                   { 
 02042 |                      if (end == itr) 
 02043 |                         return false; 
 02044 |                      else 
 02045 |                         c = (*itr); 
 02046 |                   } 
 02047 |  
 02048 |                   exponent += exp; 
 02049 |                } 
 02050 |  
 02051 |                if (end != itr) 
 02052 |                { 
 02053 |                   if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c)) 
 02054 |                      ++itr; 
 02055 |                   else if ('#' == c) 
 02056 |                   { 
 02057 |                      if (end == ++itr) 
 02058 |                         return false; 
 02059 |                      else if (('I' <= (*itr)) && ((*itr) <= 'n')) 
 02060 |                      { 
 02061 |                         if (('i' == (*itr)) || ('I' == (*itr))) 
 02062 |                         { 
 02063 |                            return parse_inf(itr, end, t, negative); 
 02064 |                         } 
 02065 |                         else if (('n' == (*itr)) || ('N' == (*itr))) 
 02066 |                         { 
 02067 |                            return parse_nan(itr, end, t); 
 02068 |                         } 
 02069 |                         else 
 02070 |                            return false; 
 02071 |                      } 
 02072 |                      else 
 02073 |                         return false; 
 02074 |                   } 
 02075 |                   else if (('I' <= (*itr)) && ((*itr) <= 'n')) 
 02076 |                   { 
 02077 |                      if (('i' == (*itr)) || ('I' == (*itr))) 
 02078 |                      { 
 02079 |                         return parse_inf(itr, end, t, negative); 
 02080 |                      } 
 02081 |                      else if (('n' == (*itr)) || ('N' == (*itr))) 
 02082 |                      { 
 02083 |                         return parse_nan(itr, end, t); 
 02084 |                      } 
 02085 |                      else 
 02086 |                         return false; 
 02087 |                   } 
 02088 |                   else 
 02089 |                      return false; 
 02090 |                } 
 02091 |             } 
 02092 |          } 
 02093 |  
 02094 |          if ((end != itr) || (!instate)) 
 02095 |             return false; 
 02096 |          else if (!valid_exponent<T>(exponent, numeric::details::real_type_tag())) 
 02097 |             return false; 
 02098 |          else if (exponent) 
 02099 |             d = compute_pow10(d,exponent); 
 02100 |  
 02101 |          t = static_cast<T>((negative) ? -d : d); 
 02102 |          return true; 
 02103 |       } 
 02104 |  
 02105 |       template <typename T> 
 02106 |       inline bool string_to_real(const std::string& s, T& t) 
 02107 |       { 
 02108 |          const typename numeric::details::number_type<T>::type num_type; 
 02109 |  
 02110 |          char_cptr begin = s.data(); 
 02111 |          char_cptr end   = s.data() + s.size(); 
 02112 |  
 02113 |          return string_to_real(begin, end, t, num_type); 
 02114 |       } 
 02115 |  
 02116 |       template <typename T> 
 02117 |       struct functor_t 
 02118 |       { 
 02119 |          /* 
 02120 |             Note: The following definitions for Type, may require tweaking 
 02121 |                   based on the compiler and target architecture. The benchmark 
 02122 |                   should provide enough information to make the right choice. 
 02123 |          */ 
 02124 |          //typedef T Type; 
 02125 |          //typedef const T Type; 
 02126 |          typedef const T& Type; 
 02127 |          typedef       T& RefType; 
 02128 |          typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3); 
 02129 |          typedef T (*tfunc_t)(Type t0, Type t1, Type t2); 
 02130 |          typedef T (*bfunc_t)(Type t0, Type t1); 
 02131 |          typedef T (*ufunc_t)(Type t0); 
 02132 |       }; 
 02133 |  
 02134 |    } // namespace details 
 02135 |  
 02136 |    struct loop_runtime_check 
 02137 |    { 
 02138 |       enum loop_types 
 02139 |       { 
 02140 |          e_invalid           = 0, 
 02141 |          e_for_loop          = 1, 
 02142 |          e_while_loop        = 2, 
 02143 |          e_repeat_until_loop = 4, 
 02144 |          e_all_loops         = 7 
 02145 |       }; 
 02146 |  
 02147 |       enum violation_type 
 02148 |       { 
 02149 |           e_unknown         = 0, 
 02150 |           e_iteration_count = 1, 
 02151 |           e_timeout         = 2 
 02152 |       }; 
 02153 |  
 02154 |       loop_types loop_set; 
 02155 |  
 02156 |       loop_runtime_check() 
 02157 |       : loop_set(e_invalid) 
 02158 |       , max_loop_iterations(0) 
 02159 |       {} 
 02160 |  
 02161 |       details::_uint64_t max_loop_iterations; 
 02162 |  
 02163 |       struct violation_context 
 02164 |       { 
 02165 |          loop_types loop; 
 02166 |          violation_type violation; 
 02167 |          details::_uint64_t iteration_count; 
 02168 |       }; 
 02169 |  
 02170 |       virtual bool check() 
 02171 |       { 
 02172 |          return true; 
 02173 |       } 
 02174 |  
 02175 |       virtual void handle_runtime_violation(const violation_context&) 
 02176 |       { 
 02177 |          throw std::runtime_error("ExprTk Loop runtime violation."); 
 02178 |       } 
 02179 |  
 02180 |       virtual ~loop_runtime_check() 
 02181 |       {} 
 02182 |    }; 
 02183 |  
 02184 |    typedef loop_runtime_check* loop_runtime_check_ptr; 
 02185 |  
 02186 |    struct vector_access_runtime_check 
 02187 |    { 
 02188 |       struct violation_context 
 02189 |       { 
 02190 |          void* base_ptr; 
 02191 |          void* end_ptr; 
 02192 |          void* access_ptr; 
 02193 |          std::size_t type_size; 
 02194 |       }; 
 02195 |  
 02196 |       virtual ~vector_access_runtime_check() 
 02197 |       {} 
 02198 |  
 02199 |       virtual bool handle_runtime_violation(violation_context& /*context*/) 
 02200 |       { 
 02201 |          throw std::runtime_error("ExprTk runtime vector access violation."); 
 02202 |          #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 02203 |          return false; 
 02204 |          #endif 
 02205 |       } 
 02206 |    }; 
 02207 |  
 02208 |    typedef vector_access_runtime_check* vector_access_runtime_check_ptr; 
 02209 |  
 02210 |    struct assert_check 
 02211 |    { 
 02212 |       struct assert_context 
 02213 |       { 
 02214 |          std::string condition; 
 02215 |          std::string message; 
 02216 |          std::string id; 
 02217 |          std::size_t offet; 
 02218 |       }; 
 02219 |  
 02220 |       virtual ~assert_check() 
 02221 |       {} 
 02222 |  
 02223 |       virtual void handle_assert(const assert_context& /*context*/) 
 02224 |       { 
 02225 |       } 
 02226 |    }; 
 02227 |  
 02228 |    typedef assert_check* assert_check_ptr; 
 02229 |  
 02230 |    struct compilation_check 
 02231 |    { 
 02232 |       struct compilation_context 
 02233 |       { 
 02234 |          std::string error_message; 
 02235 |       }; 
 02236 |  
 02237 |       virtual bool continue_compilation(compilation_context& /*context*/) = 0; 
 02238 |  
 02239 |       virtual ~compilation_check() 
 02240 |       {} 
 02241 |    }; 
 02242 |  
 02243 |    typedef compilation_check* compilation_check_ptr; 
 02244 |  
 02245 |    namespace lexer 
 02246 |    { 
 02247 |       struct token 
 02248 |       { 
 02249 |          enum token_type 
 02250 |          { 
 02251 |             e_none        =   0, e_error       =   1, e_err_symbol  =   2, 
 02252 |             e_err_number  =   3, e_err_string  =   4, e_err_sfunc   =   5, 
 02253 |             e_eof         =   6, e_number      =   7, e_symbol      =   8, 
 02254 |             e_string      =   9, e_assign      =  10, e_addass      =  11, 
 02255 |             e_subass      =  12, e_mulass      =  13, e_divass      =  14, 
 02256 |             e_modass      =  15, e_shr         =  16, e_shl         =  17, 
 02257 |             e_lte         =  18, e_ne          =  19, e_gte         =  20, 
 02258 |             e_swap        =  21, e_lt          = '<', e_gt          = '>', 
 02259 |             e_eq          = '=', e_rbracket    = ')', e_lbracket    = '(', 
 02260 |             e_rsqrbracket = ']', e_lsqrbracket = '[', e_rcrlbracket = '}', 
 02261 |             e_lcrlbracket = '{', e_comma       = ',', e_add         = '+', 
 02262 |             e_sub         = '-', e_div         = '/', e_mul         = '*', 
 02263 |             e_mod         = '%', e_pow         = '^', e_colon       = ':', 
 02264 |             e_ternary     = '?' 
 02265 |          }; 
 02266 |  
 02267 |          token() 
 02268 |          : type(e_none) 
 02269 |          , value("") 
 02270 |          , position(std::numeric_limits<std::size_t>::max()) 
 02271 |          {} 
 02272 |  
 02273 |          void clear() 
 02274 |          { 
 02275 |             type     = e_none; 
 02276 |             value    = "" 
 02277 |             position = std::numeric_limits<std::size_t>::max(); 
 02278 |          } 
 02279 |  
 02280 |          template <typename Iterator> 
 02281 |          inline token& set_operator(const token_type tt, 
 02282 |                                     const Iterator begin, const Iterator end, 
 02283 |                                     const Iterator base_begin = Iterator(0)) 
 02284 |          { 
 02285 |             type = tt; 
 02286 |             value.assign(begin,end); 
 02287 |             if (base_begin) 
 02288 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02289 |             return (*this); 
 02290 |          } 
 02291 |  
 02292 |          template <typename Iterator> 
 02293 |          inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0)) 
 02294 |          { 
 02295 |             type = e_symbol; 
 02296 |             value.assign(begin,end); 
 02297 |             if (base_begin) 
 02298 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02299 |             return (*this); 
 02300 |          } 
 02301 |  
 02302 |          template <typename Iterator> 
 02303 |          inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0)) 
 02304 |          { 
 02305 |             type = e_number; 
 02306 |             value.assign(begin,end); 
 02307 |             if (base_begin) 
 02308 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02309 |             return (*this); 
 02310 |          } 
 02311 |  
 02312 |          template <typename Iterator> 
 02313 |          inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0)) 
 02314 |          { 
 02315 |             type = e_string; 
 02316 |             value.assign(begin,end); 
 02317 |             if (base_begin) 
 02318 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02319 |             return (*this); 
 02320 |          } 
 02321 |  
 02322 |          inline token& set_string(const std::string& s, const std::size_t p) 
 02323 |          { 
 02324 |             type     = e_string; 
 02325 |             value    = s; 
 02326 |             position = p; 
 02327 |             return (*this); 
 02328 |          } 
 02329 |  
 02330 |          template <typename Iterator> 
 02331 |          inline token& set_error(const token_type et, 
 02332 |                                  const Iterator begin, const Iterator end, 
 02333 |                                  const Iterator base_begin = Iterator(0)) 
 02334 |          { 
 02335 |             if ( 
 02336 |                  (e_error      == et) || 
 02337 |                  (e_err_symbol == et) || 
 02338 |                  (e_err_number == et) || 
 02339 |                  (e_err_string == et) || 
 02340 |                  (e_err_sfunc  == et) 
 02341 |                ) 
 02342 |             { 
 02343 |                type = et; 
 02344 |             } 
 02345 |             else 
 02346 |                type = e_error; 
 02347 |  
 02348 |             value.assign(begin,end); 
 02349 |  
 02350 |             if (base_begin) 
 02351 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02352 |  
 02353 |             return (*this); 
 02354 |          } 
 02355 |  
 02356 |          static inline std::string to_str(token_type t) 
 02357 |          { 
 02358 |             switch (t) 
 02359 |             { 
 02360 |                case e_none        : return "NONE" 
 02361 |                case e_error       : return "ERROR" 
 02362 |                case e_err_symbol  : return "ERROR_SYMBOL" 
 02363 |                case e_err_number  : return "ERROR_NUMBER" 
 02364 |                case e_err_string  : return "ERROR_STRING" 
 02365 |                case e_eof         : return "EOF" 
 02366 |                case e_number      : return "NUMBER" 
 02367 |                case e_symbol      : return "SYMBOL" 
 02368 |                case e_string      : return "STRING" 
 02369 |                case e_assign      : return ":=" 
 02370 |                case e_addass      : return "+=" 
 02371 |                case e_subass      : return "-=" 
 02372 |                case e_mulass      : return "*=" 
 02373 |                case e_divass      : return "/=" 
 02374 |                case e_modass      : return "%=" 
 02375 |                case e_shr         : return ">>" 
 02376 |                case e_shl         : return "<<" 
 02377 |                case e_lte         : return "<=" 
 02378 |                case e_ne          : return "!=" 
 02379 |                case e_gte         : return ">=" 
 02380 |                case e_lt          : return "<" 
 02381 |                case e_gt          : return ">" 
 02382 |                case e_eq          : return "=" 
 02383 |                case e_rbracket    : return ")" 
 02384 |                case e_lbracket    : return "(" 
 02385 |                case e_rsqrbracket : return "]" 
 02386 |                case e_lsqrbracket : return "[" 
 02387 |                case e_rcrlbracket : return "}" 
 02388 |                case e_lcrlbracket : return "{" 
 02389 |                case e_comma       : return "," 
 02390 |                case e_add         : return "+" 
 02391 |                case e_sub         : return "-" 
 02392 |                case e_div         : return "/" 
 02393 |                case e_mul         : return "*" 
 02394 |                case e_mod         : return "%" 
 02395 |                case e_pow         : return "^" 
 02396 |                case e_colon       : return ":" 
 02397 |                case e_ternary     : return "?" 
 02398 |                case e_swap        : return "<=>" 
 02399 |                default            : return "UNKNOWN" 
 02400 |             } 
 02401 |          } 
 02402 |  
 02403 |          static inline std::string seperator_to_str(const token_type t) 
 02404 |          { 
 02405 |             switch (t) 
 02406 |             { 
 02407 |                case e_comma : return "," 
 02408 |                case e_colon : return ":" 
 02409 |                case e_eof   : return "" 
 02410 |                default      : return "UNKNOWN" 
 02411 |             } 
 02412 |  
 02413 |             #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 02414 |             return "UNKNOWN" 
 02415 |             #endif 
 02416 |          } 
 02417 |  
 02418 |          inline bool is_error() const 
 02419 |          { 
 02420 |             return ( 
 02421 |                      (e_error      == type) || 
 02422 |                      (e_err_symbol == type) || 
 02423 |                      (e_err_number == type) || 
 02424 |                      (e_err_string == type) || 
 02425 |                      (e_err_sfunc  == type) 
 02426 |                    ); 
 02427 |          } 
 02428 |  
 02429 |          token_type type; 
 02430 |          std::string value; 
 02431 |          std::size_t position; 
 02432 |       }; 
 02433 |  
 02434 |       class generator 
 02435 |       { 
 02436 |       public: 
 02437 |  
 02438 |          typedef token token_t; 
 02439 |          typedef std::vector<token_t> token_list_t; 
 02440 |          typedef token_list_t::iterator token_list_itr_t; 
 02441 |          typedef details::char_t char_t; 
 02442 |  
 02443 |          generator() 
 02444 |          : base_itr_(0) 
 02445 |          , s_itr_   (0) 
 02446 |          , s_end_   (0) 
 02447 |          { 
 02448 |             clear(); 
 02449 |          } 
 02450 |  
 02451 |          inline void clear() 
 02452 |          { 
 02453 |             base_itr_ = 0; 
 02454 |             s_itr_    = 0; 
 02455 |             s_end_    = 0; 
 02456 |             token_list_.clear(); 
 02457 |             token_itr_ = token_list_.end(); 
 02458 |             store_token_itr_ = token_list_.end(); 
 02459 |          } 
 02460 |  
 02461 |          inline bool process(const std::string& str) 
 02462 |          { 
 02463 |             base_itr_ = str.data(); 
 02464 |             s_itr_    = str.data(); 
 02465 |             s_end_    = str.data() + str.size(); 
 02466 |  
 02467 |             eof_token_.set_operator(token_t::e_eof, s_end_, s_end_, base_itr_); 
 02468 |             token_list_.clear(); 
 02469 |  
 02470 |             while (!is_end(s_itr_)) 
 02471 |             { 
 02472 |                scan_token(); 
 02473 |  
 02474 |                if (!token_list_.empty() && token_list_.back().is_error()) 
 02475 |                   return false; 
 02476 |             } 
 02477 |  
 02478 |             return true; 
 02479 |          } 
 02480 |  
 02481 |          inline bool empty() const 
 02482 |          { 
 02483 |             return token_list_.empty(); 
 02484 |          } 
 02485 |  
 02486 |          inline std::size_t size() const 
 02487 |          { 
 02488 |             return token_list_.size(); 
 02489 |          } 
 02490 |  
 02491 |          inline void begin() 
 02492 |          { 
 02493 |             token_itr_ = token_list_.begin(); 
 02494 |             store_token_itr_ = token_list_.begin(); 
 02495 |          } 
 02496 |  
 02497 |          inline void store() 
 02498 |          { 
 02499 |             store_token_itr_ = token_itr_; 
 02500 |          } 
 02501 |  
 02502 |          inline void restore() 
 02503 |          { 
 02504 |             token_itr_ = store_token_itr_; 
 02505 |          } 
 02506 |  
 02507 |          inline token_t& next_token() 
 02508 |          { 
 02509 |             if (token_list_.end() != token_itr_) 
 02510 |             { 
 02511 |                return *token_itr_++; 
 02512 |             } 
 02513 |             else 
 02514 |                return eof_token_; 
 02515 |          } 
 02516 |  
 02517 |          inline token_t& peek_next_token() 
 02518 |          { 
 02519 |             if (token_list_.end() != token_itr_) 
 02520 |             { 
 02521 |                return *token_itr_; 
 02522 |             } 
 02523 |             else 
 02524 |                return eof_token_; 
 02525 |          } 
 02526 |  
 02527 |          inline token_t& operator[](const std::size_t& index) 
 02528 |          { 
 02529 |             if (index < token_list_.size()) 
 02530 |             { 
 02531 |                return token_list_[index]; 
 02532 |             } 
 02533 |             else 
 02534 |                return eof_token_; 
 02535 |          } 
 02536 |  
 02537 |          inline token_t operator[](const std::size_t& index) const 
 02538 |          { 
 02539 |             if (index < token_list_.size()) 
 02540 |             { 
 02541 |                return token_list_[index]; 
 02542 |             } 
 02543 |             else 
 02544 |                return eof_token_; 
 02545 |          } 
 02546 |  
 02547 |          inline bool finished() const 
 02548 |          { 
 02549 |             return (token_list_.end() == token_itr_); 
 02550 |          } 
 02551 |  
 02552 |          inline void insert_front(token_t::token_type tk_type) 
 02553 |          { 
 02554 |             if ( 
 02555 |                  !token_list_.empty() && 
 02556 |                  (token_list_.end() != token_itr_) 
 02557 |                ) 
 02558 |             { 
 02559 |                token_t t = *token_itr_; 
 02560 |  
 02561 |                t.type     = tk_type; 
 02562 |                token_itr_ = token_list_.insert(token_itr_,t); 
 02563 |             } 
 02564 |          } 
 02565 |  
 02566 |          inline std::string substr(const std::size_t& begin, const std::size_t& end) const 
 02567 |          { 
 02568 |             const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_; 
 02569 |             const details::char_cptr end_itr   = ((base_itr_ + end  ) < s_end_) ? (base_itr_ + end  ) : s_end_; 
 02570 |  
 02571 |             return std::string(begin_itr,end_itr); 
 02572 |          } 
 02573 |  
 02574 |          inline std::string remaining() const 
 02575 |          { 
 02576 |             if (finished()) 
 02577 |                return "" 
 02578 |             else if (token_list_.begin() != token_itr_) 
 02579 |                return std::string(base_itr_ + (token_itr_ - 1)->position, s_end_); 
 02580 |             else 
 02581 |                return std::string(base_itr_ + token_itr_->position, s_end_); 
 02582 |          } 
 02583 |  
 02584 |       private: 
 02585 |  
 02586 |          inline bool is_end(details::char_cptr itr) const 
 02587 |          { 
 02588 |             return (s_end_ == itr); 
 02589 |          } 
 02590 |  
 02591 |          #ifndef exprtk_disable_comments 
 02592 |          inline bool is_comment_start(details::char_cptr itr) const 
 02593 |          { 
 02594 |             const char_t c0 = *(itr + 0); 
 02595 |             const char_t c1 = *(itr + 1); 
 02596 |  
 02597 |             if ('#' == c0) 
 02598 |                return true; 
 02599 |             else if (!is_end(itr + 1)) 
 02600 |             { 
 02601 |                if (('/' == c0) && ('/' == c1)) return true; 
 02602 |                if (('/' == c0) && ('*' == c1)) return true; 
 02603 |             } 
 02604 |             return false; 
 02605 |          } 
 02606 |          #else 
 02607 |          inline bool is_comment_start(details::char_cptr) const 
 02608 |          { 
 02609 |             return false; 
 02610 |          } 
 02611 |          #endif 
 02612 |  
 02613 |          inline void skip_whitespace() 
 02614 |          { 
 02615 |             while (!is_end(s_itr_) && details::is_whitespace(*s_itr_)) 
 02616 |             { 
 02617 |                ++s_itr_; 
 02618 |             } 
 02619 |          } 
 02620 |  
 02621 |          inline void skip_comments() 
 02622 |          { 
 02623 |             #ifndef exprtk_disable_comments 
 02624 |             // The following comment styles are supported: 
 02625 |             // 1. // .... \n 
 02626 |             // 2. #  .... \n 
 02627 |             // 3. /* .... */ 
 02628 |             struct test 
 02629 |             { 
 02630 |                static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr) 
 02631 |                { 
 02632 |                   mode = 0; 
 02633 |                   if      ('#' == c0)    { mode = 1; incr = 1; } 
 02634 |                   else if ('/' == c0) 
 02635 |                   { 
 02636 |                      if      ('/' == c1) { mode = 1; incr = 2; } 
 02637 |                      else if ('*' == c1) { mode = 2; incr = 2; } 
 02638 |                   } 
 02639 |                   return (0 != mode); 
 02640 |                } 
 02641 |  
 02642 |                static inline bool comment_end(const char_t c0, const char_t c1, int& mode) 
 02643 |                { 
 02644 |                   if ( 
 02645 |                        ((1 == mode) && ('\n' == c0)) || 
 02646 |                        ((2 == mode) && ( '*' == c0) && ('/' == c1)) 
 02647 |                      ) 
 02648 |                   { 
 02649 |                      mode = 0; 
 02650 |                      return true; 
 02651 |                   } 
 02652 |                   else 
 02653 |                      return false; 
 02654 |                } 
 02655 |             }; 
 02656 |  
 02657 |             int mode      = 0; 
 02658 |             int increment = 0; 
 02659 |  
 02660 |             if (is_end(s_itr_)) 
 02661 |                return; 
 02662 |             else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment)) 
 02663 |                return; 
 02664 |  
 02665 |             details::char_cptr cmt_start = s_itr_; 
 02666 |  
 02667 |             s_itr_ += increment; 
 02668 |  
 02669 |             while (!is_end(s_itr_)) 
 02670 |             { 
 02671 |                if ((1 == mode) && test::comment_end(*s_itr_, 0, mode)) 
 02672 |                { 
 02673 |                   ++s_itr_; 
 02674 |                   return; 
 02675 |                } 
 02676 |  
 02677 |                if ((2 == mode)) 
 02678 |                { 
 02679 |                   if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode)) 
 02680 |                   { 
 02681 |                      s_itr_ += 2; 
 02682 |                      return; 
 02683 |                   } 
 02684 |                } 
 02685 |  
 02686 |                ++s_itr_; 
 02687 |             } 
 02688 |  
 02689 |             if (2 == mode) 
 02690 |             { 
 02691 |                token_t t; 
 02692 |                t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_); 
 02693 |                token_list_.push_back(t); 
 02694 |             } 
 02695 |             #endif 
 02696 |          } 
 02697 |  
 02698 |          inline bool next_is_digit(const details::char_cptr itr) const 
 02699 |          { 
 02700 |             return ((itr + 1) != s_end_) && 
 02701 |                    details::is_digit(*(itr + 1)); 
 02702 |          } 
 02703 |  
 02704 |          inline void scan_token() 
 02705 |          { 
 02706 |             const char_t c = *s_itr_; 
 02707 |  
 02708 |             if (details::is_whitespace(c)) 
 02709 |             { 
 02710 |                skip_whitespace(); 
 02711 |                return; 
 02712 |             } 
 02713 |             else if (is_comment_start(s_itr_)) 
 02714 |             { 
 02715 |                skip_comments(); 
 02716 |                return; 
 02717 |             } 
 02718 |             else if (details::is_operator_char(c)) 
 02719 |             { 
 02720 |                scan_operator(); 
 02721 |                return; 
 02722 |             } 
 02723 |             else if (details::is_letter(c)) 
 02724 |             { 
 02725 |                scan_symbol(); 
 02726 |                return; 
 02727 |             } 
 02728 |             else if (('.' == c) && !next_is_digit(s_itr_)) 
 02729 |             { 
 02730 |                scan_operator(); 
 02731 |                return; 
 02732 |             } 
 02733 |             else if (details::is_digit(c) || ('.' == c)) 
 02734 |             { 
 02735 |                scan_number(); 
 02736 |                return; 
 02737 |             } 
 02738 |             else if ('$' == c) 
 02739 |             { 
 02740 |                scan_special_function(); 
 02741 |                return; 
 02742 |             } 
 02743 |             #ifndef exprtk_disable_string_capabilities 
 02744 |             else if ('\'' == c) 
 02745 |             { 
 02746 |                scan_string(); 
 02747 |                return; 
 02748 |             } 
 02749 |             #endif 
 02750 |             else if ('~' == c) 
 02751 |             { 
 02752 |                token_t t; 
 02753 |                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); 
 02754 |                token_list_.push_back(t); 
 02755 |                ++s_itr_; 
 02756 |                return; 
 02757 |             } 
 02758 |             else 
 02759 |             { 
 02760 |                token_t t; 
 02761 |                t.set_error(token::e_error, s_itr_, s_itr_ + 2, base_itr_); 
 02762 |                token_list_.push_back(t); 
 02763 |                ++s_itr_; 
 02764 |             } 
 02765 |          } 
 02766 |  
 02767 |          inline void scan_operator() 
 02768 |          { 
 02769 |             token_t t; 
 02770 |  
 02771 |             const char_t c0 = s_itr_[0]; 
 02772 |  
 02773 |             if (!is_end(s_itr_ + 1)) 
 02774 |             { 
 02775 |                const char_t c1 = s_itr_[1]; 
 02776 |  
 02777 |                if (!is_end(s_itr_ + 2)) 
 02778 |                { 
 02779 |                   const char_t c2 = s_itr_[2]; 
 02780 |  
 02781 |                   if ((c0 == '<') && (c1 == '=') && (c2 == '>')) 
 02782 |                   { 
 02783 |                      t.set_operator(token_t::e_swap, s_itr_, s_itr_ + 3, base_itr_); 
 02784 |                      token_list_.push_back(t); 
 02785 |                      s_itr_ += 3; 
 02786 |                      return; 
 02787 |                   } 
 02788 |                } 
 02789 |  
 02790 |                token_t::token_type ttype = token_t::e_none; 
 02791 |  
 02792 |                if      ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte; 
 02793 |                else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte; 
 02794 |                else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne; 
 02795 |                else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne; 
 02796 |                else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq; 
 02797 |                else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign; 
 02798 |                else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl; 
 02799 |                else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr; 
 02800 |                else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass; 
 02801 |                else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass; 
 02802 |                else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass; 
 02803 |                else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass; 
 02804 |                else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass; 
 02805 |  
 02806 |                if (token_t::e_none != ttype) 
 02807 |                { 
 02808 |                   t.set_operator(ttype, s_itr_, s_itr_ + 2, base_itr_); 
 02809 |                   token_list_.push_back(t); 
 02810 |                   s_itr_ += 2; 
 02811 |                   return; 
 02812 |                } 
 02813 |             } 
 02814 |  
 02815 |             if ('<' == c0) 
 02816 |                t.set_operator(token_t::e_lt , s_itr_, s_itr_ + 1, base_itr_); 
 02817 |             else if ('>' == c0) 
 02818 |                t.set_operator(token_t::e_gt , s_itr_, s_itr_ + 1, base_itr_); 
 02819 |             else if (';' == c0) 
 02820 |                t.set_operator(token_t::e_eof, s_itr_, s_itr_ + 1, base_itr_); 
 02821 |             else if ('&' == c0) 
 02822 |                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); 
 02823 |             else if ('|' == c0) 
 02824 |                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); 
 02825 |             else 
 02826 |                t.set_operator(token_t::token_type(c0), s_itr_, s_itr_ + 1, base_itr_); 
 02827 |  
 02828 |             token_list_.push_back(t); 
 02829 |             ++s_itr_; 
 02830 |          } 
 02831 |  
 02832 |          inline void scan_symbol() 
 02833 |          { 
 02834 |             details::char_cptr initial_itr = s_itr_; 
 02835 |  
 02836 |             while (!is_end(s_itr_)) 
 02837 |             { 
 02838 |                if (!details::is_letter_or_digit(*s_itr_) && ('_' != (*s_itr_))) 
 02839 |                { 
 02840 |                   if ('.' != (*s_itr_)) 
 02841 |                      break; 
 02842 |                   /* 
 02843 |                      Permit symbols that contain a 'dot' 
 02844 |                      Allowed   : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123 
 02845 |                      Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...> 
 02846 |                   */ 
 02847 |                   if ( 
 02848 |                        (s_itr_ != initial_itr)                     && 
 02849 |                        !is_end(s_itr_ + 1)                         && 
 02850 |                        !details::is_letter_or_digit(*(s_itr_ + 1)) && 
 02851 |                        ('_' != (*(s_itr_ + 1))) 
 02852 |                      ) 
 02853 |                      break; 
 02854 |                } 
 02855 |  
 02856 |                ++s_itr_; 
 02857 |             } 
 02858 |  
 02859 |             token_t t; 
 02860 |             t.set_symbol(initial_itr, s_itr_, base_itr_); 
 02861 |             token_list_.push_back(t); 
 02862 |          } 
 02863 |  
 02864 |          inline void scan_number() 
 02865 |          { 
 02866 |             /* 
 02867 |                Attempt to match a valid numeric value in one of the following formats: 
 02868 |                (01) 123456 
 02869 |                (02) 123456. 
 02870 |                (03) 123.456 
 02871 |                (04) 123.456e3 
 02872 |                (05) 123.456E3 
 02873 |                (06) 123.456e+3 
 02874 |                (07) 123.456E+3 
 02875 |                (08) 123.456e-3 
 02876 |                (09) 123.456E-3 
 02877 |                (00) .1234 
 02878 |                (11) .1234e3 
 02879 |                (12) .1234E+3 
 02880 |                (13) .1234e+3 
 02881 |                (14) .1234E-3 
 02882 |                (15) .1234e-3 
 02883 |             */ 
 02884 |  
 02885 |             details::char_cptr initial_itr = s_itr_; 
 02886 |             bool dot_found                 = false; 
 02887 |             bool e_found                   = false; 
 02888 |             bool post_e_sign_found         = false; 
 02889 |             bool post_e_digit_found        = false; 
 02890 |             token_t t; 
 02891 |  
 02892 |             while (!is_end(s_itr_)) 
 02893 |             { 
 02894 |                if ('.' == (*s_itr_)) 
 02895 |                { 
 02896 |                   if (dot_found) 
 02897 |                   { 
 02898 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02899 |                      token_list_.push_back(t); 
 02900 |  
 02901 |                      return; 
 02902 |                   } 
 02903 |  
 02904 |                   dot_found = true; 
 02905 |                   ++s_itr_; 
 02906 |  
 02907 |                   continue; 
 02908 |                } 
 02909 |                else if ('e' == std::tolower(*s_itr_)) 
 02910 |                { 
 02911 |                   const char_t& c = *(s_itr_ + 1); 
 02912 |  
 02913 |                   if (is_end(s_itr_ + 1)) 
 02914 |                   { 
 02915 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02916 |                      token_list_.push_back(t); 
 02917 |  
 02918 |                      return; 
 02919 |                   } 
 02920 |                   else if ( 
 02921 |                             ('+' != c) && 
 02922 |                             ('-' != c) && 
 02923 |                             !details::is_digit(c) 
 02924 |                           ) 
 02925 |                   { 
 02926 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02927 |                      token_list_.push_back(t); 
 02928 |  
 02929 |                      return; 
 02930 |                   } 
 02931 |  
 02932 |                   e_found = true; 
 02933 |                   ++s_itr_; 
 02934 |  
 02935 |                   continue; 
 02936 |                } 
 02937 |                else if (e_found && details::is_sign(*s_itr_) && !post_e_digit_found) 
 02938 |                { 
 02939 |                   if (post_e_sign_found) 
 02940 |                   { 
 02941 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02942 |                      token_list_.push_back(t); 
 02943 |  
 02944 |                      return; 
 02945 |                   } 
 02946 |  
 02947 |                   post_e_sign_found = true; 
 02948 |                   ++s_itr_; 
 02949 |  
 02950 |                   continue; 
 02951 |                } 
 02952 |                else if (e_found && details::is_digit(*s_itr_)) 
 02953 |                { 
 02954 |                   post_e_digit_found = true; 
 02955 |                   ++s_itr_; 
 02956 |  
 02957 |                   continue; 
 02958 |                } 
 02959 |                else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_)) 
 02960 |                   break; 
 02961 |                else 
 02962 |                   ++s_itr_; 
 02963 |             } 
 02964 |  
 02965 |             t.set_numeric(initial_itr, s_itr_, base_itr_); 
 02966 |             token_list_.push_back(t); 
 02967 |  
 02968 |             return; 
 02969 |          } 
 02970 |  
 02971 |          inline void scan_special_function() 
 02972 |          { 
 02973 |             details::char_cptr initial_itr = s_itr_; 
 02974 |             token_t t; 
 02975 |  
 02976 |             // $fdd(x,x,x) = at least 11 chars 
 02977 |             if (std::distance(s_itr_,s_end_) < 11) 
 02978 |             { 
 02979 |                t.set_error( 
 02980 |                   token::e_err_sfunc, 
 02981 |                   initial_itr, std::min(initial_itr + 11, s_end_), 
 02982 |                   base_itr_); 
 02983 |                token_list_.push_back(t); 
 02984 |  
 02985 |                return; 
 02986 |             } 
 02987 |  
 02988 |             if ( 
 02989 |                  !(('$' == *s_itr_)                       && 
 02990 |                    (details::imatch  ('f',*(s_itr_ + 1))) && 
 02991 |                    (details::is_digit(*(s_itr_ + 2)))     && 
 02992 |                    (details::is_digit(*(s_itr_ + 3)))) 
 02993 |                ) 
 02994 |             { 
 02995 |                t.set_error( 
 02996 |                   token::e_err_sfunc, 
 02997 |                   initial_itr, std::min(initial_itr + 4, s_end_), 
 02998 |                   base_itr_); 
 02999 |                token_list_.push_back(t); 
 03000 |  
 03001 |                return; 
 03002 |             } 
 03003 |  
 03004 |             s_itr_ += 4; // $fdd = 4chars 
 03005 |  
 03006 |             t.set_symbol(initial_itr, s_itr_, base_itr_); 
 03007 |             token_list_.push_back(t); 
 03008 |  
 03009 |             return; 
 03010 |          } 
 03011 |  
 03012 |          #ifndef exprtk_disable_string_capabilities 
 03013 |          inline void scan_string() 
 03014 |          { 
 03015 |             details::char_cptr initial_itr = s_itr_ + 1; 
 03016 |             token_t t; 
 03017 |  
 03018 |             if (std::distance(s_itr_,s_end_) < 2) 
 03019 |             { 
 03020 |                t.set_error(token::e_err_string, s_itr_, s_end_, base_itr_); 
 03021 |                token_list_.push_back(t); 
 03022 |  
 03023 |                return; 
 03024 |             } 
 03025 |  
 03026 |             ++s_itr_; 
 03027 |  
 03028 |             bool escaped_found = false; 
 03029 |             bool escaped = false; 
 03030 |  
 03031 |             while (!is_end(s_itr_)) 
 03032 |             { 
 03033 |                if (!details::is_valid_string_char(*s_itr_)) 
 03034 |                { 
 03035 |                   t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03036 |                   token_list_.push_back(t); 
 03037 |  
 03038 |                   return; 
 03039 |                } 
 03040 |                else if (!escaped && ('\\' == *s_itr_)) 
 03041 |                { 
 03042 |                   escaped_found = true; 
 03043 |                   escaped = true; 
 03044 |                   ++s_itr_; 
 03045 |  
 03046 |                   continue; 
 03047 |                } 
 03048 |                else if (!escaped) 
 03049 |                { 
 03050 |                   if ('\'' == *s_itr_) 
 03051 |                      break; 
 03052 |                } 
 03053 |                else if (escaped) 
 03054 |                { 
 03055 |                   if ( 
 03056 |                        !is_end(s_itr_) && ('0' == *(s_itr_)) && 
 03057 |                        ((s_itr_ + 4) <= s_end_) 
 03058 |                      ) 
 03059 |                   { 
 03060 |                      const bool x_separator = ('X' == std::toupper(*(s_itr_ + 1))); 
 03061 |  
 03062 |                      const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) && 
 03063 |                                               details::is_hex_digit(*(s_itr_ + 3)) ; 
 03064 |  
 03065 |                      if (!(x_separator && both_digits)) 
 03066 |                      { 
 03067 |                         t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03068 |                         token_list_.push_back(t); 
 03069 |  
 03070 |                         return; 
 03071 |                      } 
 03072 |                      else 
 03073 |                         s_itr_ += 3; 
 03074 |                   } 
 03075 |  
 03076 |                   escaped = false; 
 03077 |                } 
 03078 |  
 03079 |                ++s_itr_; 
 03080 |             } 
 03081 |  
 03082 |             if (is_end(s_itr_)) 
 03083 |             { 
 03084 |                t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03085 |                token_list_.push_back(t); 
 03086 |  
 03087 |                return; 
 03088 |             } 
 03089 |  
 03090 |             if (!escaped_found) 
 03091 |                t.set_string(initial_itr, s_itr_, base_itr_); 
 03092 |             else 
 03093 |             { 
 03094 |                std::string parsed_string(initial_itr,s_itr_); 
 03095 |  
 03096 |                if (!details::cleanup_escapes(parsed_string)) 
 03097 |                { 
 03098 |                   t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03099 |                   token_list_.push_back(t); 
 03100 |  
 03101 |                   return; 
 03102 |                } 
 03103 |  
 03104 |                t.set_string( 
 03105 |                   parsed_string, 
 03106 |                   static_cast<std::size_t>(std::distance(base_itr_,initial_itr))); 
 03107 |             } 
 03108 |  
 03109 |             token_list_.push_back(t); 
 03110 |             ++s_itr_; 
 03111 |  
 03112 |             return; 
 03113 |          } 
 03114 |          #endif 
 03115 |  
 03116 |       private: 
 03117 |  
 03118 |          token_list_t       token_list_; 
 03119 |          token_list_itr_t   token_itr_; 
 03120 |          token_list_itr_t   store_token_itr_; 
 03121 |          token_t            eof_token_; 
 03122 |          details::char_cptr base_itr_; 
 03123 |          details::char_cptr s_itr_; 
 03124 |          details::char_cptr s_end_; 
 03125 |  
 03126 |          friend class token_scanner; 
 03127 |          friend class token_modifier; 
 03128 |          friend class token_inserter; 
 03129 |          friend class token_joiner; 
 03130 |       }; // class generator 
 03131 |  
 03132 |       class helper_interface 
 03133 |       { 
 03134 |       public: 
 03135 |  
 03136 |          virtual void init()                     {              } 
 03137 |          virtual void reset()                    {              } 
 03138 |          virtual bool result()                   { return true; } 
 03139 |          virtual std::size_t process(generator&) { return 0;    } 
 03140 |          virtual ~helper_interface()             {              } 
 03141 |       }; 
 03142 |  
 03143 |       class token_scanner : public helper_interface 
 03144 |       { 
 03145 |       public: 
 03146 |  
 03147 |          virtual ~token_scanner() exprtk_override 
 03148 |          {} 
 03149 |  
 03150 |          explicit token_scanner(const std::size_t& stride) 
 03151 |          : stride_(stride) 
 03152 |          { 
 03153 |             if (stride > 4) 
 03154 |             { 
 03155 |                throw std::invalid_argument("token_scanner() - Invalid stride value"); 
 03156 |             } 
 03157 |          } 
 03158 |  
 03159 |          inline std::size_t process(generator& g) exprtk_override 
 03160 |          { 
 03161 |             if (g.token_list_.size() >= stride_) 
 03162 |             { 
 03163 |                for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i) 
 03164 |                { 
 03165 |                   token t; 
 03166 |  
 03167 |                   switch (stride_) 
 03168 |                   { 
 03169 |                      case 1 : 
 03170 |                               { 
 03171 |                                  const token& t0 = g.token_list_[i]; 
 03172 |  
 03173 |                                  if (!operator()(t0)) 
 03174 |                                  { 
 03175 |                                     return 0; 
 03176 |                                  } 
 03177 |                               } 
 03178 |                               break; 
 03179 |  
 03180 |                      case 2 : 
 03181 |                               { 
 03182 |                                  const token& t0 = g.token_list_[i    ]; 
 03183 |                                  const token& t1 = g.token_list_[i + 1]; 
 03184 |  
 03185 |                                  if (!operator()(t0, t1)) 
 03186 |                                  { 
 03187 |                                     return 0; 
 03188 |                                  } 
 03189 |                               } 
 03190 |                               break; 
 03191 |  
 03192 |                      case 3 : 
 03193 |                               { 
 03194 |                                  const token& t0 = g.token_list_[i    ]; 
 03195 |                                  const token& t1 = g.token_list_[i + 1]; 
 03196 |                                  const token& t2 = g.token_list_[i + 2]; 
 03197 |  
 03198 |                                  if (!operator()(t0, t1, t2)) 
 03199 |                                  { 
 03200 |                                     return 0; 
 03201 |                                  } 
 03202 |                               } 
 03203 |                               break; 
 03204 |  
 03205 |                      case 4 : 
 03206 |                               { 
 03207 |                                  const token& t0 = g.token_list_[i    ]; 
 03208 |                                  const token& t1 = g.token_list_[i + 1]; 
 03209 |                                  const token& t2 = g.token_list_[i + 2]; 
 03210 |                                  const token& t3 = g.token_list_[i + 3]; 
 03211 |  
 03212 |                                  if (!operator()(t0, t1, t2, t3)) 
 03213 |                                  { 
 03214 |                                     return 0; 
 03215 |                                  } 
 03216 |                               } 
 03217 |                               break; 
 03218 |                   } 
 03219 |                } 
 03220 |             } 
 03221 |  
 03222 |             return 0; 
 03223 |          } 
 03224 |  
 03225 |          virtual bool operator() (const token&) 
 03226 |          { 
 03227 |             return false; 
 03228 |          } 
 03229 |  
 03230 |          virtual bool operator() (const token&, const token&) 
 03231 |          { 
 03232 |             return false; 
 03233 |          } 
 03234 |  
 03235 |          virtual bool operator() (const token&, const token&, const token&) 
 03236 |          { 
 03237 |             return false; 
 03238 |          } 
 03239 |  
 03240 |          virtual bool operator() (const token&, const token&, const token&, const token&) 
 03241 |          { 
 03242 |             return false; 
 03243 |          } 
 03244 |  
 03245 |       private: 
 03246 |  
 03247 |          const std::size_t stride_; 
 03248 |       }; // class token_scanner 
 03249 |  
 03250 |       class token_modifier : public helper_interface 
 03251 |       { 
 03252 |       public: 
 03253 |  
 03254 |          inline std::size_t process(generator& g) exprtk_override 
 03255 |          { 
 03256 |             std::size_t changes = 0; 
 03257 |  
 03258 |             for (std::size_t i = 0; i < g.token_list_.size(); ++i) 
 03259 |             { 
 03260 |                if (modify(g.token_list_[i])) changes++; 
 03261 |             } 
 03262 |  
 03263 |             return changes; 
 03264 |          } 
 03265 |  
 03266 |          virtual bool modify(token& t) = 0; 
 03267 |       }; 
 03268 |  
 03269 |       class token_inserter : public helper_interface 
 03270 |       { 
 03271 |       public: 
 03272 |  
 03273 |          explicit token_inserter(const std::size_t& stride) 
 03274 |          : stride_(stride) 
 03275 |          { 
 03276 |             if (stride > 5) 
 03277 |             { 
 03278 |                throw std::invalid_argument("token_inserter() - Invalid stride value"); 
 03279 |             } 
 03280 |          } 
 03281 |  
 03282 |          inline std::size_t process(generator& g) exprtk_override 
 03283 |          { 
 03284 |             if (g.token_list_.empty()) 
 03285 |                return 0; 
 03286 |             else if (g.token_list_.size() < stride_) 
 03287 |                return 0; 
 03288 |  
 03289 |             std::size_t changes = 0; 
 03290 |  
 03291 |             typedef std::pair<std::size_t, token> insert_t; 
 03292 |             std::vector<insert_t> insert_list; 
 03293 |             insert_list.reserve(10000); 
 03294 |  
 03295 |             for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i) 
 03296 |             { 
 03297 |                int insert_index = -1; 
 03298 |                token t; 
 03299 |  
 03300 |                switch (stride_) 
 03301 |                { 
 03302 |                   case 1 : insert_index = insert(g.token_list_[i],t); 
 03303 |                            break; 
 03304 |  
 03305 |                   case 2 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], t); 
 03306 |                            break; 
 03307 |  
 03308 |                   case 3 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], t); 
 03309 |                            break; 
 03310 |  
 03311 |                   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); 
 03312 |                            break; 
 03313 |  
 03314 |                   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); 
 03315 |                            break; 
 03316 |                } 
 03317 |  
 03318 |                if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1))) 
 03319 |                { 
 03320 |                   insert_list.push_back(insert_t(i, t)); 
 03321 |                   changes++; 
 03322 |                } 
 03323 |             } 
 03324 |  
 03325 |             if (!insert_list.empty()) 
 03326 |             { 
 03327 |                generator::token_list_t token_list; 
 03328 |  
 03329 |                std::size_t insert_index = 0; 
 03330 |  
 03331 |                for (std::size_t i = 0; i < g.token_list_.size(); ++i) 
 03332 |                { 
 03333 |                   token_list.push_back(g.token_list_[i]); 
 03334 |  
 03335 |                   if ( 
 03336 |                        (insert_index < insert_list.size()) && 
 03337 |                        (insert_list[insert_index].first == i) 
 03338 |                      ) 
 03339 |                   { 
 03340 |                      token_list.push_back(insert_list[insert_index].second); 
 03341 |                      insert_index++; 
 03342 |                   } 
 03343 |                } 
 03344 |  
 03345 |                std::swap(g.token_list_,token_list); 
 03346 |             } 
 03347 |  
 03348 |             return changes; 
 03349 |          } 
 03350 |  
 03351 |          #define token_inserter_empty_body \ 
 03352 |          {                                 \ 
 03353 |             return -1;                     \ 
 03354 |          }                                 \ 
 03355 |  
 03356 |          inline virtual int insert(const token&, token&) 
 03357 |          token_inserter_empty_body 
 03358 |  
 03359 |          inline virtual int insert(const token&, const token&, token&) 
 03360 |          token_inserter_empty_body 
 03361 |  
 03362 |          inline virtual int insert(const token&, const token&, const token&, token&) 
 03363 |          token_inserter_empty_body 
 03364 |  
 03365 |          inline virtual int insert(const token&, const token&, const token&, const token&, token&) 
 03366 |          token_inserter_empty_body 
 03367 |  
 03368 |          inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&) 
 03369 |          token_inserter_empty_body 
 03370 |  
 03371 |          #undef token_inserter_empty_body 
 03372 |  
 03373 |       private: 
 03374 |  
 03375 |          const std::size_t stride_; 
 03376 |       }; 
 03377 |  
 03378 |       class token_joiner : public helper_interface 
 03379 |       { 
 03380 |       public: 
 03381 |  
 03382 |          explicit token_joiner(const std::size_t& stride) 
 03383 |          : stride_(stride) 
 03384 |          {} 
 03385 |  
 03386 |          inline std::size_t process(generator& g) exprtk_override 
 03387 |          { 
 03388 |             if (g.token_list_.empty()) 
 03389 |                return 0; 
 03390 |  
 03391 |             switch (stride_) 
 03392 |             { 
 03393 |                case 2  : return process_stride_2(g); 
 03394 |                case 3  : return process_stride_3(g); 
 03395 |                default : return 0; 
 03396 |             } 
 03397 |          } 
 03398 |  
 03399 |          virtual bool join(const token&, const token&, token&)               { return false; } 
 03400 |          virtual bool join(const token&, const token&, const token&, token&) { return false; } 
 03401 |  
 03402 |       private: 
 03403 |  
 03404 |          inline std::size_t process_stride_2(generator& g) 
 03405 |          { 
 03406 |             if (g.token_list_.size() < 2) 
 03407 |                return 0; 
 03408 |  
 03409 |             std::size_t changes = 0; 
 03410 |  
 03411 |             generator::token_list_t token_list; 
 03412 |             token_list.reserve(10000); 
 03413 |  
 03414 |             for (int i = 0; i < static_cast<int>(g.token_list_.size() - 1); ++i) 
 03415 |             { 
 03416 |                token t; 
 03417 |  
 03418 |                for ( ; ; ) 
 03419 |                { 
 03420 |                   if (!join(g[i], g[i + 1], t)) 
 03421 |                   { 
 03422 |                      token_list.push_back(g[i]); 
 03423 |                      break; 
 03424 |                   } 
 03425 |  
 03426 |                   token_list.push_back(t); 
 03427 |  
 03428 |                   ++changes; 
 03429 |  
 03430 |                   i += 2; 
 03431 |  
 03432 |                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1)) 
 03433 |                      break; 
 03434 |                } 
 03435 |             } 
 03436 |  
 03437 |             token_list.push_back(g.token_list_.back()); 
 03438 |  
 03439 |             assert(token_list.size() <= g.token_list_.size()); 
 03440 |  
 03441 |             std::swap(token_list, g.token_list_); 
 03442 |  
 03443 |             return changes; 
 03444 |          } 
 03445 |  
 03446 |          inline std::size_t process_stride_3(generator& g) 
 03447 |          { 
 03448 |             if (g.token_list_.size() < 3) 
 03449 |                return 0; 
 03450 |  
 03451 |             std::size_t changes = 0; 
 03452 |  
 03453 |             generator::token_list_t token_list; 
 03454 |             token_list.reserve(10000); 
 03455 |  
 03456 |             for (int i = 0; i < static_cast<int>(g.token_list_.size() - 2); ++i) 
 03457 |             { 
 03458 |                token t; 
 03459 |  
 03460 |                for ( ; ; ) 
 03461 |                { 
 03462 |                   if (!join(g[i], g[i + 1], g[i + 2], t)) 
 03463 |                   { 
 03464 |                      token_list.push_back(g[i]); 
 03465 |                      break; 
 03466 |                   } 
 03467 |  
 03468 |                   token_list.push_back(t); 
 03469 |  
 03470 |                   ++changes; 
 03471 |  
 03472 |                   i += 3; 
 03473 |  
 03474 |                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2)) 
 03475 |                      break; 
 03476 |                } 
 03477 |             } 
 03478 |  
 03479 |             token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 2)); 
 03480 |             token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 1)); 
 03481 |  
 03482 |             assert(token_list.size() <= g.token_list_.size()); 
 03483 |  
 03484 |             std::swap(token_list, g.token_list_); 
 03485 |  
 03486 |             return changes; 
 03487 |          } 
 03488 |  
 03489 |          const std::size_t stride_; 
 03490 |       }; 
 03491 |  
 03492 |       namespace helper 
 03493 |       { 
 03494 |  
 03495 |          inline void dump(const lexer::generator& generator) 
 03496 |          { 
 03497 |             for (std::size_t i = 0; i < generator.size(); ++i) 
 03498 |             { 
 03499 |                const lexer::token& t = generator[i]; 
 03500 |                printf("Token[%02d] @ %03d  %6s  -->  '%s'\n", 
 03501 |                       static_cast<int>(i), 
 03502 |                       static_cast<int>(t.position), 
 03503 |                       t.to_str(t.type).c_str(), 
 03504 |                       t.value.c_str()); 
 03505 |             } 
 03506 |          } 
 03507 |  
 03508 |          class commutative_inserter : public lexer::token_inserter 
 03509 |          { 
 03510 |          public: 
 03511 |  
 03512 |             using lexer::token_inserter::insert; 
 03513 |  
 03514 |             commutative_inserter() 
 03515 |             : lexer::token_inserter(2) 
 03516 |             {} 
 03517 |  
 03518 |             inline void ignore_symbol(const std::string& symbol) 
 03519 |             { 
 03520 |                ignore_set_.insert(symbol); 
 03521 |             } 
 03522 |  
 03523 |             inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override 
 03524 |             { 
 03525 |                bool match         = false; 
 03526 |                new_token.type     = lexer::token::e_mul; 
 03527 |                new_token.value    = "*" 
 03528 |                new_token.position = t1.position; 
 03529 |  
 03530 |                if (t0.type == lexer::token::e_symbol) 
 03531 |                { 
 03532 |                   if (ignore_set_.end() != ignore_set_.find(t0.value)) 
 03533 |                   { 
 03534 |                      return -1; 
 03535 |                   } 
 03536 |                   else if (!t0.value.empty() && ('$' == t0.value[0])) 
 03537 |                   { 
 03538 |                      return -1; 
 03539 |                   } 
 03540 |                } 
 03541 |  
 03542 |                if (t1.type == lexer::token::e_symbol) 
 03543 |                { 
 03544 |                   if (ignore_set_.end() != ignore_set_.find(t1.value)) 
 03545 |                   { 
 03546 |                      return -1; 
 03547 |                   } 
 03548 |                } 
 03549 |                if      ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03550 |                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lbracket   )) match = true; 
 03551 |                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lcrlbracket)) match = true; 
 03552 |                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lsqrbracket)) match = true; 
 03553 |                else if ((t0.type == lexer::token::e_symbol     ) && (t1.type == lexer::token::e_number     )) match = true; 
 03554 |                else if ((t0.type == lexer::token::e_rbracket   ) && (t1.type == lexer::token::e_number     )) match = true; 
 03555 |                else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number     )) match = true; 
 03556 |                else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number     )) match = true; 
 03557 |                else if ((t0.type == lexer::token::e_rbracket   ) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03558 |                else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03559 |                else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03560 |                else if ((t0.type == lexer::token::e_symbol     ) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03561 |  
 03562 |                return (match) ? 1 : -1; 
 03563 |             } 
 03564 |  
 03565 |          private: 
 03566 |  
 03567 |             std::set<std::string,details::ilesscompare> ignore_set_; 
 03568 |          }; 
 03569 |  
 03570 |          class operator_joiner exprtk_final : public token_joiner 
 03571 |          { 
 03572 |          public: 
 03573 |  
 03574 |             explicit operator_joiner(const std::size_t& stride) 
 03575 |             : token_joiner(stride) 
 03576 |             {} 
 03577 |  
 03578 |             inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override 
 03579 |             { 
 03580 |                // ': =' --> ':=' 
 03581 |                if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq)) 
 03582 |                { 
 03583 |                   t.type     = lexer::token::e_assign; 
 03584 |                   t.value    = ":=" 
 03585 |                   t.position = t0.position; 
 03586 |  
 03587 |                   return true; 
 03588 |                } 
 03589 |                // '+ =' --> '+=' 
 03590 |                else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq)) 
 03591 |                { 
 03592 |                   t.type     = lexer::token::e_addass; 
 03593 |                   t.value    = "+=" 
 03594 |                   t.position = t0.position; 
 03595 |  
 03596 |                   return true; 
 03597 |                } 
 03598 |                // '- =' --> '-=' 
 03599 |                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq)) 
 03600 |                { 
 03601 |                   t.type     = lexer::token::e_subass; 
 03602 |                   t.value    = "-=" 
 03603 |                   t.position = t0.position; 
 03604 |  
 03605 |                   return true; 
 03606 |                } 
 03607 |                // '* =' --> '*=' 
 03608 |                else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq)) 
 03609 |                { 
 03610 |                   t.type     = lexer::token::e_mulass; 
 03611 |                   t.value    = "*=" 
 03612 |                   t.position = t0.position; 
 03613 |  
 03614 |                   return true; 
 03615 |                } 
 03616 |                // '/ =' --> '/=' 
 03617 |                else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq)) 
 03618 |                { 
 03619 |                   t.type     = lexer::token::e_divass; 
 03620 |                   t.value    = "/=" 
 03621 |                   t.position = t0.position; 
 03622 |  
 03623 |                   return true; 
 03624 |                } 
 03625 |                // '% =' --> '%=' 
 03626 |                else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq)) 
 03627 |                { 
 03628 |                   t.type     = lexer::token::e_modass; 
 03629 |                   t.value    = "%=" 
 03630 |                   t.position = t0.position; 
 03631 |  
 03632 |                   return true; 
 03633 |                } 
 03634 |                // '> =' --> '>=' 
 03635 |                else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq)) 
 03636 |                { 
 03637 |                   t.type     = lexer::token::e_gte; 
 03638 |                   t.value    = ">=" 
 03639 |                   t.position = t0.position; 
 03640 |  
 03641 |                   return true; 
 03642 |                } 
 03643 |                // '< =' --> '<=' 
 03644 |                else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq)) 
 03645 |                { 
 03646 |                   t.type     = lexer::token::e_lte; 
 03647 |                   t.value    = "<=" 
 03648 |                   t.position = t0.position; 
 03649 |  
 03650 |                   return true; 
 03651 |                } 
 03652 |                // '= =' --> '==' 
 03653 |                else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq)) 
 03654 |                { 
 03655 |                   t.type     = lexer::token::e_eq; 
 03656 |                   t.value    = "==" 
 03657 |                   t.position = t0.position; 
 03658 |  
 03659 |                   return true; 
 03660 |                } 
 03661 |                // '! =' --> '!=' 
 03662 |                else if ((static_cast<details::char_t>(t0.type) == '!') && (t1.type == lexer::token::e_eq)) 
 03663 |                { 
 03664 |                   t.type     = lexer::token::e_ne; 
 03665 |                   t.value    = "!=" 
 03666 |                   t.position = t0.position; 
 03667 |  
 03668 |                   return true; 
 03669 |                } 
 03670 |                // '< >' --> '<>' 
 03671 |                else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt)) 
 03672 |                { 
 03673 |                   t.type     = lexer::token::e_ne; 
 03674 |                   t.value    = "<>" 
 03675 |                   t.position = t0.position; 
 03676 |  
 03677 |                   return true; 
 03678 |                } 
 03679 |                // '<= >' --> '<=>' 
 03680 |                else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt)) 
 03681 |                { 
 03682 |                   t.type     = lexer::token::e_swap; 
 03683 |                   t.value    = "<=>" 
 03684 |                   t.position = t0.position; 
 03685 |  
 03686 |                   return true; 
 03687 |                } 
 03688 |                // '+ -' --> '-' 
 03689 |                else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub)) 
 03690 |                { 
 03691 |                   t.type     = lexer::token::e_sub; 
 03692 |                   t.value    = "-" 
 03693 |                   t.position = t0.position; 
 03694 |  
 03695 |                   return true; 
 03696 |                } 
 03697 |                // '- +' --> '-' 
 03698 |                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add)) 
 03699 |                { 
 03700 |                   t.type     = lexer::token::e_sub; 
 03701 |                   t.value    = "-" 
 03702 |                   t.position = t0.position; 
 03703 |  
 03704 |                   return true; 
 03705 |                } 
 03706 |                // '- -' --> '+' 
 03707 |                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub)) 
 03708 |                { 
 03709 |                   /* 
 03710 |                      Note: May need to reconsider this when wanting to implement 
 03711 |                      pre/postfix decrement operator 
 03712 |                   */ 
 03713 |                   t.type     = lexer::token::e_add; 
 03714 |                   t.value    = "+" 
 03715 |                   t.position = t0.position; 
 03716 |  
 03717 |                   return true; 
 03718 |                } 
 03719 |                else 
 03720 |                   return false; 
 03721 |             } 
 03722 |  
 03723 |             inline bool join(const lexer::token& t0, 
 03724 |                              const lexer::token& t1, 
 03725 |                              const lexer::token& t2, 
 03726 |                              lexer::token& t) exprtk_override 
 03727 |             { 
 03728 |                // '[ * ]' --> '[*]' 
 03729 |                if ( 
 03730 |                     (t0.type == lexer::token::e_lsqrbracket) && 
 03731 |                     (t1.type == lexer::token::e_mul        ) && 
 03732 |                     (t2.type == lexer::token::e_rsqrbracket) 
 03733 |                   ) 
 03734 |                { 
 03735 |                   t.type     = lexer::token::e_symbol; 
 03736 |                   t.value    = "[*]" 
 03737 |                   t.position = t0.position; 
 03738 |  
 03739 |                   return true; 
 03740 |                } 
 03741 |                else 
 03742 |                   return false; 
 03743 |             } 
 03744 |          }; 
 03745 |  
 03746 |          class bracket_checker exprtk_final : public lexer::token_scanner 
 03747 |          { 
 03748 |          public: 
 03749 |  
 03750 |             using lexer::token_scanner::operator(); 
 03751 |  
 03752 |             bracket_checker() 
 03753 |             : token_scanner(1) 
 03754 |             , state_(true) 
 03755 |             {} 
 03756 |  
 03757 |             bool result() exprtk_override 
 03758 |             { 
 03759 |                if (!stack_.empty()) 
 03760 |                { 
 03761 |                   lexer::token t; 
 03762 |                   t.value      = stack_.top().first; 
 03763 |                   t.position   = stack_.top().second; 
 03764 |                   error_token_ = t; 
 03765 |                   state_       = false; 
 03766 |  
 03767 |                   return false; 
 03768 |                } 
 03769 |                else 
 03770 |                   return state_; 
 03771 |             } 
 03772 |  
 03773 |             lexer::token error_token() const 
 03774 |             { 
 03775 |                return error_token_; 
 03776 |             } 
 03777 |  
 03778 |             void reset() exprtk_override 
 03779 |             { 
 03780 |                // Why? because msvc doesn't support swap properly. 
 03781 |                stack_ = std::stack<std::pair<char,std::size_t> >(); 
 03782 |                state_ = true; 
 03783 |                error_token_.clear(); 
 03784 |             } 
 03785 |  
 03786 |             bool operator() (const lexer::token& t) exprtk_override 
 03787 |             { 
 03788 |                if ( 
 03789 |                     !t.value.empty()                       && 
 03790 |                     (lexer::token::e_string != t.type)     && 
 03791 |                     (lexer::token::e_symbol != t.type)     && 
 03792 |                     exprtk::details::is_bracket(t.value[0]) 
 03793 |                   ) 
 03794 |                { 
 03795 |                   details::char_t c = t.value[0]; 
 03796 |  
 03797 |                   if      (t.type == lexer::token::e_lbracket   ) stack_.push(std::make_pair(')',t.position)); 
 03798 |                   else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position)); 
 03799 |                   else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position)); 
 03800 |                   else if (exprtk::details::is_right_bracket(c)) 
 03801 |                   { 
 03802 |                      if (stack_.empty()) 
 03803 |                      { 
 03804 |                         state_       = false; 
 03805 |                         error_token_ = t; 
 03806 |  
 03807 |                         return false; 
 03808 |                      } 
 03809 |                      else if (c != stack_.top().first) 
 03810 |                      { 
 03811 |                         state_       = false; 
 03812 |                         error_token_ = t; 
 03813 |  
 03814 |                         return false; 
 03815 |                      } 
 03816 |                      else 
 03817 |                         stack_.pop(); 
 03818 |                   } 
 03819 |                } 
 03820 |  
 03821 |                return true; 
 03822 |             } 
 03823 |  
 03824 |          private: 
 03825 |  
 03826 |             bool state_; 
 03827 |             std::stack<std::pair<char,std::size_t> > stack_; 
 03828 |             lexer::token error_token_; 
 03829 |          }; 
 03830 |  
 03831 |          template <typename T> 
 03832 |          class numeric_checker exprtk_final : public lexer::token_scanner 
 03833 |          { 
 03834 |          public: 
 03835 |  
 03836 |             using lexer::token_scanner::operator(); 
 03837 |  
 03838 |             numeric_checker() 
 03839 |             : token_scanner (1) 
 03840 |             , current_index_(0) 
 03841 |             {} 
 03842 |  
 03843 |             bool result() exprtk_override 
 03844 |             { 
 03845 |                return error_list_.empty(); 
 03846 |             } 
 03847 |  
 03848 |             void reset() exprtk_override 
 03849 |             { 
 03850 |                error_list_.clear(); 
 03851 |                current_index_ = 0; 
 03852 |             } 
 03853 |  
 03854 |             bool operator() (const lexer::token& t) exprtk_override 
 03855 |             { 
 03856 |                if (token::e_number == t.type) 
 03857 |                { 
 03858 |                   T v; 
 03859 |  
 03860 |                   if (!exprtk::details::string_to_real(t.value,v)) 
 03861 |                   { 
 03862 |                      error_list_.push_back(current_index_); 
 03863 |                   } 
 03864 |                } 
 03865 |  
 03866 |                ++current_index_; 
 03867 |  
 03868 |                return true; 
 03869 |             } 
 03870 |  
 03871 |             std::size_t error_count() const 
 03872 |             { 
 03873 |                return error_list_.size(); 
 03874 |             } 
 03875 |  
 03876 |             std::size_t error_index(const std::size_t& i) const 
 03877 |             { 
 03878 |                if (i < error_list_.size()) 
 03879 |                   return error_list_[i]; 
 03880 |                else 
 03881 |                   return std::numeric_limits<std::size_t>::max(); 
 03882 |             } 
 03883 |  
 03884 |             void clear_errors() 
 03885 |             { 
 03886 |                error_list_.clear(); 
 03887 |             } 
 03888 |  
 03889 |          private: 
 03890 |  
 03891 |             std::size_t current_index_; 
 03892 |             std::vector<std::size_t> error_list_; 
 03893 |          }; 
 03894 |  
 03895 |          class symbol_replacer exprtk_final : public lexer::token_modifier 
 03896 |          { 
 03897 |          private: 
 03898 |  
 03899 |             typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t; 
 03900 |  
 03901 |          public: 
 03902 |  
 03903 |             bool remove(const std::string& target_symbol) 
 03904 |             { 
 03905 |                const replace_map_t::iterator itr = replace_map_.find(target_symbol); 
 03906 |  
 03907 |                if (replace_map_.end() == itr) 
 03908 |                   return false; 
 03909 |  
 03910 |                replace_map_.erase(itr); 
 03911 |  
 03912 |                return true; 
 03913 |             } 
 03914 |  
 03915 |             bool add_replace(const std::string& target_symbol, 
 03916 |                              const std::string& replace_symbol, 
 03917 |                              const lexer::token::token_type token_type = lexer::token::e_symbol) 
 03918 |             { 
 03919 |                const replace_map_t::iterator itr = replace_map_.find(target_symbol); 
 03920 |  
 03921 |                if (replace_map_.end() != itr) 
 03922 |                { 
 03923 |                   return false; 
 03924 |                } 
 03925 |  
 03926 |                replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type); 
 03927 |  
 03928 |                return true; 
 03929 |             } 
 03930 |  
 03931 |             void clear() 
 03932 |             { 
 03933 |                replace_map_.clear(); 
 03934 |             } 
 03935 |  
 03936 |          private: 
 03937 |  
 03938 |             bool modify(lexer::token& t) exprtk_override 
 03939 |             { 
 03940 |                if (lexer::token::e_symbol == t.type) 
 03941 |                { 
 03942 |                   if (replace_map_.empty()) 
 03943 |                      return false; 
 03944 |  
 03945 |                   const replace_map_t::iterator itr = replace_map_.find(t.value); 
 03946 |  
 03947 |                   if (replace_map_.end() != itr) 
 03948 |                   { 
 03949 |                      t.value = itr->second.first; 
 03950 |                      t.type  = itr->second.second; 
 03951 |  
 03952 |                      return true; 
 03953 |                   } 
 03954 |                } 
 03955 |  
 03956 |                return false; 
 03957 |             } 
 03958 |  
 03959 |             replace_map_t replace_map_; 
 03960 |          }; 
 03961 |  
 03962 |          class sequence_validator exprtk_final : public lexer::token_scanner 
 03963 |          { 
 03964 |          private: 
 03965 |  
 03966 |             typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t; 
 03967 |             typedef std::set<token_pair_t> set_t; 
 03968 |  
 03969 |          public: 
 03970 |  
 03971 |             using lexer::token_scanner::operator(); 
 03972 |  
 03973 |             sequence_validator() 
 03974 |             : lexer::token_scanner(2) 
 03975 |             { 
 03976 |                add_invalid(lexer::token::e_number, lexer::token::e_number); 
 03977 |                add_invalid(lexer::token::e_string, lexer::token::e_string); 
 03978 |                add_invalid(lexer::token::e_number, lexer::token::e_string); 
 03979 |                add_invalid(lexer::token::e_string, lexer::token::e_number); 
 03980 |  
 03981 |                add_invalid_set1(lexer::token::e_assign ); 
 03982 |                add_invalid_set1(lexer::token::e_shr    ); 
 03983 |                add_invalid_set1(lexer::token::e_shl    ); 
 03984 |                add_invalid_set1(lexer::token::e_lte    ); 
 03985 |                add_invalid_set1(lexer::token::e_ne     ); 
 03986 |                add_invalid_set1(lexer::token::e_gte    ); 
 03987 |                add_invalid_set1(lexer::token::e_lt     ); 
 03988 |                add_invalid_set1(lexer::token::e_gt     ); 
 03989 |                add_invalid_set1(lexer::token::e_eq     ); 
 03990 |                add_invalid_set1(lexer::token::e_comma  ); 
 03991 |                add_invalid_set1(lexer::token::e_add    ); 
 03992 |                add_invalid_set1(lexer::token::e_sub    ); 
 03993 |                add_invalid_set1(lexer::token::e_div    ); 
 03994 |                add_invalid_set1(lexer::token::e_mul    ); 
 03995 |                add_invalid_set1(lexer::token::e_mod    ); 
 03996 |                add_invalid_set1(lexer::token::e_pow    ); 
 03997 |                add_invalid_set1(lexer::token::e_colon  ); 
 03998 |                add_invalid_set1(lexer::token::e_ternary); 
 03999 |             } 
 04000 |  
 04001 |             bool result() exprtk_override 
 04002 |             { 
 04003 |                return error_list_.empty(); 
 04004 |             } 
 04005 |  
 04006 |             bool operator() (const lexer::token& t0, const lexer::token& t1) exprtk_override 
 04007 |             { 
 04008 |                const set_t::value_type p = std::make_pair(t0.type,t1.type); 
 04009 |  
 04010 |                if (invalid_bracket_check(t0.type,t1.type)) 
 04011 |                { 
 04012 |                   error_list_.push_back(std::make_pair(t0,t1)); 
 04013 |                } 
 04014 |                else if (invalid_comb_.find(p) != invalid_comb_.end()) 
 04015 |                { 
 04016 |                   error_list_.push_back(std::make_pair(t0,t1)); 
 04017 |                } 
 04018 |  
 04019 |                return true; 
 04020 |             } 
 04021 |  
 04022 |             std::size_t error_count() const 
 04023 |             { 
 04024 |                return error_list_.size(); 
 04025 |             } 
 04026 |  
 04027 |             std::pair<lexer::token,lexer::token> error(const std::size_t index) 
 04028 |             { 
 04029 |                if (index < error_list_.size()) 
 04030 |                { 
 04031 |                   return error_list_[index]; 
 04032 |                } 
 04033 |                else 
 04034 |                { 
 04035 |                   static const lexer::token error_token; 
 04036 |                   return std::make_pair(error_token,error_token); 
 04037 |                } 
 04038 |             } 
 04039 |  
 04040 |             void clear_errors() 
 04041 |             { 
 04042 |                error_list_.clear(); 
 04043 |             } 
 04044 |  
 04045 |          private: 
 04046 |  
 04047 |             void add_invalid(const lexer::token::token_type base, const lexer::token::token_type t) 
 04048 |             { 
 04049 |                invalid_comb_.insert(std::make_pair(base,t)); 
 04050 |             } 
 04051 |  
 04052 |             void add_invalid_set1(const lexer::token::token_type t) 
 04053 |             { 
 04054 |                add_invalid(t, lexer::token::e_assign); 
 04055 |                add_invalid(t, lexer::token::e_shr   ); 
 04056 |                add_invalid(t, lexer::token::e_shl   ); 
 04057 |                add_invalid(t, lexer::token::e_lte   ); 
 04058 |                add_invalid(t, lexer::token::e_ne    ); 
 04059 |                add_invalid(t, lexer::token::e_gte   ); 
 04060 |                add_invalid(t, lexer::token::e_lt    ); 
 04061 |                add_invalid(t, lexer::token::e_gt    ); 
 04062 |                add_invalid(t, lexer::token::e_eq    ); 
 04063 |                add_invalid(t, lexer::token::e_comma ); 
 04064 |                add_invalid(t, lexer::token::e_div   ); 
 04065 |                add_invalid(t, lexer::token::e_mul   ); 
 04066 |                add_invalid(t, lexer::token::e_mod   ); 
 04067 |                add_invalid(t, lexer::token::e_pow   ); 
 04068 |                add_invalid(t, lexer::token::e_colon ); 
 04069 |             } 
 04070 |  
 04071 |             bool invalid_bracket_check(const lexer::token::token_type base, const lexer::token::token_type t) 
 04072 |             { 
 04073 |                if (details::is_right_bracket(static_cast<details::char_t>(base))) 
 04074 |                { 
 04075 |                   switch (t) 
 04076 |                   { 
 04077 |                      case lexer::token::e_assign : return (']' != base); 
 04078 |                      case lexer::token::e_string : return (')' != base); 
 04079 |                      default                     : return false; 
 04080 |                   } 
 04081 |                } 
 04082 |                else if (details::is_left_bracket(static_cast<details::char_t>(base))) 
 04083 |                { 
 04084 |                   if (details::is_right_bracket(static_cast<details::char_t>(t))) 
 04085 |                      return false; 
 04086 |                   else if (details::is_left_bracket(static_cast<details::char_t>(t))) 
 04087 |                      return false; 
 04088 |                   else 
 04089 |                   { 
 04090 |                      switch (t) 
 04091 |                      { 
 04092 |                         case lexer::token::e_number  : return false; 
 04093 |                         case lexer::token::e_symbol  : return false; 
 04094 |                         case lexer::token::e_string  : return false; 
 04095 |                         case lexer::token::e_add     : return false; 
 04096 |                         case lexer::token::e_sub     : return false; 
 04097 |                         case lexer::token::e_colon   : return false; 
 04098 |                         case lexer::token::e_ternary : return false; 
 04099 |                         default                      : return true ; 
 04100 |                      } 
 04101 |                   } 
 04102 |                } 
 04103 |                else if (details::is_right_bracket(static_cast<details::char_t>(t))) 
 04104 |                { 
 04105 |                   switch (base) 
 04106 |                   { 
 04107 |                      case lexer::token::e_number  : return false; 
 04108 |                      case lexer::token::e_symbol  : return false; 
 04109 |                      case lexer::token::e_string  : return false; 
 04110 |                      case lexer::token::e_eof     : return false; 
 04111 |                      case lexer::token::e_colon   : return false; 
 04112 |                      case lexer::token::e_ternary : return false; 
 04113 |                      default                      : return true ; 
 04114 |                   } 
 04115 |                } 
 04116 |                else if (details::is_left_bracket(static_cast<details::char_t>(t))) 
 04117 |                { 
 04118 |                   switch (base) 
 04119 |                   { 
 04120 |                      case lexer::token::e_rbracket    : return true; 
 04121 |                      case lexer::token::e_rsqrbracket : return true; 
 04122 |                      case lexer::token::e_rcrlbracket : return true; 
 04123 |                      default                          : return false; 
 04124 |                   } 
 04125 |                } 
 04126 |  
 04127 |                return false; 
 04128 |             } 
 04129 |  
 04130 |             set_t invalid_comb_; 
 04131 |             std::vector<std::pair<lexer::token,lexer::token> > error_list_; 
 04132 |          }; 
 04133 |  
 04134 |          class sequence_validator_3tokens exprtk_final : public lexer::token_scanner 
 04135 |          { 
 04136 |          private: 
 04137 |  
 04138 |             typedef lexer::token::token_type token_t; 
 04139 |             typedef std::pair<token_t,std::pair<token_t,token_t> > token_triplet_t; 
 04140 |             typedef std::set<token_triplet_t> set_t; 
 04141 |  
 04142 |          public: 
 04143 |  
 04144 |             using lexer::token_scanner::operator(); 
 04145 |  
 04146 |             sequence_validator_3tokens() 
 04147 |             : lexer::token_scanner(3) 
 04148 |             { 
 04149 |                add_invalid(lexer::token::e_number , lexer::token::e_number , lexer::token::e_number); 
 04150 |                add_invalid(lexer::token::e_string , lexer::token::e_string , lexer::token::e_string); 
 04151 |                add_invalid(lexer::token::e_comma  , lexer::token::e_comma  , lexer::token::e_comma ); 
 04152 |  
 04153 |                add_invalid(lexer::token::e_add    , lexer::token::e_add    , lexer::token::e_add   ); 
 04154 |                add_invalid(lexer::token::e_sub    , lexer::token::e_sub    , lexer::token::e_sub   ); 
 04155 |                add_invalid(lexer::token::e_div    , lexer::token::e_div    , lexer::token::e_div   ); 
 04156 |                add_invalid(lexer::token::e_mul    , lexer::token::e_mul    , lexer::token::e_mul   ); 
 04157 |                add_invalid(lexer::token::e_mod    , lexer::token::e_mod    , lexer::token::e_mod   ); 
 04158 |                add_invalid(lexer::token::e_pow    , lexer::token::e_pow    , lexer::token::e_pow   ); 
 04159 |  
 04160 |                add_invalid(lexer::token::e_add    , lexer::token::e_sub    , lexer::token::e_add   ); 
 04161 |                add_invalid(lexer::token::e_sub    , lexer::token::e_add    , lexer::token::e_sub   ); 
 04162 |                add_invalid(lexer::token::e_div    , lexer::token::e_mul    , lexer::token::e_div   ); 
 04163 |                add_invalid(lexer::token::e_mul    , lexer::token::e_div    , lexer::token::e_mul   ); 
 04164 |                add_invalid(lexer::token::e_mod    , lexer::token::e_pow    , lexer::token::e_mod   ); 
 04165 |                add_invalid(lexer::token::e_pow    , lexer::token::e_mod    , lexer::token::e_pow   ); 
 04166 |             } 
 04167 |  
 04168 |             bool result() exprtk_override 
 04169 |             { 
 04170 |                return error_list_.empty(); 
 04171 |             } 
 04172 |  
 04173 |             bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2) exprtk_override 
 04174 |             { 
 04175 |                const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type)); 
 04176 |  
 04177 |                if (invalid_comb_.find(p) != invalid_comb_.end()) 
 04178 |                { 
 04179 |                   error_list_.push_back(std::make_pair(t0,t1)); 
 04180 |                } 
 04181 |  
 04182 |                return true; 
 04183 |             } 
 04184 |  
 04185 |             std::size_t error_count() const 
 04186 |             { 
 04187 |                return error_list_.size(); 
 04188 |             } 
 04189 |  
 04190 |             std::pair<lexer::token,lexer::token> error(const std::size_t index) 
 04191 |             { 
 04192 |                if (index < error_list_.size()) 
 04193 |                { 
 04194 |                   return error_list_[index]; 
 04195 |                } 
 04196 |                else 
 04197 |                { 
 04198 |                   static const lexer::token error_token; 
 04199 |                   return std::make_pair(error_token,error_token); 
 04200 |                } 
 04201 |             } 
 04202 |  
 04203 |             void clear_errors() 
 04204 |             { 
 04205 |                error_list_.clear(); 
 04206 |             } 
 04207 |  
 04208 |          private: 
 04209 |  
 04210 |             void add_invalid(const token_t t0, const token_t t1, const token_t t2) 
 04211 |             { 
 04212 |                invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2))); 
 04213 |             } 
 04214 |  
 04215 |             set_t invalid_comb_; 
 04216 |             std::vector<std::pair<lexer::token,lexer::token> > error_list_; 
 04217 |          }; 
 04218 |  
 04219 |          struct helper_assembly 
 04220 |          { 
 04221 |             inline bool register_scanner(lexer::token_scanner* scanner) 
 04222 |             { 
 04223 |                if (token_scanner_list.end() != std::find(token_scanner_list.begin(), 
 04224 |                                                          token_scanner_list.end  (), 
 04225 |                                                          scanner)) 
 04226 |                { 
 04227 |                   return false; 
 04228 |                } 
 04229 |  
 04230 |                token_scanner_list.push_back(scanner); 
 04231 |  
 04232 |                return true; 
 04233 |             } 
 04234 |  
 04235 |             inline bool register_modifier(lexer::token_modifier* modifier) 
 04236 |             { 
 04237 |                if (token_modifier_list.end() != std::find(token_modifier_list.begin(), 
 04238 |                                                           token_modifier_list.end  (), 
 04239 |                                                           modifier)) 
 04240 |                { 
 04241 |                   return false; 
 04242 |                } 
 04243 |  
 04244 |                token_modifier_list.push_back(modifier); 
 04245 |  
 04246 |                return true; 
 04247 |             } 
 04248 |  
 04249 |             inline bool register_joiner(lexer::token_joiner* joiner) 
 04250 |             { 
 04251 |                if (token_joiner_list.end() != std::find(token_joiner_list.begin(), 
 04252 |                                                         token_joiner_list.end  (), 
 04253 |                                                         joiner)) 
 04254 |                { 
 04255 |                   return false; 
 04256 |                } 
 04257 |  
 04258 |                token_joiner_list.push_back(joiner); 
 04259 |  
 04260 |                return true; 
 04261 |             } 
 04262 |  
 04263 |             inline bool register_inserter(lexer::token_inserter* inserter) 
 04264 |             { 
 04265 |                if (token_inserter_list.end() != std::find(token_inserter_list.begin(), 
 04266 |                                                           token_inserter_list.end  (), 
 04267 |                                                           inserter)) 
 04268 |                { 
 04269 |                   return false; 
 04270 |                } 
 04271 |  
 04272 |                token_inserter_list.push_back(inserter); 
 04273 |  
 04274 |                return true; 
 04275 |             } 
 04276 |  
 04277 |             inline bool run_modifiers(lexer::generator& g) 
 04278 |             { 
 04279 |                error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0); 
 04280 |  
 04281 |                for (std::size_t i = 0; i < token_modifier_list.size(); ++i) 
 04282 |                { 
 04283 |                   lexer::token_modifier& modifier = (*token_modifier_list[i]); 
 04284 |  
 04285 |                   modifier.reset(); 
 04286 |                   modifier.process(g); 
 04287 |  
 04288 |                   if (!modifier.result()) 
 04289 |                   { 
 04290 |                      error_token_modifier = token_modifier_list[i]; 
 04291 |  
 04292 |                      return false; 
 04293 |                   } 
 04294 |                } 
 04295 |  
 04296 |                return true; 
 04297 |             } 
 04298 |  
 04299 |             inline bool run_joiners(lexer::generator& g) 
 04300 |             { 
 04301 |                error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0); 
 04302 |  
 04303 |                for (std::size_t i = 0; i < token_joiner_list.size(); ++i) 
 04304 |                { 
 04305 |                   lexer::token_joiner& joiner = (*token_joiner_list[i]); 
 04306 |  
 04307 |                   joiner.reset(); 
 04308 |                   joiner.process(g); 
 04309 |  
 04310 |                   if (!joiner.result()) 
 04311 |                   { 
 04312 |                      error_token_joiner = token_joiner_list[i]; 
 04313 |  
 04314 |                      return false; 
 04315 |                   } 
 04316 |                } 
 04317 |  
 04318 |                return true; 
 04319 |             } 
 04320 |  
 04321 |             inline bool run_inserters(lexer::generator& g) 
 04322 |             { 
 04323 |                error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0); 
 04324 |  
 04325 |                for (std::size_t i = 0; i < token_inserter_list.size(); ++i) 
 04326 |                { 
 04327 |                   lexer::token_inserter& inserter = (*token_inserter_list[i]); 
 04328 |  
 04329 |                   inserter.reset(); 
 04330 |                   inserter.process(g); 
 04331 |  
 04332 |                   if (!inserter.result()) 
 04333 |                   { 
 04334 |                      error_token_inserter = token_inserter_list[i]; 
 04335 |  
 04336 |                      return false; 
 04337 |                   } 
 04338 |                } 
 04339 |  
 04340 |                return true; 
 04341 |             } 
 04342 |  
 04343 |             inline bool run_scanners(lexer::generator& g) 
 04344 |             { 
 04345 |                error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0); 
 04346 |  
 04347 |                for (std::size_t i = 0; i < token_scanner_list.size(); ++i) 
 04348 |                { 
 04349 |                   lexer::token_scanner& scanner = (*token_scanner_list[i]); 
 04350 |  
 04351 |                   scanner.reset(); 
 04352 |                   scanner.process(g); 
 04353 |  
 04354 |                   if (!scanner.result()) 
 04355 |                   { 
 04356 |                      error_token_scanner = token_scanner_list[i]; 
 04357 |  
 04358 |                      return false; 
 04359 |                   } 
 04360 |                } 
 04361 |  
 04362 |                return true; 
 04363 |             } 
 04364 |  
 04365 |             std::vector<lexer::token_scanner*>  token_scanner_list; 
 04366 |             std::vector<lexer::token_modifier*> token_modifier_list; 
 04367 |             std::vector<lexer::token_joiner*>   token_joiner_list; 
 04368 |             std::vector<lexer::token_inserter*> token_inserter_list; 
 04369 |  
 04370 |             lexer::token_scanner*  error_token_scanner; 
 04371 |             lexer::token_modifier* error_token_modifier; 
 04372 |             lexer::token_joiner*   error_token_joiner; 
 04373 |             lexer::token_inserter* error_token_inserter; 
 04374 |          }; 
 04375 |       } 
 04376 |  
 04377 |       class parser_helper 
 04378 |       { 
 04379 |       public: 
 04380 |  
 04381 |          typedef token     token_t; 
 04382 |          typedef generator generator_t; 
 04383 |  
 04384 |          inline bool init(const std::string& str) 
 04385 |          { 
 04386 |             if (!lexer_.process(str)) 
 04387 |             { 
 04388 |                return false; 
 04389 |             } 
 04390 |  
 04391 |             lexer_.begin(); 
 04392 |  
 04393 |             next_token(); 
 04394 |  
 04395 |             return true; 
 04396 |          } 
 04397 |  
 04398 |          inline generator_t& lexer() 
 04399 |          { 
 04400 |             return lexer_; 
 04401 |          } 
 04402 |  
 04403 |          inline const generator_t& lexer() const 
 04404 |          { 
 04405 |             return lexer_; 
 04406 |          } 
 04407 |  
 04408 |          inline void store_token() 
 04409 |          { 
 04410 |             lexer_.store(); 
 04411 |             store_current_token_ = current_token_; 
 04412 |          } 
 04413 |  
 04414 |          inline void restore_token() 
 04415 |          { 
 04416 |             lexer_.restore(); 
 04417 |             current_token_ = store_current_token_; 
 04418 |          } 
 04419 |  
 04420 |          inline void next_token() 
 04421 |          { 
 04422 |             current_token_ = lexer_.next_token(); 
 04423 |          } 
 04424 |  
 04425 |          inline const token_t& current_token() const 
 04426 |          { 
 04427 |             return current_token_; 
 04428 |          } 
 04429 |  
 04430 |          inline const token_t& peek_next_token() 
 04431 |          { 
 04432 |             return lexer_.peek_next_token(); 
 04433 |          } 
 04434 |  
 04435 |          enum token_advance_mode 
 04436 |          { 
 04437 |             e_hold    = 0, 
 04438 |             e_advance = 1 
 04439 |          }; 
 04440 |  
 04441 |          inline void advance_token(const token_advance_mode mode) 
 04442 |          { 
 04443 |             if (e_advance == mode) 
 04444 |             { 
 04445 |                next_token(); 
 04446 |             } 
 04447 |          } 
 04448 |  
 04449 |          inline bool token_is(const token_t::token_type& ttype, const token_advance_mode mode = e_advance) 
 04450 |          { 
 04451 |             if (current_token().type != ttype) 
 04452 |             { 
 04453 |                return false; 
 04454 |             } 
 04455 |  
 04456 |             advance_token(mode); 
 04457 |  
 04458 |             return true; 
 04459 |          } 
 04460 |  
 04461 |          inline bool token_is(const token_t::token_type& ttype, 
 04462 |                               const std::string& value, 
 04463 |                               const token_advance_mode mode = e_advance) 
 04464 |          { 
 04465 |             if ( 
 04466 |                  (current_token().type != ttype) || 
 04467 |                  !exprtk::details::imatch(value,current_token().value) 
 04468 |                ) 
 04469 |             { 
 04470 |                return false; 
 04471 |             } 
 04472 |  
 04473 |             advance_token(mode); 
 04474 |  
 04475 |             return true; 
 04476 |          } 
 04477 |  
 04478 |          inline bool token_is(const std::string& value, 
 04479 |                               const token_advance_mode mode = e_advance) 
 04480 |          { 
 04481 |             if (!exprtk::details::imatch(value,current_token().value)) 
 04482 |             { 
 04483 |                return false; 
 04484 |             } 
 04485 |  
 04486 |             advance_token(mode); 
 04487 |  
 04488 |             return true; 
 04489 |          } 
 04490 |  
 04491 |          inline bool token_is_arithmetic_opr(const token_advance_mode mode = e_advance) 
 04492 |          { 
 04493 |             switch (current_token().type) 
 04494 |             { 
 04495 |                case token_t::e_add : 
 04496 |                case token_t::e_sub : 
 04497 |                case token_t::e_div : 
 04498 |                case token_t::e_mul : 
 04499 |                case token_t::e_mod : 
 04500 |                case token_t::e_pow : break; 
 04501 |                default             : return false; 
 04502 |             } 
 04503 |  
 04504 |             advance_token(mode); 
 04505 |  
 04506 |             return true; 
 04507 |          } 
 04508 |  
 04509 |          inline bool token_is_ineq_opr(const token_advance_mode mode = e_advance) 
 04510 |          { 
 04511 |             switch (current_token().type) 
 04512 |             { 
 04513 |                case token_t::e_eq  : 
 04514 |                case token_t::e_lte : 
 04515 |                case token_t::e_ne  : 
 04516 |                case token_t::e_gte : 
 04517 |                case token_t::e_lt  : 
 04518 |                case token_t::e_gt  : break; 
 04519 |                default             : return false; 
 04520 |             } 
 04521 |  
 04522 |             advance_token(mode); 
 04523 |  
 04524 |             return true; 
 04525 |          } 
 04526 |  
 04527 |          inline bool token_is_left_bracket(const token_advance_mode mode = e_advance) 
 04528 |          { 
 04529 |             switch (current_token().type) 
 04530 |             { 
 04531 |                case token_t::e_lbracket    : 
 04532 |                case token_t::e_lcrlbracket : 
 04533 |                case token_t::e_lsqrbracket : break; 
 04534 |                default                     : return false; 
 04535 |             } 
 04536 |  
 04537 |             advance_token(mode); 
 04538 |  
 04539 |             return true; 
 04540 |          } 
 04541 |  
 04542 |          inline bool token_is_right_bracket(const token_advance_mode mode = e_advance) 
 04543 |          { 
 04544 |             switch (current_token().type) 
 04545 |             { 
 04546 |                case token_t::e_rbracket    : 
 04547 |                case token_t::e_rcrlbracket : 
 04548 |                case token_t::e_rsqrbracket : break; 
 04549 |                default                     : return false; 
 04550 |             } 
 04551 |  
 04552 |             advance_token(mode); 
 04553 |  
 04554 |             return true; 
 04555 |          } 
 04556 |  
 04557 |          inline bool token_is_bracket(const token_advance_mode mode = e_advance) 
 04558 |          { 
 04559 |             switch (current_token().type) 
 04560 |             { 
 04561 |                case token_t::e_rbracket    : 
 04562 |                case token_t::e_rcrlbracket : 
 04563 |                case token_t::e_rsqrbracket : 
 04564 |                case token_t::e_lbracket    : 
 04565 |                case token_t::e_lcrlbracket : 
 04566 |                case token_t::e_lsqrbracket : break; 
 04567 |                default                     : return false; 
 04568 |             } 
 04569 |  
 04570 |             advance_token(mode); 
 04571 |  
 04572 |             return true; 
 04573 |          } 
 04574 |  
 04575 |          inline bool token_is_loop(const token_advance_mode mode = e_advance) 
 04576 |          { 
 04577 |             return token_is("for"   , mode) || 
 04578 |                    token_is("while" , mode) || 
 04579 |                    token_is("repeat", mode) ; 
 04580 |          } 
 04581 |  
 04582 |          inline bool peek_token_is(const token_t::token_type& ttype) 
 04583 |          { 
 04584 |             return (lexer_.peek_next_token().type == ttype); 
 04585 |          } 
 04586 |  
 04587 |          inline bool peek_token_is(const std::string& s) 
 04588 |          { 
 04589 |             return (exprtk::details::imatch(lexer_.peek_next_token().value,s)); 
 04590 |          } 
 04591 |  
 04592 |       private: 
 04593 |  
 04594 |          generator_t lexer_; 
 04595 |          token_t     current_token_; 
 04596 |          token_t     store_current_token_; 
 04597 |       }; 
 04598 |    } 
 04599 |  
 04600 |    template <typename T> 
 04601 |    class vector_view 
 04602 |    { 
 04603 |    public: 
 04604 |  
 04605 |       typedef T* data_ptr_t; 
 04606 |  
 04607 |       vector_view(data_ptr_t data, const std::size_t& size) 
 04608 |       : base_size_(size) 
 04609 |       , size_(size) 
 04610 |       , data_(data) 
 04611 |       , data_ref_(0) 
 04612 |       { 
 04613 |          assert(size_ > 0); 
 04614 |       } 
 04615 |  
 04616 |       vector_view(const vector_view<T>& vv) 
 04617 |       : base_size_(vv.base_size_) 
 04618 |       , size_(vv.size_) 
 04619 |       , data_(vv.data_) 
 04620 |       , data_ref_(0) 
 04621 |       { 
 04622 |          assert(size_ > 0); 
 04623 |       } 
 04624 |  
 04625 |       inline void rebase(data_ptr_t data) 
 04626 |       { 
 04627 |          data_ = data; 
 04628 |  
 04629 |          if (!data_ref_.empty()) 
 04630 |          { 
 04631 |             for (std::size_t i = 0; i < data_ref_.size(); ++i) 
 04632 |             { 
 04633 |                (*data_ref_[i]) = data; 
 04634 |             } 
 04635 |          } 
 04636 |       } 
 04637 |  
 04638 |       inline data_ptr_t data() const 
 04639 |       { 
 04640 |          return data_; 
 04641 |       } 
 04642 |  
 04643 |       inline std::size_t base_size() const 
 04644 |       { 
 04645 |          return base_size_; 
 04646 |       } 
 04647 |  
 04648 |       inline std::size_t size() const 
 04649 |       { 
 04650 |          return size_; 
 04651 |       } 
 04652 |  
 04653 |       inline const T& operator[](const std::size_t index) const 
 04654 |       { 
 04655 |          assert(index < size_); 
 04656 |          return data_[index]; 
 04657 |       } 
 04658 |  
 04659 |       inline T& operator[](const std::size_t index) 
 04660 |       { 
 04661 |          assert(index < size_); 
 04662 |          return data_[index]; 
 04663 |       } 
 04664 |  
 04665 |       void set_ref(data_ptr_t* data_ref) 
 04666 |       { 
 04667 |          data_ref_.push_back(data_ref); 
 04668 |          exprtk_debug(("vector_view::set_ref() - data_ref: %p data_ref_.size(): %d\n", 
 04669 |                        reinterpret_cast<void*>(data_ref), 
 04670 |                        static_cast<int>(data_ref_.size()))); 
 04671 |       } 
 04672 |  
 04673 |       void remove_ref(data_ptr_t* data_ref) 
 04674 |       { 
 04675 |          data_ref_.erase( 
 04676 |             std::remove(data_ref_.begin(), data_ref_.end(), data_ref), 
 04677 |             data_ref_.end()); 
 04678 |          exprtk_debug(("vector_view::remove_ref() - data_ref: %p data_ref_.size(): %d\n", 
 04679 |                        reinterpret_cast<void*>(data_ref), 
 04680 |                        static_cast<int>(data_ref_.size()))); 
 04681 |       } 
 04682 |  
 04683 |       bool set_size(const std::size_t new_size) 
 04684 |       { 
 04685 |          if ((new_size > 0) && (new_size <= base_size_)) 
 04686 |          { 
 04687 |             size_ = new_size; 
 04688 |             exprtk_debug(("vector_view::set_size() - data_: %p size: %lu\n", 
 04689 |                           reinterpret_cast<void*>(data_), 
 04690 |                           size_)); 
 04691 |             return true; 
 04692 |          } 
 04693 |  
 04694 |          exprtk_debug(("vector_view::set_size() - error invalid new_size: %lu  base_size: %lu\n", 
 04695 |                        new_size, 
 04696 |                        base_size_)); 
 04697 |          return false; 
 04698 |       } 
 04699 |  
 04700 |    private: 
 04701 |  
 04702 |       const std::size_t base_size_; 
 04703 |       std::size_t size_; 
 04704 |       data_ptr_t  data_; 
 04705 |       std::vector<data_ptr_t*> data_ref_; 
 04706 |    }; 
 04707 |  
 04708 |    template <typename T> 
 04709 |    inline vector_view<T> make_vector_view(T* data, 
 04710 |                                           const std::size_t size, const std::size_t offset = 0) 
 04711 |    { 
 04712 |       return vector_view<T>(data + offset, size); 
 04713 |    } 
 04714 |  
 04715 |    template <typename T> 
 04716 |    inline vector_view<T> make_vector_view(std::vector<T>& v, 
 04717 |                                           const std::size_t size, const std::size_t offset = 0) 
 04718 |    { 
 04719 |       return vector_view<T>(v.data() + offset, size); 
 04720 |    } 
 04721 |  
 04722 |    template <typename T> class results_context; 
 04723 |  
 04724 |    template <typename T> 
 04725 |    struct type_store 
 04726 |    { 
 04727 |       enum store_type 
 04728 |       { 
 04729 |          e_unknown, 
 04730 |          e_scalar , 
 04731 |          e_vector , 
 04732 |          e_string 
 04733 |       }; 
 04734 |  
 04735 |       type_store() 
 04736 |       : data(0) 
 04737 |       , size(0) 
 04738 |       , type(e_unknown) 
 04739 |       {} 
 04740 |  
 04741 |       union 
 04742 |       { 
 04743 |          void* data; 
 04744 |          T*    vec_data; 
 04745 |       }; 
 04746 |  
 04747 |       std::size_t size; 
 04748 |       store_type  type; 
 04749 |  
 04750 |       class parameter_list 
 04751 |       { 
 04752 |       public: 
 04753 |  
 04754 |          explicit parameter_list(std::vector<type_store>& pl) 
 04755 |          : parameter_list_(pl) 
 04756 |          {} 
 04757 |  
 04758 |          inline bool empty() const 
 04759 |          { 
 04760 |             return parameter_list_.empty(); 
 04761 |          } 
 04762 |  
 04763 |          inline std::size_t size() const 
 04764 |          { 
 04765 |             return parameter_list_.size(); 
 04766 |          } 
 04767 |  
 04768 |          inline type_store& operator[](const std::size_t& index) 
 04769 |          { 
 04770 |             return parameter_list_[index]; 
 04771 |          } 
 04772 |  
 04773 |          inline const type_store& operator[](const std::size_t& index) const 
 04774 |          { 
 04775 |             return parameter_list_[index]; 
 04776 |          } 
 04777 |  
 04778 |          inline type_store& front() 
 04779 |          { 
 04780 |             return parameter_list_[0]; 
 04781 |          } 
 04782 |  
 04783 |          inline const type_store& front() const 
 04784 |          { 
 04785 |             return parameter_list_[0]; 
 04786 |          } 
 04787 |  
 04788 |          inline type_store& back() 
 04789 |          { 
 04790 |             return parameter_list_.back(); 
 04791 |          } 
 04792 |  
 04793 |          inline const type_store& back() const 
 04794 |          { 
 04795 |             return parameter_list_.back(); 
 04796 |          } 
 04797 |  
 04798 |       private: 
 04799 |  
 04800 |          std::vector<type_store>& parameter_list_; 
 04801 |  
 04802 |          friend class results_context<T>; 
 04803 |       }; 
 04804 |  
 04805 |       template <typename ViewType> 
 04806 |       struct type_view 
 04807 |       { 
 04808 |          typedef type_store<T> type_store_t; 
 04809 |          typedef ViewType      value_t; 
 04810 |  
 04811 |          explicit type_view(type_store_t& ts) 
 04812 |          : ts_(ts) 
 04813 |          , data_(reinterpret_cast<value_t*>(ts_.data)) 
 04814 |          {} 
 04815 |  
 04816 |          explicit type_view(const type_store_t& ts) 
 04817 |          : ts_(const_cast<type_store_t&>(ts)) 
 04818 |          , data_(reinterpret_cast<value_t*>(ts_.data)) 
 04819 |          {} 
 04820 |  
 04821 |          inline std::size_t size() const 
 04822 |          { 
 04823 |             return ts_.size; 
 04824 |          } 
 04825 |  
 04826 |          inline value_t& operator[](const std::size_t& i) 
 04827 |          { 
 04828 |             return data_[i]; 
 04829 |          } 
 04830 |  
 04831 |          inline const value_t& operator[](const std::size_t& i) const 
 04832 |          { 
 04833 |             return data_[i]; 
 04834 |          } 
 04835 |  
 04836 |          inline const value_t* begin() const { return data_; } 
 04837 |          inline       value_t* begin()       { return data_; } 
 04838 |  
 04839 |          inline const value_t* end() const 
 04840 |          { 
 04841 |             return static_cast<value_t*>(data_ + ts_.size); 
 04842 |          } 
 04843 |  
 04844 |          inline value_t* end() 
 04845 |          { 
 04846 |             return static_cast<value_t*>(data_ + ts_.size); 
 04847 |          } 
 04848 |  
 04849 |          type_store_t& ts_; 
 04850 |          value_t* data_; 
 04851 |       }; 
 04852 |  
 04853 |       typedef type_view<T>    vector_view; 
 04854 |       typedef type_view<char> string_view; 
 04855 |  
 04856 |       struct scalar_view 
 04857 |       { 
 04858 |          typedef type_store<T> type_store_t; 
 04859 |          typedef T value_t; 
 04860 |  
 04861 |          explicit scalar_view(type_store_t& ts) 
 04862 |          : v_(*reinterpret_cast<value_t*>(ts.data)) 
 04863 |          {} 
 04864 |  
 04865 |          explicit scalar_view(const type_store_t& ts) 
 04866 |          : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data)) 
 04867 |          {} 
 04868 |  
 04869 |          inline value_t& operator() () 
 04870 |          { 
 04871 |             return v_; 
 04872 |          } 
 04873 |  
 04874 |          inline const value_t& operator() () const 
 04875 |          { 
 04876 |             return v_; 
 04877 |          } 
 04878 |  
 04879 |          inline operator value_t() const 
 04880 |          { 
 04881 |             return v_; 
 04882 |          } 
 04883 |  
 04884 |          inline operator value_t() 
 04885 |          { 
 04886 |             return v_; 
 04887 |          } 
 04888 |  
 04889 |          template <typename IntType> 
 04890 |          inline bool to_int(IntType& i) const 
 04891 |          { 
 04892 |             if (!exprtk::details::numeric::is_integer(v_)) 
 04893 |                return false; 
 04894 |  
 04895 |             i = static_cast<IntType>(v_); 
 04896 |  
 04897 |             return true; 
 04898 |          } 
 04899 |  
 04900 |          template <typename UIntType> 
 04901 |          inline bool to_uint(UIntType& u) const 
 04902 |          { 
 04903 |             if (v_ < T(0)) 
 04904 |                return false; 
 04905 |             else if (!exprtk::details::numeric::is_integer(v_)) 
 04906 |                return false; 
 04907 |  
 04908 |             u = static_cast<UIntType>(v_); 
 04909 |  
 04910 |             return true; 
 04911 |          } 
 04912 |  
 04913 |          T& v_; 
 04914 |       }; 
 04915 |    }; 
 04916 |  
 04917 |    template <typename StringView> 
 04918 |    inline std::string to_str(const StringView& view) 
 04919 |    { 
 04920 |       return std::string(view.begin(),view.size()); 
 04921 |    } 
 04922 |  
 04923 |    #ifndef exprtk_disable_return_statement 
 04924 |    namespace details 
 04925 |    { 
 04926 |       template <typename T> class return_node; 
 04927 |       template <typename T> class return_envelope_node; 
 04928 |    } 
 04929 |    #endif 
 04930 |  
 04931 |    template <typename T> 
 04932 |    class results_context 
 04933 |    { 
 04934 |    public: 
 04935 |  
 04936 |       typedef type_store<T> type_store_t; 
 04937 |       typedef typename type_store_t::scalar_view scalar_t; 
 04938 |       typedef typename type_store_t::vector_view vector_t; 
 04939 |       typedef typename type_store_t::string_view string_t; 
 04940 |  
 04941 |       results_context() 
 04942 |       : results_available_(false) 
 04943 |       {} 
 04944 |  
 04945 |       inline std::size_t count() const 
 04946 |       { 
 04947 |          if (results_available_) 
 04948 |             return parameter_list_.size(); 
 04949 |          else 
 04950 |             return 0; 
 04951 |       } 
 04952 |  
 04953 |       inline type_store_t& operator[](const std::size_t& index) 
 04954 |       { 
 04955 |          return parameter_list_[index]; 
 04956 |       } 
 04957 |  
 04958 |       inline const type_store_t& operator[](const std::size_t& index) const 
 04959 |       { 
 04960 |          return parameter_list_[index]; 
 04961 |       } 
 04962 |  
 04963 |       inline bool get_scalar(const std::size_t& index, T& out) const 
 04964 |       { 
 04965 |          if ( 
 04966 |               (index < parameter_list_.size()) && 
 04967 |               (parameter_list_[index].type == type_store_t::e_scalar) 
 04968 |             ) 
 04969 |          { 
 04970 |             const scalar_t scalar(parameter_list_[index]); 
 04971 |             out = scalar(); 
 04972 |             return true; 
 04973 |          } 
 04974 |  
 04975 |          return false; 
 04976 |       } 
 04977 |  
 04978 |       template <typename OutputIterator> 
 04979 |       inline bool get_vector(const std::size_t& index, OutputIterator out_itr) const 
 04980 |       { 
 04981 |          if ( 
 04982 |               (index < parameter_list_.size()) && 
 04983 |               (parameter_list_[index].type == type_store_t::e_vector) 
 04984 |             ) 
 04985 |          { 
 04986 |             const vector_t vector(parameter_list_[index]); 
 04987 |             for (std::size_t i = 0; i < vector.size(); ++i) 
 04988 |             { 
 04989 |                *(out_itr++) = vector[i]; 
 04990 |             } 
 04991 |  
 04992 |             return true; 
 04993 |          } 
 04994 |  
 04995 |          return false; 
 04996 |       } 
 04997 |  
 04998 |       inline bool get_vector(const std::size_t& index, std::vector<T>& out) const 
 04999 |       { 
 05000 |          return get_vector(index,std::back_inserter(out)); 
 05001 |       } 
 05002 |  
 05003 |       inline bool get_string(const std::size_t& index, std::string& out) const 
 05004 |       { 
 05005 |          if ( 
 05006 |               (index < parameter_list_.size()) && 
 05007 |               (parameter_list_[index].type == type_store_t::e_string) 
 05008 |             ) 
 05009 |          { 
 05010 |             const string_t str(parameter_list_[index]); 
 05011 |             out.assign(str.begin(),str.size()); 
 05012 |             return true; 
 05013 |          } 
 05014 |  
 05015 |          return false; 
 05016 |       } 
 05017 |  
 05018 |    private: 
 05019 |  
 05020 |       inline void clear() 
 05021 |       { 
 05022 |          results_available_ = false; 
 05023 |       } 
 05024 |  
 05025 |       typedef std::vector<type_store_t> ts_list_t; 
 05026 |       typedef typename type_store_t::parameter_list parameter_list_t; 
 05027 |  
 05028 |       inline void assign(const parameter_list_t& pl) 
 05029 |       { 
 05030 |          parameter_list_    = pl.parameter_list_; 
 05031 |          results_available_ = true; 
 05032 |       } 
 05033 |  
 05034 |       bool results_available_; 
 05035 |       ts_list_t parameter_list_; 
 05036 |  
 05037 |       #ifndef exprtk_disable_return_statement 
 05038 |       friend class details::return_node<T>; 
 05039 |       friend class details::return_envelope_node<T>; 
 05040 |       #endif 
 05041 |    }; 
 05042 |  
 05043 |    namespace details 
 05044 |    { 
 05045 |       enum operator_type 
 05046 |       { 
 05047 |          e_default , e_null    , e_add     , e_sub     , 
 05048 |          e_mul     , e_div     , e_mod     , e_pow     , 
 05049 |          e_atan2   , e_min     , e_max     , e_avg     , 
 05050 |          e_sum     , e_prod    , e_lt      , e_lte     , 
 05051 |          e_eq      , e_equal   , e_ne      , e_nequal  , 
 05052 |          e_gte     , e_gt      , e_and     , e_nand    , 
 05053 |          e_or      , e_nor     , e_xor     , e_xnor    , 
 05054 |          e_mand    , e_mor     , e_scand   , e_scor    , 
 05055 |          e_shr     , e_shl     , e_abs     , e_acos    , 
 05056 |          e_acosh   , e_asin    , e_asinh   , e_atan    , 
 05057 |          e_atanh   , e_ceil    , e_cos     , e_cosh    , 
 05058 |          e_exp     , e_expm1   , e_floor   , e_log     , 
 05059 |          e_log10   , e_log2    , e_log1p   , e_logn    , 
 05060 |          e_neg     , e_pos     , e_round   , e_roundn  , 
 05061 |          e_root    , e_sqrt    , e_sin     , e_sinc    , 
 05062 |          e_sinh    , e_sec     , e_csc     , e_tan     , 
 05063 |          e_tanh    , e_cot     , e_clamp   , e_iclamp  , 
 05064 |          e_inrange , e_sgn     , e_r2d     , e_d2r     , 
 05065 |          e_d2g     , e_g2d     , e_hypot   , e_notl    , 
 05066 |          e_erf     , e_erfc    , e_ncdf    , e_frac    , 
 05067 |          e_trunc   , e_assign  , e_addass  , e_subass  , 
 05068 |          e_mulass  , e_divass  , e_modass  , e_in      , 
 05069 |          e_like    , e_ilike   , e_multi   , e_smulti  , 
 05070 |          e_swap    , 
 05071 |  
 05072 |          // Do not add new functions/operators after this point. 
 05073 |          e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003, 
 05074 |          e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007, 
 05075 |          e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011, 
 05076 |          e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015, 
 05077 |          e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019, 
 05078 |          e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023, 
 05079 |          e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027, 
 05080 |          e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031, 
 05081 |          e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035, 
 05082 |          e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039, 
 05083 |          e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043, 
 05084 |          e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047, 
 05085 |          e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051, 
 05086 |          e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055, 
 05087 |          e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059, 
 05088 |          e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063, 
 05089 |          e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067, 
 05090 |          e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071, 
 05091 |          e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075, 
 05092 |          e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079, 
 05093 |          e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083, 
 05094 |          e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087, 
 05095 |          e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091, 
 05096 |          e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095, 
 05097 |          e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099, 
 05098 |          e_sffinal  = 1100, 
 05099 |          e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003, 
 05100 |          e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007, 
 05101 |          e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011, 
 05102 |          e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015, 
 05103 |          e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019, 
 05104 |          e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023, 
 05105 |          e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027, 
 05106 |          e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031, 
 05107 |          e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035, 
 05108 |          e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039, 
 05109 |          e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043, 
 05110 |          e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047, 
 05111 |          e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051, 
 05112 |          e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055, 
 05113 |          e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059, 
 05114 |          e_sf4ext60 = 2060, e_sf4ext61 = 2061 
 05115 |       }; 
 05116 |  
 05117 |       inline std::string to_str(const operator_type opr) 
 05118 |       { 
 05119 |          switch (opr) 
 05120 |          { 
 05121 |             case e_add    : return  "+"  ; 
 05122 |             case e_sub    : return  "-"  ; 
 05123 |             case e_mul    : return  "*"  ; 
 05124 |             case e_div    : return  "/"  ; 
 05125 |             case e_mod    : return  "%"  ; 
 05126 |             case e_pow    : return  "^"  ; 
 05127 |             case e_assign : return ":="  ; 
 05128 |             case e_addass : return "+="  ; 
 05129 |             case e_subass : return "-="  ; 
 05130 |             case e_mulass : return "*="  ; 
 05131 |             case e_divass : return "/="  ; 
 05132 |             case e_modass : return "%="  ; 
 05133 |             case e_lt     : return  "<"  ; 
 05134 |             case e_lte    : return "<="  ; 
 05135 |             case e_eq     : return "=="  ; 
 05136 |             case e_equal  : return  "="  ; 
 05137 |             case e_ne     : return "!="  ; 
 05138 |             case e_nequal : return "<>"  ; 
 05139 |             case e_gte    : return ">="  ; 
 05140 |             case e_gt     : return  ">"  ; 
 05141 |             case e_and    : return "and" ; 
 05142 |             case e_or     : return "or"  ; 
 05143 |             case e_xor    : return "xor" ; 
 05144 |             case e_nand   : return "nand" 
 05145 |             case e_nor    : return "nor" ; 
 05146 |             case e_xnor   : return "xnor" 
 05147 |             default       : return "N/A" ; 
 05148 |          } 
 05149 |       } 
 05150 |  
 05151 |       struct base_operation_t 
 05152 |       { 
 05153 |          base_operation_t(const operator_type t, const unsigned int& np) 
 05154 |          : type(t) 
 05155 |          , num_params(np) 
 05156 |          {} 
 05157 |  
 05158 |          operator_type type; 
 05159 |          unsigned int num_params; 
 05160 |       }; 
 05161 |  
 05162 |       namespace loop_unroll 
 05163 |       { 
 05164 |          const unsigned int global_loop_batch_size = 
 05165 |          #ifndef exprtk_disable_superscalar_unroll 
 05166 |          16; 
 05167 |          #else 
 05168 |           4; 
 05169 |          #endif 
 05170 |  
 05171 |          struct details 
 05172 |          { 
 05173 |             explicit details(const std::size_t& vsize, 
 05174 |                              const unsigned int loop_batch_size = global_loop_batch_size) 
 05175 |             : batch_size(loop_batch_size   ) 
 05176 |             , remainder (vsize % batch_size) 
 05177 |             , upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0))) 
 05178 |             {} 
 05179 |  
 05180 |             unsigned int batch_size; 
 05181 |             int remainder; 
 05182 |             int upper_bound; 
 05183 |          }; 
 05184 |       } 
 05185 |  
 05186 |       #ifdef exprtk_enable_debugging 
 05187 |       inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0) 
 05188 |       { 
 05189 |          if (size) 
 05190 |             exprtk_debug(("%s - addr: %p size: %d\n", 
 05191 |                           s.c_str(), 
 05192 |                           ptr, 
 05193 |                           static_cast<unsigned int>(size))); 
 05194 |          else 
 05195 |             exprtk_debug(("%s - addr: %p\n", s.c_str(), ptr)); 
 05196 |       } 
 05197 |  
 05198 |       template <typename T> 
 05199 |       inline void dump_vector(const std::string& vec_name, const T* data, const std::size_t size) 
 05200 |       { 
 05201 |          printf("----- %s (%p) -----\n", 
 05202 |                 vec_name.c_str(), 
 05203 |                 static_cast<const void*>(data)); 
 05204 |          printf("[ "); 
 05205 |          for (std::size_t i = 0; i <  size; ++i) 
 05206 |          { 
 05207 |             printf("%8.3f\t", data[i]); 
 05208 |          } 
 05209 |          printf(" ]\n"); 
 05210 |          printf("---------------------\n"); 
 05211 |       } 
 05212 |       #else 
 05213 |       inline void dump_ptr(const std::string&, const void*) {} 
 05214 |       inline void dump_ptr(const std::string&, const void*, const std::size_t) {} 
 05215 |       template <typename T> 
 05216 |       inline void dump_vector(const std::string&, const T*, const std::size_t) {} 
 05217 |       #endif 
 05218 |  
 05219 |       template <typename T> 
 05220 |       class vec_data_store 
 05221 |       { 
 05222 |       public: 
 05223 |  
 05224 |          typedef vec_data_store<T> type; 
 05225 |          typedef T* data_t; 
 05226 |  
 05227 |       private: 
 05228 |  
 05229 |          struct control_block 
 05230 |          { 
 05231 |             control_block() 
 05232 |             : ref_count(1) 
 05233 |             , size     (0) 
 05234 |             , data     (0) 
 05235 |             , destruct (true) 
 05236 |             {} 
 05237 |  
 05238 |             explicit control_block(const std::size_t& dsize) 
 05239 |             : ref_count(1    ) 
 05240 |             , size     (dsize) 
 05241 |             , data     (0    ) 
 05242 |             , destruct (true ) 
 05243 |             { create_data(); } 
 05244 |  
 05245 |             control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false) 
 05246 |             : ref_count(1     ) 
 05247 |             , size     (dsize ) 
 05248 |             , data     (dptr  ) 
 05249 |             , destruct (dstrct) 
 05250 |             {} 
 05251 |  
 05252 |            ~control_block() 
 05253 |             { 
 05254 |                if (data && destruct && (0 == ref_count)) 
 05255 |                { 
 05256 |                   dump_ptr("~vec_data_store::control_block() data",data); 
 05257 |                   delete[] data; 
 05258 |                   data = reinterpret_cast<data_t>(0); 
 05259 |                } 
 05260 |             } 
 05261 |  
 05262 |             static inline control_block* create(const std::size_t& dsize, data_t data_ptr = data_t(0), bool dstrct = false) 
 05263 |             { 
 05264 |                if (dsize) 
 05265 |                { 
 05266 |                   if (0 == data_ptr) 
 05267 |                      return (new control_block(dsize)); 
 05268 |                   else 
 05269 |                      return (new control_block(dsize, data_ptr, dstrct)); 
 05270 |                } 
 05271 |                else 
 05272 |                   return (new control_block); 
 05273 |             } 
 05274 |  
 05275 |             static inline void destroy(control_block*& cntrl_blck) 
 05276 |             { 
 05277 |                if (cntrl_blck) 
 05278 |                { 
 05279 |                   if ( 
 05280 |                        (0 !=   cntrl_blck->ref_count) && 
 05281 |                        (0 == --cntrl_blck->ref_count) 
 05282 |                      ) 
 05283 |                   { 
 05284 |                      delete cntrl_blck; 
 05285 |                   } 
 05286 |  
 05287 |                   cntrl_blck = 0; 
 05288 |                } 
 05289 |             } 
 05290 |  
 05291 |             std::size_t ref_count; 
 05292 |             std::size_t size; 
 05293 |             data_t      data; 
 05294 |             bool        destruct; 
 05295 |  
 05296 |          private: 
 05297 |  
 05298 |             control_block(const control_block&) exprtk_delete; 
 05299 |             control_block& operator=(const control_block&) exprtk_delete; 
 05300 |  
 05301 |             inline void create_data() 
 05302 |             { 
 05303 |                destruct = true; 
 05304 |                data     = new T[size]; 
 05305 |                std::fill_n(data, size, T(0)); 
 05306 |                dump_ptr("control_block::create_data() - data", data, size); 
 05307 |             } 
 05308 |          }; 
 05309 |  
 05310 |       public: 
 05311 |  
 05312 |          vec_data_store() 
 05313 |          : control_block_(control_block::create(0)) 
 05314 |          {} 
 05315 |  
 05316 |          explicit vec_data_store(const std::size_t& size) 
 05317 |          : control_block_(control_block::create(size,reinterpret_cast<data_t>(0),true)) 
 05318 |          {} 
 05319 |  
 05320 |          vec_data_store(const std::size_t& size, data_t data, bool dstrct = false) 
 05321 |          : control_block_(control_block::create(size, data, dstrct)) 
 05322 |          {} 
 05323 |  
 05324 |          vec_data_store(const type& vds) 
 05325 |          { 
 05326 |             control_block_ = vds.control_block_; 
 05327 |             control_block_->ref_count++; 
 05328 |          } 
 05329 |  
 05330 |         ~vec_data_store() 
 05331 |          { 
 05332 |             control_block::destroy(control_block_); 
 05333 |          } 
 05334 |  
 05335 |          type& operator=(const type& vds) 
 05336 |          { 
 05337 |             if (this != &vds) 
 05338 |             { 
 05339 |                const std::size_t final_size = min_size(control_block_, vds.control_block_); 
 05340 |  
 05341 |                vds.control_block_->size = final_size; 
 05342 |                    control_block_->size = final_size; 
 05343 |  
 05344 |                if (control_block_->destruct || (0 == control_block_->data)) 
 05345 |                { 
 05346 |                   control_block::destroy(control_block_); 
 05347 |  
 05348 |                   control_block_ = vds.control_block_; 
 05349 |                   control_block_->ref_count++; 
 05350 |                } 
 05351 |             } 
 05352 |  
 05353 |             return (*this); 
 05354 |          } 
 05355 |  
 05356 |          inline data_t data() 
 05357 |          { 
 05358 |             return control_block_->data; 
 05359 |          } 
 05360 |  
 05361 |          inline data_t data() const 
 05362 |          { 
 05363 |             return control_block_->data; 
 05364 |          } 
 05365 |  
 05366 |          inline std::size_t size() const 
 05367 |          { 
 05368 |             return control_block_->size; 
 05369 |          } 
 05370 |  
 05371 |          inline data_t& ref() 
 05372 |          { 
 05373 |             return control_block_->data; 
 05374 |          } 
 05375 |  
 05376 |          inline void dump() const 
 05377 |          { 
 05378 |             #ifdef exprtk_enable_debugging 
 05379 |             exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n", 
 05380 |                           size(), 
 05381 |                           data(), 
 05382 |                           (control_block_->destruct ? 'T' : 'F'))); 
 05383 |  
 05384 |             for (std::size_t i = 0; i < size(); ++i) 
 05385 |             { 
 05386 |                if (5 == i) 
 05387 |                   exprtk_debug(("\n")); 
 05388 |  
 05389 |                exprtk_debug(("%15.10f ", data()[i])); 
 05390 |             } 
 05391 |             exprtk_debug(("\n")); 
 05392 |             #endif 
 05393 |          } 
 05394 |  
 05395 |          static inline void match_sizes(type& vds0, type& vds1) 
 05396 |          { 
 05397 |             const std::size_t size = min_size(vds0.control_block_,vds1.control_block_); 
 05398 |             vds0.control_block_->size = size; 
 05399 |             vds1.control_block_->size = size; 
 05400 |          } 
 05401 |  
 05402 |       private: 
 05403 |  
 05404 |          static inline std::size_t min_size(const control_block* cb0, const control_block* cb1) 
 05405 |          { 
 05406 |             const std::size_t size0 = cb0->size; 
 05407 |             const std::size_t size1 = cb1->size; 
 05408 |  
 05409 |             if (size0 && size1) 
 05410 |                return std::min(size0,size1); 
 05411 |             else 
 05412 |                return (size0) ? size0 : size1; 
 05413 |          } 
 05414 |  
 05415 |          control_block* control_block_; 
 05416 |       }; 
 05417 |  
 05418 |       namespace numeric 
 05419 |       { 
 05420 |          namespace details 
 05421 |          { 
 05422 |             template <typename T> 
 05423 |             inline T process_impl(const operator_type operation, const T arg) 
 05424 |             { 
 05425 |                switch (operation) 
 05426 |                { 
 05427 |                   case e_abs   : return numeric::abs  (arg); 
 05428 |                   case e_acos  : return numeric::acos (arg); 
 05429 |                   case e_acosh : return numeric::acosh(arg); 
 05430 |                   case e_asin  : return numeric::asin (arg); 
 05431 |                   case e_asinh : return numeric::asinh(arg); 
 05432 |                   case e_atan  : return numeric::atan (arg); 
 05433 |                   case e_atanh : return numeric::atanh(arg); 
 05434 |                   case e_ceil  : return numeric::ceil (arg); 
 05435 |                   case e_cos   : return numeric::cos  (arg); 
 05436 |                   case e_cosh  : return numeric::cosh (arg); 
 05437 |                   case e_exp   : return numeric::exp  (arg); 
 05438 |                   case e_expm1 : return numeric::expm1(arg); 
 05439 |                   case e_floor : return numeric::floor(arg); 
 05440 |                   case e_log   : return numeric::log  (arg); 
 05441 |                   case e_log10 : return numeric::log10(arg); 
 05442 |                   case e_log2  : return numeric::log2 (arg); 
 05443 |                   case e_log1p : return numeric::log1p(arg); 
 05444 |                   case e_neg   : return numeric::neg  (arg); 
 05445 |                   case e_pos   : return numeric::pos  (arg); 
 05446 |                   case e_round : return numeric::round(arg); 
 05447 |                   case e_sin   : return numeric::sin  (arg); 
 05448 |                   case e_sinc  : return numeric::sinc (arg); 
 05449 |                   case e_sinh  : return numeric::sinh (arg); 
 05450 |                   case e_sqrt  : return numeric::sqrt (arg); 
 05451 |                   case e_tan   : return numeric::tan  (arg); 
 05452 |                   case e_tanh  : return numeric::tanh (arg); 
 05453 |                   case e_cot   : return numeric::cot  (arg); 
 05454 |                   case e_sec   : return numeric::sec  (arg); 
 05455 |                   case e_csc   : return numeric::csc  (arg); 
 05456 |                   case e_r2d   : return numeric::r2d  (arg); 
 05457 |                   case e_d2r   : return numeric::d2r  (arg); 
 05458 |                   case e_d2g   : return numeric::d2g  (arg); 
 05459 |                   case e_g2d   : return numeric::g2d  (arg); 
 05460 |                   case e_notl  : return numeric::notl (arg); 
 05461 |                   case e_sgn   : return numeric::sgn  (arg); 
 05462 |                   case e_erf   : return numeric::erf  (arg); 
 05463 |                   case e_erfc  : return numeric::erfc (arg); 
 05464 |                   case e_ncdf  : return numeric::ncdf (arg); 
 05465 |                   case e_frac  : return numeric::frac (arg); 
 05466 |                   case e_trunc : return numeric::trunc(arg); 
 05467 |  
 05468 |                   default      : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n")); 
 05469 |                                  return std::numeric_limits<T>::quiet_NaN(); 
 05470 |                } 
 05471 |             } 
 05472 |  
 05473 |             template <typename T> 
 05474 |             inline T process_impl(const operator_type operation, const T arg0, const T arg1) 
 05475 |             { 
 05476 |                switch (operation) 
 05477 |                { 
 05478 |                   case e_add    : return (arg0 + arg1); 
 05479 |                   case e_sub    : return (arg0 - arg1); 
 05480 |                   case e_mul    : return (arg0 * arg1); 
 05481 |                   case e_div    : return (arg0 / arg1); 
 05482 |                   case e_mod    : return modulus<T>(arg0,arg1); 
 05483 |                   case e_pow    : return pow<T>(arg0,arg1); 
 05484 |                   case e_atan2  : return atan2<T>(arg0,arg1); 
 05485 |                   case e_min    : return std::min<T>(arg0,arg1); 
 05486 |                   case e_max    : return std::max<T>(arg0,arg1); 
 05487 |                   case e_logn   : return logn<T>(arg0,arg1); 
 05488 |                   case e_lt     : return (arg0 <  arg1) ? T(1) : T(0); 
 05489 |                   case e_lte    : return (arg0 <= arg1) ? T(1) : T(0); 
 05490 |                   case e_eq     : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0); 
 05491 |                   case e_ne     : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0); 
 05492 |                   case e_gte    : return (arg0 >= arg1) ? T(1) : T(0); 
 05493 |                   case e_gt     : return (arg0 >  arg1) ? T(1) : T(0); 
 05494 |                   case e_and    : return and_opr <T>(arg0,arg1); 
 05495 |                   case e_nand   : return nand_opr<T>(arg0,arg1); 
 05496 |                   case e_or     : return or_opr  <T>(arg0,arg1); 
 05497 |                   case e_nor    : return nor_opr <T>(arg0,arg1); 
 05498 |                   case e_xor    : return xor_opr <T>(arg0,arg1); 
 05499 |                   case e_xnor   : return xnor_opr<T>(arg0,arg1); 
 05500 |                   case e_root   : return root    <T>(arg0,arg1); 
 05501 |                   case e_roundn : return roundn  <T>(arg0,arg1); 
 05502 |                   case e_equal  : return equal   <T>(arg0,arg1); 
 05503 |                   case e_nequal : return nequal  <T>(arg0,arg1); 
 05504 |                   case e_hypot  : return hypot   <T>(arg0,arg1); 
 05505 |                   case e_shr    : return shr     <T>(arg0,arg1); 
 05506 |                   case e_shl    : return shl     <T>(arg0,arg1); 
 05507 |  
 05508 |                   default       : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n")); 
 05509 |                                   return std::numeric_limits<T>::quiet_NaN(); 
 05510 |                } 
 05511 |             } 
 05512 |  
 05513 |             template <typename T> 
 05514 |             inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag) 
 05515 |             { 
 05516 |                switch (operation) 
 05517 |                { 
 05518 |                   case e_add    : return (arg0 + arg1); 
 05519 |                   case e_sub    : return (arg0 - arg1); 
 05520 |                   case e_mul    : return (arg0 * arg1); 
 05521 |                   case e_div    : return (arg0 / arg1); 
 05522 |                   case e_mod    : return arg0 % arg1; 
 05523 |                   case e_pow    : return pow<T>(arg0,arg1); 
 05524 |                   case e_min    : return std::min<T>(arg0,arg1); 
 05525 |                   case e_max    : return std::max<T>(arg0,arg1); 
 05526 |                   case e_logn   : return logn<T>(arg0,arg1); 
 05527 |                   case e_lt     : return (arg0 <  arg1) ? T(1) : T(0); 
 05528 |                   case e_lte    : return (arg0 <= arg1) ? T(1) : T(0); 
 05529 |                   case e_eq     : return (arg0 == arg1) ? T(1) : T(0); 
 05530 |                   case e_ne     : return (arg0 != arg1) ? T(1) : T(0); 
 05531 |                   case e_gte    : return (arg0 >= arg1) ? T(1) : T(0); 
 05532 |                   case e_gt     : return (arg0 >  arg1) ? T(1) : T(0); 
 05533 |                   case e_and    : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0); 
 05534 |                   case e_nand   : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1); 
 05535 |                   case e_or     : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0); 
 05536 |                   case e_nor    : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1); 
 05537 |                   case e_xor    : return arg0 ^ arg1; 
 05538 |                   case e_xnor   : return !(arg0 ^ arg1); 
 05539 |                   case e_root   : return root<T>(arg0,arg1); 
 05540 |                   case e_equal  : return arg0 == arg1; 
 05541 |                   case e_nequal : return arg0 != arg1; 
 05542 |                   case e_hypot  : return hypot<T>(arg0,arg1); 
 05543 |                   case e_shr    : return arg0 >> arg1; 
 05544 |                   case e_shl    : return arg0 << arg1; 
 05545 |  
 05546 |                   default       : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n")); 
 05547 |                                   return std::numeric_limits<T>::quiet_NaN(); 
 05548 |                } 
 05549 |             } 
 05550 |          } 
 05551 |  
 05552 |          template <typename T> 
 05553 |          inline T process(const operator_type operation, const T arg) 
 05554 |          { 
 05555 |             return exprtk::details::numeric::details::process_impl(operation,arg); 
 05556 |          } 
 05557 |  
 05558 |          template <typename T> 
 05559 |          inline T process(const operator_type operation, const T arg0, const T arg1) 
 05560 |          { 
 05561 |             return exprtk::details::numeric::details::process_impl(operation, arg0, arg1); 
 05562 |          } 
 05563 |       } 
 05564 |  
 05565 |       template <typename Node> 
 05566 |       struct node_collector_interface 
 05567 |       { 
 05568 |          typedef Node* node_ptr_t; 
 05569 |          typedef Node** node_pp_t; 
 05570 |          typedef std::vector<node_pp_t> noderef_list_t; 
 05571 |  
 05572 |          virtual ~node_collector_interface() 
 05573 |          {} 
 05574 |  
 05575 |          virtual void collect_nodes(noderef_list_t&) 
 05576 |          {} 
 05577 |       }; 
 05578 |  
 05579 |       template <typename Node> 
 05580 |       struct node_depth_base; 
 05581 |  
 05582 |       template <typename T> 
 05583 |       class expression_node : public node_collector_interface<expression_node<T> > 
 05584 |                             , public node_depth_base<expression_node<T> > 
 05585 |       { 
 05586 |       public: 
 05587 |  
 05588 |          enum node_type 
 05589 |          { 
 05590 |             e_none          , e_null          , e_constant    , e_unary        , 
 05591 |             e_binary        , e_binary_ext    , e_trinary     , e_quaternary   , 
 05592 |             e_vararg        , e_conditional   , e_while       , e_repeat       , 
 05593 |             e_for           , e_switch        , e_mswitch     , e_return       , 
 05594 |             e_retenv        , e_variable      , e_stringvar   , e_stringconst  , 
 05595 |             e_stringvarrng  , e_cstringvarrng , e_strgenrange , e_strconcat    , 
 05596 |             e_stringvarsize , e_strswap       , e_stringsize  , e_stringvararg , 
 05597 |             e_function      , e_vafunction    , e_genfunction , e_strfunction  , 
 05598 |             e_strcondition  , e_strccondition , e_add         , e_sub          , 
 05599 |             e_mul           , e_div           , e_mod         , e_pow          , 
 05600 |             e_lt            , e_lte           , e_gt          , e_gte          , 
 05601 |             e_eq            , e_ne            , e_and         , e_nand         , 
 05602 |             e_or            , e_nor           , e_xor         , e_xnor         , 
 05603 |             e_in            , e_like          , e_ilike       , e_inranges     , 
 05604 |             e_ipow          , e_ipowinv       , e_abs         , e_acos         , 
 05605 |             e_acosh         , e_asin          , e_asinh       , e_atan         , 
 05606 |             e_atanh         , e_ceil          , e_cos         , e_cosh         , 
 05607 |             e_exp           , e_expm1         , e_floor       , e_log          , 
 05608 |             e_log10         , e_log2          , e_log1p       , e_neg          , 
 05609 |             e_pos           , e_round         , e_sin         , e_sinc         , 
 05610 |             e_sinh          , e_sqrt          , e_tan         , e_tanh         , 
 05611 |             e_cot           , e_sec           , e_csc         , e_r2d          , 
 05612 |             e_d2r           , e_d2g           , e_g2d         , e_notl         , 
 05613 |             e_sgn           , e_erf           , e_erfc        , e_ncdf         , 
 05614 |             e_frac          , e_trunc         , e_uvouv       , e_vov          , 
 05615 |             e_cov           , e_voc           , e_vob         , e_bov          , 
 05616 |             e_cob           , e_boc           , e_vovov       , e_vovoc        , 
 05617 |             e_vocov         , e_covov         , e_covoc       , e_vovovov      , 
 05618 |             e_vovovoc       , e_vovocov       , e_vocovov     , e_covovov      , 
 05619 |             e_covocov       , e_vocovoc       , e_covovoc     , e_vococov      , 
 05620 |             e_sf3ext        , e_sf4ext        , e_nulleq      , e_strass       , 
 05621 |             e_vector        , e_vecsize       , e_vecelem     , e_veccelem     , 
 05622 |             e_vecelemrtc    , e_veccelemrtc   , e_rbvecelem   , e_rbvecelemrtc , 
 05623 |             e_rbveccelem    , e_rbveccelemrtc , e_vecinit     , e_vecvalass    , 
 05624 |             e_vecvecass     , e_vecopvalass   , e_vecopvecass , e_vecfunc      , 
 05625 |             e_vecvecswap    , e_vecvecineq    , e_vecvalineq  , e_valvecineq   , 
 05626 |             e_vecvecarith   , e_vecvalarith   , e_valvecarith , e_vecunaryop   , 
 05627 |             e_vecondition   , e_break         , e_continue    , e_swap         , 
 05628 |             e_assert 
 05629 |          }; 
 05630 |  
 05631 |          typedef T value_type; 
 05632 |          typedef expression_node<T>* expression_ptr; 
 05633 |          typedef node_collector_interface<expression_node<T> > nci_t; 
 05634 |          typedef typename nci_t::noderef_list_t noderef_list_t; 
 05635 |          typedef node_depth_base<expression_node<T> > ndb_t; 
 05636 |  
 05637 |          virtual ~expression_node() 
 05638 |          {} 
 05639 |  
 05640 |          inline virtual T value() const 
 05641 |          { 
 05642 |             return std::numeric_limits<T>::quiet_NaN(); 
 05643 |          } 
 05644 |  
 05645 |          inline virtual expression_node<T>* branch(const std::size_t& index = 0) const 
 05646 |          { 
 05647 |             return reinterpret_cast<expression_ptr>(index * 0); 
 05648 |          } 
 05649 |  
 05650 |          inline virtual node_type type() const 
 05651 |          { 
 05652 |             return e_none; 
 05653 |          } 
 05654 |  
 05655 |          inline virtual bool valid() const 
 05656 |          { 
 05657 |             return true; 
 05658 |          } 
 05659 |       }; // class expression_node 
 05660 |  
 05661 |       template <typename T> 
 05662 |       inline bool is_generally_string_node(const expression_node<T>* node); 
 05663 |  
 05664 |       inline bool is_true(const double v) 
 05665 |       { 
 05666 |          return std::not_equal_to<double>()(0.0,v); 
 05667 |       } 
 05668 |  
 05669 |       inline bool is_true(const long double v) 
 05670 |       { 
 05671 |          return std::not_equal_to<long double>()(0.0L,v); 
 05672 |       } 
 05673 |  
 05674 |       inline bool is_true(const float v) 
 05675 |       { 
 05676 |          return std::not_equal_to<float>()(0.0f,v); 
 05677 |       } 
 05678 |  
 05679 |       template <typename T> 
 05680 |       inline bool is_true(const expression_node<T>* node) 
 05681 |       { 
 05682 |          return std::not_equal_to<T>()(T(0),node->value()); 
 05683 |       } 
 05684 |  
 05685 |       template <typename T> 
 05686 |       inline bool is_true(const std::pair<expression_node<T>*,bool>& node) 
 05687 |       { 
 05688 |          return std::not_equal_to<T>()(T(0),node.first->value()); 
 05689 |       } 
 05690 |  
 05691 |       template <typename T> 
 05692 |       inline bool is_false(const expression_node<T>* node) 
 05693 |       { 
 05694 |          return std::equal_to<T>()(T(0),node->value()); 
 05695 |       } 
 05696 |  
 05697 |       template <typename T> 
 05698 |       inline bool is_false(const std::pair<expression_node<T>*,bool>& node) 
 05699 |       { 
 05700 |          return std::equal_to<T>()(T(0),node.first->value()); 
 05701 |       } 
 05702 |  
 05703 |       template <typename T> 
 05704 |       inline bool is_literal_node(const expression_node<T>* node) 
 05705 |       { 
 05706 |          return node && (details::expression_node<T>::e_constant == node->type()); 
 05707 |       } 
 05708 |  
 05709 |       template <typename T> 
 05710 |       inline bool is_unary_node(const expression_node<T>* node) 
 05711 |       { 
 05712 |          return node && (details::expression_node<T>::e_unary == node->type()); 
 05713 |       } 
 05714 |  
 05715 |       template <typename T> 
 05716 |       inline bool is_neg_unary_node(const expression_node<T>* node) 
 05717 |       { 
 05718 |          return node && (details::expression_node<T>::e_neg == node->type()); 
 05719 |       } 
 05720 |  
 05721 |       template <typename T> 
 05722 |       inline bool is_binary_node(const expression_node<T>* node) 
 05723 |       { 
 05724 |          return node && (details::expression_node<T>::e_binary == node->type()); 
 05725 |       } 
 05726 |  
 05727 |       template <typename T> 
 05728 |       inline bool is_variable_node(const expression_node<T>* node) 
 05729 |       { 
 05730 |          return node && (details::expression_node<T>::e_variable == node->type()); 
 05731 |       } 
 05732 |  
 05733 |       template <typename T> 
 05734 |       inline bool is_ivariable_node(const expression_node<T>* node) 
 05735 |       { 
 05736 |          return node && 
 05737 |                 ( 
 05738 |                   details::expression_node<T>::e_variable      == node->type() || 
 05739 |                   details::expression_node<T>::e_vecelem       == node->type() || 
 05740 |                   details::expression_node<T>::e_veccelem      == node->type() || 
 05741 |                   details::expression_node<T>::e_vecelemrtc    == node->type() || 
 05742 |                   details::expression_node<T>::e_veccelemrtc   == node->type() || 
 05743 |                   details::expression_node<T>::e_rbvecelem     == node->type() || 
 05744 |                   details::expression_node<T>::e_rbveccelem    == node->type() || 
 05745 |                   details::expression_node<T>::e_rbvecelemrtc  == node->type() || 
 05746 |                   details::expression_node<T>::e_rbveccelemrtc == node->type() 
 05747 |                 ); 
 05748 |       } 
 05749 |  
 05750 |       template <typename T> 
 05751 |       inline bool is_vector_elem_node(const expression_node<T>* node) 
 05752 |       { 
 05753 |          return node && (details::expression_node<T>::e_vecelem == node->type()); 
 05754 |       } 
 05755 |  
 05756 |       template <typename T> 
 05757 |       inline bool is_vector_celem_node(const expression_node<T>* node) 
 05758 |       { 
 05759 |          return node && (details::expression_node<T>::e_veccelem == node->type()); 
 05760 |       } 
 05761 |  
 05762 |       template <typename T> 
 05763 |       inline bool is_vector_elem_rtc_node(const expression_node<T>* node) 
 05764 |       { 
 05765 |          return node && (details::expression_node<T>::e_vecelemrtc == node->type()); 
 05766 |       } 
 05767 |  
 05768 |       template <typename T> 
 05769 |       inline bool is_vector_celem_rtc_node(const expression_node<T>* node) 
 05770 |       { 
 05771 |          return node && (details::expression_node<T>::e_veccelemrtc == node->type()); 
 05772 |       } 
 05773 |  
 05774 |       template <typename T> 
 05775 |       inline bool is_rebasevector_elem_node(const expression_node<T>* node) 
 05776 |       { 
 05777 |          return node && (details::expression_node<T>::e_rbvecelem == node->type()); 
 05778 |       } 
 05779 |  
 05780 |       template <typename T> 
 05781 |       inline bool is_rebasevector_elem_rtc_node(const expression_node<T>* node) 
 05782 |       { 
 05783 |          return node && (details::expression_node<T>::e_rbvecelemrtc == node->type()); 
 05784 |       } 
 05785 |  
 05786 |       template <typename T> 
 05787 |       inline bool is_rebasevector_celem_rtc_node(const expression_node<T>* node) 
 05788 |       { 
 05789 |          return node && (details::expression_node<T>::e_rbveccelemrtc == node->type()); 
 05790 |       } 
 05791 |  
 05792 |       template <typename T> 
 05793 |       inline bool is_rebasevector_celem_node(const expression_node<T>* node) 
 05794 |       { 
 05795 |          return node && (details::expression_node<T>::e_rbveccelem == node->type()); 
 05796 |       } 
 05797 |  
 05798 |       template <typename T> 
 05799 |       inline bool is_vector_node(const expression_node<T>* node) 
 05800 |       { 
 05801 |          return node && (details::expression_node<T>::e_vector == node->type()); 
 05802 |       } 
 05803 |  
 05804 |       template <typename T> 
 05805 |       inline bool is_ivector_node(const expression_node<T>* node) 
 05806 |       { 
 05807 |          if (node) 
 05808 |          { 
 05809 |             switch (node->type()) 
 05810 |             { 
 05811 |                case details::expression_node<T>::e_vector      : 
 05812 |                case details::expression_node<T>::e_vecvalass   : 
 05813 |                case details::expression_node<T>::e_vecvecass   : 
 05814 |                case details::expression_node<T>::e_vecopvalass : 
 05815 |                case details::expression_node<T>::e_vecopvecass : 
 05816 |                case details::expression_node<T>::e_vecvecswap  : 
 05817 |                case details::expression_node<T>::e_vecvecarith : 
 05818 |                case details::expression_node<T>::e_vecvalarith : 
 05819 |                case details::expression_node<T>::e_valvecarith : 
 05820 |                case details::expression_node<T>::e_vecunaryop  : 
 05821 |                case details::expression_node<T>::e_vecondition : return true; 
 05822 |                default                                         : return false; 
 05823 |             } 
 05824 |          } 
 05825 |          else 
 05826 |             return false; 
 05827 |       } 
 05828 |  
 05829 |       template <typename T> 
 05830 |       inline bool is_constant_node(const expression_node<T>* node) 
 05831 |       { 
 05832 |          return node && 
 05833 |          ( 
 05834 |            details::expression_node<T>::e_constant    == node->type() || 
 05835 |            details::expression_node<T>::e_stringconst == node->type() 
 05836 |          ); 
 05837 |       } 
 05838 |  
 05839 |       template <typename T> 
 05840 |       inline bool is_null_node(const expression_node<T>* node) 
 05841 |       { 
 05842 |          return node && (details::expression_node<T>::e_null == node->type()); 
 05843 |       } 
 05844 |  
 05845 |       template <typename T> 
 05846 |       inline bool is_break_node(const expression_node<T>* node) 
 05847 |       { 
 05848 |          return node && (details::expression_node<T>::e_break == node->type()); 
 05849 |       } 
 05850 |  
 05851 |       template <typename T> 
 05852 |       inline bool is_continue_node(const expression_node<T>* node) 
 05853 |       { 
 05854 |          return node && (details::expression_node<T>::e_continue == node->type()); 
 05855 |       } 
 05856 |  
 05857 |       template <typename T> 
 05858 |       inline bool is_swap_node(const expression_node<T>* node) 
 05859 |       { 
 05860 |          return node && (details::expression_node<T>::e_swap == node->type()); 
 05861 |       } 
 05862 |  
 05863 |       template <typename T> 
 05864 |       inline bool is_function(const expression_node<T>* node) 
 05865 |       { 
 05866 |          return node && (details::expression_node<T>::e_function == node->type()); 
 05867 |       } 
 05868 |  
 05869 |       template <typename T> 
 05870 |       inline bool is_vararg_node(const expression_node<T>* node) 
 05871 |       { 
 05872 |          return node && (details::expression_node<T>::e_vararg == node->type()); 
 05873 |       } 
 05874 |  
 05875 |       template <typename T> 
 05876 |       inline bool is_return_node(const expression_node<T>* node) 
 05877 |       { 
 05878 |          return node && (details::expression_node<T>::e_return == node->type()); 
 05879 |       } 
 05880 |  
 05881 |       template <typename T> class unary_node; 
 05882 |  
 05883 |       template <typename T> 
 05884 |       inline bool is_negate_node(const expression_node<T>* node) 
 05885 |       { 
 05886 |          if (node && is_unary_node(node)) 
 05887 |          { 
 05888 |             return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation()); 
 05889 |          } 
 05890 |          else 
 05891 |             return false; 
 05892 |       } 
 05893 |  
 05894 |       template <typename T> 
 05895 |       inline bool is_assert_node(const expression_node<T>* node) 
 05896 |       { 
 05897 |          return node && (details::expression_node<T>::e_assert == node->type()); 
 05898 |       } 
 05899 |  
 05900 |       template <typename T> 
 05901 |       inline bool branch_deletable(const expression_node<T>* node) 
 05902 |       { 
 05903 |          return (0 != node)             && 
 05904 |                 !is_variable_node(node) && 
 05905 |                 !is_string_node  (node) ; 
 05906 |       } 
 05907 |  
 05908 |       template <std::size_t N, typename T> 
 05909 |       inline bool all_nodes_valid(expression_node<T>* const (&b)[N]) 
 05910 |       { 
 05911 |          for (std::size_t i = 0; i < N; ++i) 
 05912 |          { 
 05913 |             if (0 == b[i]) return false; 
 05914 |          } 
 05915 |  
 05916 |          return true; 
 05917 |       } 
 05918 |  
 05919 |       template <typename T, 
 05920 |                 typename Allocator, 
 05921 |                 template <typename, typename> class Sequence> 
 05922 |       inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b) 
 05923 |       { 
 05924 |          for (std::size_t i = 0; i < b.size(); ++i) 
 05925 |          { 
 05926 |             if (0 == b[i]) return false; 
 05927 |          } 
 05928 |  
 05929 |          return true; 
 05930 |       } 
 05931 |  
 05932 |       template <std::size_t N, typename T> 
 05933 |       inline bool all_nodes_variables(expression_node<T>* const (&b)[N]) 
 05934 |       { 
 05935 |          for (std::size_t i = 0; i < N; ++i) 
 05936 |          { 
 05937 |             if (0 == b[i]) 
 05938 |                return false; 
 05939 |             else if (!is_variable_node(b[i])) 
 05940 |                return false; 
 05941 |          } 
 05942 |  
 05943 |          return true; 
 05944 |       } 
 05945 |  
 05946 |       template <typename T, 
 05947 |                 typename Allocator, 
 05948 |                 template <typename, typename> class Sequence> 
 05949 |       inline bool all_nodes_variables(const Sequence<expression_node<T>*,Allocator>& b) 
 05950 |       { 
 05951 |          for (std::size_t i = 0; i < b.size(); ++i) 
 05952 |          { 
 05953 |             if (0 == b[i]) 
 05954 |                return false; 
 05955 |             else if (!is_variable_node(b[i])) 
 05956 |                return false; 
 05957 |          } 
 05958 |  
 05959 |          return true; 
 05960 |       } 
 05961 |  
 05962 |       template <typename Node> 
 05963 |       class node_collection_destructor 
 05964 |       { 
 05965 |       public: 
 05966 |  
 05967 |          typedef node_collector_interface<Node> nci_t; 
 05968 |  
 05969 |          typedef typename nci_t::node_ptr_t     node_ptr_t; 
 05970 |          typedef typename nci_t::node_pp_t      node_pp_t; 
 05971 |          typedef typename nci_t::noderef_list_t noderef_list_t; 
 05972 |  
 05973 |          static void delete_nodes(node_ptr_t& root) 
 05974 |          { 
 05975 |             std::vector<node_pp_t> node_delete_list; 
 05976 |             node_delete_list.reserve(1000); 
 05977 |  
 05978 |             collect_nodes(root, node_delete_list); 
 05979 |  
 05980 |             for (std::size_t i = 0; i < node_delete_list.size(); ++i) 
 05981 |             { 
 05982 |                node_ptr_t& node = *node_delete_list[i]; 
 05983 |                exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", reinterpret_cast<void*>(node))); 
 05984 |                delete node; 
 05985 |                node = reinterpret_cast<node_ptr_t>(0); 
 05986 |             } 
 05987 |          } 
 05988 |  
 05989 |       private: 
 05990 |  
 05991 |          static void collect_nodes(node_ptr_t& root, noderef_list_t& node_delete_list) 
 05992 |          { 
 05993 |             std::deque<node_ptr_t> node_list; 
 05994 |             node_list.push_back(root); 
 05995 |             node_delete_list.push_back(&root); 
 05996 |  
 05997 |             noderef_list_t child_node_delete_list; 
 05998 |             child_node_delete_list.reserve(1000); 
 05999 |  
 06000 |             while (!node_list.empty()) 
 06001 |             { 
 06002 |                node_list.front()->collect_nodes(child_node_delete_list); 
 06003 |  
 06004 |                if (!child_node_delete_list.empty()) 
 06005 |                { 
 06006 |                   for (std::size_t i = 0; i < child_node_delete_list.size(); ++i) 
 06007 |                   { 
 06008 |                      node_pp_t& node = child_node_delete_list[i]; 
 06009 |  
 06010 |                      if (0 == (*node)) 
 06011 |                      { 
 06012 |                         exprtk_debug(("ncd::collect_nodes() - null node encountered.\n")); 
 06013 |                      } 
 06014 |  
 06015 |                      node_list.push_back(*node); 
 06016 |                   } 
 06017 |  
 06018 |                   node_delete_list.insert( 
 06019 |                      node_delete_list.end(), 
 06020 |                      child_node_delete_list.begin(), child_node_delete_list.end()); 
 06021 |  
 06022 |                   child_node_delete_list.clear(); 
 06023 |                } 
 06024 |  
 06025 |                node_list.pop_front(); 
 06026 |             } 
 06027 |  
 06028 |             std::reverse(node_delete_list.begin(), node_delete_list.end()); 
 06029 |          } 
 06030 |       }; 
 06031 |  
 06032 |       template <typename NodeAllocator, typename T, std::size_t N> 
 06033 |       inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N]) 
 06034 |       { 
 06035 |          for (std::size_t i = 0; i < N; ++i) 
 06036 |          { 
 06037 |             free_node(node_allocator,b[i]); 
 06038 |          } 
 06039 |       } 
 06040 |  
 06041 |       template <typename NodeAllocator, 
 06042 |                 typename T, 
 06043 |                 typename Allocator, 
 06044 |                 template <typename, typename> class Sequence> 
 06045 |       inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b) 
 06046 |       { 
 06047 |          for (std::size_t i = 0; i < b.size(); ++i) 
 06048 |          { 
 06049 |             free_node(node_allocator,b[i]); 
 06050 |          } 
 06051 |  
 06052 |          b.clear(); 
 06053 |       } 
 06054 |  
 06055 |       template <typename NodeAllocator, typename T> 
 06056 |       inline void free_node(NodeAllocator&, expression_node<T>*& node) 
 06057 |       { 
 06058 |          if ((0 == node) || is_variable_node(node) || is_string_node(node)) 
 06059 |          { 
 06060 |             return; 
 06061 |          } 
 06062 |  
 06063 |          node_collection_destructor<expression_node<T> > 
 06064 |             ::delete_nodes(node); 
 06065 |       } 
 06066 |  
 06067 |       template <typename T> 
 06068 |       inline void destroy_node(expression_node<T>*& node) 
 06069 |       { 
 06070 |          if (0 != node) 
 06071 |          { 
 06072 |             node_collection_destructor<expression_node<T> > 
 06073 |                ::delete_nodes(node); 
 06074 |          } 
 06075 |       } 
 06076 |  
 06077 |       template <typename Node> 
 06078 |       struct node_depth_base 
 06079 |       { 
 06080 |          typedef Node* node_ptr_t; 
 06081 |          typedef std::pair<node_ptr_t,bool> nb_pair_t; 
 06082 |  
 06083 |          node_depth_base() 
 06084 |          : depth_set(false) 
 06085 |          , depth(0) 
 06086 |          {} 
 06087 |  
 06088 |          virtual ~node_depth_base() 
 06089 |          {} 
 06090 |  
 06091 |          virtual std::size_t node_depth() const { return 1; } 
 06092 |  
 06093 |          std::size_t compute_node_depth(const Node* const& node) const 
 06094 |          { 
 06095 |             if (!depth_set) 
 06096 |             { 
 06097 |                depth = 1 + (node ? node->node_depth() : 0); 
 06098 |                depth_set = true; 
 06099 |             } 
 06100 |  
 06101 |             return depth; 
 06102 |          } 
 06103 |  
 06104 |          std::size_t compute_node_depth(const nb_pair_t& branch) const 
 06105 |          { 
 06106 |             if (!depth_set) 
 06107 |             { 
 06108 |                depth = 1 + (branch.first ? branch.first->node_depth() : 0); 
 06109 |                depth_set = true; 
 06110 |             } 
 06111 |  
 06112 |             return depth; 
 06113 |          } 
 06114 |  
 06115 |          template <std::size_t N> 
 06116 |          std::size_t compute_node_depth(const nb_pair_t (&branch)[N]) const 
 06117 |          { 
 06118 |             if (!depth_set) 
 06119 |             { 
 06120 |                depth = 0; 
 06121 |  
 06122 |                for (std::size_t i = 0; i < N; ++i) 
 06123 |                { 
 06124 |                   if (branch[i].first) 
 06125 |                   { 
 06126 |                      depth = std::max(depth,branch[i].first->node_depth()); 
 06127 |                   } 
 06128 |                } 
 06129 |  
 06130 |                depth += 1; 
 06131 |                depth_set = true; 
 06132 |             } 
 06133 |  
 06134 |             return depth; 
 06135 |          } 
 06136 |  
 06137 |          template <typename BranchType> 
 06138 |          std::size_t max_node_depth(const BranchType& n0, const BranchType& n1) const 
 06139 |          { 
 06140 |             return std::max(compute_node_depth(n0), compute_node_depth(n1)); 
 06141 |          } 
 06142 |  
 06143 |          template <typename BranchType> 
 06144 |          std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, const BranchType& n2) const 
 06145 |          { 
 06146 |             return std::max(compute_node_depth(n0), 
 06147 |                    std::max(compute_node_depth(n1), compute_node_depth(n2))); 
 06148 |          } 
 06149 |  
 06150 |          template <typename BranchType> 
 06151 |          std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, 
 06152 |                                     const BranchType& n2, const BranchType& n3) const 
 06153 |          { 
 06154 |             return std::max( 
 06155 |                      std::max(compute_node_depth(n0), compute_node_depth(n1)), 
 06156 |                      std::max(compute_node_depth(n2), compute_node_depth(n3))); 
 06157 |          } 
 06158 |  
 06159 |          template <typename BranchType> 
 06160 |          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const 
 06161 |          { 
 06162 |             if (!depth_set) 
 06163 |             { 
 06164 |                depth = 1 + max_node_depth(n0, n1); 
 06165 |                depth_set = true; 
 06166 |             } 
 06167 |  
 06168 |             return depth; 
 06169 |          } 
 06170 |  
 06171 |          template <typename BranchType> 
 06172 |          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1, 
 06173 |                                         const BranchType& n2) const 
 06174 |          { 
 06175 |             if (!depth_set) 
 06176 |             { 
 06177 |                depth = 1 + max_node_depth(n0, n1, n2); 
 06178 |                depth_set = true; 
 06179 |             } 
 06180 |  
 06181 |             return depth; 
 06182 |          } 
 06183 |  
 06184 |          template <typename BranchType> 
 06185 |          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1, 
 06186 |                                         const BranchType& n2, const BranchType& n3) const 
 06187 |          { 
 06188 |             if (!depth_set) 
 06189 |             { 
 06190 |                depth = 1 + max_node_depth(n0, n1, n2, n3); 
 06191 |                depth_set = true; 
 06192 |             } 
 06193 |  
 06194 |             return depth; 
 06195 |          } 
 06196 |  
 06197 |          template <typename Allocator, 
 06198 |                    template <typename, typename> class Sequence> 
 06199 |          std::size_t compute_node_depth(const Sequence<node_ptr_t, Allocator>& branch_list) const 
 06200 |          { 
 06201 |             if (!depth_set) 
 06202 |             { 
 06203 |                for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06204 |                { 
 06205 |                   if (branch_list[i]) 
 06206 |                   { 
 06207 |                      depth = std::max(depth, compute_node_depth(branch_list[i])); 
 06208 |                   } 
 06209 |                } 
 06210 |  
 06211 |                depth_set = true; 
 06212 |             } 
 06213 |  
 06214 |             return depth; 
 06215 |          } 
 06216 |  
 06217 |          template <typename Allocator, 
 06218 |                    template <typename, typename> class Sequence> 
 06219 |          std::size_t compute_node_depth(const Sequence<nb_pair_t,Allocator>& branch_list) const 
 06220 |          { 
 06221 |             if (!depth_set) 
 06222 |             { 
 06223 |                for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06224 |                { 
 06225 |                   if (branch_list[i].first) 
 06226 |                   { 
 06227 |                      depth = std::max(depth, compute_node_depth(branch_list[i].first)); 
 06228 |                   } 
 06229 |                } 
 06230 |  
 06231 |                depth_set = true; 
 06232 |             } 
 06233 |  
 06234 |             return depth; 
 06235 |          } 
 06236 |  
 06237 |          mutable bool depth_set; 
 06238 |          mutable std::size_t depth; 
 06239 |  
 06240 |          template <typename NodeSequence> 
 06241 |          void collect(node_ptr_t const& node, 
 06242 |                       const bool deletable, 
 06243 |                       NodeSequence& delete_node_list) const 
 06244 |          { 
 06245 |             if ((0 != node) && deletable) 
 06246 |             { 
 06247 |                delete_node_list.push_back(const_cast<node_ptr_t*>(&node)); 
 06248 |             } 
 06249 |          } 
 06250 |  
 06251 |          template <typename NodeSequence> 
 06252 |          void collect(const nb_pair_t& branch, 
 06253 |                       NodeSequence& delete_node_list) const 
 06254 |          { 
 06255 |             collect(branch.first, branch.second, delete_node_list); 
 06256 |          } 
 06257 |  
 06258 |          template <typename NodeSequence> 
 06259 |          void collect(Node*& node, 
 06260 |                       NodeSequence& delete_node_list) const 
 06261 |          { 
 06262 |             collect(node, branch_deletable(node), delete_node_list); 
 06263 |          } 
 06264 |  
 06265 |          template <std::size_t N, typename NodeSequence> 
 06266 |          void collect(const nb_pair_t(&branch)[N], 
 06267 |                       NodeSequence& delete_node_list) const 
 06268 |          { 
 06269 |             for (std::size_t i = 0; i < N; ++i) 
 06270 |             { 
 06271 |                collect(branch[i].first, branch[i].second, delete_node_list); 
 06272 |             } 
 06273 |          } 
 06274 |  
 06275 |          template <typename Allocator, 
 06276 |                    template <typename, typename> class Sequence, 
 06277 |                    typename NodeSequence> 
 06278 |          void collect(const Sequence<nb_pair_t, Allocator>& branch, 
 06279 |                       NodeSequence& delete_node_list) const 
 06280 |          { 
 06281 |             for (std::size_t i = 0; i < branch.size(); ++i) 
 06282 |             { 
 06283 |                collect(branch[i].first, branch[i].second, delete_node_list); 
 06284 |             } 
 06285 |          } 
 06286 |  
 06287 |          template <typename Allocator, 
 06288 |                    template <typename, typename> class Sequence, 
 06289 |                    typename NodeSequence> 
 06290 |          void collect(const Sequence<node_ptr_t, Allocator>& branch_list, 
 06291 |                       NodeSequence& delete_node_list) const 
 06292 |          { 
 06293 |             for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06294 |             { 
 06295 |                collect(branch_list[i], branch_deletable(branch_list[i]), delete_node_list); 
 06296 |             } 
 06297 |          } 
 06298 |  
 06299 |          template <typename Boolean, 
 06300 |                    typename AllocatorT, 
 06301 |                    typename AllocatorB, 
 06302 |                    template <typename, typename> class Sequence, 
 06303 |                    typename NodeSequence> 
 06304 |          void collect(const Sequence<node_ptr_t, AllocatorT>& branch_list, 
 06305 |                       const Sequence<Boolean, AllocatorB>& branch_deletable_list, 
 06306 |                       NodeSequence& delete_node_list) const 
 06307 |          { 
 06308 |             for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06309 |             { 
 06310 |                collect(branch_list[i], branch_deletable_list[i], delete_node_list); 
 06311 |             } 
 06312 |          } 
 06313 |       }; 
 06314 |  
 06315 |       template <typename Type> 
 06316 |       class vector_holder 
 06317 |       { 
 06318 |       private: 
 06319 |  
 06320 |          typedef Type value_type; 
 06321 |          typedef value_type* value_ptr; 
 06322 |          typedef const value_ptr const_value_ptr; 
 06323 |          typedef vector_holder<Type> vector_holder_t; 
 06324 |  
 06325 |          class vector_holder_base 
 06326 |          { 
 06327 |          public: 
 06328 |  
 06329 |             virtual ~vector_holder_base() 
 06330 |             {} 
 06331 |  
 06332 |             inline value_ptr operator[](const std::size_t& index) const 
 06333 |             { 
 06334 |                return value_at(index); 
 06335 |             } 
 06336 |  
 06337 |             inline std::size_t size() const 
 06338 |             { 
 06339 |                return vector_size(); 
 06340 |             } 
 06341 |  
 06342 |             inline std::size_t base_size() const 
 06343 |             { 
 06344 |                return vector_base_size(); 
 06345 |             } 
 06346 |  
 06347 |             inline value_ptr data() const 
 06348 |             { 
 06349 |                return value_at(0); 
 06350 |             } 
 06351 |  
 06352 |             virtual inline bool rebaseable() const 
 06353 |             { 
 06354 |                return false; 
 06355 |             } 
 06356 |  
 06357 |             virtual void set_ref(value_ptr*) 
 06358 |             {} 
 06359 |  
 06360 |             virtual void remove_ref(value_ptr*) 
 06361 |             {} 
 06362 |  
 06363 |             virtual vector_view<Type>* rebaseable_instance() 
 06364 |             { 
 06365 |                return reinterpret_cast<vector_view<Type>*>(0); 
 06366 |             } 
 06367 |  
 06368 |          protected: 
 06369 |  
 06370 |             virtual value_ptr value_at(const std::size_t&) const = 0; 
 06371 |             virtual std::size_t vector_size()              const = 0; 
 06372 |             virtual std::size_t vector_base_size()         const = 0; 
 06373 |          }; 
 06374 |  
 06375 |          class array_vector_impl exprtk_final : public vector_holder_base 
 06376 |          { 
 06377 |          public: 
 06378 |  
 06379 |             array_vector_impl(const Type* vec, const std::size_t& vec_size) 
 06380 |             : vec_(vec) 
 06381 |             , size_(vec_size) 
 06382 |             {} 
 06383 |  
 06384 |          protected: 
 06385 |  
 06386 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06387 |             { 
 06388 |                assert(index < size_); 
 06389 |                return const_cast<const_value_ptr>(vec_ + index); 
 06390 |             } 
 06391 |  
 06392 |             std::size_t vector_size() const exprtk_override 
 06393 |             { 
 06394 |                return size_; 
 06395 |             } 
 06396 |  
 06397 |             std::size_t vector_base_size() const exprtk_override 
 06398 |             { 
 06399 |                return vector_size(); 
 06400 |             } 
 06401 |  
 06402 |          private: 
 06403 |  
 06404 |             array_vector_impl(const array_vector_impl&) exprtk_delete; 
 06405 |             array_vector_impl& operator=(const array_vector_impl&) exprtk_delete; 
 06406 |  
 06407 |             const Type* vec_; 
 06408 |             const std::size_t size_; 
 06409 |          }; 
 06410 |  
 06411 |          template <typename Allocator, 
 06412 |                    template <typename, typename> class Sequence> 
 06413 |          class sequence_vector_impl exprtk_final : public vector_holder_base 
 06414 |          { 
 06415 |          public: 
 06416 |  
 06417 |             typedef Sequence<Type,Allocator> sequence_t; 
 06418 |  
 06419 |             explicit sequence_vector_impl(sequence_t& seq) 
 06420 |             : sequence_(seq) 
 06421 |             {} 
 06422 |  
 06423 |          protected: 
 06424 |  
 06425 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06426 |             { 
 06427 |                assert(index < sequence_.size()); 
 06428 |                return (&sequence_[index]); 
 06429 |             } 
 06430 |  
 06431 |             std::size_t vector_size() const exprtk_override 
 06432 |             { 
 06433 |                return sequence_.size(); 
 06434 |             } 
 06435 |  
 06436 |             std::size_t vector_base_size() const exprtk_override 
 06437 |             { 
 06438 |                return vector_size(); 
 06439 |             } 
 06440 |  
 06441 |          private: 
 06442 |  
 06443 |             sequence_vector_impl(const sequence_vector_impl&) exprtk_delete; 
 06444 |             sequence_vector_impl& operator=(const sequence_vector_impl&) exprtk_delete; 
 06445 |  
 06446 |             sequence_t& sequence_; 
 06447 |          }; 
 06448 |  
 06449 |          class vector_view_impl exprtk_final : public vector_holder_base 
 06450 |          { 
 06451 |          public: 
 06452 |  
 06453 |             typedef exprtk::vector_view<Type> vector_view_t; 
 06454 |  
 06455 |             explicit vector_view_impl(vector_view_t& vec_view) 
 06456 |             : vec_view_(vec_view) 
 06457 |             { 
 06458 |                assert(vec_view_.size() > 0); 
 06459 |             } 
 06460 |  
 06461 |             void set_ref(value_ptr* ref) exprtk_override 
 06462 |             { 
 06463 |                vec_view_.set_ref(ref); 
 06464 |             } 
 06465 |  
 06466 |             void remove_ref(value_ptr* ref) exprtk_override 
 06467 |             { 
 06468 |                vec_view_.remove_ref(ref); 
 06469 |             } 
 06470 |  
 06471 |             bool rebaseable() const exprtk_override 
 06472 |             { 
 06473 |                return true; 
 06474 |             } 
 06475 |  
 06476 |             vector_view<Type>* rebaseable_instance() exprtk_override 
 06477 |             { 
 06478 |                return &vec_view_; 
 06479 |             } 
 06480 |  
 06481 |          protected: 
 06482 |  
 06483 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06484 |             { 
 06485 |                assert(index < vec_view_.size()); 
 06486 |                return (&vec_view_[index]); 
 06487 |             } 
 06488 |  
 06489 |             std::size_t vector_size() const exprtk_override 
 06490 |             { 
 06491 |                return vec_view_.size(); 
 06492 |             } 
 06493 |  
 06494 |             std::size_t vector_base_size() const exprtk_override 
 06495 |             { 
 06496 |                return vec_view_.base_size(); 
 06497 |             } 
 06498 |  
 06499 |          private: 
 06500 |  
 06501 |             vector_view_impl(const vector_view_impl&) exprtk_delete; 
 06502 |             vector_view_impl& operator=(const vector_view_impl&) exprtk_delete; 
 06503 |  
 06504 |             vector_view_t& vec_view_; 
 06505 |          }; 
 06506 |  
 06507 |          class resizable_vector_impl exprtk_final : public vector_holder_base 
 06508 |          { 
 06509 |          public: 
 06510 |  
 06511 |             resizable_vector_impl(vector_holder& vec_view_holder, 
 06512 |                                   const Type* vec, 
 06513 |                                   const std::size_t& vec_size) 
 06514 |             : vec_(vec) 
 06515 |             , size_(vec_size) 
 06516 |             , vec_view_holder_(*vec_view_holder.rebaseable_instance()) 
 06517 |             { 
 06518 |                assert(vec_view_holder.rebaseable_instance()); 
 06519 |                assert(size_ <= vector_base_size()); 
 06520 |             } 
 06521 |  
 06522 |             virtual ~resizable_vector_impl() exprtk_override 
 06523 |             {} 
 06524 |  
 06525 |          protected: 
 06526 |  
 06527 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06528 |             { 
 06529 |                assert(index < vector_size()); 
 06530 |                return const_cast<const_value_ptr>(vec_ + index); 
 06531 |             } 
 06532 |  
 06533 |             std::size_t vector_size() const exprtk_override 
 06534 |             { 
 06535 |                return vec_view_holder_.size(); 
 06536 |             } 
 06537 |  
 06538 |             std::size_t vector_base_size() const exprtk_override 
 06539 |             { 
 06540 |                return vec_view_holder_.base_size(); 
 06541 |             } 
 06542 |  
 06543 |             bool rebaseable() const exprtk_override 
 06544 |             { 
 06545 |                return true; 
 06546 |             } 
 06547 |  
 06548 |             virtual vector_view<Type>* rebaseable_instance() exprtk_override 
 06549 |             { 
 06550 |                return &vec_view_holder_; 
 06551 |             } 
 06552 |  
 06553 |          private: 
 06554 |  
 06555 |             resizable_vector_impl(const resizable_vector_impl&) exprtk_delete; 
 06556 |             resizable_vector_impl& operator=(const resizable_vector_impl&) exprtk_delete; 
 06557 |  
 06558 |             const Type* vec_; 
 06559 |             const std::size_t size_; 
 06560 |             vector_view<Type>& vec_view_holder_; 
 06561 |          }; 
 06562 |  
 06563 |       public: 
 06564 |  
 06565 |          typedef typename details::vec_data_store<Type> vds_t; 
 06566 |  
 06567 |          vector_holder(Type* vec, const std::size_t& vec_size) 
 06568 |          : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size)) 
 06569 |          {} 
 06570 |  
 06571 |          explicit vector_holder(const vds_t& vds) 
 06572 |          : vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size())) 
 06573 |          {} 
 06574 |  
 06575 |          template <typename Allocator> 
 06576 |          explicit vector_holder(std::vector<Type,Allocator>& vec) 
 06577 |          : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec)) 
 06578 |          {} 
 06579 |  
 06580 |          explicit vector_holder(exprtk::vector_view<Type>& vec) 
 06581 |          : vector_holder_base_(new(buffer)vector_view_impl(vec)) 
 06582 |          {} 
 06583 |  
 06584 |          explicit vector_holder(vector_holder_t& vec_holder, const vds_t& vds) 
 06585 |          : vector_holder_base_(new(buffer)resizable_vector_impl(vec_holder, vds.data(), vds.size())) 
 06586 |          {} 
 06587 |  
 06588 |          inline value_ptr operator[](const std::size_t& index) const 
 06589 |          { 
 06590 |             return (*vector_holder_base_)[index]; 
 06591 |          } 
 06592 |  
 06593 |          inline std::size_t size() const 
 06594 |          { 
 06595 |             return vector_holder_base_->size(); 
 06596 |          } 
 06597 |  
 06598 |          inline std::size_t base_size() const 
 06599 |          { 
 06600 |             return vector_holder_base_->base_size(); 
 06601 |          } 
 06602 |  
 06603 |          inline value_ptr data() const 
 06604 |          { 
 06605 |             return vector_holder_base_->data(); 
 06606 |          } 
 06607 |  
 06608 |          void set_ref(value_ptr* ref) 
 06609 |          { 
 06610 |             if (rebaseable()) 
 06611 |             { 
 06612 |                vector_holder_base_->set_ref(ref); 
 06613 |             } 
 06614 |          } 
 06615 |  
 06616 |          void remove_ref(value_ptr* ref) 
 06617 |          { 
 06618 |             if (rebaseable()) 
 06619 |             { 
 06620 |                vector_holder_base_->remove_ref(ref); 
 06621 |             } 
 06622 |          } 
 06623 |  
 06624 |          bool rebaseable() const 
 06625 |          { 
 06626 |             return vector_holder_base_->rebaseable(); 
 06627 |          } 
 06628 |  
 06629 |          vector_view<Type>* rebaseable_instance() 
 06630 |          { 
 06631 |             return vector_holder_base_->rebaseable_instance(); 
 06632 |          } 
 06633 |  
 06634 |       private: 
 06635 |  
 06636 |          vector_holder(const vector_holder<Type>&) exprtk_delete; 
 06637 |          vector_holder<Type>& operator=(const vector_holder<Type>&) exprtk_delete; 
 06638 |  
 06639 |          mutable vector_holder_base* vector_holder_base_; 
 06640 |          uchar_t buffer[64]; 
 06641 |       }; 
 06642 |  
 06643 |       template <typename T> 
 06644 |       class null_node exprtk_final : public expression_node<T> 
 06645 |       { 
 06646 |       public: 
 06647 |  
 06648 |          inline T value() const exprtk_override 
 06649 |          { 
 06650 |             return std::numeric_limits<T>::quiet_NaN(); 
 06651 |          } 
 06652 |  
 06653 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06654 |          { 
 06655 |             return expression_node<T>::e_null; 
 06656 |          } 
 06657 |       }; 
 06658 |  
 06659 |       template <typename T, std::size_t N> 
 06660 |       inline void construct_branch_pair(std::pair<expression_node<T>*,bool> (&branch)[N], 
 06661 |                                         expression_node<T>* b, 
 06662 |                                         const std::size_t& index) 
 06663 |       { 
 06664 |          if (b && (index < N)) 
 06665 |          { 
 06666 |             branch[index] = std::make_pair(b,branch_deletable(b)); 
 06667 |          } 
 06668 |       } 
 06669 |  
 06670 |       template <typename T> 
 06671 |       inline void construct_branch_pair(std::pair<expression_node<T>*,bool>& branch, expression_node<T>* b) 
 06672 |       { 
 06673 |          if (b) 
 06674 |          { 
 06675 |             branch = std::make_pair(b,branch_deletable(b)); 
 06676 |          } 
 06677 |       } 
 06678 |  
 06679 |       template <std::size_t N, typename T> 
 06680 |       inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N], 
 06681 |                                 expression_node<T>* b0, 
 06682 |                                 expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0), 
 06683 |                                 expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0), 
 06684 |                                 expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0), 
 06685 |                                 expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0), 
 06686 |                                 expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0), 
 06687 |                                 expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0), 
 06688 |                                 expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0), 
 06689 |                                 expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0), 
 06690 |                                 expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0)) 
 06691 |       { 
 06692 |          construct_branch_pair(branch, b0, 0); 
 06693 |          construct_branch_pair(branch, b1, 1); 
 06694 |          construct_branch_pair(branch, b2, 2); 
 06695 |          construct_branch_pair(branch, b3, 3); 
 06696 |          construct_branch_pair(branch, b4, 4); 
 06697 |          construct_branch_pair(branch, b5, 5); 
 06698 |          construct_branch_pair(branch, b6, 6); 
 06699 |          construct_branch_pair(branch, b7, 7); 
 06700 |          construct_branch_pair(branch, b8, 8); 
 06701 |          construct_branch_pair(branch, b9, 9); 
 06702 |       } 
 06703 |  
 06704 |       template <typename T> 
 06705 |       class null_eq_node exprtk_final : public expression_node<T> 
 06706 |       { 
 06707 |       public: 
 06708 |  
 06709 |          typedef expression_node<T>* expression_ptr; 
 06710 |          typedef std::pair<expression_ptr,bool> branch_t; 
 06711 |  
 06712 |          explicit null_eq_node(expression_ptr branch, const bool equality = true) 
 06713 |          : equality_(equality) 
 06714 |          { 
 06715 |             construct_branch_pair(branch_, branch); 
 06716 |             assert(valid()); 
 06717 |          } 
 06718 |  
 06719 |          inline T value() const exprtk_override 
 06720 |          { 
 06721 |             const T v = branch_.first->value(); 
 06722 |             const bool result = details::numeric::is_nan(v); 
 06723 |  
 06724 |             if (result) 
 06725 |                return equality_ ? T(1) : T(0); 
 06726 |             else 
 06727 |                return equality_ ? T(0) : T(1); 
 06728 |          } 
 06729 |  
 06730 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06731 |          { 
 06732 |             return expression_node<T>::e_nulleq; 
 06733 |          } 
 06734 |  
 06735 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06736 |          { 
 06737 |             return branch_.first; 
 06738 |          } 
 06739 |  
 06740 |          inline bool valid() const exprtk_override 
 06741 |          { 
 06742 |             return branch_.first; 
 06743 |          } 
 06744 |  
 06745 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 06746 |          { 
 06747 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 06748 |          } 
 06749 |  
 06750 |          std::size_t node_depth() const exprtk_override 
 06751 |          { 
 06752 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 06753 |          } 
 06754 |  
 06755 |       private: 
 06756 |  
 06757 |          bool equality_; 
 06758 |          branch_t branch_; 
 06759 |       }; 
 06760 |  
 06761 |       template <typename T> 
 06762 |       class literal_node exprtk_final : public expression_node<T> 
 06763 |       { 
 06764 |       public: 
 06765 |  
 06766 |          explicit literal_node(const T& v) 
 06767 |          : value_(v) 
 06768 |          {} 
 06769 |  
 06770 |          inline T value() const exprtk_override 
 06771 |          { 
 06772 |             return value_; 
 06773 |          } 
 06774 |  
 06775 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06776 |          { 
 06777 |             return expression_node<T>::e_constant; 
 06778 |          } 
 06779 |  
 06780 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06781 |          { 
 06782 |             return reinterpret_cast<expression_node<T>*>(0); 
 06783 |          } 
 06784 |  
 06785 |       private: 
 06786 |  
 06787 |          literal_node(const literal_node<T>&) exprtk_delete; 
 06788 |          literal_node<T>& operator=(const literal_node<T>&) exprtk_delete; 
 06789 |  
 06790 |          const T value_; 
 06791 |       }; 
 06792 |  
 06793 |       template <typename T> 
 06794 |       struct range_pack; 
 06795 |  
 06796 |       template <typename T> 
 06797 |       struct range_data_type; 
 06798 |  
 06799 |       template <typename T> 
 06800 |       class range_interface 
 06801 |       { 
 06802 |       public: 
 06803 |  
 06804 |          typedef range_pack<T> range_t; 
 06805 |  
 06806 |          virtual ~range_interface() 
 06807 |          {} 
 06808 |  
 06809 |          virtual range_t& range_ref() = 0; 
 06810 |  
 06811 |          virtual const range_t& range_ref() const = 0; 
 06812 |       }; 
 06813 |  
 06814 |       #ifndef exprtk_disable_string_capabilities 
 06815 |       template <typename T> 
 06816 |       class string_base_node 
 06817 |       { 
 06818 |       public: 
 06819 |  
 06820 |          typedef range_data_type<T> range_data_type_t; 
 06821 |  
 06822 |          virtual ~string_base_node() 
 06823 |          {} 
 06824 |  
 06825 |          virtual std::string str () const = 0; 
 06826 |  
 06827 |          virtual char_cptr   base() const = 0; 
 06828 |  
 06829 |          virtual std::size_t size() const = 0; 
 06830 |       }; 
 06831 |  
 06832 |       template <typename T> 
 06833 |       class string_literal_node exprtk_final 
 06834 |                                 : public expression_node <T> 
 06835 |                                 , public string_base_node<T> 
 06836 |                                 , public range_interface <T> 
 06837 |       { 
 06838 |       public: 
 06839 |  
 06840 |          typedef range_pack<T> range_t; 
 06841 |  
 06842 |          explicit string_literal_node(const std::string& v) 
 06843 |          : value_(v) 
 06844 |          { 
 06845 |             rp_.n0_c = std::make_pair<bool,std::size_t>(true, 0); 
 06846 |             rp_.n1_c = std::make_pair<bool,std::size_t>(true, v.size()); 
 06847 |             rp_.cache.first  = rp_.n0_c.second; 
 06848 |             rp_.cache.second = rp_.n1_c.second; 
 06849 |          } 
 06850 |  
 06851 |          inline T value() const exprtk_override 
 06852 |          { 
 06853 |             return std::numeric_limits<T>::quiet_NaN(); 
 06854 |          } 
 06855 |  
 06856 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06857 |          { 
 06858 |             return expression_node<T>::e_stringconst; 
 06859 |          } 
 06860 |  
 06861 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06862 |          { 
 06863 |             return reinterpret_cast<expression_node<T>*>(0); 
 06864 |          } 
 06865 |  
 06866 |          std::string str() const exprtk_override 
 06867 |          { 
 06868 |             return value_; 
 06869 |          } 
 06870 |  
 06871 |          char_cptr base() const exprtk_override 
 06872 |          { 
 06873 |             return value_.data(); 
 06874 |          } 
 06875 |  
 06876 |          std::size_t size() const exprtk_override 
 06877 |          { 
 06878 |             return value_.size(); 
 06879 |          } 
 06880 |  
 06881 |          range_t& range_ref() exprtk_override 
 06882 |          { 
 06883 |             return rp_; 
 06884 |          } 
 06885 |  
 06886 |          const range_t& range_ref() const exprtk_override 
 06887 |          { 
 06888 |             return rp_; 
 06889 |          } 
 06890 |  
 06891 |       private: 
 06892 |  
 06893 |          string_literal_node(const string_literal_node<T>&) exprtk_delete; 
 06894 |          string_literal_node<T>& operator=(const string_literal_node<T>&) exprtk_delete; 
 06895 |  
 06896 |          const std::string value_; 
 06897 |          range_t rp_; 
 06898 |       }; 
 06899 |       #endif 
 06900 |  
 06901 |       template <typename T> 
 06902 |       class unary_node : public expression_node<T> 
 06903 |       { 
 06904 |       public: 
 06905 |  
 06906 |          typedef expression_node<T>* expression_ptr; 
 06907 |          typedef std::pair<expression_ptr,bool> branch_t; 
 06908 |  
 06909 |          unary_node(const operator_type& opr, expression_ptr branch) 
 06910 |          : operation_(opr) 
 06911 |          { 
 06912 |             construct_branch_pair(branch_,branch); 
 06913 |             assert(valid()); 
 06914 |          } 
 06915 |  
 06916 |          inline T value() const exprtk_override 
 06917 |          { 
 06918 |             return numeric::process<T> 
 06919 |                      (operation_,branch_.first->value()); 
 06920 |          } 
 06921 |  
 06922 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06923 |          { 
 06924 |             return expression_node<T>::e_unary; 
 06925 |          } 
 06926 |  
 06927 |          inline operator_type operation() 
 06928 |          { 
 06929 |             return operation_; 
 06930 |          } 
 06931 |  
 06932 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06933 |          { 
 06934 |             return branch_.first; 
 06935 |          } 
 06936 |  
 06937 |          inline bool valid() const exprtk_override 
 06938 |          { 
 06939 |             return branch_.first && branch_.first->valid(); 
 06940 |          } 
 06941 |  
 06942 |          inline void release() 
 06943 |          { 
 06944 |             branch_.second = false; 
 06945 |          } 
 06946 |  
 06947 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 06948 |          { 
 06949 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 06950 |          } 
 06951 |  
 06952 |          std::size_t node_depth() const exprtk_final 
 06953 |          { 
 06954 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 06955 |          } 
 06956 |  
 06957 |       private: 
 06958 |  
 06959 |          operator_type operation_; 
 06960 |          branch_t branch_; 
 06961 |       }; 
 06962 |  
 06963 |       template <typename T> 
 06964 |       class binary_node : public expression_node<T> 
 06965 |       { 
 06966 |       public: 
 06967 |  
 06968 |          typedef expression_node<T>* expression_ptr; 
 06969 |          typedef std::pair<expression_ptr,bool> branch_t; 
 06970 |  
 06971 |          binary_node(const operator_type& opr, 
 06972 |                      expression_ptr branch0, 
 06973 |                      expression_ptr branch1) 
 06974 |          : operation_(opr) 
 06975 |          { 
 06976 |             init_branches<2>(branch_, branch0, branch1); 
 06977 |             assert(valid()); 
 06978 |          } 
 06979 |  
 06980 |          inline T value() const exprtk_override 
 06981 |          { 
 06982 |             return numeric::process<T> 
 06983 |                    ( 
 06984 |                       operation_, 
 06985 |                       branch_[0].first->value(), 
 06986 |                       branch_[1].first->value() 
 06987 |                    ); 
 06988 |          } 
 06989 |  
 06990 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06991 |          { 
 06992 |             return expression_node<T>::e_binary; 
 06993 |          } 
 06994 |  
 06995 |          inline operator_type operation() 
 06996 |          { 
 06997 |             return operation_; 
 06998 |          } 
 06999 |  
 07000 |          inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override 
 07001 |          { 
 07002 |             assert(index < 2); 
 07003 |             return branch_[index].first; 
 07004 |          } 
 07005 |  
 07006 |          inline bool valid() const exprtk_override 
 07007 |          { 
 07008 |             return 
 07009 |                branch_[0].first && branch_[0].first->valid() && 
 07010 |                branch_[1].first && branch_[1].first->valid() ; 
 07011 |          } 
 07012 |  
 07013 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07014 |          { 
 07015 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07016 |          } 
 07017 |  
 07018 |          std::size_t node_depth() const exprtk_final 
 07019 |          { 
 07020 |             return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_); 
 07021 |          } 
 07022 |  
 07023 |       private: 
 07024 |  
 07025 |          operator_type operation_; 
 07026 |          branch_t branch_[2]; 
 07027 |       }; 
 07028 |  
 07029 |       template <typename T, typename Operation> 
 07030 |       class binary_ext_node exprtk_final : public expression_node<T> 
 07031 |       { 
 07032 |       public: 
 07033 |  
 07034 |          typedef expression_node<T>* expression_ptr; 
 07035 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07036 |  
 07037 |          binary_ext_node(expression_ptr branch0, expression_ptr branch1) 
 07038 |          { 
 07039 |             init_branches<2>(branch_, branch0, branch1); 
 07040 |             assert(valid()); 
 07041 |          } 
 07042 |  
 07043 |          inline T value() const exprtk_override 
 07044 |          { 
 07045 |             const T arg0 = branch_[0].first->value(); 
 07046 |             const T arg1 = branch_[1].first->value(); 
 07047 |             return Operation::process(arg0,arg1); 
 07048 |          } 
 07049 |  
 07050 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07051 |          { 
 07052 |             return expression_node<T>::e_binary_ext; 
 07053 |          } 
 07054 |  
 07055 |          inline operator_type operation() 
 07056 |          { 
 07057 |             return Operation::operation(); 
 07058 |          } 
 07059 |  
 07060 |          inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override 
 07061 |          { 
 07062 |             assert(index < 2); 
 07063 |             return branch_[index].first; 
 07064 |          } 
 07065 |  
 07066 |          inline bool valid() const exprtk_override 
 07067 |          { 
 07068 |             return 
 07069 |                branch_[0].first && branch_[0].first->valid() && 
 07070 |                branch_[1].first && branch_[1].first->valid() ; 
 07071 |          } 
 07072 |  
 07073 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07074 |          { 
 07075 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07076 |          } 
 07077 |  
 07078 |          std::size_t node_depth() const exprtk_override 
 07079 |          { 
 07080 |             return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_); 
 07081 |          } 
 07082 |  
 07083 |       protected: 
 07084 |  
 07085 |          branch_t branch_[2]; 
 07086 |       }; 
 07087 |  
 07088 |       template <typename T> 
 07089 |       class trinary_node : public expression_node<T> 
 07090 |       { 
 07091 |       public: 
 07092 |  
 07093 |          typedef expression_node<T>* expression_ptr; 
 07094 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07095 |  
 07096 |          trinary_node(const operator_type& opr, 
 07097 |                       expression_ptr branch0, 
 07098 |                       expression_ptr branch1, 
 07099 |                       expression_ptr branch2) 
 07100 |          : operation_(opr) 
 07101 |          { 
 07102 |             init_branches<3>(branch_, branch0, branch1, branch2); 
 07103 |             assert(valid()); 
 07104 |          } 
 07105 |  
 07106 |          inline T value() const exprtk_override 
 07107 |          { 
 07108 |             const T arg0 = branch_[0].first->value(); 
 07109 |             const T arg1 = branch_[1].first->value(); 
 07110 |             const T arg2 = branch_[2].first->value(); 
 07111 |  
 07112 |             switch (operation_) 
 07113 |             { 
 07114 |                case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1)); 
 07115 |  
 07116 |                case e_clamp   : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1); 
 07117 |  
 07118 |                case e_iclamp  : if ((arg1 <= arg0) || (arg1 >= arg2)) 
 07119 |                                    return arg1; 
 07120 |                                 else 
 07121 |                                    return ((T(2) * arg1  <= (arg2 + arg0)) ? arg0 : arg2); 
 07122 |  
 07123 |                default        : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n")); 
 07124 |                                 return std::numeric_limits<T>::quiet_NaN(); 
 07125 |             } 
 07126 |          } 
 07127 |  
 07128 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07129 |          { 
 07130 |             return expression_node<T>::e_trinary; 
 07131 |          } 
 07132 |  
 07133 |          inline bool valid() const exprtk_override 
 07134 |          { 
 07135 |             return 
 07136 |                branch_[0].first && branch_[0].first->valid() && 
 07137 |                branch_[1].first && branch_[1].first->valid() && 
 07138 |                branch_[2].first && branch_[2].first->valid() ; 
 07139 |          } 
 07140 |  
 07141 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07142 |          { 
 07143 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07144 |          } 
 07145 |  
 07146 |          std::size_t node_depth() const exprtk_override exprtk_final 
 07147 |          { 
 07148 |             return expression_node<T>::ndb_t::template compute_node_depth<3>(branch_); 
 07149 |          } 
 07150 |  
 07151 |       protected: 
 07152 |  
 07153 |          operator_type operation_; 
 07154 |          branch_t branch_[3]; 
 07155 |       }; 
 07156 |  
 07157 |       template <typename T> 
 07158 |       class quaternary_node : public expression_node<T> 
 07159 |       { 
 07160 |       public: 
 07161 |  
 07162 |          typedef expression_node<T>* expression_ptr; 
 07163 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07164 |  
 07165 |          quaternary_node(const operator_type& opr, 
 07166 |                          expression_ptr branch0, 
 07167 |                          expression_ptr branch1, 
 07168 |                          expression_ptr branch2, 
 07169 |                          expression_ptr branch3) 
 07170 |          : operation_(opr) 
 07171 |          { 
 07172 |             init_branches<4>(branch_, branch0, branch1, branch2, branch3); 
 07173 |          } 
 07174 |  
 07175 |          inline T value() const exprtk_override 
 07176 |          { 
 07177 |             return std::numeric_limits<T>::quiet_NaN(); 
 07178 |          } 
 07179 |  
 07180 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07181 |          { 
 07182 |             return expression_node<T>::e_quaternary; 
 07183 |          } 
 07184 |  
 07185 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07186 |          { 
 07187 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07188 |          } 
 07189 |  
 07190 |          std::size_t node_depth() const exprtk_override exprtk_final 
 07191 |          { 
 07192 |             return expression_node<T>::ndb_t::template compute_node_depth<4>(branch_); 
 07193 |          } 
 07194 |  
 07195 |          inline bool valid() const exprtk_override 
 07196 |          { 
 07197 |             return 
 07198 |                branch_[0].first && branch_[0].first->valid() && 
 07199 |                branch_[1].first && branch_[1].first->valid() && 
 07200 |                branch_[2].first && branch_[2].first->valid() && 
 07201 |                branch_[3].first && branch_[3].first->valid() ; 
 07202 |          } 
 07203 |  
 07204 |       protected: 
 07205 |  
 07206 |          operator_type operation_; 
 07207 |          branch_t branch_[4]; 
 07208 |       }; 
 07209 |  
 07210 |       template <typename T> 
 07211 |       class conditional_node exprtk_final : public expression_node<T> 
 07212 |       { 
 07213 |       public: 
 07214 |  
 07215 |          typedef expression_node<T>* expression_ptr; 
 07216 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07217 |  
 07218 |          conditional_node(expression_ptr condition, 
 07219 |                           expression_ptr consequent, 
 07220 |                           expression_ptr alternative) 
 07221 |          { 
 07222 |             construct_branch_pair(condition_  , condition  ); 
 07223 |             construct_branch_pair(consequent_ , consequent ); 
 07224 |             construct_branch_pair(alternative_, alternative); 
 07225 |             assert(valid()); 
 07226 |          } 
 07227 |  
 07228 |          inline T value() const exprtk_override 
 07229 |          { 
 07230 |             if (is_true(condition_)) 
 07231 |                return consequent_.first->value(); 
 07232 |             else 
 07233 |                return alternative_.first->value(); 
 07234 |          } 
 07235 |  
 07236 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07237 |          { 
 07238 |             return expression_node<T>::e_conditional; 
 07239 |          } 
 07240 |  
 07241 |          inline bool valid() const exprtk_override 
 07242 |          { 
 07243 |             return 
 07244 |                condition_  .first && condition_  .first->valid() && 
 07245 |                consequent_ .first && consequent_ .first->valid() && 
 07246 |                alternative_.first && alternative_.first->valid() ; 
 07247 |          } 
 07248 |  
 07249 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07250 |          { 
 07251 |             expression_node<T>::ndb_t::collect(condition_   , node_delete_list); 
 07252 |             expression_node<T>::ndb_t::collect(consequent_  , node_delete_list); 
 07253 |             expression_node<T>::ndb_t::collect(alternative_ , node_delete_list); 
 07254 |          } 
 07255 |  
 07256 |          std::size_t node_depth() const exprtk_override 
 07257 |          { 
 07258 |             return expression_node<T>::ndb_t::compute_node_depth 
 07259 |                (condition_, consequent_, alternative_); 
 07260 |          } 
 07261 |  
 07262 |       private: 
 07263 |  
 07264 |          branch_t condition_; 
 07265 |          branch_t consequent_; 
 07266 |          branch_t alternative_; 
 07267 |       }; 
 07268 |  
 07269 |       template <typename T> 
 07270 |       class cons_conditional_node exprtk_final : public expression_node<T> 
 07271 |       { 
 07272 |       public: 
 07273 |  
 07274 |          // Consequent only conditional statement node 
 07275 |          typedef expression_node<T>* expression_ptr; 
 07276 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07277 |  
 07278 |          cons_conditional_node(expression_ptr condition, 
 07279 |                                expression_ptr consequent) 
 07280 |          { 
 07281 |             construct_branch_pair(condition_ , condition ); 
 07282 |             construct_branch_pair(consequent_, consequent); 
 07283 |             assert(valid()); 
 07284 |          } 
 07285 |  
 07286 |          inline T value() const exprtk_override 
 07287 |          { 
 07288 |             if (is_true(condition_)) 
 07289 |                return consequent_.first->value(); 
 07290 |             else 
 07291 |                return std::numeric_limits<T>::quiet_NaN(); 
 07292 |          } 
 07293 |  
 07294 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07295 |          { 
 07296 |             return expression_node<T>::e_conditional; 
 07297 |          } 
 07298 |  
 07299 |          inline bool valid() const exprtk_override 
 07300 |          { 
 07301 |             return 
 07302 |                condition_ .first && condition_ .first->valid() && 
 07303 |                consequent_.first && consequent_.first->valid() ; 
 07304 |          } 
 07305 |  
 07306 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07307 |          { 
 07308 |             expression_node<T>::ndb_t::collect(condition_  , node_delete_list); 
 07309 |             expression_node<T>::ndb_t::collect(consequent_ , node_delete_list); 
 07310 |          } 
 07311 |  
 07312 |          std::size_t node_depth() const exprtk_override 
 07313 |          { 
 07314 |             return expression_node<T>::ndb_t:: 
 07315 |                compute_node_depth(condition_, consequent_); 
 07316 |          } 
 07317 |  
 07318 |       private: 
 07319 |  
 07320 |          branch_t condition_; 
 07321 |          branch_t consequent_; 
 07322 |       }; 
 07323 |  
 07324 |       #ifndef exprtk_disable_break_continue 
 07325 |       template <typename T> 
 07326 |       class break_exception 
 07327 |       { 
 07328 |       public: 
 07329 |  
 07330 |          explicit break_exception(const T& v) 
 07331 |          : value(v) 
 07332 |          {} 
 07333 |  
 07334 |          T value; 
 07335 |       }; 
 07336 |  
 07337 |       class continue_exception {}; 
 07338 |  
 07339 |       template <typename T> 
 07340 |       class break_node exprtk_final : public expression_node<T> 
 07341 |       { 
 07342 |       public: 
 07343 |  
 07344 |          typedef expression_node<T>* expression_ptr; 
 07345 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07346 |  
 07347 |          explicit break_node(expression_ptr ret = expression_ptr(0)) 
 07348 |          { 
 07349 |             construct_branch_pair(return_, ret); 
 07350 |          } 
 07351 |  
 07352 |          inline T value() const exprtk_override 
 07353 |          { 
 07354 |             const T result = return_.first ? 
 07355 |                              return_.first->value() : 
 07356 |                              std::numeric_limits<T>::quiet_NaN(); 
 07357 |  
 07358 |             throw break_exception<T>(result); 
 07359 |  
 07360 |             #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 07361 |             return std::numeric_limits<T>::quiet_NaN(); 
 07362 |             #endif 
 07363 |          } 
 07364 |  
 07365 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07366 |          { 
 07367 |             return expression_node<T>::e_break; 
 07368 |          } 
 07369 |  
 07370 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07371 |          { 
 07372 |             expression_node<T>::ndb_t::collect(return_, node_delete_list); 
 07373 |          } 
 07374 |  
 07375 |          std::size_t node_depth() const exprtk_override 
 07376 |          { 
 07377 |             return expression_node<T>::ndb_t::compute_node_depth(return_); 
 07378 |          } 
 07379 |  
 07380 |       private: 
 07381 |  
 07382 |          branch_t return_; 
 07383 |       }; 
 07384 |  
 07385 |       template <typename T> 
 07386 |       class continue_node exprtk_final : public expression_node<T> 
 07387 |       { 
 07388 |       public: 
 07389 |  
 07390 |          inline T value() const exprtk_override 
 07391 |          { 
 07392 |             throw continue_exception(); 
 07393 |             #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 07394 |             return std::numeric_limits<T>::quiet_NaN(); 
 07395 |             #endif 
 07396 |          } 
 07397 |  
 07398 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07399 |          { 
 07400 |             return expression_node<T>::e_break; 
 07401 |          } 
 07402 |       }; 
 07403 |       #endif 
 07404 |  
 07405 |       struct loop_runtime_checker 
 07406 |       { 
 07407 |          loop_runtime_checker(loop_runtime_check_ptr loop_runtime_check, 
 07408 |                               loop_runtime_check::loop_types lp_typ = loop_runtime_check::e_invalid) 
 07409 |          : iteration_count_(0) 
 07410 |          , loop_runtime_check_(loop_runtime_check) 
 07411 |          , max_loop_iterations_(loop_runtime_check_->max_loop_iterations) 
 07412 |          , loop_type_(lp_typ) 
 07413 |          { 
 07414 |             assert(loop_runtime_check_); 
 07415 |          } 
 07416 |  
 07417 |          inline void reset(const _uint64_t initial_value = 0) const 
 07418 |          { 
 07419 |             iteration_count_ = initial_value; 
 07420 |          } 
 07421 |  
 07422 |          inline bool check() const 
 07423 |          { 
 07424 |             assert(loop_runtime_check_); 
 07425 |  
 07426 |             if ( 
 07427 |                  (++iteration_count_ <= max_loop_iterations_) && 
 07428 |                  loop_runtime_check_->check() 
 07429 |                ) 
 07430 |             { 
 07431 |                return true; 
 07432 |             } 
 07433 |  
 07434 |             loop_runtime_check::violation_context ctxt; 
 07435 |             ctxt.loop      = loop_type_; 
 07436 |             ctxt.violation = loop_runtime_check::e_iteration_count; 
 07437 |  
 07438 |             loop_runtime_check_->handle_runtime_violation(ctxt); 
 07439 |  
 07440 |             return false; 
 07441 |          } 
 07442 |  
 07443 |          bool valid() const 
 07444 |          { 
 07445 |             return 0 != loop_runtime_check_; 
 07446 |          } 
 07447 |  
 07448 |          mutable _uint64_t iteration_count_; 
 07449 |          mutable loop_runtime_check_ptr loop_runtime_check_; 
 07450 |          const details::_uint64_t& max_loop_iterations_; 
 07451 |          loop_runtime_check::loop_types loop_type_; 
 07452 |       }; 
 07453 |  
 07454 |       template <typename T> 
 07455 |       class while_loop_node : public expression_node<T> 
 07456 |       { 
 07457 |       public: 
 07458 |  
 07459 |          typedef expression_node<T>* expression_ptr; 
 07460 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07461 |  
 07462 |          while_loop_node(expression_ptr condition, 
 07463 |                          expression_ptr loop_body) 
 07464 |          { 
 07465 |             construct_branch_pair(condition_, condition); 
 07466 |             construct_branch_pair(loop_body_, loop_body); 
 07467 |             assert(valid()); 
 07468 |          } 
 07469 |  
 07470 |          inline T value() const exprtk_override 
 07471 |          { 
 07472 |             T result = T(0); 
 07473 |  
 07474 |             while (is_true(condition_)) 
 07475 |             { 
 07476 |                result = loop_body_.first->value(); 
 07477 |             } 
 07478 |  
 07479 |             return result; 
 07480 |          } 
 07481 |  
 07482 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07483 |          { 
 07484 |             return expression_node<T>::e_while; 
 07485 |          } 
 07486 |  
 07487 |          inline bool valid() const exprtk_override 
 07488 |          { 
 07489 |             return 
 07490 |                condition_.first && condition_.first->valid() && 
 07491 |                loop_body_.first && loop_body_.first->valid() ; 
 07492 |          } 
 07493 |  
 07494 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07495 |          { 
 07496 |             expression_node<T>::ndb_t::collect(condition_ , node_delete_list); 
 07497 |             expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list); 
 07498 |          } 
 07499 |  
 07500 |          std::size_t node_depth() const exprtk_override 
 07501 |          { 
 07502 |             return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_); 
 07503 |          } 
 07504 |  
 07505 |       protected: 
 07506 |  
 07507 |          branch_t condition_; 
 07508 |          branch_t loop_body_; 
 07509 |       }; 
 07510 |  
 07511 |       template <typename T> 
 07512 |       class while_loop_rtc_node exprtk_final 
 07513 |                                 : public while_loop_node<T> 
 07514 |                                 , public loop_runtime_checker 
 07515 |       { 
 07516 |       public: 
 07517 |  
 07518 |          typedef while_loop_node<T>  parent_t; 
 07519 |          typedef expression_node<T>* expression_ptr; 
 07520 |  
 07521 |          while_loop_rtc_node(expression_ptr condition, 
 07522 |                              expression_ptr loop_body, 
 07523 |                              loop_runtime_check_ptr loop_rt_chk) 
 07524 |          : parent_t(condition, loop_body) 
 07525 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop) 
 07526 |          { 
 07527 |             assert(valid()); 
 07528 |          } 
 07529 |  
 07530 |          inline T value() const exprtk_override 
 07531 |          { 
 07532 |  
 07533 |             T result = T(0); 
 07534 |  
 07535 |             loop_runtime_checker::reset(); 
 07536 |  
 07537 |             while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07538 |             { 
 07539 |                result = parent_t::loop_body_.first->value(); 
 07540 |             } 
 07541 |  
 07542 |             return result; 
 07543 |          } 
 07544 |  
 07545 |          using parent_t::valid; 
 07546 |  
 07547 |          bool valid() const exprtk_override exprtk_final 
 07548 |          { 
 07549 |             return parent_t::valid() && 
 07550 |                    loop_runtime_checker::valid(); 
 07551 |          } 
 07552 |       }; 
 07553 |  
 07554 |       template <typename T> 
 07555 |       class repeat_until_loop_node : public expression_node<T> 
 07556 |       { 
 07557 |       public: 
 07558 |  
 07559 |          typedef expression_node<T>* expression_ptr; 
 07560 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07561 |  
 07562 |          repeat_until_loop_node(expression_ptr condition, 
 07563 |                                 expression_ptr loop_body) 
 07564 |          { 
 07565 |             construct_branch_pair(condition_, condition); 
 07566 |             construct_branch_pair(loop_body_, loop_body); 
 07567 |             assert(valid()); 
 07568 |          } 
 07569 |  
 07570 |          inline T value() const exprtk_override 
 07571 |          { 
 07572 |             T result = T(0); 
 07573 |  
 07574 |             do 
 07575 |             { 
 07576 |                result = loop_body_.first->value(); 
 07577 |             } 
 07578 |             while (is_false(condition_.first)); 
 07579 |  
 07580 |             return result; 
 07581 |          } 
 07582 |  
 07583 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07584 |          { 
 07585 |             return expression_node<T>::e_repeat; 
 07586 |          } 
 07587 |  
 07588 |          inline bool valid() const exprtk_override 
 07589 |          { 
 07590 |             return 
 07591 |                condition_.first && condition_.first->valid() && 
 07592 |                loop_body_.first && loop_body_.first->valid() ; 
 07593 |          } 
 07594 |  
 07595 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07596 |          { 
 07597 |             expression_node<T>::ndb_t::collect(condition_ , node_delete_list); 
 07598 |             expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list); 
 07599 |          } 
 07600 |  
 07601 |          std::size_t node_depth() const exprtk_override 
 07602 |          { 
 07603 |             return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_); 
 07604 |          } 
 07605 |  
 07606 |       protected: 
 07607 |  
 07608 |          branch_t condition_; 
 07609 |          branch_t loop_body_; 
 07610 |       }; 
 07611 |  
 07612 |       template <typename T> 
 07613 |       class repeat_until_loop_rtc_node exprtk_final 
 07614 |                                        : public repeat_until_loop_node<T> 
 07615 |                                        , public loop_runtime_checker 
 07616 |       { 
 07617 |       public: 
 07618 |  
 07619 |          typedef repeat_until_loop_node<T> parent_t; 
 07620 |          typedef expression_node<T>*       expression_ptr; 
 07621 |  
 07622 |          repeat_until_loop_rtc_node(expression_ptr condition, 
 07623 |                                     expression_ptr loop_body, 
 07624 |                                     loop_runtime_check_ptr loop_rt_chk) 
 07625 |          : parent_t(condition, loop_body) 
 07626 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop) 
 07627 |          { 
 07628 |             assert(valid()); 
 07629 |          } 
 07630 |  
 07631 |          inline T value() const exprtk_override 
 07632 |          { 
 07633 |             T result = T(0); 
 07634 |  
 07635 |             loop_runtime_checker::reset(1); 
 07636 |  
 07637 |             do 
 07638 |             { 
 07639 |                result = parent_t::loop_body_.first->value(); 
 07640 |             } 
 07641 |             while (is_false(parent_t::condition_.first) && loop_runtime_checker::check()); 
 07642 |  
 07643 |             return result; 
 07644 |          } 
 07645 |  
 07646 |          using parent_t::valid; 
 07647 |  
 07648 |          inline bool valid() const exprtk_override exprtk_final 
 07649 |          { 
 07650 |             return parent_t::valid() && 
 07651 |                    loop_runtime_checker::valid(); 
 07652 |          } 
 07653 |       }; 
 07654 |  
 07655 |       template <typename T> 
 07656 |       class for_loop_node : public expression_node<T> 
 07657 |       { 
 07658 |       public: 
 07659 |  
 07660 |          typedef expression_node<T>* expression_ptr; 
 07661 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07662 |  
 07663 |          for_loop_node(expression_ptr initialiser, 
 07664 |                        expression_ptr condition, 
 07665 |                        expression_ptr incrementor, 
 07666 |                        expression_ptr loop_body) 
 07667 |          { 
 07668 |             construct_branch_pair(initialiser_, initialiser); 
 07669 |             construct_branch_pair(condition_  , condition  ); 
 07670 |             construct_branch_pair(incrementor_, incrementor); 
 07671 |             construct_branch_pair(loop_body_  , loop_body  ); 
 07672 |             assert(valid()); 
 07673 |          } 
 07674 |  
 07675 |          inline T value() const exprtk_override 
 07676 |          { 
 07677 |             T result = T(0); 
 07678 |  
 07679 |             if (initialiser_.first) 
 07680 |                initialiser_.first->value(); 
 07681 |  
 07682 |             if (incrementor_.first) 
 07683 |             { 
 07684 |                while (is_true(condition_)) 
 07685 |                { 
 07686 |                   result = loop_body_.first->value(); 
 07687 |                   incrementor_.first->value(); 
 07688 |                } 
 07689 |             } 
 07690 |             else 
 07691 |             { 
 07692 |                while (is_true(condition_)) 
 07693 |                { 
 07694 |                   result = loop_body_.first->value(); 
 07695 |                } 
 07696 |             } 
 07697 |  
 07698 |             return result; 
 07699 |          } 
 07700 |  
 07701 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07702 |          { 
 07703 |             return expression_node<T>::e_for; 
 07704 |          } 
 07705 |  
 07706 |          inline bool valid() const exprtk_override 
 07707 |          { 
 07708 |             return condition_.first && loop_body_.first; 
 07709 |          } 
 07710 |  
 07711 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07712 |          { 
 07713 |             expression_node<T>::ndb_t::collect(initialiser_ , node_delete_list); 
 07714 |             expression_node<T>::ndb_t::collect(condition_   , node_delete_list); 
 07715 |             expression_node<T>::ndb_t::collect(incrementor_ , node_delete_list); 
 07716 |             expression_node<T>::ndb_t::collect(loop_body_   , node_delete_list); 
 07717 |          } 
 07718 |  
 07719 |          std::size_t node_depth() const exprtk_override 
 07720 |          { 
 07721 |             return expression_node<T>::ndb_t::compute_node_depth 
 07722 |                (initialiser_, condition_, incrementor_, loop_body_); 
 07723 |          } 
 07724 |  
 07725 |       protected: 
 07726 |  
 07727 |          branch_t initialiser_; 
 07728 |          branch_t condition_  ; 
 07729 |          branch_t incrementor_; 
 07730 |          branch_t loop_body_  ; 
 07731 |       }; 
 07732 |  
 07733 |       template <typename T> 
 07734 |       class for_loop_rtc_node exprtk_final 
 07735 |                               : public for_loop_node<T> 
 07736 |                               , public loop_runtime_checker 
 07737 |       { 
 07738 |       public: 
 07739 |  
 07740 |          typedef for_loop_node<T>    parent_t; 
 07741 |          typedef expression_node<T>* expression_ptr; 
 07742 |  
 07743 |          for_loop_rtc_node(expression_ptr initialiser, 
 07744 |                            expression_ptr condition, 
 07745 |                            expression_ptr incrementor, 
 07746 |                            expression_ptr loop_body, 
 07747 |                            loop_runtime_check_ptr loop_rt_chk) 
 07748 |          : parent_t(initialiser, condition, incrementor, loop_body) 
 07749 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop) 
 07750 |          { 
 07751 |             assert(valid()); 
 07752 |          } 
 07753 |  
 07754 |          inline T value() const exprtk_override 
 07755 |          { 
 07756 |             T result = T(0); 
 07757 |  
 07758 |             loop_runtime_checker::reset(); 
 07759 |  
 07760 |             if (parent_t::initialiser_.first) 
 07761 |                parent_t::initialiser_.first->value(); 
 07762 |  
 07763 |             if (parent_t::incrementor_.first) 
 07764 |             { 
 07765 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07766 |                { 
 07767 |                   result = parent_t::loop_body_.first->value(); 
 07768 |                   parent_t::incrementor_.first->value(); 
 07769 |                } 
 07770 |             } 
 07771 |             else 
 07772 |             { 
 07773 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07774 |                { 
 07775 |                   result = parent_t::loop_body_.first->value(); 
 07776 |                } 
 07777 |             } 
 07778 |  
 07779 |             return result; 
 07780 |          } 
 07781 |  
 07782 |          using parent_t::valid; 
 07783 |  
 07784 |          inline bool valid() const exprtk_override exprtk_final 
 07785 |          { 
 07786 |             return parent_t::valid() && 
 07787 |                    loop_runtime_checker::valid(); 
 07788 |          } 
 07789 |       }; 
 07790 |  
 07791 |       #ifndef exprtk_disable_break_continue 
 07792 |       template <typename T> 
 07793 |       class while_loop_bc_node : public while_loop_node<T> 
 07794 |       { 
 07795 |       public: 
 07796 |  
 07797 |          typedef while_loop_node<T>  parent_t; 
 07798 |          typedef expression_node<T>* expression_ptr; 
 07799 |  
 07800 |          while_loop_bc_node(expression_ptr condition, 
 07801 |                             expression_ptr loop_body) 
 07802 |          : parent_t(condition, loop_body) 
 07803 |          { 
 07804 |             assert(parent_t::valid()); 
 07805 |          } 
 07806 |  
 07807 |          inline T value() const exprtk_override 
 07808 |          { 
 07809 |             T result = T(0); 
 07810 |  
 07811 |             while (is_true(parent_t::condition_)) 
 07812 |             { 
 07813 |                try 
 07814 |                { 
 07815 |                   result = parent_t::loop_body_.first->value(); 
 07816 |                } 
 07817 |                catch(const break_exception<T>& e) 
 07818 |                { 
 07819 |                   return e.value; 
 07820 |                } 
 07821 |                catch(const continue_exception&) 
 07822 |                {} 
 07823 |             } 
 07824 |  
 07825 |             return result; 
 07826 |          } 
 07827 |       }; 
 07828 |  
 07829 |       template <typename T> 
 07830 |       class while_loop_bc_rtc_node exprtk_final 
 07831 |                                    : public while_loop_bc_node<T> 
 07832 |                                    , public loop_runtime_checker 
 07833 |       { 
 07834 |       public: 
 07835 |  
 07836 |          typedef while_loop_bc_node<T> parent_t; 
 07837 |          typedef expression_node<T>*   expression_ptr; 
 07838 |  
 07839 |          while_loop_bc_rtc_node(expression_ptr condition, 
 07840 |                                 expression_ptr loop_body, 
 07841 |                                 loop_runtime_check_ptr loop_rt_chk) 
 07842 |          : parent_t(condition, loop_body) 
 07843 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop) 
 07844 |          { 
 07845 |             assert(valid()); 
 07846 |          } 
 07847 |  
 07848 |          inline T value() const exprtk_override 
 07849 |          { 
 07850 |             T result = T(0); 
 07851 |  
 07852 |             loop_runtime_checker::reset(); 
 07853 |  
 07854 |             while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07855 |             { 
 07856 |                try 
 07857 |                { 
 07858 |                   result = parent_t::loop_body_.first->value(); 
 07859 |                } 
 07860 |                catch(const break_exception<T>& e) 
 07861 |                { 
 07862 |                   return e.value; 
 07863 |                } 
 07864 |                catch(const continue_exception&) 
 07865 |                {} 
 07866 |             } 
 07867 |  
 07868 |             return result; 
 07869 |          } 
 07870 |  
 07871 |          using parent_t::valid; 
 07872 |  
 07873 |          inline bool valid() const exprtk_override exprtk_final 
 07874 |          { 
 07875 |             return parent_t::valid() && 
 07876 |                    loop_runtime_checker::valid(); 
 07877 |          } 
 07878 |       }; 
 07879 |  
 07880 |       template <typename T> 
 07881 |       class repeat_until_loop_bc_node : public repeat_until_loop_node<T> 
 07882 |       { 
 07883 |       public: 
 07884 |  
 07885 |          typedef repeat_until_loop_node<T> parent_t; 
 07886 |          typedef expression_node<T>*       expression_ptr; 
 07887 |  
 07888 |          repeat_until_loop_bc_node(expression_ptr condition, 
 07889 |                                    expression_ptr loop_body) 
 07890 |          : parent_t(condition, loop_body) 
 07891 |          { 
 07892 |             assert(parent_t::valid()); 
 07893 |          } 
 07894 |  
 07895 |          inline T value() const exprtk_override 
 07896 |          { 
 07897 |             T result = T(0); 
 07898 |  
 07899 |             do 
 07900 |             { 
 07901 |                try 
 07902 |                { 
 07903 |                   result = parent_t::loop_body_.first->value(); 
 07904 |                } 
 07905 |                catch(const break_exception<T>& e) 
 07906 |                { 
 07907 |                   return e.value; 
 07908 |                } 
 07909 |                catch(const continue_exception&) 
 07910 |                {} 
 07911 |             } 
 07912 |             while (is_false(parent_t::condition_.first)); 
 07913 |  
 07914 |             return result; 
 07915 |          } 
 07916 |       }; 
 07917 |  
 07918 |       template <typename T> 
 07919 |       class repeat_until_loop_bc_rtc_node exprtk_final 
 07920 |                                           : public repeat_until_loop_bc_node<T> 
 07921 |                                           , public loop_runtime_checker 
 07922 |       { 
 07923 |       public: 
 07924 |  
 07925 |          typedef repeat_until_loop_bc_node<T> parent_t; 
 07926 |          typedef expression_node<T>*          expression_ptr; 
 07927 |  
 07928 |          repeat_until_loop_bc_rtc_node(expression_ptr condition, 
 07929 |                                        expression_ptr loop_body, 
 07930 |                                        loop_runtime_check_ptr loop_rt_chk) 
 07931 |          : parent_t(condition, loop_body) 
 07932 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop) 
 07933 |          { 
 07934 |             assert(valid()); 
 07935 |          } 
 07936 |  
 07937 |          inline T value() const exprtk_override 
 07938 |          { 
 07939 |             T result = T(0); 
 07940 |  
 07941 |             loop_runtime_checker::reset(); 
 07942 |  
 07943 |             do 
 07944 |             { 
 07945 |                try 
 07946 |                { 
 07947 |                   result = parent_t::loop_body_.first->value(); 
 07948 |                } 
 07949 |                catch(const break_exception<T>& e) 
 07950 |                { 
 07951 |                   return e.value; 
 07952 |                } 
 07953 |                catch(const continue_exception&) 
 07954 |                {} 
 07955 |             } 
 07956 |             while (is_false(parent_t::condition_.first) && loop_runtime_checker::check()); 
 07957 |  
 07958 |             return result; 
 07959 |          } 
 07960 |  
 07961 |          using parent_t::valid; 
 07962 |  
 07963 |          inline bool valid() const exprtk_override exprtk_final 
 07964 |          { 
 07965 |             return parent_t::valid() && 
 07966 |                    loop_runtime_checker::valid(); 
 07967 |          } 
 07968 |       }; 
 07969 |  
 07970 |       template <typename T> 
 07971 |       class for_loop_bc_node : public for_loop_node<T> 
 07972 |       { 
 07973 |       public: 
 07974 |  
 07975 |          typedef for_loop_node<T>    parent_t; 
 07976 |          typedef expression_node<T>* expression_ptr; 
 07977 |  
 07978 |          for_loop_bc_node(expression_ptr initialiser, 
 07979 |                           expression_ptr condition, 
 07980 |                           expression_ptr incrementor, 
 07981 |                           expression_ptr loop_body) 
 07982 |          : parent_t(initialiser, condition, incrementor, loop_body) 
 07983 |          { 
 07984 |             assert(parent_t::valid()); 
 07985 |          } 
 07986 |  
 07987 |          inline T value() const exprtk_override 
 07988 |          { 
 07989 |             T result = T(0); 
 07990 |  
 07991 |             if (parent_t::initialiser_.first) 
 07992 |                parent_t::initialiser_.first->value(); 
 07993 |  
 07994 |             if (parent_t::incrementor_.first) 
 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 |                   parent_t::incrementor_.first->value(); 
 08010 |                } 
 08011 |             } 
 08012 |             else 
 08013 |             { 
 08014 |                while (is_true(parent_t::condition_)) 
 08015 |                { 
 08016 |                   try 
 08017 |                   { 
 08018 |                      result = parent_t::loop_body_.first->value(); 
 08019 |                   } 
 08020 |                   catch(const break_exception<T>& e) 
 08021 |                   { 
 08022 |                      return e.value; 
 08023 |                   } 
 08024 |                   catch(const continue_exception&) 
 08025 |                   {} 
 08026 |                } 
 08027 |             } 
 08028 |  
 08029 |             return result; 
 08030 |          } 
 08031 |       }; 
 08032 |  
 08033 |       template <typename T> 
 08034 |       class for_loop_bc_rtc_node exprtk_final 
 08035 |                                  : public for_loop_bc_node<T> 
 08036 |                                  , public loop_runtime_checker 
 08037 |       { 
 08038 |       public: 
 08039 |  
 08040 |          typedef for_loop_bc_node<T> parent_t; 
 08041 |          typedef expression_node<T>* expression_ptr; 
 08042 |  
 08043 |          for_loop_bc_rtc_node(expression_ptr initialiser, 
 08044 |                               expression_ptr condition, 
 08045 |                               expression_ptr incrementor, 
 08046 |                               expression_ptr loop_body, 
 08047 |                               loop_runtime_check_ptr loop_rt_chk) 
 08048 |          : parent_t(initialiser, condition, incrementor, loop_body) 
 08049 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop) 
 08050 |          { 
 08051 |             assert(valid()); 
 08052 |          } 
 08053 |  
 08054 |          inline T value() const exprtk_override 
 08055 |          { 
 08056 |             T result = T(0); 
 08057 |  
 08058 |             loop_runtime_checker::reset(); 
 08059 |  
 08060 |             if (parent_t::initialiser_.first) 
 08061 |                parent_t::initialiser_.first->value(); 
 08062 |  
 08063 |             if (parent_t::incrementor_.first) 
 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 |                   parent_t::incrementor_.first->value(); 
 08079 |                } 
 08080 |             } 
 08081 |             else 
 08082 |             { 
 08083 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 08084 |                { 
 08085 |                   try 
 08086 |                   { 
 08087 |                      result = parent_t::loop_body_.first->value(); 
 08088 |                   } 
 08089 |                   catch(const break_exception<T>& e) 
 08090 |                   { 
 08091 |                      return e.value; 
 08092 |                   } 
 08093 |                   catch(const continue_exception&) 
 08094 |                   {} 
 08095 |                } 
 08096 |             } 
 08097 |  
 08098 |             return result; 
 08099 |          } 
 08100 |  
 08101 |          using parent_t::valid; 
 08102 |  
 08103 |          inline bool valid() const exprtk_override exprtk_final 
 08104 |          { 
 08105 |             return parent_t::valid() && 
 08106 |                    loop_runtime_checker::valid(); 
 08107 |          } 
 08108 |       }; 
 08109 |       #endif 
 08110 |  
 08111 |       template <typename T> 
 08112 |       class switch_node : public expression_node<T> 
 08113 |       { 
 08114 |       public: 
 08115 |  
 08116 |          typedef expression_node<T>* expression_ptr; 
 08117 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08118 |  
 08119 |          template <typename Allocator, 
 08120 |                    template <typename, typename> class Sequence> 
 08121 |          explicit switch_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 08122 |          { 
 08123 |             if (1 != (arg_list.size() & 1)) 
 08124 |                return; 
 08125 |  
 08126 |             arg_list_.resize(arg_list.size()); 
 08127 |  
 08128 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 08129 |             { 
 08130 |                if (arg_list[i] && arg_list[i]->valid()) 
 08131 |                { 
 08132 |                   construct_branch_pair(arg_list_[i], arg_list[i]); 
 08133 |                } 
 08134 |                else 
 08135 |                { 
 08136 |                   arg_list_.clear(); 
 08137 |                   return; 
 08138 |                } 
 08139 |             } 
 08140 |  
 08141 |             assert(valid()); 
 08142 |          } 
 08143 |  
 08144 |          inline T value() const exprtk_override 
 08145 |          { 
 08146 |             const std::size_t upper_bound = (arg_list_.size() - 1); 
 08147 |  
 08148 |             for (std::size_t i = 0; i < upper_bound; i += 2) 
 08149 |             { 
 08150 |                expression_ptr condition  = arg_list_[i    ].first; 
 08151 |                expression_ptr consequent = arg_list_[i + 1].first; 
 08152 |  
 08153 |                if (is_true(condition)) 
 08154 |                { 
 08155 |                   return consequent->value(); 
 08156 |                } 
 08157 |             } 
 08158 |  
 08159 |             return arg_list_[upper_bound].first->value(); 
 08160 |          } 
 08161 |  
 08162 |          inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final 
 08163 |          { 
 08164 |             return expression_node<T>::e_switch; 
 08165 |          } 
 08166 |  
 08167 |          inline bool valid() const exprtk_override 
 08168 |          { 
 08169 |             return !arg_list_.empty(); 
 08170 |          } 
 08171 |  
 08172 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08173 |          { 
 08174 |             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list); 
 08175 |          } 
 08176 |  
 08177 |          std::size_t node_depth() const exprtk_override exprtk_final 
 08178 |          { 
 08179 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 08180 |          } 
 08181 |  
 08182 |       protected: 
 08183 |  
 08184 |          std::vector<branch_t> arg_list_; 
 08185 |       }; 
 08186 |  
 08187 |       template <typename T, typename Switch_N> 
 08188 |       class switch_n_node exprtk_final : public switch_node<T> 
 08189 |       { 
 08190 |       public: 
 08191 |  
 08192 |          typedef expression_node<T>* expression_ptr; 
 08193 |  
 08194 |          template <typename Allocator, 
 08195 |                    template <typename, typename> class Sequence> 
 08196 |          explicit switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 08197 |          : switch_node<T>(arg_list) 
 08198 |          {} 
 08199 |  
 08200 |          inline T value() const exprtk_override 
 08201 |          { 
 08202 |             return Switch_N::process(switch_node<T>::arg_list_); 
 08203 |          } 
 08204 |       }; 
 08205 |  
 08206 |       template <typename T> 
 08207 |       class multi_switch_node exprtk_final : public expression_node<T> 
 08208 |       { 
 08209 |       public: 
 08210 |  
 08211 |          typedef expression_node<T>* expression_ptr; 
 08212 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08213 |  
 08214 |          template <typename Allocator, 
 08215 |                    template <typename, typename> class Sequence> 
 08216 |          explicit multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 08217 |          { 
 08218 |             if (0 != (arg_list.size() & 1)) 
 08219 |                return; 
 08220 |  
 08221 |             arg_list_.resize(arg_list.size()); 
 08222 |  
 08223 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 08224 |             { 
 08225 |                if (arg_list[i] && arg_list[i]->valid()) 
 08226 |                { 
 08227 |                   construct_branch_pair(arg_list_[i], arg_list[i]); 
 08228 |                } 
 08229 |                else 
 08230 |                { 
 08231 |                   arg_list_.clear(); 
 08232 |                   return; 
 08233 |                } 
 08234 |             } 
 08235 |  
 08236 |             assert(valid()); 
 08237 |          } 
 08238 |  
 08239 |          inline T value() const exprtk_override 
 08240 |          { 
 08241 |             const std::size_t upper_bound = (arg_list_.size() - 1); 
 08242 |  
 08243 |             T result = T(0); 
 08244 |  
 08245 |             for (std::size_t i = 0; i < upper_bound; i += 2) 
 08246 |             { 
 08247 |                expression_ptr condition  = arg_list_[i    ].first; 
 08248 |                expression_ptr consequent = arg_list_[i + 1].first; 
 08249 |  
 08250 |                if (is_true(condition)) 
 08251 |                { 
 08252 |                   result = consequent->value(); 
 08253 |                } 
 08254 |             } 
 08255 |  
 08256 |             return result; 
 08257 |          } 
 08258 |  
 08259 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08260 |          { 
 08261 |             return expression_node<T>::e_mswitch; 
 08262 |          } 
 08263 |  
 08264 |          inline bool valid() const exprtk_override 
 08265 |          { 
 08266 |             return !arg_list_.empty() && (0 == (arg_list_.size() % 2)); 
 08267 |          } 
 08268 |  
 08269 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08270 |          { 
 08271 |             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list); 
 08272 |          } 
 08273 |  
 08274 |          std::size_t node_depth() const exprtk_override exprtk_final 
 08275 |          { 
 08276 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 08277 |          } 
 08278 |  
 08279 |       private: 
 08280 |  
 08281 |          std::vector<branch_t> arg_list_; 
 08282 |       }; 
 08283 |  
 08284 |       template <typename T> 
 08285 |       class ivariable 
 08286 |       { 
 08287 |       public: 
 08288 |  
 08289 |          virtual ~ivariable() 
 08290 |          {} 
 08291 |  
 08292 |          virtual T& ref() = 0; 
 08293 |          virtual const T& ref() const = 0; 
 08294 |       }; 
 08295 |  
 08296 |       template <typename T> 
 08297 |       class variable_node exprtk_final 
 08298 |                           : public expression_node<T> 
 08299 |                           , public ivariable      <T> 
 08300 |       { 
 08301 |       public: 
 08302 |  
 08303 |          static T null_value; 
 08304 |  
 08305 |          explicit variable_node() 
 08306 |          : value_(&null_value) 
 08307 |          {} 
 08308 |  
 08309 |          explicit variable_node(T& v) 
 08310 |          : value_(&v) 
 08311 |          {} 
 08312 |  
 08313 |          inline bool operator <(const variable_node<T>& v) const 
 08314 |          { 
 08315 |             return this < (&v); 
 08316 |          } 
 08317 |  
 08318 |          inline T value() const exprtk_override 
 08319 |          { 
 08320 |             return (*value_); 
 08321 |          } 
 08322 |  
 08323 |          inline T& ref() exprtk_override 
 08324 |          { 
 08325 |             return (*value_); 
 08326 |          } 
 08327 |  
 08328 |          inline const T& ref() const exprtk_override 
 08329 |          { 
 08330 |             return (*value_); 
 08331 |          } 
 08332 |  
 08333 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08334 |          { 
 08335 |             return expression_node<T>::e_variable; 
 08336 |          } 
 08337 |  
 08338 |       private: 
 08339 |  
 08340 |          T* value_; 
 08341 |       }; 
 08342 |  
 08343 |       template <typename T> 
 08344 |       T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN()); 
 08345 |  
 08346 |       template <typename T> 
 08347 |       struct range_pack 
 08348 |       { 
 08349 |          typedef expression_node<T>*           expression_node_ptr; 
 08350 |          typedef std::pair<std::size_t,std::size_t> cached_range_t; 
 08351 |  
 08352 |          range_pack() 
 08353 |          : n0_e (std::make_pair(false,expression_node_ptr(0))) 
 08354 |          , n1_e (std::make_pair(false,expression_node_ptr(0))) 
 08355 |          , n0_c (std::make_pair(false,0)) 
 08356 |          , n1_c (std::make_pair(false,0)) 
 08357 |          , cache(std::make_pair(0,0)) 
 08358 |          {} 
 08359 |  
 08360 |          void clear() 
 08361 |          { 
 08362 |             n0_e  = std::make_pair(false,expression_node_ptr(0)); 
 08363 |             n1_e  = std::make_pair(false,expression_node_ptr(0)); 
 08364 |             n0_c  = std::make_pair(false,0); 
 08365 |             n1_c  = std::make_pair(false,0); 
 08366 |             cache = std::make_pair(0,0); 
 08367 |          } 
 08368 |  
 08369 |          void free() 
 08370 |          { 
 08371 |             if (n0_e.first && n0_e.second) 
 08372 |             { 
 08373 |                n0_e.first = false; 
 08374 |  
 08375 |                if ( 
 08376 |                     !is_variable_node(n0_e.second) && 
 08377 |                     !is_string_node  (n0_e.second) 
 08378 |                   ) 
 08379 |                { 
 08380 |                   destroy_node(n0_e.second); 
 08381 |                } 
 08382 |             } 
 08383 |  
 08384 |             if (n1_e.first && n1_e.second) 
 08385 |             { 
 08386 |                n1_e.first = false; 
 08387 |  
 08388 |                if ( 
 08389 |                     !is_variable_node(n1_e.second) && 
 08390 |                     !is_string_node  (n1_e.second) 
 08391 |                   ) 
 08392 |                { 
 08393 |                   destroy_node(n1_e.second); 
 08394 |                } 
 08395 |             } 
 08396 |          } 
 08397 |  
 08398 |          bool const_range() const 
 08399 |          { 
 08400 |            return ( n0_c.first &&  n1_c.first) && 
 08401 |                   (!n0_e.first && !n1_e.first); 
 08402 |          } 
 08403 |  
 08404 |          bool var_range() const 
 08405 |          { 
 08406 |            return ( n0_e.first &&  n1_e.first) && 
 08407 |                   (!n0_c.first && !n1_c.first); 
 08408 |          } 
 08409 |  
 08410 |          bool operator() (std::size_t& r0, std::size_t& r1, 
 08411 |                           const std::size_t& size = std::numeric_limits<std::size_t>::max()) const 
 08412 |          { 
 08413 |             if (n0_c.first) 
 08414 |                r0 = n0_c.second; 
 08415 |             else if (n0_e.first) 
 08416 |             { 
 08417 |                r0 = static_cast<std::size_t>(details::numeric::to_int64(n0_e.second->value())); 
 08418 |             } 
 08419 |             else 
 08420 |                return false; 
 08421 |  
 08422 |             if (n1_c.first) 
 08423 |                r1 = n1_c.second; 
 08424 |             else if (n1_e.first) 
 08425 |             { 
 08426 |                r1 = static_cast<std::size_t>(details::numeric::to_int64(n1_e.second->value())); 
 08427 |             } 
 08428 |             else 
 08429 |                return false; 
 08430 |  
 08431 |             if ( 
 08432 |                  (std::numeric_limits<std::size_t>::max() != size) && 
 08433 |                  (std::numeric_limits<std::size_t>::max() == r1  ) 
 08434 |                ) 
 08435 |             { 
 08436 |                r1 = size; 
 08437 |             } 
 08438 |  
 08439 |             cache.first  = r0; 
 08440 |             cache.second = r1; 
 08441 |  
 08442 |             #ifndef exprtk_enable_range_runtime_checks 
 08443 |             return (r0 <= r1); 
 08444 |             #else 
 08445 |             return range_runtime_check(r0, r1, size); 
 08446 |             #endif 
 08447 |          } 
 08448 |  
 08449 |          inline std::size_t const_size() const 
 08450 |          { 
 08451 |             return (n1_c.second - n0_c.second); 
 08452 |          } 
 08453 |  
 08454 |          inline std::size_t cache_size() const 
 08455 |          { 
 08456 |             return (cache.second - cache.first); 
 08457 |          } 
 08458 |  
 08459 |          std::pair<bool,expression_node_ptr> n0_e; 
 08460 |          std::pair<bool,expression_node_ptr> n1_e; 
 08461 |          std::pair<bool,std::size_t        > n0_c; 
 08462 |          std::pair<bool,std::size_t        > n1_c; 
 08463 |          mutable cached_range_t             cache; 
 08464 |  
 08465 |          #ifdef exprtk_enable_range_runtime_checks 
 08466 |          bool range_runtime_check(const std::size_t r0, 
 08467 |                                   const std::size_t r1, 
 08468 |                                   const std::size_t size) const 
 08469 |          { 
 08470 |             if (r0 > size) 
 08471 |             { 
 08472 |                throw std::runtime_error("range error: (r0 < 0) || (r0 > size)"); 
 08473 |                #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 08474 |                return false; 
 08475 |                #endif 
 08476 |             } 
 08477 |  
 08478 |             if (r1 > size) 
 08479 |             { 
 08480 |                throw std::runtime_error("range error: (r1 < 0) || (r1 > size)"); 
 08481 |                #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 08482 |                return false; 
 08483 |                #endif 
 08484 |             } 
 08485 |  
 08486 |             return (r0 <= r1); 
 08487 |          } 
 08488 |          #endif 
 08489 |       }; 
 08490 |  
 08491 |       template <typename T> 
 08492 |       class string_base_node; 
 08493 |  
 08494 |       template <typename T> 
 08495 |       struct range_data_type 
 08496 |       { 
 08497 |          typedef range_pack<T> range_t; 
 08498 |          typedef string_base_node<T>* strbase_ptr_t; 
 08499 |  
 08500 |          range_data_type() 
 08501 |          : range(0) 
 08502 |          , data (0) 
 08503 |          , size (0) 
 08504 |          , type_size(0) 
 08505 |          , str_node (0) 
 08506 |          {} 
 08507 |  
 08508 |          range_t*      range; 
 08509 |          void*         data; 
 08510 |          std::size_t   size; 
 08511 |          std::size_t   type_size; 
 08512 |          strbase_ptr_t str_node; 
 08513 |       }; 
 08514 |  
 08515 |       template <typename T> class vector_node; 
 08516 |  
 08517 |       template <typename T> 
 08518 |       class vector_interface 
 08519 |       { 
 08520 |       public: 
 08521 |  
 08522 |          typedef vector_node<T>*   vector_node_ptr; 
 08523 |          typedef vec_data_store<T> vds_t; 
 08524 |  
 08525 |          virtual ~vector_interface() 
 08526 |          {} 
 08527 |  
 08528 |          virtual std::size_t size     () const = 0; 
 08529 |  
 08530 |          virtual std::size_t base_size() const = 0; 
 08531 |  
 08532 |          virtual vector_node_ptr vec  () const = 0; 
 08533 |  
 08534 |          virtual vector_node_ptr vec  ()       = 0; 
 08535 |  
 08536 |          virtual       vds_t& vds     ()       = 0; 
 08537 |  
 08538 |          virtual const vds_t& vds     () const = 0; 
 08539 |  
 08540 |          virtual bool side_effect     () const { return false; } 
 08541 |       }; 
 08542 |  
 08543 |       template <typename T> 
 08544 |       class vector_node exprtk_final 
 08545 |                         : public expression_node <T> 
 08546 |                         , public vector_interface<T> 
 08547 |       { 
 08548 |       public: 
 08549 |  
 08550 |          typedef expression_node<T>* expression_ptr; 
 08551 |          typedef vector_holder<T>    vector_holder_t; 
 08552 |          typedef vector_node<T>*     vector_node_ptr; 
 08553 |          typedef vec_data_store<T>   vds_t; 
 08554 |  
 08555 |          explicit vector_node(vector_holder_t* vh) 
 08556 |          : vector_holder_(vh) 
 08557 |          , vds_((*vector_holder_).size(),(*vector_holder_)[0]) 
 08558 |          { 
 08559 |             vector_holder_->set_ref(&vds_.ref()); 
 08560 |          } 
 08561 |  
 08562 |          vector_node(const vds_t& vds, vector_holder_t* vh) 
 08563 |          : vector_holder_(vh) 
 08564 |          , vds_(vds) 
 08565 |          {} 
 08566 |  
 08567 |         ~vector_node() exprtk_override 
 08568 |          { 
 08569 |             assert(valid()); 
 08570 |             vector_holder_->remove_ref(&vds_.ref()); 
 08571 |          } 
 08572 |  
 08573 |          inline T value() const exprtk_override 
 08574 |          { 
 08575 |             return vds().data()[0]; 
 08576 |          } 
 08577 |  
 08578 |          vector_node_ptr vec() const exprtk_override 
 08579 |          { 
 08580 |             return const_cast<vector_node_ptr>(this); 
 08581 |          } 
 08582 |  
 08583 |          vector_node_ptr vec() exprtk_override 
 08584 |          { 
 08585 |             return this; 
 08586 |          } 
 08587 |  
 08588 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08589 |          { 
 08590 |             return expression_node<T>::e_vector; 
 08591 |          } 
 08592 |  
 08593 |          inline bool valid() const exprtk_override 
 08594 |          { 
 08595 |             return vector_holder_; 
 08596 |          } 
 08597 |  
 08598 |          std::size_t size() const exprtk_override 
 08599 |          { 
 08600 |             return vec_holder().size(); 
 08601 |          } 
 08602 |  
 08603 |          std::size_t base_size() const exprtk_override 
 08604 |          { 
 08605 |             return vec_holder().base_size(); 
 08606 |          } 
 08607 |  
 08608 |          vds_t& vds() exprtk_override 
 08609 |          { 
 08610 |             return vds_; 
 08611 |          } 
 08612 |  
 08613 |          const vds_t& vds() const exprtk_override 
 08614 |          { 
 08615 |             return vds_; 
 08616 |          } 
 08617 |  
 08618 |          inline vector_holder_t& vec_holder() 
 08619 |          { 
 08620 |             return (*vector_holder_); 
 08621 |          } 
 08622 |  
 08623 |          inline vector_holder_t& vec_holder() const 
 08624 |          { 
 08625 |             return (*vector_holder_); 
 08626 |          } 
 08627 |  
 08628 |       private: 
 08629 |  
 08630 |          vector_holder_t* vector_holder_; 
 08631 |          vds_t                      vds_; 
 08632 |       }; 
 08633 |  
 08634 |       template <typename T> 
 08635 |       class vector_size_node exprtk_final 
 08636 |                         : public expression_node <T> 
 08637 |       { 
 08638 |       public: 
 08639 |  
 08640 |          typedef expression_node<T>* expression_ptr; 
 08641 |          typedef vector_holder<T>    vector_holder_t; 
 08642 |  
 08643 |          explicit vector_size_node(vector_holder_t* vh) 
 08644 |          : vector_holder_(vh) 
 08645 |          {} 
 08646 |  
 08647 |         ~vector_size_node() exprtk_override 
 08648 |          { 
 08649 |             assert(valid()); 
 08650 |          } 
 08651 |  
 08652 |          inline T value() const exprtk_override 
 08653 |          { 
 08654 |             assert(vector_holder_); 
 08655 |             return static_cast<T>(vector_holder_->size()); 
 08656 |          } 
 08657 |  
 08658 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08659 |          { 
 08660 |             return expression_node<T>::e_vecsize; 
 08661 |          } 
 08662 |  
 08663 |          inline bool valid() const exprtk_override 
 08664 |          { 
 08665 |             return vector_holder_ && vector_holder_->size(); 
 08666 |          } 
 08667 |  
 08668 |          inline vector_holder_t* vec_holder() 
 08669 |          { 
 08670 |             return vector_holder_; 
 08671 |          } 
 08672 |  
 08673 |       private: 
 08674 |  
 08675 |          vector_holder_t* vector_holder_; 
 08676 |       }; 
 08677 |  
 08678 |       template <typename T> 
 08679 |       class vector_elem_node exprtk_final 
 08680 |                              : public expression_node<T> 
 08681 |                              , public ivariable      <T> 
 08682 |       { 
 08683 |       public: 
 08684 |  
 08685 |          typedef expression_node<T>*            expression_ptr; 
 08686 |          typedef vector_holder<T>               vector_holder_t; 
 08687 |          typedef vector_holder_t*               vector_holder_ptr; 
 08688 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08689 |  
 08690 |          vector_elem_node(expression_ptr vec_node, 
 08691 |                           expression_ptr index, 
 08692 |                           vector_holder_ptr vec_holder) 
 08693 |          : vector_holder_(vec_holder) 
 08694 |          , vector_base_((*vec_holder)[0]) 
 08695 |          { 
 08696 |             construct_branch_pair(vector_node_, vec_node); 
 08697 |             construct_branch_pair(index_      , index   ); 
 08698 |             assert(valid()); 
 08699 |          } 
 08700 |  
 08701 |          inline T value() const exprtk_override 
 08702 |          { 
 08703 |             return *access_vector(); 
 08704 |          } 
 08705 |  
 08706 |          inline T& ref() exprtk_override 
 08707 |          { 
 08708 |             return *access_vector(); 
 08709 |          } 
 08710 |  
 08711 |          inline const T& ref() const exprtk_override 
 08712 |          { 
 08713 |             return *access_vector(); 
 08714 |          } 
 08715 |  
 08716 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08717 |          { 
 08718 |             return expression_node<T>::e_vecelem; 
 08719 |          } 
 08720 |  
 08721 |          inline bool valid() const exprtk_override 
 08722 |          { 
 08723 |             return 
 08724 |                vector_holder_        && 
 08725 |                index_.first          && 
 08726 |                vector_node_.first    && 
 08727 |                index_.first->valid() && 
 08728 |                vector_node_.first->valid(); 
 08729 |          } 
 08730 |  
 08731 |          inline vector_holder_t& vec_holder() 
 08732 |          { 
 08733 |             return (*vector_holder_); 
 08734 |          } 
 08735 |  
 08736 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08737 |          { 
 08738 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08739 |             expression_node<T>::ndb_t::collect(index_      , node_delete_list); 
 08740 |          } 
 08741 |  
 08742 |          std::size_t node_depth() const exprtk_override 
 08743 |          { 
 08744 |             return expression_node<T>::ndb_t::compute_node_depth 
 08745 |                (vector_node_, index_); 
 08746 |          } 
 08747 |  
 08748 |       private: 
 08749 |  
 08750 |          inline T* access_vector() const 
 08751 |          { 
 08752 |             vector_node_.first->value(); 
 08753 |             return (vector_base_ + details::numeric::to_uint64(index_.first->value())); 
 08754 |          } 
 08755 |  
 08756 |          vector_holder_ptr vector_holder_; 
 08757 |          T* vector_base_; 
 08758 |          branch_t vector_node_; 
 08759 |          branch_t index_; 
 08760 |       }; 
 08761 |  
 08762 |       template <typename T> 
 08763 |       class vector_celem_node exprtk_final 
 08764 |                               : public expression_node<T> 
 08765 |                               , public ivariable      <T> 
 08766 |       { 
 08767 |       public: 
 08768 |  
 08769 |          typedef expression_node<T>*            expression_ptr; 
 08770 |          typedef vector_holder<T>               vector_holder_t; 
 08771 |          typedef vector_holder_t*               vector_holder_ptr; 
 08772 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08773 |  
 08774 |          vector_celem_node(expression_ptr vec_node, 
 08775 |                            const std::size_t index, 
 08776 |                            vector_holder_ptr vec_holder) 
 08777 |          : index_(index) 
 08778 |          , vector_holder_(vec_holder) 
 08779 |          , vector_base_((*vec_holder)[0]) 
 08780 |          { 
 08781 |             construct_branch_pair(vector_node_, vec_node); 
 08782 |             assert(valid()); 
 08783 |          } 
 08784 |  
 08785 |          inline T value() const exprtk_override 
 08786 |          { 
 08787 |             return *access_vector(); 
 08788 |          } 
 08789 |  
 08790 |          inline T& ref() exprtk_override 
 08791 |          { 
 08792 |             return *access_vector(); 
 08793 |          } 
 08794 |  
 08795 |          inline const T& ref() const exprtk_override 
 08796 |          { 
 08797 |             return *access_vector(); 
 08798 |          } 
 08799 |  
 08800 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08801 |          { 
 08802 |             return expression_node<T>::e_veccelem; 
 08803 |          } 
 08804 |  
 08805 |          inline bool valid() const exprtk_override 
 08806 |          { 
 08807 |             return 
 08808 |                vector_holder_     && 
 08809 |                vector_node_.first && 
 08810 |                vector_node_.first->valid(); 
 08811 |          } 
 08812 |  
 08813 |          inline vector_holder_t& vec_holder() 
 08814 |          { 
 08815 |             return (*vector_holder_); 
 08816 |          } 
 08817 |  
 08818 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08819 |          { 
 08820 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08821 |          } 
 08822 |  
 08823 |          std::size_t node_depth() const exprtk_override 
 08824 |          { 
 08825 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 08826 |          } 
 08827 |  
 08828 |       private: 
 08829 |  
 08830 |          inline T* access_vector() const 
 08831 |          { 
 08832 |             vector_node_.first->value(); 
 08833 |             return (vector_base_ + index_); 
 08834 |          } 
 08835 |  
 08836 |          const std::size_t index_; 
 08837 |          vector_holder_ptr vector_holder_; 
 08838 |          T* vector_base_; 
 08839 |          branch_t vector_node_; 
 08840 |       }; 
 08841 |  
 08842 |       template <typename T> 
 08843 |       class vector_elem_rtc_node exprtk_final 
 08844 |                                  : public expression_node<T> 
 08845 |                                  , public ivariable      <T> 
 08846 |       { 
 08847 |       public: 
 08848 |  
 08849 |          typedef expression_node<T>*            expression_ptr; 
 08850 |          typedef vector_holder<T>               vector_holder_t; 
 08851 |          typedef vector_holder_t*               vector_holder_ptr; 
 08852 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08853 |  
 08854 |          vector_elem_rtc_node(expression_ptr vec_node, 
 08855 |                               expression_ptr index, 
 08856 |                               vector_holder_ptr vec_holder, 
 08857 |                               vector_access_runtime_check_ptr vec_rt_chk) 
 08858 |          : vector_holder_(vec_holder) 
 08859 |          , vector_base_((*vec_holder)[0]) 
 08860 |          , vec_rt_chk_(vec_rt_chk) 
 08861 |          , max_vector_index_(vector_holder_->size() - 1) 
 08862 |          { 
 08863 |             construct_branch_pair(vector_node_, vec_node); 
 08864 |             construct_branch_pair(index_      , index   ); 
 08865 |             assert(valid()); 
 08866 |          } 
 08867 |  
 08868 |          inline T value() const exprtk_override 
 08869 |          { 
 08870 |             return *access_vector(); 
 08871 |          } 
 08872 |  
 08873 |          inline T& ref() exprtk_override 
 08874 |          { 
 08875 |             return *access_vector(); 
 08876 |          } 
 08877 |  
 08878 |          inline const T& ref() const exprtk_override 
 08879 |          { 
 08880 |             return *access_vector(); 
 08881 |          } 
 08882 |  
 08883 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08884 |          { 
 08885 |             return expression_node<T>::e_vecelemrtc; 
 08886 |          } 
 08887 |  
 08888 |          inline bool valid() const exprtk_override 
 08889 |          { 
 08890 |             return 
 08891 |                vector_holder_        && 
 08892 |                index_.first          && 
 08893 |                vector_node_.first    && 
 08894 |                index_.first->valid() && 
 08895 |                vector_node_.first->valid(); 
 08896 |          } 
 08897 |  
 08898 |          inline vector_holder_t& vec_holder() 
 08899 |          { 
 08900 |             return (*vector_holder_); 
 08901 |          } 
 08902 |  
 08903 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08904 |          { 
 08905 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08906 |             expression_node<T>::ndb_t::collect(index_,       node_delete_list); 
 08907 |          } 
 08908 |  
 08909 |          std::size_t node_depth() const exprtk_override 
 08910 |          { 
 08911 |             return expression_node<T>::ndb_t::compute_node_depth 
 08912 |                (vector_node_, index_); 
 08913 |          } 
 08914 |  
 08915 |       private: 
 08916 |  
 08917 |          inline T* access_vector() const 
 08918 |          { 
 08919 |             const _uint64_t index = details::numeric::to_uint64(index_.first->value()); 
 08920 |             vector_node_.first->value(); 
 08921 |  
 08922 |             if (index <= max_vector_index_) 
 08923 |             { 
 08924 |                return (vector_holder_->data() + index); 
 08925 |             } 
 08926 |  
 08927 |             assert(vec_rt_chk_); 
 08928 |  
 08929 |             vector_access_runtime_check::violation_context context; 
 08930 |             context.base_ptr   = reinterpret_cast<void*>(vector_base_); 
 08931 |             context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size()); 
 08932 |             context.access_ptr = reinterpret_cast<void*>(vector_base_ + index); 
 08933 |             context.type_size  = sizeof(T); 
 08934 |  
 08935 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 08936 |                reinterpret_cast<T*>(context.access_ptr) : 
 08937 |                vector_base_ ; 
 08938 |          } 
 08939 |  
 08940 |          vector_holder_ptr vector_holder_; 
 08941 |          T*                vector_base_; 
 08942 |          branch_t          vector_node_; 
 08943 |          branch_t          index_; 
 08944 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 08945 |          const std::size_t max_vector_index_; 
 08946 |       }; 
 08947 |  
 08948 |       template <typename T> 
 08949 |       class vector_celem_rtc_node exprtk_final 
 08950 |                                  : public expression_node<T> 
 08951 |                                  , public ivariable      <T> 
 08952 |       { 
 08953 |       public: 
 08954 |  
 08955 |          typedef expression_node<T>*            expression_ptr; 
 08956 |          typedef vector_holder<T>               vector_holder_t; 
 08957 |          typedef vector_holder_t*               vector_holder_ptr; 
 08958 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08959 |  
 08960 |          vector_celem_rtc_node(expression_ptr vec_node, 
 08961 |                                const std::size_t index, 
 08962 |                                vector_holder_ptr vec_holder, 
 08963 |                                vector_access_runtime_check_ptr vec_rt_chk) 
 08964 |          : index_(index) 
 08965 |          , max_vector_index_(vec_holder->size() - 1) 
 08966 |          , vector_holder_(vec_holder) 
 08967 |          , vector_base_((*vec_holder)[0]) 
 08968 |          , vec_rt_chk_(vec_rt_chk) 
 08969 |          { 
 08970 |             construct_branch_pair(vector_node_, vec_node); 
 08971 |             assert(valid()); 
 08972 |          } 
 08973 |  
 08974 |          inline T value() const exprtk_override 
 08975 |          { 
 08976 |             return *access_vector(); 
 08977 |          } 
 08978 |  
 08979 |          inline T& ref() exprtk_override 
 08980 |          { 
 08981 |             return *access_vector(); 
 08982 |          } 
 08983 |  
 08984 |          inline const T& ref() const exprtk_override 
 08985 |          { 
 08986 |             return *access_vector(); 
 08987 |          } 
 08988 |  
 08989 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08990 |          { 
 08991 |             return expression_node<T>::e_veccelemrtc; 
 08992 |          } 
 08993 |  
 08994 |          inline bool valid() const exprtk_override 
 08995 |          { 
 08996 |             return 
 08997 |                vector_holder_     && 
 08998 |                vector_node_.first && 
 08999 |                vector_node_.first->valid(); 
 09000 |          } 
 09001 |  
 09002 |          inline vector_holder_t& vec_holder() 
 09003 |          { 
 09004 |             return (*vector_holder_); 
 09005 |          } 
 09006 |  
 09007 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09008 |          { 
 09009 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09010 |          } 
 09011 |  
 09012 |          std::size_t node_depth() const exprtk_override 
 09013 |          { 
 09014 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 09015 |          } 
 09016 |  
 09017 |       private: 
 09018 |  
 09019 |          inline T* access_vector() const 
 09020 |          { 
 09021 |             vector_node_.first->value(); 
 09022 |  
 09023 |             if (index_ <= max_vector_index_) 
 09024 |             { 
 09025 |                return (vector_holder_->data() + index_); 
 09026 |             } 
 09027 |  
 09028 |             assert(vec_rt_chk_); 
 09029 |  
 09030 |             vector_access_runtime_check::violation_context context; 
 09031 |             context.base_ptr   = reinterpret_cast<void*>(vector_base_); 
 09032 |             context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size()); 
 09033 |             context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_); 
 09034 |             context.type_size  = sizeof(T); 
 09035 |  
 09036 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 09037 |                reinterpret_cast<T*>(context.access_ptr) : 
 09038 |                vector_base_ ; 
 09039 |          } 
 09040 |  
 09041 |          const std::size_t index_; 
 09042 |          const std::size_t max_vector_index_; 
 09043 |          vector_holder_ptr vector_holder_; 
 09044 |          T*                vector_base_; 
 09045 |          branch_t          vector_node_; 
 09046 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 09047 |       }; 
 09048 |  
 09049 |       template <typename T> 
 09050 |       class rebasevector_elem_node exprtk_final 
 09051 |                                    : public expression_node<T> 
 09052 |                                    , public ivariable      <T> 
 09053 |       { 
 09054 |       public: 
 09055 |  
 09056 |          typedef expression_node<T>*            expression_ptr; 
 09057 |          typedef vector_holder<T>               vector_holder_t; 
 09058 |          typedef vector_holder_t*               vector_holder_ptr; 
 09059 |          typedef vec_data_store<T>              vds_t; 
 09060 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09061 |  
 09062 |          rebasevector_elem_node(expression_ptr vec_node, 
 09063 |                                 expression_ptr index, 
 09064 |                                 vector_holder_ptr vec_holder) 
 09065 |          : vector_holder_(vec_holder) 
 09066 |          { 
 09067 |             construct_branch_pair(vector_node_, vec_node); 
 09068 |             construct_branch_pair(index_      , index   ); 
 09069 |             assert(valid()); 
 09070 |          } 
 09071 |  
 09072 |          inline T value() const exprtk_override 
 09073 |          { 
 09074 |             return *access_vector(); 
 09075 |          } 
 09076 |  
 09077 |          inline T& ref() exprtk_override 
 09078 |          { 
 09079 |             return *access_vector(); 
 09080 |          } 
 09081 |  
 09082 |          inline const T& ref() const exprtk_override 
 09083 |          { 
 09084 |             return *access_vector(); 
 09085 |          } 
 09086 |  
 09087 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09088 |          { 
 09089 |             return expression_node<T>::e_rbvecelem; 
 09090 |          } 
 09091 |  
 09092 |          inline bool valid() const exprtk_override 
 09093 |          { 
 09094 |             return 
 09095 |                vector_holder_        && 
 09096 |                index_.first          && 
 09097 |                vector_node_.first    && 
 09098 |                index_.first->valid() && 
 09099 |                vector_node_.first->valid(); 
 09100 |          } 
 09101 |  
 09102 |          inline vector_holder_t& vec_holder() 
 09103 |          { 
 09104 |             return (*vector_holder_); 
 09105 |          } 
 09106 |  
 09107 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09108 |          { 
 09109 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09110 |             expression_node<T>::ndb_t::collect(index_,       node_delete_list); 
 09111 |          } 
 09112 |  
 09113 |          std::size_t node_depth() const exprtk_override 
 09114 |          { 
 09115 |             return expression_node<T>::ndb_t::compute_node_depth 
 09116 |                (vector_node_, index_); 
 09117 |          } 
 09118 |  
 09119 |       private: 
 09120 |  
 09121 |          inline T* access_vector() const 
 09122 |          { 
 09123 |             vector_node_.first->value(); 
 09124 |             return (vector_holder_->data() + details::numeric::to_uint64(index_.first->value())); 
 09125 |          } 
 09126 |  
 09127 |          vector_holder_ptr vector_holder_; 
 09128 |          branch_t          vector_node_; 
 09129 |          branch_t          index_; 
 09130 |       }; 
 09131 |  
 09132 |       template <typename T> 
 09133 |       class rebasevector_celem_node exprtk_final 
 09134 |                                     : public expression_node<T> 
 09135 |                                     , public ivariable      <T> 
 09136 |       { 
 09137 |       public: 
 09138 |  
 09139 |          typedef expression_node<T>* expression_ptr; 
 09140 |          typedef vector_holder<T>    vector_holder_t; 
 09141 |          typedef vector_holder_t*    vector_holder_ptr; 
 09142 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09143 |  
 09144 |          rebasevector_celem_node(expression_ptr vec_node, 
 09145 |                                  const std::size_t index, 
 09146 |                                  vector_holder_ptr vec_holder) 
 09147 |          : index_(index) 
 09148 |          , vector_holder_(vec_holder) 
 09149 |          { 
 09150 |             construct_branch_pair(vector_node_, vec_node); 
 09151 |             assert(valid()); 
 09152 |          } 
 09153 |  
 09154 |          inline T value() const exprtk_override 
 09155 |          { 
 09156 |             vector_node_.first->value(); 
 09157 |             return ref();; 
 09158 |          } 
 09159 |  
 09160 |          inline T& ref() exprtk_override 
 09161 |          { 
 09162 |             return *(vector_holder_->data() + index_); 
 09163 |          } 
 09164 |  
 09165 |          inline const T& ref() const exprtk_override 
 09166 |          { 
 09167 |             return *(vector_holder_->data() + index_); 
 09168 |          } 
 09169 |  
 09170 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09171 |          { 
 09172 |             return expression_node<T>::e_rbveccelem; 
 09173 |          } 
 09174 |  
 09175 |          inline bool valid() const exprtk_override 
 09176 |          { 
 09177 |             return 
 09178 |                vector_holder_     && 
 09179 |                vector_node_.first && 
 09180 |                vector_node_.first->valid(); 
 09181 |          } 
 09182 |  
 09183 |          inline vector_holder_t& vec_holder() 
 09184 |          { 
 09185 |             return (*vector_holder_); 
 09186 |          } 
 09187 |  
 09188 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09189 |          { 
 09190 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09191 |          } 
 09192 |  
 09193 |          std::size_t node_depth() const exprtk_override 
 09194 |          { 
 09195 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 09196 |          } 
 09197 |  
 09198 |       private: 
 09199 |  
 09200 |          const std::size_t index_; 
 09201 |          vector_holder_ptr vector_holder_; 
 09202 |          branch_t          vector_node_; 
 09203 |       }; 
 09204 |  
 09205 |       template <typename T> 
 09206 |       class rebasevector_elem_rtc_node exprtk_final 
 09207 |                                        : public expression_node<T> 
 09208 |                                        , public ivariable      <T> 
 09209 |       { 
 09210 |       public: 
 09211 |  
 09212 |          typedef expression_node<T>*            expression_ptr; 
 09213 |          typedef vector_holder<T>               vector_holder_t; 
 09214 |          typedef vector_holder_t*               vector_holder_ptr; 
 09215 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09216 |  
 09217 |          rebasevector_elem_rtc_node(expression_ptr vec_node, 
 09218 |                                     expression_ptr index, 
 09219 |                                     vector_holder_ptr vec_holder, 
 09220 |                                     vector_access_runtime_check_ptr vec_rt_chk) 
 09221 |          : vector_holder_(vec_holder) 
 09222 |          , vec_rt_chk_(vec_rt_chk) 
 09223 |          { 
 09224 |             construct_branch_pair(vector_node_, vec_node); 
 09225 |             construct_branch_pair(index_      , index   ); 
 09226 |             assert(valid()); 
 09227 |          } 
 09228 |  
 09229 |          inline T value() const exprtk_override 
 09230 |          { 
 09231 |             return *access_vector(); 
 09232 |          } 
 09233 |  
 09234 |          inline T& ref() exprtk_override 
 09235 |          { 
 09236 |             return *access_vector(); 
 09237 |          } 
 09238 |  
 09239 |          inline const T& ref() const exprtk_override 
 09240 |          { 
 09241 |             return *access_vector(); 
 09242 |          } 
 09243 |  
 09244 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09245 |          { 
 09246 |             return expression_node<T>::e_rbvecelemrtc; 
 09247 |          } 
 09248 |  
 09249 |          inline bool valid() const exprtk_override 
 09250 |          { 
 09251 |             return 
 09252 |                vector_holder_        && 
 09253 |                index_.first          && 
 09254 |                vector_node_.first    && 
 09255 |                index_.first->valid() && 
 09256 |                vector_node_.first->valid(); 
 09257 |          } 
 09258 |  
 09259 |          inline vector_holder_t& vec_holder() 
 09260 |          { 
 09261 |             return (*vector_holder_); 
 09262 |          } 
 09263 |  
 09264 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09265 |          { 
 09266 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09267 |             expression_node<T>::ndb_t::collect(index_      , node_delete_list); 
 09268 |          } 
 09269 |  
 09270 |          std::size_t node_depth() const exprtk_override 
 09271 |          { 
 09272 |             return expression_node<T>::ndb_t::compute_node_depth 
 09273 |                (vector_node_, index_); 
 09274 |          } 
 09275 |  
 09276 |       private: 
 09277 |  
 09278 |          inline T* access_vector() const 
 09279 |          { 
 09280 |             vector_node_.first->value(); 
 09281 |             const _uint64_t index = details::numeric::to_uint64(index_.first->value()); 
 09282 |  
 09283 |             if (index <= (vector_holder_->size() - 1)) 
 09284 |             { 
 09285 |                return (vector_holder_->data() + index); 
 09286 |             } 
 09287 |  
 09288 |             assert(vec_rt_chk_); 
 09289 |  
 09290 |             vector_access_runtime_check::violation_context context; 
 09291 |             context.base_ptr   = reinterpret_cast<void*>(vector_holder_->data()); 
 09292 |             context.end_ptr    = reinterpret_cast<void*>(vector_holder_->data() + vector_holder_->size()); 
 09293 |             context.access_ptr = reinterpret_cast<void*>(vector_holder_->data() + index); 
 09294 |             context.type_size  = sizeof(T); 
 09295 |  
 09296 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 09297 |                    reinterpret_cast<T*>(context.access_ptr) : 
 09298 |                    vector_holder_->data() ; 
 09299 |          } 
 09300 |  
 09301 |          vector_holder_ptr vector_holder_; 
 09302 |          branch_t          vector_node_; 
 09303 |          branch_t          index_; 
 09304 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 09305 |       }; 
 09306 |  
 09307 |       template <typename T> 
 09308 |       class rebasevector_celem_rtc_node exprtk_final 
 09309 |                                     : public expression_node<T> 
 09310 |                                     , public ivariable      <T> 
 09311 |       { 
 09312 |       public: 
 09313 |  
 09314 |          typedef expression_node<T>*            expression_ptr; 
 09315 |          typedef vector_holder<T>               vector_holder_t; 
 09316 |          typedef vector_holder_t*               vector_holder_ptr; 
 09317 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09318 |  
 09319 |          rebasevector_celem_rtc_node(expression_ptr vec_node, 
 09320 |                                      const std::size_t index, 
 09321 |                                      vector_holder_ptr vec_holder, 
 09322 |                                      vector_access_runtime_check_ptr vec_rt_chk) 
 09323 |          : index_(index) 
 09324 |          , vector_holder_(vec_holder) 
 09325 |          , vector_base_((*vec_holder)[0]) 
 09326 |          , vec_rt_chk_(vec_rt_chk) 
 09327 |          { 
 09328 |             construct_branch_pair(vector_node_, vec_node); 
 09329 |             assert(valid()); 
 09330 |          } 
 09331 |  
 09332 |          inline T value() const exprtk_override 
 09333 |          { 
 09334 |             return *access_vector(); 
 09335 |          } 
 09336 |  
 09337 |          inline T& ref() exprtk_override 
 09338 |          { 
 09339 |             return *access_vector(); 
 09340 |          } 
 09341 |  
 09342 |          inline const T& ref() const exprtk_override 
 09343 |          { 
 09344 |             return *access_vector(); 
 09345 |          } 
 09346 |  
 09347 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09348 |          { 
 09349 |             return expression_node<T>::e_rbveccelemrtc; 
 09350 |          } 
 09351 |  
 09352 |          inline bool valid() const exprtk_override 
 09353 |          { 
 09354 |             return 
 09355 |                vector_holder_     && 
 09356 |                vector_node_.first && 
 09357 |                vector_node_.first->valid(); 
 09358 |          } 
 09359 |  
 09360 |          inline vector_holder_t& vec_holder() 
 09361 |          { 
 09362 |             return (*vector_holder_); 
 09363 |          } 
 09364 |  
 09365 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09366 |          { 
 09367 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09368 |          } 
 09369 |  
 09370 |          std::size_t node_depth() const exprtk_override 
 09371 |          { 
 09372 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 09373 |          } 
 09374 |  
 09375 |       private: 
 09376 |  
 09377 |          inline T* access_vector() const 
 09378 |          { 
 09379 |             vector_node_.first->value(); 
 09380 |  
 09381 |             if (index_ <= vector_holder_->size() - 1) 
 09382 |             { 
 09383 |                return (vector_holder_->data() + index_); 
 09384 |             } 
 09385 |  
 09386 |             assert(vec_rt_chk_); 
 09387 |  
 09388 |             vector_access_runtime_check::violation_context context; 
 09389 |             context.base_ptr   = reinterpret_cast<void*>(vector_base_); 
 09390 |             context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size()); 
 09391 |             context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_); 
 09392 |             context.type_size  = sizeof(T); 
 09393 |  
 09394 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 09395 |                reinterpret_cast<T*>(context.access_ptr) : 
 09396 |                vector_base_ ; 
 09397 |          } 
 09398 |  
 09399 |          const std::size_t index_; 
 09400 |          vector_holder_ptr vector_holder_; 
 09401 |          T*                vector_base_; 
 09402 |          branch_t          vector_node_; 
 09403 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 09404 |       }; 
 09405 |  
 09406 |       template <typename T> 
 09407 |       class vector_initialisation_node exprtk_final : public expression_node<T> 
 09408 |       { 
 09409 |       public: 
 09410 |  
 09411 |          typedef expression_node<T>* expression_ptr; 
 09412 |  
 09413 |          vector_initialisation_node(T* vector_base, 
 09414 |                                     const std::size_t& size, 
 09415 |                                     const std::vector<expression_ptr>& initialiser_list, 
 09416 |                                     const bool single_value_initialse) 
 09417 |          : vector_base_(vector_base) 
 09418 |          , initialiser_list_(initialiser_list) 
 09419 |          , size_(size) 
 09420 |          , single_value_initialse_(single_value_initialse) 
 09421 |          , zero_value_initialse_(false) 
 09422 |          , const_nonzero_literal_value_initialse_(false) 
 09423 |          , single_initialiser_value_(T(0)) 
 09424 |          { 
 09425 |             if (single_value_initialse_) 
 09426 |             { 
 09427 |                if (initialiser_list_.empty()) 
 09428 |                   zero_value_initialse_ = true; 
 09429 |                else if ( 
 09430 |                          (initialiser_list_.size() == 1) && 
 09431 |                          details::is_constant_node(initialiser_list_[0]) && 
 09432 |                          (T(0) == initialiser_list_[0]->value()) 
 09433 |                        ) 
 09434 |                { 
 09435 |                   zero_value_initialse_ = true; 
 09436 |                } 
 09437 |                else 
 09438 |                { 
 09439 |                   assert(initialiser_list_.size() == 1); 
 09440 |  
 09441 |                   if (details::is_constant_node(initialiser_list_[0])) 
 09442 |                   { 
 09443 |                      const_nonzero_literal_value_initialse_ = true; 
 09444 |                      single_initialiser_value_ = initialiser_list_[0]->value(); 
 09445 |                      assert(T(0) != single_initialiser_value_); 
 09446 |                   } 
 09447 |                } 
 09448 |             } 
 09449 |          } 
 09450 |  
 09451 |          inline T value() const exprtk_override 
 09452 |          { 
 09453 |             if (single_value_initialse_) 
 09454 |             { 
 09455 |                if (zero_value_initialse_) 
 09456 |                { 
 09457 |                   details::set_zero_value(vector_base_, size_); 
 09458 |                } 
 09459 |                else if (const_nonzero_literal_value_initialse_) 
 09460 |                { 
 09461 |                   for (std::size_t i = 0; i < size_; ++i) 
 09462 |                   { 
 09463 |                      *(vector_base_ + i) = single_initialiser_value_; 
 09464 |                   } 
 09465 |                } 
 09466 |                else 
 09467 |                { 
 09468 |                   for (std::size_t i = 0; i < size_; ++i) 
 09469 |                   { 
 09470 |                      *(vector_base_ + i) = initialiser_list_[0]->value(); 
 09471 |                   } 
 09472 |                } 
 09473 |             } 
 09474 |             else 
 09475 |             { 
 09476 |                const std::size_t initialiser_list_size = initialiser_list_.size(); 
 09477 |  
 09478 |                for (std::size_t i = 0; i < initialiser_list_size; ++i) 
 09479 |                { 
 09480 |                   *(vector_base_ + i) = initialiser_list_[i]->value(); 
 09481 |                } 
 09482 |  
 09483 |                if (initialiser_list_size < size_) 
 09484 |                { 
 09485 |                   details::set_zero_value( 
 09486 |                      vector_base_ + initialiser_list_size, 
 09487 |                      (size_ - initialiser_list_size)); 
 09488 |                } 
 09489 |             } 
 09490 |  
 09491 |             return *(vector_base_); 
 09492 |          } 
 09493 |  
 09494 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09495 |          { 
 09496 |             return expression_node<T>::e_vecinit; 
 09497 |          } 
 09498 |  
 09499 |          inline bool valid() const exprtk_override 
 09500 |          { 
 09501 |             return vector_base_; 
 09502 |          } 
 09503 |  
 09504 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09505 |          { 
 09506 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09507 |          } 
 09508 |  
 09509 |          std::size_t node_depth() const exprtk_override 
 09510 |          { 
 09511 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09512 |          } 
 09513 |  
 09514 |       private: 
 09515 |  
 09516 |          vector_initialisation_node(const vector_initialisation_node<T>&) exprtk_delete; 
 09517 |          vector_initialisation_node<T>& operator=(const vector_initialisation_node<T>&) exprtk_delete; 
 09518 |  
 09519 |          mutable T* vector_base_; 
 09520 |          std::vector<expression_ptr> initialiser_list_; 
 09521 |          const std::size_t size_; 
 09522 |          const bool single_value_initialse_; 
 09523 |          bool zero_value_initialse_; 
 09524 |          bool const_nonzero_literal_value_initialse_; 
 09525 |          T single_initialiser_value_; 
 09526 |       }; 
 09527 |  
 09528 |       template <typename T> 
 09529 |       class vector_init_zero_value_node exprtk_final : public expression_node<T> 
 09530 |       { 
 09531 |       public: 
 09532 |  
 09533 |          typedef expression_node<T>* expression_ptr; 
 09534 |  
 09535 |          vector_init_zero_value_node(T* vector_base, 
 09536 |                                      const std::size_t& size, 
 09537 |                                      const std::vector<expression_ptr>& initialiser_list) 
 09538 |          : vector_base_(vector_base) 
 09539 |          , size_(size) 
 09540 |          , initialiser_list_(initialiser_list) 
 09541 |          {} 
 09542 |  
 09543 |          inline T value() const exprtk_override 
 09544 |          { 
 09545 |             details::set_zero_value(vector_base_, size_); 
 09546 |             return *(vector_base_); 
 09547 |          } 
 09548 |  
 09549 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09550 |          { 
 09551 |             return expression_node<T>::e_vecinit; 
 09552 |          } 
 09553 |  
 09554 |          inline bool valid() const exprtk_override 
 09555 |          { 
 09556 |             return vector_base_; 
 09557 |          } 
 09558 |  
 09559 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09560 |          { 
 09561 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09562 |          } 
 09563 |  
 09564 |          std::size_t node_depth() const exprtk_override 
 09565 |          { 
 09566 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09567 |          } 
 09568 |  
 09569 |       private: 
 09570 |  
 09571 |          vector_init_zero_value_node(const vector_init_zero_value_node<T>&) exprtk_delete; 
 09572 |          vector_init_zero_value_node<T>& operator=(const vector_init_zero_value_node<T>&) exprtk_delete; 
 09573 |  
 09574 |          mutable T* vector_base_; 
 09575 |          const std::size_t size_; 
 09576 |          std::vector<expression_ptr> initialiser_list_; 
 09577 |       }; 
 09578 |  
 09579 |       template <typename T> 
 09580 |       class vector_init_single_constvalue_node exprtk_final : public expression_node<T> 
 09581 |       { 
 09582 |       public: 
 09583 |  
 09584 |          typedef expression_node<T>* expression_ptr; 
 09585 |  
 09586 |          vector_init_single_constvalue_node(T* vector_base, 
 09587 |                                             const std::size_t& size, 
 09588 |                                             const std::vector<expression_ptr>& initialiser_list) 
 09589 |          : vector_base_(vector_base) 
 09590 |          , size_(size) 
 09591 |          , initialiser_list_(initialiser_list) 
 09592 |          { 
 09593 |             single_initialiser_value_ = initialiser_list_[0]->value(); 
 09594 |             assert(valid()); 
 09595 |          } 
 09596 |  
 09597 |          inline T value() const exprtk_override 
 09598 |          { 
 09599 |             for (std::size_t i = 0; i < size_; ++i) 
 09600 |             { 
 09601 |                *(vector_base_ + i) = single_initialiser_value_; 
 09602 |             } 
 09603 |  
 09604 |             return *(vector_base_); 
 09605 |          } 
 09606 |  
 09607 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09608 |          { 
 09609 |             return expression_node<T>::e_vecinit; 
 09610 |          } 
 09611 |  
 09612 |          inline bool valid() const exprtk_override 
 09613 |          { 
 09614 |             return vector_base_ && 
 09615 |                    (initialiser_list_.size() == 1) && 
 09616 |                    (details::is_constant_node(initialiser_list_[0])) && 
 09617 |                    (single_initialiser_value_ != T(0)); 
 09618 |          } 
 09619 |  
 09620 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09621 |          { 
 09622 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09623 |          } 
 09624 |  
 09625 |          std::size_t node_depth() const exprtk_override 
 09626 |          { 
 09627 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09628 |          } 
 09629 |  
 09630 |       private: 
 09631 |  
 09632 |          vector_init_single_constvalue_node(const vector_init_single_constvalue_node<T>&) exprtk_delete; 
 09633 |          vector_init_single_constvalue_node<T>& operator=(const vector_init_single_constvalue_node<T>&) exprtk_delete; 
 09634 |  
 09635 |          mutable T* vector_base_; 
 09636 |          const std::size_t size_; 
 09637 |          std::vector<expression_ptr> initialiser_list_; 
 09638 |          T single_initialiser_value_; 
 09639 |       }; 
 09640 |  
 09641 |       template <typename T> 
 09642 |       class vector_init_single_value_node exprtk_final : public expression_node<T> 
 09643 |       { 
 09644 |       public: 
 09645 |  
 09646 |          typedef expression_node<T>* expression_ptr; 
 09647 |  
 09648 |          vector_init_single_value_node(T* vector_base, 
 09649 |                                        const std::size_t& size, 
 09650 |                                        const std::vector<expression_ptr>& initialiser_list) 
 09651 |          : vector_base_(vector_base) 
 09652 |          , size_(size) 
 09653 |          , initialiser_list_(initialiser_list) 
 09654 |          { 
 09655 |             assert(valid()); 
 09656 |          } 
 09657 |  
 09658 |          inline T value() const exprtk_override 
 09659 |          { 
 09660 |             expression_node<T>& node = *initialiser_list_[0]; 
 09661 |  
 09662 |             for (std::size_t i = 0; i < size_; ++i) 
 09663 |             { 
 09664 |                *(vector_base_ + i) = node.value(); 
 09665 |             } 
 09666 |  
 09667 |             return *(vector_base_); 
 09668 |          } 
 09669 |  
 09670 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09671 |          { 
 09672 |             return expression_node<T>::e_vecinit; 
 09673 |          } 
 09674 |  
 09675 |          inline bool valid() const exprtk_override 
 09676 |          { 
 09677 |             return vector_base_ && 
 09678 |                    (initialiser_list_.size() == 1) && 
 09679 |                    !details::is_constant_node(initialiser_list_[0]); 
 09680 |          } 
 09681 |  
 09682 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09683 |          { 
 09684 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09685 |          } 
 09686 |  
 09687 |          std::size_t node_depth() const exprtk_override 
 09688 |          { 
 09689 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09690 |          } 
 09691 |  
 09692 |       private: 
 09693 |  
 09694 |          vector_init_single_value_node(const vector_init_single_value_node<T>&) exprtk_delete; 
 09695 |          vector_init_single_value_node<T>& operator=(const vector_init_single_value_node<T>&) exprtk_delete; 
 09696 |  
 09697 |          mutable T* vector_base_; 
 09698 |          const std::size_t size_; 
 09699 |          std::vector<expression_ptr> initialiser_list_; 
 09700 |       }; 
 09701 |  
 09702 |       template <typename T> 
 09703 |       class vector_init_iota_constconst_node exprtk_final : public expression_node<T> 
 09704 |       { 
 09705 |       public: 
 09706 |  
 09707 |          typedef expression_node<T>* expression_ptr; 
 09708 |  
 09709 |          vector_init_iota_constconst_node(T* vector_base, 
 09710 |                                           const std::size_t& size, 
 09711 |                                           const std::vector<expression_ptr>& initialiser_list) 
 09712 |          : vector_base_(vector_base) 
 09713 |          , size_(size) 
 09714 |          , initialiser_list_(initialiser_list) 
 09715 |          { 
 09716 |             base_value_      = initialiser_list_[0]->value(); 
 09717 |             increment_value_ = initialiser_list_[1]->value(); 
 09718 |  
 09719 |             assert(valid()); 
 09720 |          } 
 09721 |  
 09722 |          inline T value() const exprtk_override 
 09723 |          { 
 09724 |             T value = base_value_; 
 09725 |  
 09726 |             for (std::size_t i = 0; i < size_; ++i, value += increment_value_) 
 09727 |             { 
 09728 |                *(vector_base_ + i) = value; 
 09729 |             } 
 09730 |  
 09731 |             return *(vector_base_); 
 09732 |          } 
 09733 |  
 09734 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09735 |          { 
 09736 |             return expression_node<T>::e_vecinit; 
 09737 |          } 
 09738 |  
 09739 |          inline bool valid() const exprtk_override 
 09740 |          { 
 09741 |             return vector_base_ && 
 09742 |                    (initialiser_list_.size() == 2) && 
 09743 |                    (details::is_constant_node(initialiser_list_[0])) && 
 09744 |                    (details::is_constant_node(initialiser_list_[1])) ; 
 09745 |          } 
 09746 |  
 09747 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09748 |          { 
 09749 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09750 |          } 
 09751 |  
 09752 |          std::size_t node_depth() const exprtk_override 
 09753 |          { 
 09754 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09755 |          } 
 09756 |  
 09757 |       private: 
 09758 |  
 09759 |          vector_init_iota_constconst_node(const vector_init_iota_constconst_node<T>&) exprtk_delete; 
 09760 |          vector_init_iota_constconst_node<T>& operator=(const vector_init_iota_constconst_node<T>&) exprtk_delete; 
 09761 |  
 09762 |          mutable T* vector_base_; 
 09763 |          const std::size_t size_; 
 09764 |          std::vector<expression_ptr> initialiser_list_; 
 09765 |          T base_value_; 
 09766 |          T increment_value_; 
 09767 |       }; 
 09768 |  
 09769 |       template <typename T> 
 09770 |       class vector_init_iota_constnconst_node exprtk_final : public expression_node<T> 
 09771 |       { 
 09772 |       public: 
 09773 |  
 09774 |          typedef expression_node<T>* expression_ptr; 
 09775 |  
 09776 |          vector_init_iota_constnconst_node(T* vector_base, 
 09777 |                                            const std::size_t& size, 
 09778 |                                            const std::vector<expression_ptr>& initialiser_list) 
 09779 |          : vector_base_(vector_base) 
 09780 |          , size_(size) 
 09781 |          , initialiser_list_(initialiser_list) 
 09782 |          { 
 09783 |             assert(valid()); 
 09784 |             base_value_ = initialiser_list_[0]->value(); 
 09785 |          } 
 09786 |  
 09787 |          inline T value() const exprtk_override 
 09788 |          { 
 09789 |             T value = base_value_; 
 09790 |             expression_node<T>& increment = *initialiser_list_[1]; 
 09791 |  
 09792 |             for (std::size_t i = 0; i < size_; ++i, value += increment.value()) 
 09793 |             { 
 09794 |                *(vector_base_ + i) = value; 
 09795 |             } 
 09796 |  
 09797 |             return *(vector_base_); 
 09798 |          } 
 09799 |  
 09800 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09801 |          { 
 09802 |             return expression_node<T>::e_vecinit; 
 09803 |          } 
 09804 |  
 09805 |          inline bool valid() const exprtk_override 
 09806 |          { 
 09807 |             return vector_base_ && 
 09808 |                   (initialiser_list_.size() == 2) && 
 09809 |                   ( details::is_constant_node(initialiser_list_[0])) && 
 09810 |                   (!details::is_constant_node(initialiser_list_[1])); 
 09811 |          } 
 09812 |  
 09813 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09814 |          { 
 09815 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09816 |          } 
 09817 |  
 09818 |          std::size_t node_depth() const exprtk_override 
 09819 |          { 
 09820 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09821 |          } 
 09822 |  
 09823 |       private: 
 09824 |  
 09825 |          vector_init_iota_constnconst_node(const vector_init_iota_constnconst_node<T>&) exprtk_delete; 
 09826 |          vector_init_iota_constnconst_node<T>& operator=(const vector_init_iota_constnconst_node<T>&) exprtk_delete; 
 09827 |  
 09828 |          mutable T* vector_base_; 
 09829 |          const std::size_t size_; 
 09830 |          std::vector<expression_ptr> initialiser_list_; 
 09831 |          T base_value_; 
 09832 |       }; 
 09833 |  
 09834 |       template <typename T> 
 09835 |       class vector_init_iota_nconstconst_node exprtk_final : public expression_node<T> 
 09836 |       { 
 09837 |       public: 
 09838 |  
 09839 |          typedef expression_node<T>* expression_ptr; 
 09840 |  
 09841 |          vector_init_iota_nconstconst_node(T* vector_base, 
 09842 |                                            const std::size_t& size, 
 09843 |                                            const std::vector<expression_ptr>& initialiser_list) 
 09844 |          : vector_base_(vector_base) 
 09845 |          , size_(size) 
 09846 |          , initialiser_list_(initialiser_list) 
 09847 |          { 
 09848 |             assert(valid()); 
 09849 |          } 
 09850 |  
 09851 |          inline T value() const exprtk_override 
 09852 |          { 
 09853 |             T value = initialiser_list_[0]->value(); 
 09854 |             const T increment = initialiser_list_[1]->value(); 
 09855 |  
 09856 |             for (std::size_t i = 0; i < size_; ++i, value += increment) 
 09857 |             { 
 09858 |                *(vector_base_ + i) = value; 
 09859 |             } 
 09860 |  
 09861 |             return *(vector_base_); 
 09862 |          } 
 09863 |  
 09864 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09865 |          { 
 09866 |             return expression_node<T>::e_vecinit; 
 09867 |          } 
 09868 |  
 09869 |          inline bool valid() const exprtk_override 
 09870 |          { 
 09871 |             return vector_base_ && 
 09872 |                    (initialiser_list_.size() == 2) && 
 09873 |                    (!details::is_constant_node(initialiser_list_[0])) && 
 09874 |                    (details::is_constant_node(initialiser_list_[1])); 
 09875 |          } 
 09876 |  
 09877 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09878 |          { 
 09879 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09880 |          } 
 09881 |  
 09882 |          std::size_t node_depth() const exprtk_override 
 09883 |          { 
 09884 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09885 |          } 
 09886 |  
 09887 |       private: 
 09888 |  
 09889 |          vector_init_iota_nconstconst_node(const vector_init_iota_nconstconst_node<T>&) exprtk_delete; 
 09890 |          vector_init_iota_nconstconst_node<T>& operator=(const vector_init_iota_nconstconst_node<T>&) exprtk_delete; 
 09891 |  
 09892 |          mutable T* vector_base_; 
 09893 |          const std::size_t size_; 
 09894 |          std::vector<expression_ptr> initialiser_list_; 
 09895 |       }; 
 09896 |  
 09897 |       template <typename T> 
 09898 |       class vector_init_iota_nconstnconst_node exprtk_final : public expression_node<T> 
 09899 |       { 
 09900 |       public: 
 09901 |  
 09902 |          typedef expression_node<T>* expression_ptr; 
 09903 |  
 09904 |          vector_init_iota_nconstnconst_node(T* vector_base, 
 09905 |                                             const std::size_t& size, 
 09906 |                                             const std::vector<expression_ptr>& initialiser_list) 
 09907 |          : vector_base_(vector_base) 
 09908 |          , size_(size) 
 09909 |          , initialiser_list_(initialiser_list) 
 09910 |          { 
 09911 |             assert(valid()); 
 09912 |          } 
 09913 |  
 09914 |          inline T value() const exprtk_override 
 09915 |          { 
 09916 |             T value = initialiser_list_[0]->value(); 
 09917 |             expression_node<T>& increment = *initialiser_list_[1]; 
 09918 |  
 09919 |             for (std::size_t i = 0; i < size_; ++i, value += increment.value()) 
 09920 |             { 
 09921 |                *(vector_base_ + i) = value; 
 09922 |             } 
 09923 |  
 09924 |             return *(vector_base_); 
 09925 |          } 
 09926 |  
 09927 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09928 |          { 
 09929 |             return expression_node<T>::e_vecinit; 
 09930 |          } 
 09931 |  
 09932 |          inline bool valid() const exprtk_override 
 09933 |          { 
 09934 |             return vector_base_ && 
 09935 |                    (initialiser_list_.size() == 2) && 
 09936 |                    (!details::is_constant_node(initialiser_list_[0])) && 
 09937 |                    (!details::is_constant_node(initialiser_list_[1])); 
 09938 |          } 
 09939 |  
 09940 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09941 |          { 
 09942 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09943 |          } 
 09944 |  
 09945 |          std::size_t node_depth() const exprtk_override 
 09946 |          { 
 09947 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09948 |          } 
 09949 |  
 09950 |       private: 
 09951 |  
 09952 |          vector_init_iota_nconstnconst_node(const vector_init_iota_nconstnconst_node<T>&) exprtk_delete; 
 09953 |          vector_init_iota_nconstnconst_node<T>& operator=(const vector_init_iota_nconstnconst_node<T>&) exprtk_delete; 
 09954 |  
 09955 |          mutable T* vector_base_; 
 09956 |          const std::size_t size_; 
 09957 |          std::vector<expression_ptr> initialiser_list_; 
 09958 |       }; 
 09959 |  
 09960 |       template <typename T> 
 09961 |       class swap_node exprtk_final : public expression_node<T> 
 09962 |       { 
 09963 |       public: 
 09964 |  
 09965 |          typedef expression_node<T>* expression_ptr; 
 09966 |          typedef variable_node<T>*   variable_node_ptr; 
 09967 |  
 09968 |          swap_node(variable_node_ptr var0, variable_node_ptr var1) 
 09969 |          : var0_(var0) 
 09970 |          , var1_(var1) 
 09971 |          {} 
 09972 |  
 09973 |          inline T value() const exprtk_override 
 09974 |          { 
 09975 |             std::swap(var0_->ref(),var1_->ref()); 
 09976 |             return var1_->ref(); 
 09977 |          } 
 09978 |  
 09979 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09980 |          { 
 09981 |             return expression_node<T>::e_swap; 
 09982 |          } 
 09983 |  
 09984 |       private: 
 09985 |  
 09986 |          variable_node_ptr var0_; 
 09987 |          variable_node_ptr var1_; 
 09988 |       }; 
 09989 |  
 09990 |       template <typename T> 
 09991 |       class swap_generic_node exprtk_final : public binary_node<T> 
 09992 |       { 
 09993 |       public: 
 09994 |  
 09995 |          typedef expression_node<T>* expression_ptr; 
 09996 |          typedef ivariable<T>*       ivariable_ptr; 
 09997 |  
 09998 |          swap_generic_node(expression_ptr var0, expression_ptr var1) 
 09999 |          : binary_node<T>(details::e_swap, var0, var1) 
 10000 |          , var0_(dynamic_cast<ivariable_ptr>(var0)) 
 10001 |          , var1_(dynamic_cast<ivariable_ptr>(var1)) 
 10002 |          {} 
 10003 |  
 10004 |          inline T value() const exprtk_override 
 10005 |          { 
 10006 |             std::swap(var0_->ref(),var1_->ref()); 
 10007 |             return var1_->ref(); 
 10008 |          } 
 10009 |  
 10010 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10011 |          { 
 10012 |             return expression_node<T>::e_swap; 
 10013 |          } 
 10014 |  
 10015 |       private: 
 10016 |  
 10017 |          ivariable_ptr var0_; 
 10018 |          ivariable_ptr var1_; 
 10019 |       }; 
 10020 |  
 10021 |       template <typename T> 
 10022 |       class swap_vecvec_node exprtk_final 
 10023 |                              : public binary_node     <T> 
 10024 |                              , public vector_interface<T> 
 10025 |       { 
 10026 |       public: 
 10027 |  
 10028 |          typedef expression_node<T>* expression_ptr; 
 10029 |          typedef vector_node    <T>* vector_node_ptr; 
 10030 |          typedef vec_data_store <T>  vds_t; 
 10031 |  
 10032 |          using binary_node<T>::branch; 
 10033 |  
 10034 |          swap_vecvec_node(expression_ptr branch0, 
 10035 |                           expression_ptr branch1) 
 10036 |          : binary_node<T>(details::e_swap, branch0, branch1) 
 10037 |          , vec0_node_ptr_(0) 
 10038 |          , vec1_node_ptr_(0) 
 10039 |          , initialised_  (false) 
 10040 |          { 
 10041 |             if (is_ivector_node(branch(0))) 
 10042 |             { 
 10043 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 10044 |  
 10045 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 10046 |                { 
 10047 |                   vec0_node_ptr_ = vi->vec(); 
 10048 |                   vds()          = vi->vds(); 
 10049 |                } 
 10050 |             } 
 10051 |  
 10052 |             if (is_ivector_node(branch(1))) 
 10053 |             { 
 10054 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 10055 |  
 10056 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 10057 |                { 
 10058 |                   vec1_node_ptr_ = vi->vec(); 
 10059 |                } 
 10060 |             } 
 10061 |  
 10062 |             if (vec0_node_ptr_ && vec1_node_ptr_) 
 10063 |             { 
 10064 |                initialised_ = size() <= base_size(); 
 10065 |             } 
 10066 |  
 10067 |             assert(valid()); 
 10068 |          } 
 10069 |  
 10070 |          inline T value() const exprtk_override 
 10071 |          { 
 10072 |             binary_node<T>::branch(0)->value(); 
 10073 |             binary_node<T>::branch(1)->value(); 
 10074 |  
 10075 |             T* vec0 = vec0_node_ptr_->vds().data(); 
 10076 |             T* vec1 = vec1_node_ptr_->vds().data(); 
 10077 |  
 10078 |             assert(size() <= base_size()); 
 10079 |             const std::size_t n = size(); 
 10080 |  
 10081 |             for (std::size_t i = 0; i < n; ++i) 
 10082 |             { 
 10083 |                std::swap(vec0[i],vec1[i]); 
 10084 |             } 
 10085 |  
 10086 |             return vec1_node_ptr_->value(); 
 10087 |          } 
 10088 |  
 10089 |          vector_node_ptr vec() const exprtk_override 
 10090 |          { 
 10091 |             return vec0_node_ptr_; 
 10092 |          } 
 10093 |  
 10094 |          vector_node_ptr vec() exprtk_override 
 10095 |          { 
 10096 |             return vec0_node_ptr_; 
 10097 |          } 
 10098 |  
 10099 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10100 |          { 
 10101 |             return expression_node<T>::e_vecvecswap; 
 10102 |          } 
 10103 |  
 10104 |          inline bool valid() const exprtk_override 
 10105 |          { 
 10106 |             return initialised_ && binary_node<T>::valid(); 
 10107 |          } 
 10108 |  
 10109 |          std::size_t size() const exprtk_override 
 10110 |          { 
 10111 |             return std::min( 
 10112 |                vec0_node_ptr_->vec_holder().size(), 
 10113 |                vec1_node_ptr_->vec_holder().size()); 
 10114 |          } 
 10115 |  
 10116 |          std::size_t base_size() const exprtk_override 
 10117 |          { 
 10118 |             return std::min( 
 10119 |                vec0_node_ptr_->vec_holder().base_size(), 
 10120 |                vec1_node_ptr_->vec_holder().base_size()); 
 10121 |          } 
 10122 |  
 10123 |          vds_t& vds() exprtk_override 
 10124 |          { 
 10125 |             return vds_; 
 10126 |          } 
 10127 |  
 10128 |          const vds_t& vds() const exprtk_override 
 10129 |          { 
 10130 |             return vds_; 
 10131 |          } 
 10132 |  
 10133 |       private: 
 10134 |  
 10135 |          vector_node<T>* vec0_node_ptr_; 
 10136 |          vector_node<T>* vec1_node_ptr_; 
 10137 |          bool            initialised_; 
 10138 |          vds_t           vds_; 
 10139 |       }; 
 10140 |  
 10141 |       #ifndef exprtk_disable_string_capabilities 
 10142 |       template <typename T> 
 10143 |       class stringvar_node exprtk_final 
 10144 |                            : public expression_node <T> 
 10145 |                            , public string_base_node<T> 
 10146 |                            , public range_interface <T> 
 10147 |       { 
 10148 |       public: 
 10149 |  
 10150 |          typedef typename range_interface<T>::range_t range_t; 
 10151 |  
 10152 |          static std::string null_value; 
 10153 |  
 10154 |          explicit stringvar_node() 
 10155 |          : value_(&null_value) 
 10156 |          {} 
 10157 |  
 10158 |          explicit stringvar_node(std::string& v) 
 10159 |          : value_(&v) 
 10160 |          { 
 10161 |             rp_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10162 |             rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size()); 
 10163 |             rp_.cache.first  = rp_.n0_c.second; 
 10164 |             rp_.cache.second = rp_.n1_c.second; 
 10165 |          } 
 10166 |  
 10167 |          inline bool operator <(const stringvar_node<T>& v) const 
 10168 |          { 
 10169 |             return this < (&v); 
 10170 |          } 
 10171 |  
 10172 |          inline T value() const exprtk_override 
 10173 |          { 
 10174 |             rp_.n1_c.second  = (*value_).size(); 
 10175 |             rp_.cache.second = rp_.n1_c.second; 
 10176 |  
 10177 |             return std::numeric_limits<T>::quiet_NaN(); 
 10178 |          } 
 10179 |  
 10180 |          std::string str() const exprtk_override 
 10181 |          { 
 10182 |             return ref(); 
 10183 |          } 
 10184 |  
 10185 |          char_cptr base() const exprtk_override 
 10186 |          { 
 10187 |             return &(*value_)[0]; 
 10188 |          } 
 10189 |  
 10190 |          std::size_t size() const exprtk_override 
 10191 |          { 
 10192 |             return ref().size(); 
 10193 |          } 
 10194 |  
 10195 |          std::string& ref() 
 10196 |          { 
 10197 |             return (*value_); 
 10198 |          } 
 10199 |  
 10200 |          const std::string& ref() const 
 10201 |          { 
 10202 |             return (*value_); 
 10203 |          } 
 10204 |  
 10205 |          range_t& range_ref() exprtk_override 
 10206 |          { 
 10207 |             return rp_; 
 10208 |          } 
 10209 |  
 10210 |          const range_t& range_ref() const exprtk_override 
 10211 |          { 
 10212 |             return rp_; 
 10213 |          } 
 10214 |  
 10215 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10216 |          { 
 10217 |             return expression_node<T>::e_stringvar; 
 10218 |          } 
 10219 |  
 10220 |          void rebase(std::string& s) 
 10221 |          { 
 10222 |             value_ = &s; 
 10223 |             rp_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10224 |             rp_.n1_c = std::make_pair<bool,std::size_t>(true,value_->size() - 1); 
 10225 |             rp_.cache.first  = rp_.n0_c.second; 
 10226 |             rp_.cache.second = rp_.n1_c.second; 
 10227 |          } 
 10228 |  
 10229 |       private: 
 10230 |  
 10231 |          std::string* value_; 
 10232 |          mutable range_t rp_; 
 10233 |       }; 
 10234 |  
 10235 |       template <typename T> 
 10236 |       std::string stringvar_node<T>::null_value = std::string(""); 
 10237 |  
 10238 |       template <typename T> 
 10239 |       class string_range_node exprtk_final 
 10240 |                               : public expression_node <T> 
 10241 |                               , public string_base_node<T> 
 10242 |                               , public range_interface <T> 
 10243 |       { 
 10244 |       public: 
 10245 |  
 10246 |          typedef typename range_interface<T>::range_t range_t; 
 10247 |  
 10248 |          static std::string null_value; 
 10249 |  
 10250 |          explicit string_range_node(std::string& v, const range_t& rp) 
 10251 |          : value_(&v) 
 10252 |          , rp_(rp) 
 10253 |          {} 
 10254 |  
 10255 |          virtual ~string_range_node() 
 10256 |          { 
 10257 |             rp_.free(); 
 10258 |          } 
 10259 |  
 10260 |          inline bool operator <(const string_range_node<T>& v) const 
 10261 |          { 
 10262 |             return this < (&v); 
 10263 |          } 
 10264 |  
 10265 |          inline T value() const exprtk_override 
 10266 |          { 
 10267 |             return std::numeric_limits<T>::quiet_NaN(); 
 10268 |          } 
 10269 |  
 10270 |          inline std::string str() const exprtk_override 
 10271 |          { 
 10272 |             return (*value_); 
 10273 |          } 
 10274 |  
 10275 |          char_cptr base() const exprtk_override 
 10276 |          { 
 10277 |             return &(*value_)[0]; 
 10278 |          } 
 10279 |  
 10280 |          std::size_t size() const exprtk_override 
 10281 |          { 
 10282 |             return ref().size(); 
 10283 |          } 
 10284 |  
 10285 |          inline range_t range() const 
 10286 |          { 
 10287 |             return rp_; 
 10288 |          } 
 10289 |  
 10290 |          inline virtual std::string& ref() 
 10291 |          { 
 10292 |             return (*value_); 
 10293 |          } 
 10294 |  
 10295 |          inline virtual const std::string& ref() const 
 10296 |          { 
 10297 |             return (*value_); 
 10298 |          } 
 10299 |  
 10300 |          inline range_t& range_ref() exprtk_override 
 10301 |          { 
 10302 |             return rp_; 
 10303 |          } 
 10304 |  
 10305 |          inline const range_t& range_ref() const exprtk_override 
 10306 |          { 
 10307 |             return rp_; 
 10308 |          } 
 10309 |  
 10310 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10311 |          { 
 10312 |             return expression_node<T>::e_stringvarrng; 
 10313 |          } 
 10314 |  
 10315 |       private: 
 10316 |  
 10317 |          std::string* value_; 
 10318 |          range_t      rp_; 
 10319 |       }; 
 10320 |  
 10321 |       template <typename T> 
 10322 |       std::string string_range_node<T>::null_value = std::string(""); 
 10323 |  
 10324 |       template <typename T> 
 10325 |       class const_string_range_node exprtk_final 
 10326 |                                     : public expression_node <T> 
 10327 |                                     , public string_base_node<T> 
 10328 |                                     , public range_interface <T> 
 10329 |       { 
 10330 |       public: 
 10331 |  
 10332 |          typedef typename range_interface<T>::range_t range_t; 
 10333 |  
 10334 |          explicit const_string_range_node(const std::string& v, const range_t& rp) 
 10335 |          : value_(v) 
 10336 |          , rp_(rp) 
 10337 |          {} 
 10338 |  
 10339 |         ~const_string_range_node() exprtk_override 
 10340 |          { 
 10341 |             rp_.free(); 
 10342 |          } 
 10343 |  
 10344 |          inline T value() const exprtk_override 
 10345 |          { 
 10346 |             return std::numeric_limits<T>::quiet_NaN(); 
 10347 |          } 
 10348 |  
 10349 |          std::string str() const exprtk_override 
 10350 |          { 
 10351 |             return value_; 
 10352 |          } 
 10353 |  
 10354 |          char_cptr base() const exprtk_override 
 10355 |          { 
 10356 |             return value_.data(); 
 10357 |          } 
 10358 |  
 10359 |          std::size_t size() const exprtk_override 
 10360 |          { 
 10361 |             return value_.size(); 
 10362 |          } 
 10363 |  
 10364 |          range_t range() const 
 10365 |          { 
 10366 |             return rp_; 
 10367 |          } 
 10368 |  
 10369 |          range_t& range_ref() exprtk_override 
 10370 |          { 
 10371 |             return rp_; 
 10372 |          } 
 10373 |  
 10374 |          const range_t& range_ref() const exprtk_override 
 10375 |          { 
 10376 |             return rp_; 
 10377 |          } 
 10378 |  
 10379 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10380 |          { 
 10381 |             return expression_node<T>::e_cstringvarrng; 
 10382 |          } 
 10383 |  
 10384 |       private: 
 10385 |  
 10386 |          const_string_range_node(const const_string_range_node<T>&) exprtk_delete; 
 10387 |          const_string_range_node<T>& operator=(const const_string_range_node<T>&) exprtk_delete; 
 10388 |  
 10389 |          const std::string value_; 
 10390 |          range_t rp_; 
 10391 |       }; 
 10392 |  
 10393 |       template <typename T> 
 10394 |       class generic_string_range_node exprtk_final 
 10395 |                                       : public expression_node <T> 
 10396 |                                       , public string_base_node<T> 
 10397 |                                       , public range_interface <T> 
 10398 |       { 
 10399 |       public: 
 10400 |  
 10401 |          typedef expression_node <T>* expression_ptr; 
 10402 |          typedef stringvar_node  <T>* strvar_node_ptr; 
 10403 |          typedef string_base_node<T>* str_base_ptr; 
 10404 |          typedef typename range_interface<T>::range_t range_t; 
 10405 |          typedef range_t*             range_ptr; 
 10406 |          typedef range_interface<T>   irange_t; 
 10407 |          typedef irange_t*            irange_ptr; 
 10408 |          typedef std::pair<expression_ptr,bool>  branch_t; 
 10409 |  
 10410 |          generic_string_range_node(expression_ptr str_branch, const range_t& brange) 
 10411 |          : initialised_(false) 
 10412 |          , str_base_ptr_ (0) 
 10413 |          , str_range_ptr_(0) 
 10414 |          , base_range_(brange) 
 10415 |          { 
 10416 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10417 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 10418 |             range_.cache.first  = range_.n0_c.second; 
 10419 |             range_.cache.second = range_.n1_c.second; 
 10420 |  
 10421 |             construct_branch_pair(branch_, str_branch); 
 10422 |  
 10423 |             if (is_generally_string_node(branch_.first)) 
 10424 |             { 
 10425 |                str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first); 
 10426 |  
 10427 |                if (0 == str_base_ptr_) 
 10428 |                   return; 
 10429 |  
 10430 |                str_range_ptr_ = dynamic_cast<irange_ptr>(branch_.first); 
 10431 |  
 10432 |                if (0 == str_range_ptr_) 
 10433 |                   return; 
 10434 |             } 
 10435 |  
 10436 |             initialised_ = (str_base_ptr_ && str_range_ptr_); 
 10437 |             assert(valid()); 
 10438 |          } 
 10439 |  
 10440 |         ~generic_string_range_node() exprtk_override 
 10441 |          { 
 10442 |             base_range_.free(); 
 10443 |          } 
 10444 |  
 10445 |          inline T value() const exprtk_override 
 10446 |          { 
 10447 |             branch_.first->value(); 
 10448 |  
 10449 |             std::size_t str_r0 = 0; 
 10450 |             std::size_t str_r1 = 0; 
 10451 |  
 10452 |             std::size_t r0 = 0; 
 10453 |             std::size_t r1 = 0; 
 10454 |  
 10455 |             const range_t& range = str_range_ptr_->range_ref(); 
 10456 |  
 10457 |             const std::size_t base_str_size = str_base_ptr_->size(); 
 10458 |  
 10459 |             if ( 
 10460 |                   range      (str_r0, str_r1, base_str_size         ) && 
 10461 |                   base_range_(r0    , r1    , base_str_size - str_r0) 
 10462 |                ) 
 10463 |             { 
 10464 |                const std::size_t size = r1 - r0; 
 10465 |  
 10466 |                range_.n1_c.second  = size; 
 10467 |                range_.cache.second = range_.n1_c.second; 
 10468 |  
 10469 |                value_.assign(str_base_ptr_->base() + str_r0 + r0, size); 
 10470 |             } 
 10471 |  
 10472 |             return std::numeric_limits<T>::quiet_NaN(); 
 10473 |          } 
 10474 |  
 10475 |          std::string str() const exprtk_override 
 10476 |          { 
 10477 |             return value_; 
 10478 |          } 
 10479 |  
 10480 |          char_cptr base() const exprtk_override 
 10481 |          { 
 10482 |             return &value_[0]; 
 10483 |          } 
 10484 |  
 10485 |          std::size_t size() const exprtk_override 
 10486 |          { 
 10487 |             return value_.size(); 
 10488 |          } 
 10489 |  
 10490 |          range_t& range_ref() exprtk_override 
 10491 |          { 
 10492 |             return range_; 
 10493 |          } 
 10494 |  
 10495 |          const range_t& range_ref() const exprtk_override 
 10496 |          { 
 10497 |             return range_; 
 10498 |          } 
 10499 |  
 10500 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10501 |          { 
 10502 |             return expression_node<T>::e_strgenrange; 
 10503 |          } 
 10504 |  
 10505 |          inline bool valid() const exprtk_override 
 10506 |          { 
 10507 |             return initialised_ && branch_.first; 
 10508 |          } 
 10509 |  
 10510 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 10511 |          { 
 10512 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 10513 |          } 
 10514 |  
 10515 |          std::size_t node_depth() const exprtk_override 
 10516 |          { 
 10517 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 10518 |          } 
 10519 |  
 10520 |       private: 
 10521 |  
 10522 |          bool                initialised_; 
 10523 |          branch_t            branch_; 
 10524 |          str_base_ptr        str_base_ptr_; 
 10525 |          irange_ptr          str_range_ptr_; 
 10526 |          mutable range_t     base_range_; 
 10527 |          mutable range_t     range_; 
 10528 |          mutable std::string value_; 
 10529 |       }; 
 10530 |  
 10531 |       template <typename T> 
 10532 |       class string_concat_node exprtk_final 
 10533 |                                : public binary_node     <T> 
 10534 |                                , public string_base_node<T> 
 10535 |                                , public range_interface <T> 
 10536 |       { 
 10537 |       public: 
 10538 |  
 10539 |          typedef typename range_interface<T>::range_t range_t; 
 10540 |          typedef range_interface<T>   irange_t; 
 10541 |          typedef irange_t*            irange_ptr; 
 10542 |          typedef range_t*             range_ptr; 
 10543 |          typedef expression_node <T>* expression_ptr; 
 10544 |          typedef string_base_node<T>* str_base_ptr; 
 10545 |  
 10546 |          using binary_node<T>::branch; 
 10547 |  
 10548 |          string_concat_node(const operator_type& opr, 
 10549 |                             expression_ptr branch0, 
 10550 |                             expression_ptr branch1) 
 10551 |          : binary_node<T>(opr, branch0, branch1) 
 10552 |          , initialised_(false) 
 10553 |          , str0_base_ptr_ (0) 
 10554 |          , str1_base_ptr_ (0) 
 10555 |          , str0_range_ptr_(0) 
 10556 |          , str1_range_ptr_(0) 
 10557 |          { 
 10558 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10559 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 10560 |  
 10561 |             range_.cache.first  = range_.n0_c.second; 
 10562 |             range_.cache.second = range_.n1_c.second; 
 10563 |  
 10564 |             if (is_generally_string_node(branch(0))) 
 10565 |             { 
 10566 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 10567 |  
 10568 |                if (0 == str0_base_ptr_) 
 10569 |                   return; 
 10570 |  
 10571 |                str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0)); 
 10572 |  
 10573 |                if (0 == str0_range_ptr_) 
 10574 |                   return; 
 10575 |             } 
 10576 |  
 10577 |             if (is_generally_string_node(branch(1))) 
 10578 |             { 
 10579 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 10580 |  
 10581 |                if (0 == str1_base_ptr_) 
 10582 |                   return; 
 10583 |  
 10584 |                str1_range_ptr_ = dynamic_cast<irange_ptr>(branch(1)); 
 10585 |  
 10586 |                if (0 == str1_range_ptr_) 
 10587 |                   return; 
 10588 |             } 
 10589 |  
 10590 |             initialised_ = str0_base_ptr_  && 
 10591 |                            str1_base_ptr_  && 
 10592 |                            str0_range_ptr_ && 
 10593 |                            str1_range_ptr_ ; 
 10594 |  
 10595 |             assert(valid()); 
 10596 |          } 
 10597 |  
 10598 |          inline T value() const exprtk_override 
 10599 |          { 
 10600 |             branch(0)->value(); 
 10601 |             branch(1)->value(); 
 10602 |  
 10603 |             std::size_t str0_r0 = 0; 
 10604 |             std::size_t str0_r1 = 0; 
 10605 |  
 10606 |             std::size_t str1_r0 = 0; 
 10607 |             std::size_t str1_r1 = 0; 
 10608 |  
 10609 |             const range_t& range0 = str0_range_ptr_->range_ref(); 
 10610 |             const range_t& range1 = str1_range_ptr_->range_ref(); 
 10611 |  
 10612 |             if ( 
 10613 |                   range0(str0_r0, str0_r1, str0_base_ptr_->size()) && 
 10614 |                   range1(str1_r0, str1_r1, str1_base_ptr_->size()) 
 10615 |                ) 
 10616 |             { 
 10617 |                const std::size_t size0 = (str0_r1 - str0_r0); 
 10618 |                const std::size_t size1 = (str1_r1 - str1_r0); 
 10619 |  
 10620 |                value_.assign(str0_base_ptr_->base() + str0_r0, size0); 
 10621 |                value_.append(str1_base_ptr_->base() + str1_r0, size1); 
 10622 |  
 10623 |                range_.n1_c.second  = value_.size(); 
 10624 |                range_.cache.second = range_.n1_c.second; 
 10625 |             } 
 10626 |  
 10627 |             return std::numeric_limits<T>::quiet_NaN(); 
 10628 |          } 
 10629 |  
 10630 |          std::string str() const exprtk_override 
 10631 |          { 
 10632 |             return value_; 
 10633 |          } 
 10634 |  
 10635 |          char_cptr base() const exprtk_override 
 10636 |          { 
 10637 |             return &value_[0]; 
 10638 |          } 
 10639 |  
 10640 |          std::size_t size() const exprtk_override 
 10641 |          { 
 10642 |             return value_.size(); 
 10643 |          } 
 10644 |  
 10645 |          range_t& range_ref() exprtk_override 
 10646 |          { 
 10647 |             return range_; 
 10648 |          } 
 10649 |  
 10650 |          const range_t& range_ref() const exprtk_override 
 10651 |          { 
 10652 |             return range_; 
 10653 |          } 
 10654 |  
 10655 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10656 |          { 
 10657 |             return expression_node<T>::e_strconcat; 
 10658 |          } 
 10659 |  
 10660 |          inline bool valid() const exprtk_override 
 10661 |          { 
 10662 |             return initialised_ && binary_node<T>::valid(); 
 10663 |          } 
 10664 |  
 10665 |       private: 
 10666 |  
 10667 |          bool                initialised_; 
 10668 |          str_base_ptr        str0_base_ptr_; 
 10669 |          str_base_ptr        str1_base_ptr_; 
 10670 |          irange_ptr          str0_range_ptr_; 
 10671 |          irange_ptr          str1_range_ptr_; 
 10672 |          mutable range_t     range_; 
 10673 |          mutable std::string value_; 
 10674 |       }; 
 10675 |  
 10676 |       template <typename T> 
 10677 |       class swap_string_node exprtk_final 
 10678 |                              : public binary_node     <T> 
 10679 |                              , public string_base_node<T> 
 10680 |                              , public range_interface <T> 
 10681 |       { 
 10682 |       public: 
 10683 |  
 10684 |          typedef typename range_interface<T>::range_t range_t; 
 10685 |          typedef range_t*             range_ptr; 
 10686 |          typedef range_interface<T>   irange_t; 
 10687 |          typedef irange_t*            irange_ptr; 
 10688 |          typedef expression_node <T>* expression_ptr; 
 10689 |          typedef stringvar_node  <T>* strvar_node_ptr; 
 10690 |          typedef string_base_node<T>* str_base_ptr; 
 10691 |  
 10692 |          using binary_node<T>::branch; 
 10693 |  
 10694 |          swap_string_node(expression_ptr branch0, expression_ptr branch1) 
 10695 |          : binary_node<T>(details::e_swap, branch0, branch1) 
 10696 |          , initialised_(false) 
 10697 |          , str0_node_ptr_(0) 
 10698 |          , str1_node_ptr_(0) 
 10699 |          { 
 10700 |             if (is_string_node(branch(0))) 
 10701 |             { 
 10702 |                str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0)); 
 10703 |             } 
 10704 |  
 10705 |             if (is_string_node(branch(1))) 
 10706 |             { 
 10707 |                str1_node_ptr_ = static_cast<strvar_node_ptr>(branch(1)); 
 10708 |             } 
 10709 |  
 10710 |             initialised_ = (str0_node_ptr_ && str1_node_ptr_); 
 10711 |             assert(valid()); 
 10712 |          } 
 10713 |  
 10714 |          inline T value() const exprtk_override 
 10715 |          { 
 10716 |             branch(0)->value(); 
 10717 |             branch(1)->value(); 
 10718 |  
 10719 |             std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref()); 
 10720 |  
 10721 |             return std::numeric_limits<T>::quiet_NaN(); 
 10722 |          } 
 10723 |  
 10724 |          std::string str() const exprtk_override 
 10725 |          { 
 10726 |             return str0_node_ptr_->str(); 
 10727 |          } 
 10728 |  
 10729 |          char_cptr base() const exprtk_override 
 10730 |          { 
 10731 |            return str0_node_ptr_->base(); 
 10732 |          } 
 10733 |  
 10734 |          std::size_t size() const exprtk_override 
 10735 |          { 
 10736 |             return str0_node_ptr_->size(); 
 10737 |          } 
 10738 |  
 10739 |          range_t& range_ref() exprtk_override 
 10740 |          { 
 10741 |             return str0_node_ptr_->range_ref(); 
 10742 |          } 
 10743 |  
 10744 |          const range_t& range_ref() const exprtk_override 
 10745 |          { 
 10746 |             return str0_node_ptr_->range_ref(); 
 10747 |          } 
 10748 |  
 10749 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10750 |          { 
 10751 |             return expression_node<T>::e_strswap; 
 10752 |          } 
 10753 |  
 10754 |          inline bool valid() const exprtk_override 
 10755 |          { 
 10756 |             return initialised_ && binary_node<T>::valid(); 
 10757 |          } 
 10758 |  
 10759 |       private: 
 10760 |  
 10761 |          bool initialised_; 
 10762 |          strvar_node_ptr str0_node_ptr_; 
 10763 |          strvar_node_ptr str1_node_ptr_; 
 10764 |       }; 
 10765 |  
 10766 |       template <typename T> 
 10767 |       class swap_genstrings_node exprtk_final : public binary_node<T> 
 10768 |       { 
 10769 |       public: 
 10770 |  
 10771 |          typedef typename range_interface<T>::range_t range_t; 
 10772 |          typedef range_t*             range_ptr; 
 10773 |          typedef range_interface<T>   irange_t; 
 10774 |          typedef irange_t*            irange_ptr; 
 10775 |          typedef expression_node <T>* expression_ptr; 
 10776 |          typedef string_base_node<T>* str_base_ptr; 
 10777 |  
 10778 |          using binary_node<T>::branch; 
 10779 |  
 10780 |          swap_genstrings_node(expression_ptr branch0, 
 10781 |                               expression_ptr branch1) 
 10782 |          : binary_node<T>(details::e_default, branch0, branch1) 
 10783 |          , str0_base_ptr_ (0) 
 10784 |          , str1_base_ptr_ (0) 
 10785 |          , str0_range_ptr_(0) 
 10786 |          , str1_range_ptr_(0) 
 10787 |          , initialised_(false) 
 10788 |          { 
 10789 |             if (is_generally_string_node(branch(0))) 
 10790 |             { 
 10791 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 10792 |  
 10793 |                if (0 == str0_base_ptr_) 
 10794 |                   return; 
 10795 |  
 10796 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); 
 10797 |  
 10798 |                if (0 == range) 
 10799 |                   return; 
 10800 |  
 10801 |                str0_range_ptr_ = &(range->range_ref()); 
 10802 |             } 
 10803 |  
 10804 |             if (is_generally_string_node(branch(1))) 
 10805 |             { 
 10806 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 10807 |  
 10808 |                if (0 == str1_base_ptr_) 
 10809 |                   return; 
 10810 |  
 10811 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 10812 |  
 10813 |                if (0 == range) 
 10814 |                   return; 
 10815 |  
 10816 |                str1_range_ptr_ = &(range->range_ref()); 
 10817 |             } 
 10818 |  
 10819 |             initialised_ = str0_base_ptr_  && 
 10820 |                            str1_base_ptr_  && 
 10821 |                            str0_range_ptr_ && 
 10822 |                            str1_range_ptr_ ; 
 10823 |  
 10824 |             assert(valid()); 
 10825 |          } 
 10826 |  
 10827 |          inline T value() const exprtk_override 
 10828 |          { 
 10829 |             branch(0)->value(); 
 10830 |             branch(1)->value(); 
 10831 |  
 10832 |             std::size_t str0_r0 = 0; 
 10833 |             std::size_t str0_r1 = 0; 
 10834 |  
 10835 |             std::size_t str1_r0 = 0; 
 10836 |             std::size_t str1_r1 = 0; 
 10837 |  
 10838 |             const range_t& range0 = (*str0_range_ptr_); 
 10839 |             const range_t& range1 = (*str1_range_ptr_); 
 10840 |  
 10841 |             if ( 
 10842 |                   range0(str0_r0, str0_r1, str0_base_ptr_->size()) && 
 10843 |                   range1(str1_r0, str1_r1, str1_base_ptr_->size()) 
 10844 |                ) 
 10845 |             { 
 10846 |                const std::size_t size0    = range0.cache_size(); 
 10847 |                const std::size_t size1    = range1.cache_size(); 
 10848 |                const std::size_t max_size = std::min(size0,size1); 
 10849 |  
 10850 |                char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0); 
 10851 |                char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0); 
 10852 |  
 10853 |                loop_unroll::details lud(max_size); 
 10854 |                char_cptr upper_bound = s0 + lud.upper_bound; 
 10855 |  
 10856 |                while (s0 < upper_bound) 
 10857 |                { 
 10858 |                   #define exprtk_loop(N)   \ 
 10859 |                   std::swap(s0[N], s1[N]); \ 
 10860 |  
 10861 |                   exprtk_loop( 0) exprtk_loop( 1) 
 10862 |                   exprtk_loop( 2) exprtk_loop( 3) 
 10863 |                   #ifndef exprtk_disable_superscalar_unroll 
 10864 |                   exprtk_loop( 4) exprtk_loop( 5) 
 10865 |                   exprtk_loop( 6) exprtk_loop( 7) 
 10866 |                   exprtk_loop( 8) exprtk_loop( 9) 
 10867 |                   exprtk_loop(10) exprtk_loop(11) 
 10868 |                   exprtk_loop(12) exprtk_loop(13) 
 10869 |                   exprtk_loop(14) exprtk_loop(15) 
 10870 |                   #endif 
 10871 |  
 10872 |                   s0 += lud.batch_size; 
 10873 |                   s1 += lud.batch_size; 
 10874 |                } 
 10875 |  
 10876 |                int i = 0; 
 10877 |  
 10878 |                switch (lud.remainder) 
 10879 |                { 
 10880 |                   #define case_stmt(N)                       \ 
 10881 |                   case N : { std::swap(s0[i], s1[i]); ++i; } \ 
 10882 |                   exprtk_fallthrough                         \ 
 10883 |  
 10884 |                   #ifndef exprtk_disable_superscalar_unroll 
 10885 |                   case_stmt(15) case_stmt(14) 
 10886 |                   case_stmt(13) case_stmt(12) 
 10887 |                   case_stmt(11) case_stmt(10) 
 10888 |                   case_stmt( 9) case_stmt( 8) 
 10889 |                   case_stmt( 7) case_stmt( 6) 
 10890 |                   case_stmt( 5) case_stmt( 4) 
 10891 |                   #endif 
 10892 |                   case_stmt( 3) case_stmt( 2) 
 10893 |                   case_stmt( 1) 
 10894 |                   default: break; 
 10895 |                } 
 10896 |  
 10897 |                #undef exprtk_loop 
 10898 |                #undef case_stmt 
 10899 |             } 
 10900 |  
 10901 |             return std::numeric_limits<T>::quiet_NaN(); 
 10902 |          } 
 10903 |  
 10904 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10905 |          { 
 10906 |             return expression_node<T>::e_strswap; 
 10907 |          } 
 10908 |  
 10909 |          inline bool valid() const exprtk_override 
 10910 |          { 
 10911 |             return initialised_ && binary_node<T>::valid(); 
 10912 |          } 
 10913 |  
 10914 |       private: 
 10915 |  
 10916 |          swap_genstrings_node(const swap_genstrings_node<T>&) exprtk_delete; 
 10917 |          swap_genstrings_node<T>& operator=(const swap_genstrings_node<T>&) exprtk_delete; 
 10918 |  
 10919 |          str_base_ptr str0_base_ptr_; 
 10920 |          str_base_ptr str1_base_ptr_; 
 10921 |          range_ptr    str0_range_ptr_; 
 10922 |          range_ptr    str1_range_ptr_; 
 10923 |          bool         initialised_; 
 10924 |       }; 
 10925 |  
 10926 |       template <typename T> 
 10927 |       class stringvar_size_node exprtk_final : public expression_node<T> 
 10928 |       { 
 10929 |       public: 
 10930 |  
 10931 |          static const std::string null_value; 
 10932 |  
 10933 |          explicit stringvar_size_node() 
 10934 |          : value_(&null_value) 
 10935 |          {} 
 10936 |  
 10937 |          explicit stringvar_size_node(std::string& v) 
 10938 |          : value_(&v) 
 10939 |          {} 
 10940 |  
 10941 |          inline T value() const exprtk_override 
 10942 |          { 
 10943 |             return T((*value_).size()); 
 10944 |          } 
 10945 |  
 10946 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10947 |          { 
 10948 |             return expression_node<T>::e_stringvarsize; 
 10949 |          } 
 10950 |  
 10951 |       private: 
 10952 |  
 10953 |          const std::string* value_; 
 10954 |       }; 
 10955 |  
 10956 |       template <typename T> 
 10957 |       const std::string stringvar_size_node<T>::null_value = std::string(""); 
 10958 |  
 10959 |       template <typename T> 
 10960 |       class string_size_node exprtk_final : public expression_node<T> 
 10961 |       { 
 10962 |       public: 
 10963 |  
 10964 |          typedef expression_node <T>* expression_ptr; 
 10965 |          typedef string_base_node<T>* str_base_ptr; 
 10966 |          typedef std::pair<expression_ptr,bool>  branch_t; 
 10967 |  
 10968 |          explicit string_size_node(expression_ptr branch) 
 10969 |          : str_base_ptr_(0) 
 10970 |          { 
 10971 |             construct_branch_pair(branch_, branch); 
 10972 |  
 10973 |             if (is_generally_string_node(branch_.first)) 
 10974 |             { 
 10975 |                str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first); 
 10976 |             } 
 10977 |  
 10978 |             assert(valid()); 
 10979 |          } 
 10980 |  
 10981 |          inline T value() const exprtk_override 
 10982 |          { 
 10983 |             branch_.first->value(); 
 10984 |             return T(str_base_ptr_->size()); 
 10985 |          } 
 10986 |  
 10987 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10988 |          { 
 10989 |             return expression_node<T>::e_stringsize; 
 10990 |          } 
 10991 |  
 10992 |          inline bool valid() const exprtk_override 
 10993 |          { 
 10994 |             return str_base_ptr_; 
 10995 |          } 
 10996 |  
 10997 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 10998 |          { 
 10999 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 11000 |          } 
 11001 |  
 11002 |          std::size_t node_depth() const exprtk_override 
 11003 |          { 
 11004 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 11005 |          } 
 11006 |  
 11007 |       private: 
 11008 |  
 11009 |          branch_t     branch_; 
 11010 |          str_base_ptr str_base_ptr_; 
 11011 |       }; 
 11012 |  
 11013 |       struct asn_assignment 
 11014 |       { 
 11015 |          static inline void execute(std::string& s, char_cptr data, const std::size_t size) 
 11016 |          { s.assign(data,size); } 
 11017 |       }; 
 11018 |  
 11019 |       struct asn_addassignment 
 11020 |       { 
 11021 |          static inline void execute(std::string& s, char_cptr data, const std::size_t size) 
 11022 |          { s.append(data,size); } 
 11023 |       }; 
 11024 |  
 11025 |       template <typename T, typename AssignmentProcess = asn_assignment> 
 11026 |       class assignment_string_node exprtk_final 
 11027 |                                    : public binary_node     <T> 
 11028 |                                    , public string_base_node<T> 
 11029 |                                    , public range_interface <T> 
 11030 |       { 
 11031 |       public: 
 11032 |  
 11033 |          typedef typename range_interface<T>::range_t range_t; 
 11034 |          typedef range_t*             range_ptr; 
 11035 |          typedef range_interface <T>  irange_t; 
 11036 |          typedef irange_t*            irange_ptr; 
 11037 |          typedef expression_node <T>* expression_ptr; 
 11038 |          typedef stringvar_node  <T>* strvar_node_ptr; 
 11039 |          typedef string_base_node<T>* str_base_ptr; 
 11040 |  
 11041 |          using binary_node<T>::branch; 
 11042 |  
 11043 |          assignment_string_node(const operator_type& opr, 
 11044 |                                 expression_ptr branch0, 
 11045 |                                 expression_ptr branch1) 
 11046 |          : binary_node<T>(opr, branch0, branch1) 
 11047 |          , initialised_(false) 
 11048 |          , str0_base_ptr_ (0) 
 11049 |          , str1_base_ptr_ (0) 
 11050 |          , str0_node_ptr_ (0) 
 11051 |          , str1_range_ptr_(0) 
 11052 |          { 
 11053 |             if (is_string_node(branch(0))) 
 11054 |             { 
 11055 |                str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0)); 
 11056 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 11057 |             } 
 11058 |  
 11059 |             if (is_generally_string_node(branch(1))) 
 11060 |             { 
 11061 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 11062 |  
 11063 |                if (0 == str1_base_ptr_) 
 11064 |                   return; 
 11065 |  
 11066 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 11067 |  
 11068 |                if (0 == range) 
 11069 |                   return; 
 11070 |  
 11071 |                str1_range_ptr_ = &(range->range_ref()); 
 11072 |             } 
 11073 |  
 11074 |             initialised_ = str0_base_ptr_  && 
 11075 |                            str1_base_ptr_  && 
 11076 |                            str0_node_ptr_  && 
 11077 |                            str1_range_ptr_ ; 
 11078 |  
 11079 |             assert(valid()); 
 11080 |          } 
 11081 |  
 11082 |          inline T value() const exprtk_override 
 11083 |          { 
 11084 |             branch(1)->value(); 
 11085 |  
 11086 |             std::size_t r0 = 0; 
 11087 |             std::size_t r1 = 0; 
 11088 |  
 11089 |             const range_t& range = (*str1_range_ptr_); 
 11090 |  
 11091 |             if (range(r0, r1, str1_base_ptr_->size())) 
 11092 |             { 
 11093 |                AssignmentProcess::execute( 
 11094 |                   str0_node_ptr_->ref(), 
 11095 |                   str1_base_ptr_->base() + r0, (r1 - r0)); 
 11096 |  
 11097 |                branch(0)->value(); 
 11098 |             } 
 11099 |  
 11100 |             return std::numeric_limits<T>::quiet_NaN(); 
 11101 |          } 
 11102 |  
 11103 |          std::string str() const exprtk_override 
 11104 |          { 
 11105 |             return str0_node_ptr_->str(); 
 11106 |          } 
 11107 |  
 11108 |          char_cptr base() const exprtk_override 
 11109 |          { 
 11110 |            return str0_node_ptr_->base(); 
 11111 |          } 
 11112 |  
 11113 |          std::size_t size() const exprtk_override 
 11114 |          { 
 11115 |             return str0_node_ptr_->size(); 
 11116 |          } 
 11117 |  
 11118 |          range_t& range_ref() exprtk_override 
 11119 |          { 
 11120 |             return str0_node_ptr_->range_ref(); 
 11121 |          } 
 11122 |  
 11123 |          const range_t& range_ref() const exprtk_override 
 11124 |          { 
 11125 |             return str0_node_ptr_->range_ref(); 
 11126 |          } 
 11127 |  
 11128 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11129 |          { 
 11130 |             return expression_node<T>::e_strass; 
 11131 |          } 
 11132 |  
 11133 |          inline bool valid() const exprtk_override 
 11134 |          { 
 11135 |             return initialised_ && binary_node<T>::valid(); 
 11136 |          } 
 11137 |  
 11138 |       private: 
 11139 |  
 11140 |          bool            initialised_; 
 11141 |          str_base_ptr    str0_base_ptr_; 
 11142 |          str_base_ptr    str1_base_ptr_; 
 11143 |          strvar_node_ptr str0_node_ptr_; 
 11144 |          range_ptr       str1_range_ptr_; 
 11145 |       }; 
 11146 |  
 11147 |       template <typename T, typename AssignmentProcess = asn_assignment> 
 11148 |       class assignment_string_range_node exprtk_final 
 11149 |                                          : public binary_node     <T> 
 11150 |                                          , public string_base_node<T> 
 11151 |                                          , public range_interface <T> 
 11152 |       { 
 11153 |       public: 
 11154 |  
 11155 |          typedef typename range_interface<T>::range_t range_t; 
 11156 |          typedef range_t*              range_ptr; 
 11157 |          typedef range_interface  <T>  irange_t; 
 11158 |          typedef irange_t*             irange_ptr; 
 11159 |          typedef expression_node  <T>* expression_ptr; 
 11160 |          typedef stringvar_node   <T>* strvar_node_ptr; 
 11161 |          typedef string_range_node<T>* str_rng_node_ptr; 
 11162 |          typedef string_base_node <T>* str_base_ptr; 
 11163 |  
 11164 |          using binary_node<T>::branch; 
 11165 |  
 11166 |          assignment_string_range_node(const operator_type& opr, 
 11167 |                                       expression_ptr branch0, 
 11168 |                                       expression_ptr branch1) 
 11169 |          : binary_node<T>(opr, branch0, branch1) 
 11170 |          , initialised_(false) 
 11171 |          , str0_base_ptr_    (0) 
 11172 |          , str1_base_ptr_    (0) 
 11173 |          , str0_rng_node_ptr_(0) 
 11174 |          , str0_range_ptr_   (0) 
 11175 |          , str1_range_ptr_   (0) 
 11176 |          { 
 11177 |             if (is_string_range_node(branch(0))) 
 11178 |             { 
 11179 |                str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(branch(0)); 
 11180 |                str0_base_ptr_     = dynamic_cast<str_base_ptr>(branch(0)); 
 11181 |                irange_ptr range   = dynamic_cast<irange_ptr>(branch(0)); 
 11182 |  
 11183 |                if (0 == range) 
 11184 |                   return; 
 11185 |  
 11186 |                str0_range_ptr_ = &(range->range_ref()); 
 11187 |             } 
 11188 |  
 11189 |             if (is_generally_string_node(branch(1))) 
 11190 |             { 
 11191 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 11192 |  
 11193 |                if (0 == str1_base_ptr_) 
 11194 |                   return; 
 11195 |  
 11196 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 11197 |  
 11198 |                if (0 == range) 
 11199 |                   return; 
 11200 |  
 11201 |                str1_range_ptr_ = &(range->range_ref()); 
 11202 |             } 
 11203 |  
 11204 |             initialised_ = str0_base_ptr_     && 
 11205 |                            str1_base_ptr_     && 
 11206 |                            str0_rng_node_ptr_ && 
 11207 |                            str0_range_ptr_    && 
 11208 |                            str1_range_ptr_    ; 
 11209 |  
 11210 |             assert(valid()); 
 11211 |          } 
 11212 |  
 11213 |          inline T value() const exprtk_override 
 11214 |          { 
 11215 |             branch(0)->value(); 
 11216 |             branch(1)->value(); 
 11217 |  
 11218 |             std::size_t s0_r0 = 0; 
 11219 |             std::size_t s0_r1 = 0; 
 11220 |  
 11221 |             std::size_t s1_r0 = 0; 
 11222 |             std::size_t s1_r1 = 0; 
 11223 |  
 11224 |             const range_t& range0 = (*str0_range_ptr_); 
 11225 |             const range_t& range1 = (*str1_range_ptr_); 
 11226 |  
 11227 |             if ( 
 11228 |                   range0(s0_r0, s0_r1, str0_base_ptr_->size()) && 
 11229 |                   range1(s1_r0, s1_r1, str1_base_ptr_->size()) 
 11230 |                ) 
 11231 |             { 
 11232 |                const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0)); 
 11233 |  
 11234 |                std::copy( 
 11235 |                   str1_base_ptr_->base() + s1_r0, 
 11236 |                   str1_base_ptr_->base() + s1_r0 + size, 
 11237 |                   const_cast<char_ptr>(base() + s0_r0)); 
 11238 |             } 
 11239 |  
 11240 |             return std::numeric_limits<T>::quiet_NaN(); 
 11241 |          } 
 11242 |  
 11243 |          std::string str() const exprtk_override 
 11244 |          { 
 11245 |             return str0_base_ptr_->str(); 
 11246 |          } 
 11247 |  
 11248 |          char_cptr base() const exprtk_override 
 11249 |          { 
 11250 |             return str0_base_ptr_->base(); 
 11251 |          } 
 11252 |  
 11253 |          std::size_t size() const exprtk_override 
 11254 |          { 
 11255 |             return str0_base_ptr_->size(); 
 11256 |          } 
 11257 |  
 11258 |          range_t& range_ref() exprtk_override 
 11259 |          { 
 11260 |             return str0_rng_node_ptr_->range_ref(); 
 11261 |          } 
 11262 |  
 11263 |          const range_t& range_ref() const exprtk_override 
 11264 |          { 
 11265 |             return str0_rng_node_ptr_->range_ref(); 
 11266 |          } 
 11267 |  
 11268 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11269 |          { 
 11270 |             return expression_node<T>::e_strass; 
 11271 |          } 
 11272 |  
 11273 |          inline bool valid() const exprtk_override 
 11274 |          { 
 11275 |             return initialised_ && binary_node<T>::valid(); 
 11276 |          } 
 11277 |  
 11278 |       private: 
 11279 |  
 11280 |          bool             initialised_; 
 11281 |          str_base_ptr     str0_base_ptr_; 
 11282 |          str_base_ptr     str1_base_ptr_; 
 11283 |          str_rng_node_ptr str0_rng_node_ptr_; 
 11284 |          range_ptr        str0_range_ptr_; 
 11285 |          range_ptr        str1_range_ptr_; 
 11286 |       }; 
 11287 |  
 11288 |       template <typename T> 
 11289 |       class conditional_string_node exprtk_final 
 11290 |                                     : public trinary_node    <T> 
 11291 |                                     , public string_base_node<T> 
 11292 |                                     , public range_interface <T> 
 11293 |       { 
 11294 |       public: 
 11295 |  
 11296 |          typedef typename range_interface<T>::range_t range_t; 
 11297 |          typedef range_t*             range_ptr; 
 11298 |          typedef range_interface <T>  irange_t; 
 11299 |          typedef irange_t*            irange_ptr; 
 11300 |          typedef expression_node <T>* expression_ptr; 
 11301 |          typedef string_base_node<T>* str_base_ptr; 
 11302 |  
 11303 |          conditional_string_node(expression_ptr condition, 
 11304 |                                  expression_ptr consequent, 
 11305 |                                  expression_ptr alternative) 
 11306 |          : trinary_node<T>(details::e_default, consequent, alternative, condition) 
 11307 |          , initialised_(false) 
 11308 |          , str0_base_ptr_ (0) 
 11309 |          , str1_base_ptr_ (0) 
 11310 |          , str0_range_ptr_(0) 
 11311 |          , str1_range_ptr_(0) 
 11312 |          , condition_  (condition  ) 
 11313 |          , consequent_ (consequent ) 
 11314 |          , alternative_(alternative) 
 11315 |          { 
 11316 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 11317 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 11318 |  
 11319 |             range_.cache.first  = range_.n0_c.second; 
 11320 |             range_.cache.second = range_.n1_c.second; 
 11321 |  
 11322 |             if (is_generally_string_node(trinary_node<T>::branch_[0].first)) 
 11323 |             { 
 11324 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first); 
 11325 |  
 11326 |                if (0 == str0_base_ptr_) 
 11327 |                   return; 
 11328 |  
 11329 |                str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first); 
 11330 |  
 11331 |                if (0 == str0_range_ptr_) 
 11332 |                   return; 
 11333 |             } 
 11334 |  
 11335 |             if (is_generally_string_node(trinary_node<T>::branch_[1].first)) 
 11336 |             { 
 11337 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first); 
 11338 |  
 11339 |                if (0 == str1_base_ptr_) 
 11340 |                   return; 
 11341 |  
 11342 |                str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first); 
 11343 |  
 11344 |                if (0 == str1_range_ptr_) 
 11345 |                   return; 
 11346 |             } 
 11347 |  
 11348 |             initialised_ = str0_base_ptr_  && 
 11349 |                            str1_base_ptr_  && 
 11350 |                            str0_range_ptr_ && 
 11351 |                            str1_range_ptr_ ; 
 11352 |  
 11353 |             assert(valid()); 
 11354 |          } 
 11355 |  
 11356 |          inline T value() const exprtk_override 
 11357 |          { 
 11358 |             std::size_t r0 = 0; 
 11359 |             std::size_t r1 = 0; 
 11360 |  
 11361 |             if (is_true(condition_)) 
 11362 |             { 
 11363 |                consequent_->value(); 
 11364 |  
 11365 |                const range_t& range = str0_range_ptr_->range_ref(); 
 11366 |  
 11367 |                if (range(r0, r1, str0_base_ptr_->size())) 
 11368 |                { 
 11369 |                   const std::size_t size = (r1 - r0); 
 11370 |  
 11371 |                   value_.assign(str0_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(1); 
 11377 |                } 
 11378 |             } 
 11379 |             else 
 11380 |             { 
 11381 |                alternative_->value(); 
 11382 |  
 11383 |                const range_t& range = str1_range_ptr_->range_ref(); 
 11384 |  
 11385 |                if (range(r0, r1, str1_base_ptr_->size())) 
 11386 |                { 
 11387 |                   const std::size_t size = (r1 - r0); 
 11388 |  
 11389 |                   value_.assign(str1_base_ptr_->base() + r0, size); 
 11390 |  
 11391 |                   range_.n1_c.second  = value_.size(); 
 11392 |                   range_.cache.second = range_.n1_c.second; 
 11393 |  
 11394 |                   return T(0); 
 11395 |                } 
 11396 |             } 
 11397 |  
 11398 |             return std::numeric_limits<T>::quiet_NaN(); 
 11399 |          } 
 11400 |  
 11401 |          std::string str() const exprtk_override 
 11402 |          { 
 11403 |             return value_; 
 11404 |          } 
 11405 |  
 11406 |          char_cptr base() const exprtk_override 
 11407 |          { 
 11408 |             return &value_[0]; 
 11409 |          } 
 11410 |  
 11411 |          std::size_t size() const exprtk_override 
 11412 |          { 
 11413 |             return value_.size(); 
 11414 |          } 
 11415 |  
 11416 |          range_t& range_ref() exprtk_override 
 11417 |          { 
 11418 |             return range_; 
 11419 |          } 
 11420 |  
 11421 |          const range_t& range_ref() const exprtk_override 
 11422 |          { 
 11423 |             return range_; 
 11424 |          } 
 11425 |  
 11426 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11427 |          { 
 11428 |             return expression_node<T>::e_strcondition; 
 11429 |          } 
 11430 |  
 11431 |          inline bool valid() const exprtk_override 
 11432 |          { 
 11433 |             return 
 11434 |                initialised_                         && 
 11435 |                condition_  && condition_  ->valid() && 
 11436 |                consequent_ && consequent_ ->valid() && 
 11437 |                alternative_&& alternative_->valid() ; 
 11438 |          } 
 11439 |  
 11440 |       private: 
 11441 |  
 11442 |          bool initialised_; 
 11443 |          str_base_ptr str0_base_ptr_; 
 11444 |          str_base_ptr str1_base_ptr_; 
 11445 |          irange_ptr   str0_range_ptr_; 
 11446 |          irange_ptr   str1_range_ptr_; 
 11447 |          mutable range_t     range_; 
 11448 |          mutable std::string value_; 
 11449 |  
 11450 |          expression_ptr condition_; 
 11451 |          expression_ptr consequent_; 
 11452 |          expression_ptr alternative_; 
 11453 |       }; 
 11454 |  
 11455 |       template <typename T> 
 11456 |       class cons_conditional_str_node exprtk_final 
 11457 |                                       : public binary_node     <T> 
 11458 |                                       , public string_base_node<T> 
 11459 |                                       , public range_interface <T> 
 11460 |       { 
 11461 |       public: 
 11462 |  
 11463 |          typedef typename range_interface<T>::range_t range_t; 
 11464 |          typedef range_t*             range_ptr; 
 11465 |          typedef range_interface <T>  irange_t; 
 11466 |          typedef irange_t*            irange_ptr; 
 11467 |          typedef expression_node <T>* expression_ptr; 
 11468 |          typedef string_base_node<T>* str_base_ptr; 
 11469 |  
 11470 |          using binary_node<T>::branch; 
 11471 |  
 11472 |          cons_conditional_str_node(expression_ptr condition, 
 11473 |                                    expression_ptr consequent) 
 11474 |          : binary_node<T>(details::e_default, consequent, condition) 
 11475 |          , initialised_(false) 
 11476 |          , str0_base_ptr_ (0) 
 11477 |          , str0_range_ptr_(0) 
 11478 |          , condition_ (condition ) 
 11479 |          , consequent_(consequent) 
 11480 |          { 
 11481 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 11482 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 11483 |  
 11484 |             range_.cache.first  = range_.n0_c.second; 
 11485 |             range_.cache.second = range_.n1_c.second; 
 11486 |  
 11487 |             if (is_generally_string_node(branch(0))) 
 11488 |             { 
 11489 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 11490 |  
 11491 |                if (0 == str0_base_ptr_) 
 11492 |                   return; 
 11493 |  
 11494 |                str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0)); 
 11495 |  
 11496 |                if (0 == str0_range_ptr_) 
 11497 |                   return; 
 11498 |             } 
 11499 |  
 11500 |             initialised_ = str0_base_ptr_ && str0_range_ptr_ ; 
 11501 |             assert(valid()); 
 11502 |          } 
 11503 |  
 11504 |          inline T value() const exprtk_override 
 11505 |          { 
 11506 |             if (is_true(condition_)) 
 11507 |             { 
 11508 |                consequent_->value(); 
 11509 |  
 11510 |                const range_t& range = str0_range_ptr_->range_ref(); 
 11511 |  
 11512 |                std::size_t r0 = 0; 
 11513 |                std::size_t r1 = 0; 
 11514 |  
 11515 |                if (range(r0, r1, str0_base_ptr_->size())) 
 11516 |                { 
 11517 |                   const std::size_t size = (r1 - r0); 
 11518 |  
 11519 |                   value_.assign(str0_base_ptr_->base() + r0, size); 
 11520 |  
 11521 |                   range_.n1_c.second  = value_.size(); 
 11522 |                   range_.cache.second = range_.n1_c.second; 
 11523 |  
 11524 |                   return T(1); 
 11525 |                } 
 11526 |             } 
 11527 |  
 11528 |             return std::numeric_limits<T>::quiet_NaN(); 
 11529 |          } 
 11530 |  
 11531 |          std::string str() const 
 11532 |          { 
 11533 |             return value_; 
 11534 |          } 
 11535 |  
 11536 |          char_cptr base() const 
 11537 |          { 
 11538 |             return &value_[0]; 
 11539 |          } 
 11540 |  
 11541 |          std::size_t size() const 
 11542 |          { 
 11543 |             return value_.size(); 
 11544 |          } 
 11545 |  
 11546 |          range_t& range_ref() 
 11547 |          { 
 11548 |             return range_; 
 11549 |          } 
 11550 |  
 11551 |          const range_t& range_ref() const 
 11552 |          { 
 11553 |             return range_; 
 11554 |          } 
 11555 |  
 11556 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11557 |          { 
 11558 |             return expression_node<T>::e_strccondition; 
 11559 |          } 
 11560 |  
 11561 |          inline bool valid() const exprtk_override 
 11562 |          { 
 11563 |             return 
 11564 |                initialised_                         && 
 11565 |                condition_  && condition_  ->valid() && 
 11566 |                consequent_ && consequent_ ->valid() ; 
 11567 |          } 
 11568 |  
 11569 |       private: 
 11570 |  
 11571 |          bool initialised_; 
 11572 |          str_base_ptr str0_base_ptr_; 
 11573 |          irange_ptr   str0_range_ptr_; 
 11574 |          mutable range_t     range_; 
 11575 |          mutable std::string value_; 
 11576 |  
 11577 |          expression_ptr condition_; 
 11578 |          expression_ptr consequent_; 
 11579 |       }; 
 11580 |  
 11581 |       template <typename T, typename VarArgFunction> 
 11582 |       class str_vararg_node exprtk_final 
 11583 |                             : public expression_node <T> 
 11584 |                             , public string_base_node<T> 
 11585 |                             , public range_interface <T> 
 11586 |       { 
 11587 |       public: 
 11588 |  
 11589 |          typedef typename range_interface<T>::range_t range_t; 
 11590 |          typedef range_t*             range_ptr; 
 11591 |          typedef range_interface <T>  irange_t; 
 11592 |          typedef irange_t*            irange_ptr; 
 11593 |          typedef expression_node <T>* expression_ptr; 
 11594 |          typedef string_base_node<T>* str_base_ptr; 
 11595 |          typedef std::pair<expression_ptr,bool> branch_t; 
 11596 |  
 11597 |          template <typename Allocator, 
 11598 |                    template <typename, typename> class Sequence> 
 11599 |          explicit str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 11600 |          : initialised_(false) 
 11601 |          , str_base_ptr_ (0) 
 11602 |          , str_range_ptr_(0) 
 11603 |          { 
 11604 |             construct_branch_pair(final_node_, const_cast<expression_ptr>(arg_list.back())); 
 11605 |  
 11606 |             if (0 == final_node_.first) 
 11607 |                return; 
 11608 |             else if (!is_generally_string_node(final_node_.first)) 
 11609 |                return; 
 11610 |  
 11611 |             str_base_ptr_ = dynamic_cast<str_base_ptr>(final_node_.first); 
 11612 |  
 11613 |             if (0 == str_base_ptr_) 
 11614 |                return; 
 11615 |  
 11616 |             str_range_ptr_ = dynamic_cast<irange_ptr>(final_node_.first); 
 11617 |  
 11618 |             if (0 == str_range_ptr_) 
 11619 |                return; 
 11620 |  
 11621 |             if (arg_list.size() > 1) 
 11622 |             { 
 11623 |                const std::size_t arg_list_size = arg_list.size() - 1; 
 11624 |  
 11625 |                arg_list_.resize(arg_list_size); 
 11626 |  
 11627 |                for (std::size_t i = 0; i < arg_list_size; ++i) 
 11628 |                { 
 11629 |                   if (arg_list[i] && arg_list[i]->valid()) 
 11630 |                   { 
 11631 |                      construct_branch_pair(arg_list_[i], arg_list[i]); 
 11632 |                   } 
 11633 |                   else 
 11634 |                   { 
 11635 |                      arg_list_.clear(); 
 11636 |                      return; 
 11637 |                   } 
 11638 |                } 
 11639 |  
 11640 |                initialised_ = true; 
 11641 |             } 
 11642 |  
 11643 |             initialised_ &= str_base_ptr_ && str_range_ptr_; 
 11644 |             assert(valid()); 
 11645 |          } 
 11646 |  
 11647 |          inline T value() const exprtk_override 
 11648 |          { 
 11649 |             if (!arg_list_.empty()) 
 11650 |             { 
 11651 |                VarArgFunction::process(arg_list_); 
 11652 |             } 
 11653 |  
 11654 |             final_node_.first->value(); 
 11655 |  
 11656 |             return std::numeric_limits<T>::quiet_NaN(); 
 11657 |          } 
 11658 |  
 11659 |          std::string str() const exprtk_override 
 11660 |          { 
 11661 |             return str_base_ptr_->str(); 
 11662 |          } 
 11663 |  
 11664 |          char_cptr base() const exprtk_override 
 11665 |          { 
 11666 |             return str_base_ptr_->base(); 
 11667 |          } 
 11668 |  
 11669 |          std::size_t size() const exprtk_override 
 11670 |          { 
 11671 |             return str_base_ptr_->size(); 
 11672 |          } 
 11673 |  
 11674 |          range_t& range_ref() exprtk_override 
 11675 |          { 
 11676 |             return str_range_ptr_->range_ref(); 
 11677 |          } 
 11678 |  
 11679 |          const range_t& range_ref() const exprtk_override 
 11680 |          { 
 11681 |             return str_range_ptr_->range_ref(); 
 11682 |          } 
 11683 |  
 11684 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11685 |          { 
 11686 |             return expression_node<T>::e_stringvararg; 
 11687 |          } 
 11688 |  
 11689 |          inline bool valid() const exprtk_override 
 11690 |          { 
 11691 |             return 
 11692 |                initialised_ && 
 11693 |                final_node_.first && final_node_.first->valid(); 
 11694 |          } 
 11695 |  
 11696 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 11697 |          { 
 11698 |             expression_node<T>::ndb_t::collect(final_node_ , node_delete_list); 
 11699 |             expression_node<T>::ndb_t::collect(arg_list_   , node_delete_list); 
 11700 |          } 
 11701 |  
 11702 |          std::size_t node_depth() const exprtk_override 
 11703 |          { 
 11704 |             return std::max( 
 11705 |                expression_node<T>::ndb_t::compute_node_depth(final_node_), 
 11706 |                expression_node<T>::ndb_t::compute_node_depth(arg_list_  )); 
 11707 |          } 
 11708 |  
 11709 |       private: 
 11710 |  
 11711 |          bool                  initialised_; 
 11712 |          branch_t              final_node_; 
 11713 |          str_base_ptr          str_base_ptr_; 
 11714 |          irange_ptr            str_range_ptr_; 
 11715 |          std::vector<branch_t> arg_list_; 
 11716 |       }; 
 11717 |       #endif 
 11718 |  
 11719 |       template <typename T> 
 11720 |       class assert_node exprtk_final : public expression_node<T> 
 11721 |       { 
 11722 |       public: 
 11723 |  
 11724 |          typedef expression_node<T>* expression_ptr; 
 11725 |          typedef std::pair<expression_ptr,bool> branch_t; 
 11726 |          typedef string_base_node<T>* str_base_ptr; 
 11727 |          typedef assert_check::assert_context assert_context_t; 
 11728 |  
 11729 |          assert_node(expression_ptr   assert_condition_node, 
 11730 |                      expression_ptr   assert_message_node, 
 11731 |                      assert_check_ptr assert_check, 
 11732 |                      assert_context_t context) 
 11733 |          : assert_message_str_base_(0) 
 11734 |          , assert_check_(assert_check) 
 11735 |          , context_(context) 
 11736 |          { 
 11737 |             construct_branch_pair(assert_condition_node_, assert_condition_node); 
 11738 |             construct_branch_pair(assert_message_node_  , assert_message_node  ); 
 11739 |  
 11740 |             #ifndef exprtk_disable_string_capabilities 
 11741 |             if ( 
 11742 |                   assert_message_node_.first && 
 11743 |                   details::is_generally_string_node(assert_message_node_.first) 
 11744 |                ) 
 11745 |             { 
 11746 |                assert_message_str_base_ = dynamic_cast<str_base_ptr>(assert_message_node_.first); 
 11747 |             } 
 11748 |             #endif 
 11749 |  
 11750 |             assert(valid()); 
 11751 |          } 
 11752 |  
 11753 |          inline T value() const exprtk_override 
 11754 |          { 
 11755 |             if (details::is_true(assert_condition_node_.first->value())) 
 11756 |             { 
 11757 |                return T(1); 
 11758 |             } 
 11759 |  
 11760 |             #ifndef exprtk_disable_string_capabilities 
 11761 |             if (assert_message_node_.first) 
 11762 |             { 
 11763 |                assert_message_node_.first->value(); 
 11764 |                assert(assert_message_str_base_); 
 11765 |                context_.message = assert_message_str_base_->str(); 
 11766 |             } 
 11767 |             #endif 
 11768 |  
 11769 |             assert_check_->handle_assert(context_); 
 11770 |             return T(0); 
 11771 |          } 
 11772 |  
 11773 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11774 |          { 
 11775 |             return expression_node<T>::e_assert; 
 11776 |          } 
 11777 |  
 11778 |          inline bool valid() const exprtk_override 
 11779 |          { 
 11780 |             return ( 
 11781 |                      assert_check_ && 
 11782 |                      assert_condition_node_.first && 
 11783 |                      assert_condition_node_.first->valid() 
 11784 |                    ) && 
 11785 |                    ( 
 11786 |                      (0 == assert_message_node_.first) || 
 11787 |                      ( 
 11788 |                        assert_message_node_.first && 
 11789 |                        assert_message_str_base_   && 
 11790 |                        assert_message_node_.first->valid() && 
 11791 |                        details::is_generally_string_node(assert_message_node_.first) 
 11792 |                      ) 
 11793 |                    ); 
 11794 |          } 
 11795 |  
 11796 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 11797 |          { 
 11798 |             expression_node<T>::ndb_t::collect(assert_condition_node_, node_delete_list); 
 11799 |             expression_node<T>::ndb_t::collect(assert_message_node_  , node_delete_list); 
 11800 |          } 
 11801 |  
 11802 |          std::size_t node_depth() const exprtk_override 
 11803 |          { 
 11804 |             return expression_node<T>::ndb_t::compute_node_depth 
 11805 |                (assert_condition_node_, assert_message_node_); 
 11806 |          } 
 11807 |  
 11808 |       private: 
 11809 |  
 11810 |          branch_t         assert_condition_node_; 
 11811 |          branch_t         assert_message_node_; 
 11812 |          str_base_ptr     assert_message_str_base_; 
 11813 |          assert_check_ptr assert_check_; 
 11814 |          mutable assert_context_t context_; 
 11815 |       }; 
 11816 |  
 11817 |       template <typename T, std::size_t N> 
 11818 |       inline T axn(const T a, const T x) 
 11819 |       { 
 11820 |          // a*x^n 
 11821 |          return a * exprtk::details::numeric::fast_exp<T,N>::result(x); 
 11822 |       } 
 11823 |  
 11824 |       template <typename T, std::size_t N> 
 11825 |       inline T axnb(const T a, const T x, const T b) 
 11826 |       { 
 11827 |          // a*x^n+b 
 11828 |          return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b; 
 11829 |       } 
 11830 |  
 11831 |       template <typename T> 
 11832 |       struct sf_base 
 11833 |       { 
 11834 |          typedef typename details::functor_t<T>::Type Type; 
 11835 |          typedef typename details::functor_t<T> functor_t; 
 11836 |          typedef typename functor_t::qfunc_t quaternary_functor_t; 
 11837 |          typedef typename functor_t::tfunc_t trinary_functor_t; 
 11838 |          typedef typename functor_t::bfunc_t binary_functor_t; 
 11839 |          typedef typename functor_t::ufunc_t unary_functor_t; 
 11840 |       }; 
 11841 |  
 11842 |       #define define_sfop3(NN, OP0, OP1)                 \ 
 11843 |       template <typename T>                              \ 
 11844 |       struct sf##NN##_op : public sf_base<T>             \ 
 11845 |       {                                                  \ 
 11846 |          typedef typename sf_base<T>::Type const Type;   \ 
 11847 |          static inline T process(Type x, Type y, Type z) \ 
 11848 |          {                                               \ 
 11849 |             return (OP0);                                \ 
 11850 |          }                                               \ 
 11851 |          static inline std::string id()                  \ 
 11852 |          {                                               \ 
 11853 |             return (OP1);                                \ 
 11854 |          }                                               \ 
 11855 |       };                                                 \ 
 11856 |  
 11857 |       define_sfop3(00,(x + y) / z       ,"(t+t)/t") 
 11858 |       define_sfop3(01,(x + y) * z       ,"(t+t)*t") 
 11859 |       define_sfop3(02,(x + y) - z       ,"(t+t)-t") 
 11860 |       define_sfop3(03,(x + y) + z       ,"(t+t)+t") 
 11861 |       define_sfop3(04,(x - y) + z       ,"(t-t)+t") 
 11862 |       define_sfop3(05,(x - y) / z       ,"(t-t)/t") 
 11863 |       define_sfop3(06,(x - y) * z       ,"(t-t)*t") 
 11864 |       define_sfop3(07,(x * y) + z       ,"(t*t)+t") 
 11865 |       define_sfop3(08,(x * y) - z       ,"(t*t)-t") 
 11866 |       define_sfop3(09,(x * y) / z       ,"(t*t)/t") 
 11867 |       define_sfop3(10,(x * y) * z       ,"(t*t)*t") 
 11868 |       define_sfop3(11,(x / y) + z       ,"(t/t)+t") 
 11869 |       define_sfop3(12,(x / y) - z       ,"(t/t)-t") 
 11870 |       define_sfop3(13,(x / y) / z       ,"(t/t)/t") 
 11871 |       define_sfop3(14,(x / y) * z       ,"(t/t)*t") 
 11872 |       define_sfop3(15,x / (y + z)       ,"t/(t+t)") 
 11873 |       define_sfop3(16,x / (y - z)       ,"t/(t-t)") 
 11874 |       define_sfop3(17,x / (y * z)       ,"t/(t*t)") 
 11875 |       define_sfop3(18,x / (y / z)       ,"t/(t/t)") 
 11876 |       define_sfop3(19,x * (y + z)       ,"t*(t+t)") 
 11877 |       define_sfop3(20,x * (y - z)       ,"t*(t-t)") 
 11878 |       define_sfop3(21,x * (y * z)       ,"t*(t*t)") 
 11879 |       define_sfop3(22,x * (y / z)       ,"t*(t/t)") 
 11880 |       define_sfop3(23,x - (y + z)       ,"t-(t+t)") 
 11881 |       define_sfop3(24,x - (y - z)       ,"t-(t-t)") 
 11882 |       define_sfop3(25,x - (y / z)       ,"t-(t/t)") 
 11883 |       define_sfop3(26,x - (y * z)       ,"t-(t*t)") 
 11884 |       define_sfop3(27,x + (y * z)       ,"t+(t*t)") 
 11885 |       define_sfop3(28,x + (y / z)       ,"t+(t/t)") 
 11886 |       define_sfop3(29,x + (y + z)       ,"t+(t+t)") 
 11887 |       define_sfop3(30,x + (y - z)       ,"t+(t-t)") 
 11888 |       define_sfop3(31,(axnb<T,2>(x,y,z)),"       ") 
 11889 |       define_sfop3(32,(axnb<T,3>(x,y,z)),"       ") 
 11890 |       define_sfop3(33,(axnb<T,4>(x,y,z)),"       ") 
 11891 |       define_sfop3(34,(axnb<T,5>(x,y,z)),"       ") 
 11892 |       define_sfop3(35,(axnb<T,6>(x,y,z)),"       ") 
 11893 |       define_sfop3(36,(axnb<T,7>(x,y,z)),"       ") 
 11894 |       define_sfop3(37,(axnb<T,8>(x,y,z)),"       ") 
 11895 |       define_sfop3(38,(axnb<T,9>(x,y,z)),"       ") 
 11896 |       define_sfop3(39,x * numeric::log(y)   + z,"") 
 11897 |       define_sfop3(40,x * numeric::log(y)   - z,"") 
 11898 |       define_sfop3(41,x * numeric::log10(y) + z,"") 
 11899 |       define_sfop3(42,x * numeric::log10(y) - z,"") 
 11900 |       define_sfop3(43,x * numeric::sin(y) + z  ,"") 
 11901 |       define_sfop3(44,x * numeric::sin(y) - z  ,"") 
 11902 |       define_sfop3(45,x * numeric::cos(y) + z  ,"") 
 11903 |       define_sfop3(46,x * numeric::cos(y) - z  ,"") 
 11904 |       define_sfop3(47,details::is_true(x) ? y : z,"") 
 11905 |  
 11906 |       #define define_sfop4(NN, OP0, OP1)                         \ 
 11907 |       template <typename T>                                      \ 
 11908 |       struct sf##NN##_op : public sf_base<T>                     \ 
 11909 |       {                                                          \ 
 11910 |          typedef typename sf_base<T>::Type const Type;           \ 
 11911 |          static inline T process(Type x, Type y, Type z, Type w) \ 
 11912 |          {                                                       \ 
 11913 |             return (OP0);                                        \ 
 11914 |          }                                                       \ 
 11915 |          static inline std::string id()                          \ 
 11916 |          {                                                       \ 
 11917 |             return (OP1);                                        \ 
 11918 |          }                                                       \ 
 11919 |       };                                                         \ 
 11920 |  
 11921 |       define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)") 
 11922 |       define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)") 
 11923 |       define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)") 
 11924 |       define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)") 
 11925 |       define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)") 
 11926 |       define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)") 
 11927 |       define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)") 
 11928 |       define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)") 
 11929 |       define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)") 
 11930 |       define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)") 
 11931 |       define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)") 
 11932 |       define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)") 
 11933 |       define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)") 
 11934 |       define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)") 
 11935 |       define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)") 
 11936 |       define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)") 
 11937 |       define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)") 
 11938 |       define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t") 
 11939 |       define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t") 
 11940 |       define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t") 
 11941 |       define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t") 
 11942 |       define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t") 
 11943 |       define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t") 
 11944 |       define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t") 
 11945 |       define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t") 
 11946 |       define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)") 
 11947 |       define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)") 
 11948 |       define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)") 
 11949 |       define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)") 
 11950 |       define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)") 
 11951 |       define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)") 
 11952 |       define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)") 
 11953 |       define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))") 
 11954 |       define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))") 
 11955 |       define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))") 
 11956 |       define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))") 
 11957 |  
 11958 |       define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"") 
 11959 |       define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"") 
 11960 |       define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"") 
 11961 |       define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"") 
 11962 |       define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"") 
 11963 |       define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"") 
 11964 |       define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"") 
 11965 |       define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"") 
 11966 |       define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"") 
 11967 |       define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"") 
 11968 |       define_sfop4(94,((x <  y) ? z : w),"") 
 11969 |       define_sfop4(95,((x <= y) ? z : w),"") 
 11970 |       define_sfop4(96,((x >  y) ? z : w),"") 
 11971 |       define_sfop4(97,((x >= y) ? z : w),"") 
 11972 |       define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"") 
 11973 |       define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"") 
 11974 |  
 11975 |       define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)") 
 11976 |       define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)") 
 11977 |       define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)") 
 11978 |       define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)") 
 11979 |       define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)") 
 11980 |       define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)") 
 11981 |       define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)") 
 11982 |       define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)") 
 11983 |       define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)") 
 11984 |       define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)") 
 11985 |       define_sfop4(ext10,((x + y) + (z + w)),"(t+t)+(t+t)") 
 11986 |       define_sfop4(ext11,((x + y) * (z - w)),"(t+t)*(t-t)") 
 11987 |       define_sfop4(ext12,((x + y) / (z - w)),"(t+t)/(t-t)") 
 11988 |       define_sfop4(ext13,((x - y) - (z + w)),"(t-t)-(t+t)") 
 11989 |       define_sfop4(ext14,((x - y) + (z + w)),"(t-t)+(t+t)") 
 11990 |       define_sfop4(ext15,((x - y) * (z + w)),"(t-t)*(t+t)") 
 11991 |       define_sfop4(ext16,((x - y) / (z + w)),"(t-t)/(t+t)") 
 11992 |       define_sfop4(ext17,((x * y) - (z + w)),"(t*t)-(t+t)") 
 11993 |       define_sfop4(ext18,((x / y) - (z + w)),"(t/t)-(t+t)") 
 11994 |       define_sfop4(ext19,((x * y) + (z + w)),"(t*t)+(t+t)") 
 11995 |       define_sfop4(ext20,((x / y) + (z + w)),"(t/t)+(t+t)") 
 11996 |       define_sfop4(ext21,((x * y) + (z - w)),"(t*t)+(t-t)") 
 11997 |       define_sfop4(ext22,((x / y) + (z - w)),"(t/t)+(t-t)") 
 11998 |       define_sfop4(ext23,((x * y) - (z - w)),"(t*t)-(t-t)") 
 11999 |       define_sfop4(ext24,((x / y) - (z - w)),"(t/t)-(t-t)") 
 12000 |       define_sfop4(ext25,((x + y) * (z * w)),"(t+t)*(t*t)") 
 12001 |       define_sfop4(ext26,((x + y) * (z / w)),"(t+t)*(t/t)") 
 12002 |       define_sfop4(ext27,((x + y) / (z * w)),"(t+t)/(t*t)") 
 12003 |       define_sfop4(ext28,((x + y) / (z / w)),"(t+t)/(t/t)") 
 12004 |       define_sfop4(ext29,((x - y) / (z * w)),"(t-t)/(t*t)") 
 12005 |       define_sfop4(ext30,((x - y) / (z / w)),"(t-t)/(t/t)") 
 12006 |       define_sfop4(ext31,((x - y) * (z * w)),"(t-t)*(t*t)") 
 12007 |       define_sfop4(ext32,((x - y) * (z / w)),"(t-t)*(t/t)") 
 12008 |       define_sfop4(ext33,((x * y) * (z + w)),"(t*t)*(t+t)") 
 12009 |       define_sfop4(ext34,((x / y) * (z + w)),"(t/t)*(t+t)") 
 12010 |       define_sfop4(ext35,((x * y) / (z + w)),"(t*t)/(t+t)") 
 12011 |       define_sfop4(ext36,((x / y) / (z + w)),"(t/t)/(t+t)") 
 12012 |       define_sfop4(ext37,((x * y) / (z - w)),"(t*t)/(t-t)") 
 12013 |       define_sfop4(ext38,((x / y) / (z - w)),"(t/t)/(t-t)") 
 12014 |       define_sfop4(ext39,((x * y) * (z - w)),"(t*t)*(t-t)") 
 12015 |       define_sfop4(ext40,((x * y) / (z * w)),"(t*t)/(t*t)") 
 12016 |       define_sfop4(ext41,((x / y) * (z / w)),"(t/t)*(t/t)") 
 12017 |       define_sfop4(ext42,((x / y) * (z - w)),"(t/t)*(t-t)") 
 12018 |       define_sfop4(ext43,((x * y) * (z * w)),"(t*t)*(t*t)") 
 12019 |       define_sfop4(ext44,(x + (y * (z / w))),"t+(t*(t/t))") 
 12020 |       define_sfop4(ext45,(x - (y * (z / w))),"t-(t*(t/t))") 
 12021 |       define_sfop4(ext46,(x + (y / (z * w))),"t+(t/(t*t))") 
 12022 |       define_sfop4(ext47,(x - (y / (z * w))),"t-(t/(t*t))") 
 12023 |       define_sfop4(ext48,(((x - y) - z) * w),"((t-t)-t)*t") 
 12024 |       define_sfop4(ext49,(((x - y) - z) / w),"((t-t)-t)/t") 
 12025 |       define_sfop4(ext50,(((x - y) + z) * w),"((t-t)+t)*t") 
 12026 |       define_sfop4(ext51,(((x - y) + z) / w),"((t-t)+t)/t") 
 12027 |       define_sfop4(ext52,((x + (y - z)) * w),"(t+(t-t))*t") 
 12028 |       define_sfop4(ext53,((x + (y - z)) / w),"(t+(t-t))/t") 
 12029 |       define_sfop4(ext54,((x + y) / (z + w)),"(t+t)/(t+t)") 
 12030 |       define_sfop4(ext55,((x - y) / (z - w)),"(t-t)/(t-t)") 
 12031 |       define_sfop4(ext56,((x + y) * (z + w)),"(t+t)*(t+t)") 
 12032 |       define_sfop4(ext57,((x - y) * (z - w)),"(t-t)*(t-t)") 
 12033 |       define_sfop4(ext58,((x - y) + (z - w)),"(t-t)+(t-t)") 
 12034 |       define_sfop4(ext59,((x - y) - (z - w)),"(t-t)-(t-t)") 
 12035 |       define_sfop4(ext60,((x / y) + (z * w)),"(t/t)+(t*t)") 
 12036 |       define_sfop4(ext61,(((x * y) * z) / w),"((t*t)*t)/t") 
 12037 |  
 12038 |       #undef define_sfop3 
 12039 |       #undef define_sfop4 
 12040 |  
 12041 |       template <typename T, typename SpecialFunction> 
 12042 |       class sf3_node exprtk_final : public trinary_node<T> 
 12043 |       { 
 12044 |       public: 
 12045 |  
 12046 |          typedef expression_node<T>* expression_ptr; 
 12047 |  
 12048 |          sf3_node(const operator_type& opr, 
 12049 |                   expression_ptr branch0, 
 12050 |                   expression_ptr branch1, 
 12051 |                   expression_ptr branch2) 
 12052 |          : trinary_node<T>(opr, branch0, branch1, branch2) 
 12053 |          {} 
 12054 |  
 12055 |          inline T value() const exprtk_override 
 12056 |          { 
 12057 |             const T x = trinary_node<T>::branch_[0].first->value(); 
 12058 |             const T y = trinary_node<T>::branch_[1].first->value(); 
 12059 |             const T z = trinary_node<T>::branch_[2].first->value(); 
 12060 |  
 12061 |             return SpecialFunction::process(x, y, z); 
 12062 |          } 
 12063 |       }; 
 12064 |  
 12065 |       template <typename T, typename SpecialFunction> 
 12066 |       class sf4_node exprtk_final : public quaternary_node<T> 
 12067 |       { 
 12068 |       public: 
 12069 |  
 12070 |          typedef expression_node<T>* expression_ptr; 
 12071 |  
 12072 |          sf4_node(const operator_type& opr, 
 12073 |                   expression_ptr branch0, 
 12074 |                   expression_ptr branch1, 
 12075 |                   expression_ptr branch2, 
 12076 |                   expression_ptr branch3) 
 12077 |          : quaternary_node<T>(opr, branch0, branch1, branch2, branch3) 
 12078 |          {} 
 12079 |  
 12080 |          inline T value() const exprtk_override 
 12081 |          { 
 12082 |             const T x = quaternary_node<T>::branch_[0].first->value(); 
 12083 |             const T y = quaternary_node<T>::branch_[1].first->value(); 
 12084 |             const T z = quaternary_node<T>::branch_[2].first->value(); 
 12085 |             const T w = quaternary_node<T>::branch_[3].first->value(); 
 12086 |  
 12087 |             return SpecialFunction::process(x, y, z, w); 
 12088 |          } 
 12089 |       }; 
 12090 |  
 12091 |       template <typename T, typename SpecialFunction> 
 12092 |       class sf3_var_node exprtk_final : public expression_node<T> 
 12093 |       { 
 12094 |       public: 
 12095 |  
 12096 |          typedef expression_node<T>* expression_ptr; 
 12097 |  
 12098 |          sf3_var_node(const T& v0, const T& v1, const T& v2) 
 12099 |          : v0_(v0) 
 12100 |          , v1_(v1) 
 12101 |          , v2_(v2) 
 12102 |          {} 
 12103 |  
 12104 |          inline T value() const exprtk_override 
 12105 |          { 
 12106 |             return SpecialFunction::process(v0_, v1_, v2_); 
 12107 |          } 
 12108 |  
 12109 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12110 |          { 
 12111 |             return expression_node<T>::e_trinary; 
 12112 |          } 
 12113 |  
 12114 |       private: 
 12115 |  
 12116 |          sf3_var_node(const sf3_var_node<T,SpecialFunction>&) exprtk_delete; 
 12117 |          sf3_var_node<T,SpecialFunction>& operator=(const sf3_var_node<T,SpecialFunction>&) exprtk_delete; 
 12118 |  
 12119 |          const T& v0_; 
 12120 |          const T& v1_; 
 12121 |          const T& v2_; 
 12122 |       }; 
 12123 |  
 12124 |       template <typename T, typename SpecialFunction> 
 12125 |       class sf4_var_node exprtk_final : public expression_node<T> 
 12126 |       { 
 12127 |       public: 
 12128 |  
 12129 |          typedef expression_node<T>* expression_ptr; 
 12130 |  
 12131 |          sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3) 
 12132 |          : v0_(v0) 
 12133 |          , v1_(v1) 
 12134 |          , v2_(v2) 
 12135 |          , v3_(v3) 
 12136 |          {} 
 12137 |  
 12138 |          inline T value() const exprtk_override 
 12139 |          { 
 12140 |             return SpecialFunction::process(v0_, v1_, v2_, v3_); 
 12141 |          } 
 12142 |  
 12143 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12144 |          { 
 12145 |             return expression_node<T>::e_trinary; 
 12146 |          } 
 12147 |  
 12148 |       private: 
 12149 |  
 12150 |          sf4_var_node(const sf4_var_node<T,SpecialFunction>&) exprtk_delete; 
 12151 |          sf4_var_node<T,SpecialFunction>& operator=(const sf4_var_node<T,SpecialFunction>&) exprtk_delete; 
 12152 |  
 12153 |          const T& v0_; 
 12154 |          const T& v1_; 
 12155 |          const T& v2_; 
 12156 |          const T& v3_; 
 12157 |       }; 
 12158 |  
 12159 |       template <typename T, typename VarArgFunction> 
 12160 |       class vararg_node exprtk_final : public expression_node<T> 
 12161 |       { 
 12162 |       public: 
 12163 |  
 12164 |          typedef expression_node<T>* expression_ptr; 
 12165 |          typedef std::pair<expression_ptr,bool> branch_t; 
 12166 |  
 12167 |          template <typename Allocator, 
 12168 |                    template <typename, typename> class Sequence> 
 12169 |          explicit vararg_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 12170 |          : initialised_(false) 
 12171 |          { 
 12172 |             arg_list_.resize(arg_list.size()); 
 12173 |  
 12174 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 12175 |             { 
 12176 |                if (arg_list[i] && arg_list[i]->valid()) 
 12177 |                { 
 12178 |                   construct_branch_pair(arg_list_[i],arg_list[i]); 
 12179 |                } 
 12180 |                else 
 12181 |                { 
 12182 |                   arg_list_.clear(); 
 12183 |                   return; 
 12184 |                } 
 12185 |             } 
 12186 |  
 12187 |             initialised_ = (arg_list_.size() == arg_list.size()); 
 12188 |             assert(valid()); 
 12189 |          } 
 12190 |  
 12191 |          inline T value() const exprtk_override 
 12192 |          { 
 12193 |             return VarArgFunction::process(arg_list_); 
 12194 |          } 
 12195 |  
 12196 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12197 |          { 
 12198 |             return expression_node<T>::e_vararg; 
 12199 |          } 
 12200 |  
 12201 |          inline bool valid() const exprtk_override 
 12202 |          { 
 12203 |             return initialised_; 
 12204 |          } 
 12205 |  
 12206 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 12207 |          { 
 12208 |             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list); 
 12209 |          } 
 12210 |  
 12211 |          std::size_t node_depth() const exprtk_override 
 12212 |          { 
 12213 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 12214 |          } 
 12215 |  
 12216 |          std::size_t size() const 
 12217 |          { 
 12218 |             return arg_list_.size(); 
 12219 |          } 
 12220 |  
 12221 |          expression_ptr operator[](const std::size_t& index) const 
 12222 |          { 
 12223 |             return arg_list_[index].first; 
 12224 |          } 
 12225 |  
 12226 |       private: 
 12227 |  
 12228 |          std::vector<branch_t> arg_list_; 
 12229 |          bool initialised_; 
 12230 |       }; 
 12231 |  
 12232 |       template <typename T, typename VarArgFunction> 
 12233 |       class vararg_varnode exprtk_final : public expression_node<T> 
 12234 |       { 
 12235 |       public: 
 12236 |  
 12237 |          typedef expression_node<T>* expression_ptr; 
 12238 |  
 12239 |          template <typename Allocator, 
 12240 |                    template <typename, typename> class Sequence> 
 12241 |          explicit vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list) 
 12242 |          : initialised_(false) 
 12243 |          { 
 12244 |             arg_list_.resize(arg_list.size()); 
 12245 |  
 12246 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 12247 |             { 
 12248 |                if (arg_list[i] && arg_list[i]->valid() && is_variable_node(arg_list[i])) 
 12249 |                { 
 12250 |                   variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]); 
 12251 |                   arg_list_[i] = (&var_node_ptr->ref()); 
 12252 |                } 
 12253 |                else 
 12254 |                { 
 12255 |                   arg_list_.clear(); 
 12256 |                   return; 
 12257 |                } 
 12258 |             } 
 12259 |  
 12260 |             initialised_ = (arg_list.size() == arg_list_.size()); 
 12261 |             assert(valid()); 
 12262 |          } 
 12263 |  
 12264 |          inline T value() const exprtk_override 
 12265 |          { 
 12266 |             return VarArgFunction::process(arg_list_); 
 12267 |          } 
 12268 |  
 12269 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12270 |          { 
 12271 |             return expression_node<T>::e_vararg; 
 12272 |          } 
 12273 |  
 12274 |          inline bool valid() const exprtk_override 
 12275 |          { 
 12276 |             return initialised_; 
 12277 |          } 
 12278 |  
 12279 |       private: 
 12280 |  
 12281 |          std::vector<const T*> arg_list_; 
 12282 |          bool initialised_; 
 12283 |       }; 
 12284 |  
 12285 |       template <typename T, typename VecFunction> 
 12286 |       class vectorize_node exprtk_final : public expression_node<T> 
 12287 |       { 
 12288 |       public: 
 12289 |  
 12290 |          typedef expression_node<T>* expression_ptr; 
 12291 |          typedef std::pair<expression_ptr,bool> branch_t; 
 12292 |  
 12293 |          explicit vectorize_node(const expression_ptr v) 
 12294 |          : ivec_ptr_(0) 
 12295 |          { 
 12296 |             construct_branch_pair(v_, v); 
 12297 |  
 12298 |             if (is_ivector_node(v_.first)) 
 12299 |             { 
 12300 |                ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v_.first); 
 12301 |             } 
 12302 |          } 
 12303 |  
 12304 |          inline T value() const exprtk_override 
 12305 |          { 
 12306 |             v_.first->value(); 
 12307 |             return VecFunction::process(ivec_ptr_); 
 12308 |          } 
 12309 |  
 12310 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12311 |          { 
 12312 |             return expression_node<T>::e_vecfunc; 
 12313 |          } 
 12314 |  
 12315 |          inline bool valid() const exprtk_override 
 12316 |          { 
 12317 |             return ivec_ptr_ && v_.first && v_.first->valid(); 
 12318 |          } 
 12319 |  
 12320 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 12321 |          { 
 12322 |             expression_node<T>::ndb_t::collect(v_, node_delete_list); 
 12323 |          } 
 12324 |  
 12325 |          std::size_t node_depth() const exprtk_override 
 12326 |          { 
 12327 |             return expression_node<T>::ndb_t::compute_node_depth(v_); 
 12328 |          } 
 12329 |  
 12330 |       private: 
 12331 |  
 12332 |          vector_interface<T>* ivec_ptr_; 
 12333 |          branch_t                    v_; 
 12334 |       }; 
 12335 |  
 12336 |       template <typename T> 
 12337 |       class assignment_node exprtk_final : public binary_node<T> 
 12338 |       { 
 12339 |       public: 
 12340 |  
 12341 |          typedef expression_node<T>* expression_ptr; 
 12342 |          using binary_node<T>::branch; 
 12343 |  
 12344 |          assignment_node(const operator_type& opr, 
 12345 |                          expression_ptr branch0, 
 12346 |                          expression_ptr branch1) 
 12347 |          : binary_node<T>(opr, branch0, branch1) 
 12348 |          , var_node_ptr_(0) 
 12349 |          { 
 12350 |             if (is_variable_node(branch(0))) 
 12351 |             { 
 12352 |                var_node_ptr_ = static_cast<variable_node<T>*>(branch(0)); 
 12353 |             } 
 12354 |          } 
 12355 |  
 12356 |          inline T value() const exprtk_override 
 12357 |          { 
 12358 |             T& result = var_node_ptr_->ref(); 
 12359 |                result = branch(1)->value(); 
 12360 |  
 12361 |             return result; 
 12362 |          } 
 12363 |  
 12364 |          inline bool valid() const exprtk_override 
 12365 |          { 
 12366 |             return var_node_ptr_ && binary_node<T>::valid(); 
 12367 |          } 
 12368 |  
 12369 |       private: 
 12370 |  
 12371 |          variable_node<T>* var_node_ptr_; 
 12372 |       }; 
 12373 |  
 12374 |       template <typename T> 
 12375 |       class assignment_vec_elem_node exprtk_final : public binary_node<T> 
 12376 |       { 
 12377 |       public: 
 12378 |  
 12379 |          typedef expression_node<T>* expression_ptr; 
 12380 |          using binary_node<T>::branch; 
 12381 |  
 12382 |          assignment_vec_elem_node(const operator_type& opr, 
 12383 |                                   expression_ptr branch0, 
 12384 |                                   expression_ptr branch1) 
 12385 |          : binary_node<T>(opr, branch0, branch1) 
 12386 |          , vec_node_ptr_(0) 
 12387 |          { 
 12388 |             if (is_vector_elem_node(branch(0))) 
 12389 |             { 
 12390 |                vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0)); 
 12391 |             } 
 12392 |  
 12393 |             assert(valid()); 
 12394 |          } 
 12395 |  
 12396 |          inline T value() const exprtk_override 
 12397 |          { 
 12398 |             T& result = vec_node_ptr_->ref(); 
 12399 |                result = branch(1)->value(); 
 12400 |  
 12401 |             return result; 
 12402 |          } 
 12403 |  
 12404 |          inline bool valid() const exprtk_override 
 12405 |          { 
 12406 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12407 |          } 
 12408 |  
 12409 |       private: 
 12410 |  
 12411 |          vector_elem_node<T>* vec_node_ptr_; 
 12412 |       }; 
 12413 |  
 12414 |       template <typename T> 
 12415 |       class assignment_vec_elem_rtc_node exprtk_final : public binary_node<T> 
 12416 |       { 
 12417 |       public: 
 12418 |  
 12419 |          typedef expression_node<T>* expression_ptr; 
 12420 |          using binary_node<T>::branch; 
 12421 |  
 12422 |          assignment_vec_elem_rtc_node(const operator_type& opr, 
 12423 |                                       expression_ptr branch0, 
 12424 |                                       expression_ptr branch1) 
 12425 |          : binary_node<T>(opr, branch0, branch1) 
 12426 |          , vec_node_ptr_(0) 
 12427 |          { 
 12428 |             if (is_vector_elem_rtc_node(branch(0))) 
 12429 |             { 
 12430 |                vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0)); 
 12431 |             } 
 12432 |  
 12433 |             assert(valid()); 
 12434 |          } 
 12435 |  
 12436 |          inline T value() const exprtk_override 
 12437 |          { 
 12438 |             T& result = vec_node_ptr_->ref(); 
 12439 |                result = branch(1)->value(); 
 12440 |  
 12441 |             return result; 
 12442 |          } 
 12443 |  
 12444 |          inline bool valid() const exprtk_override 
 12445 |          { 
 12446 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12447 |          } 
 12448 |  
 12449 |       private: 
 12450 |  
 12451 |          vector_elem_rtc_node<T>* vec_node_ptr_; 
 12452 |       }; 
 12453 |  
 12454 |       template <typename T> 
 12455 |       class assignment_rebasevec_elem_node exprtk_final : public binary_node<T> 
 12456 |       { 
 12457 |       public: 
 12458 |  
 12459 |          typedef expression_node<T>* expression_ptr; 
 12460 |          using expression_node<T>::branch; 
 12461 |  
 12462 |          assignment_rebasevec_elem_node(const operator_type& opr, 
 12463 |                                         expression_ptr branch0, 
 12464 |                                         expression_ptr branch1) 
 12465 |          : binary_node<T>(opr, branch0, branch1) 
 12466 |          , rbvec_node_ptr_(0) 
 12467 |          { 
 12468 |             if (is_rebasevector_elem_node(branch(0))) 
 12469 |             { 
 12470 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0)); 
 12471 |             } 
 12472 |  
 12473 |             assert(valid()); 
 12474 |          } 
 12475 |  
 12476 |          inline T value() const exprtk_override 
 12477 |          { 
 12478 |             T& result = rbvec_node_ptr_->ref(); 
 12479 |                result = branch(1)->value(); 
 12480 |  
 12481 |             return result; 
 12482 |          } 
 12483 |  
 12484 |          inline bool valid() const exprtk_override 
 12485 |          { 
 12486 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 12487 |          } 
 12488 |  
 12489 |       private: 
 12490 |  
 12491 |          rebasevector_elem_node<T>* rbvec_node_ptr_; 
 12492 |       }; 
 12493 |  
 12494 |       template <typename T> 
 12495 |       class assignment_rebasevec_elem_rtc_node exprtk_final : public binary_node<T> 
 12496 |       { 
 12497 |       public: 
 12498 |  
 12499 |          typedef expression_node<T>* expression_ptr; 
 12500 |          using expression_node<T>::branch; 
 12501 |  
 12502 |          assignment_rebasevec_elem_rtc_node(const operator_type& opr, 
 12503 |                                             expression_ptr branch0, 
 12504 |                                             expression_ptr branch1) 
 12505 |          : binary_node<T>(opr, branch0, branch1) 
 12506 |          , rbvec_node_ptr_(0) 
 12507 |          { 
 12508 |             if (is_rebasevector_elem_rtc_node(branch(0))) 
 12509 |             { 
 12510 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0)); 
 12511 |             } 
 12512 |  
 12513 |             assert(valid()); 
 12514 |          } 
 12515 |  
 12516 |          inline T value() const exprtk_override 
 12517 |          { 
 12518 |             T& result = rbvec_node_ptr_->ref(); 
 12519 |                result = branch(1)->value(); 
 12520 |  
 12521 |             return result; 
 12522 |          } 
 12523 |  
 12524 |          inline bool valid() const exprtk_override 
 12525 |          { 
 12526 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 12527 |          } 
 12528 |  
 12529 |       private: 
 12530 |  
 12531 |          rebasevector_elem_rtc_node<T>* rbvec_node_ptr_; 
 12532 |       }; 
 12533 |  
 12534 |       template <typename T> 
 12535 |       class assignment_rebasevec_celem_node exprtk_final : public binary_node<T> 
 12536 |       { 
 12537 |       public: 
 12538 |  
 12539 |          typedef expression_node<T>* expression_ptr; 
 12540 |          using binary_node<T>::branch; 
 12541 |  
 12542 |          assignment_rebasevec_celem_node(const operator_type& opr, 
 12543 |                                          expression_ptr branch0, 
 12544 |                                          expression_ptr branch1) 
 12545 |          : binary_node<T>(opr, branch0, branch1) 
 12546 |          , rbvec_node_ptr_(0) 
 12547 |          { 
 12548 |             if (is_rebasevector_celem_node(branch(0))) 
 12549 |             { 
 12550 |                rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0)); 
 12551 |             } 
 12552 |  
 12553 |             assert(valid()); 
 12554 |          } 
 12555 |  
 12556 |          inline T value() const exprtk_override 
 12557 |          { 
 12558 |             T& result = rbvec_node_ptr_->ref(); 
 12559 |                result = branch(1)->value(); 
 12560 |  
 12561 |             return result; 
 12562 |          } 
 12563 |  
 12564 |          inline bool valid() const exprtk_override 
 12565 |          { 
 12566 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 12567 |          } 
 12568 |  
 12569 |       private: 
 12570 |  
 12571 |          rebasevector_celem_node<T>* rbvec_node_ptr_; 
 12572 |       }; 
 12573 |  
 12574 |       template <typename T> 
 12575 |       class assignment_vec_node exprtk_final 
 12576 |                                 : public binary_node     <T> 
 12577 |                                 , public vector_interface<T> 
 12578 |       { 
 12579 |       public: 
 12580 |  
 12581 |          typedef expression_node<T>* expression_ptr; 
 12582 |          typedef vector_node<T>*     vector_node_ptr; 
 12583 |          typedef vec_data_store<T>   vds_t; 
 12584 |  
 12585 |          using binary_node<T>::branch; 
 12586 |  
 12587 |          assignment_vec_node(const operator_type& opr, 
 12588 |                              expression_ptr branch0, 
 12589 |                              expression_ptr branch1) 
 12590 |          : binary_node<T>(opr, branch0, branch1) 
 12591 |          , vec_node_ptr_(0) 
 12592 |          { 
 12593 |             if (is_vector_node(branch(0))) 
 12594 |             { 
 12595 |                vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 12596 |                vds()         = vec_node_ptr_->vds(); 
 12597 |             } 
 12598 |  
 12599 |             assert(valid()); 
 12600 |          } 
 12601 |  
 12602 |          inline T value() const exprtk_override 
 12603 |          { 
 12604 |             const T v = branch(1)->value(); 
 12605 |  
 12606 |             T* vec = vds().data(); 
 12607 |  
 12608 |             loop_unroll::details lud(size()); 
 12609 |             const T* upper_bound = vec + lud.upper_bound; 
 12610 |  
 12611 |             while (vec < upper_bound) 
 12612 |             { 
 12613 |                #define exprtk_loop(N) \ 
 12614 |                vec[N] = v;            \ 
 12615 |  
 12616 |                exprtk_loop( 0) exprtk_loop( 1) 
 12617 |                exprtk_loop( 2) exprtk_loop( 3) 
 12618 |                #ifndef exprtk_disable_superscalar_unroll 
 12619 |                exprtk_loop( 4) exprtk_loop( 5) 
 12620 |                exprtk_loop( 6) exprtk_loop( 7) 
 12621 |                exprtk_loop( 8) exprtk_loop( 9) 
 12622 |                exprtk_loop(10) exprtk_loop(11) 
 12623 |                exprtk_loop(12) exprtk_loop(13) 
 12624 |                exprtk_loop(14) exprtk_loop(15) 
 12625 |                #endif 
 12626 |  
 12627 |                vec += lud.batch_size; 
 12628 |             } 
 12629 |  
 12630 |             switch (lud.remainder) 
 12631 |             { 
 12632 |                #define case_stmt(N) \ 
 12633 |                case N : *vec++ = v; \ 
 12634 |                exprtk_fallthrough   \ 
 12635 |  
 12636 |                #ifndef exprtk_disable_superscalar_unroll 
 12637 |                case_stmt(15) case_stmt(14) 
 12638 |                case_stmt(13) case_stmt(12) 
 12639 |                case_stmt(11) case_stmt(10) 
 12640 |                case_stmt( 9) case_stmt( 8) 
 12641 |                case_stmt( 7) case_stmt( 6) 
 12642 |                case_stmt( 5) case_stmt( 4) 
 12643 |                #endif 
 12644 |                case_stmt( 3) case_stmt( 2) 
 12645 |                case 1 : *vec++ = v; 
 12646 |             } 
 12647 |  
 12648 |             #undef exprtk_loop 
 12649 |             #undef case_stmt 
 12650 |  
 12651 |             return vec_node_ptr_->value(); 
 12652 |          } 
 12653 |  
 12654 |          vector_node_ptr vec() const exprtk_override 
 12655 |          { 
 12656 |             return vec_node_ptr_; 
 12657 |          } 
 12658 |  
 12659 |          vector_node_ptr vec() exprtk_override 
 12660 |          { 
 12661 |             return vec_node_ptr_; 
 12662 |          } 
 12663 |  
 12664 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12665 |          { 
 12666 |             return expression_node<T>::e_vecvalass; 
 12667 |          } 
 12668 |  
 12669 |          inline bool valid() const exprtk_override 
 12670 |          { 
 12671 |             return 
 12672 |                vec_node_ptr_ && 
 12673 |                (vds().size() <= vec_node_ptr_->vec_holder().base_size()) && 
 12674 |                binary_node<T>::valid(); 
 12675 |          } 
 12676 |  
 12677 |          std::size_t size() const exprtk_override 
 12678 |          { 
 12679 |             return vec_node_ptr_->vec_holder().size(); 
 12680 |          } 
 12681 |  
 12682 |          std::size_t base_size() const exprtk_override 
 12683 |          { 
 12684 |             return vec_node_ptr_->vec_holder().base_size(); 
 12685 |          } 
 12686 |  
 12687 |          vds_t& vds() exprtk_override 
 12688 |          { 
 12689 |             return vds_; 
 12690 |          } 
 12691 |  
 12692 |          const vds_t& vds() const exprtk_override 
 12693 |          { 
 12694 |             return vds_; 
 12695 |          } 
 12696 |  
 12697 |       private: 
 12698 |  
 12699 |          vector_node<T>* vec_node_ptr_; 
 12700 |          vds_t           vds_; 
 12701 |       }; 
 12702 |  
 12703 |       template <typename T> 
 12704 |       class assignment_vecvec_node exprtk_final 
 12705 |                                    : public binary_node     <T> 
 12706 |                                    , public vector_interface<T> 
 12707 |       { 
 12708 |       public: 
 12709 |  
 12710 |          typedef expression_node<T>* expression_ptr; 
 12711 |          typedef vector_node<T>*     vector_node_ptr; 
 12712 |          typedef vec_data_store<T>   vds_t; 
 12713 |  
 12714 |          using binary_node<T>::branch; 
 12715 |  
 12716 |          assignment_vecvec_node(const operator_type& opr, 
 12717 |                                 expression_ptr branch0, 
 12718 |                                 expression_ptr branch1) 
 12719 |          : binary_node<T>(opr, branch0, branch1) 
 12720 |          , vec0_node_ptr_(0) 
 12721 |          , vec1_node_ptr_(0) 
 12722 |          , initialised_(false) 
 12723 |          , src_is_ivec_(false) 
 12724 |          { 
 12725 |             if (is_vector_node(branch(0))) 
 12726 |             { 
 12727 |                vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 12728 |                vds()          = vec0_node_ptr_->vds(); 
 12729 |             } 
 12730 |  
 12731 |             if (is_vector_node(branch(1))) 
 12732 |             { 
 12733 |                vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1)); 
 12734 |                vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); 
 12735 |             } 
 12736 |             else if (is_ivector_node(branch(1))) 
 12737 |             { 
 12738 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 12739 |  
 12740 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 12741 |                { 
 12742 |                   vec1_node_ptr_ = vi->vec(); 
 12743 |  
 12744 |                   if (!vi->side_effect()) 
 12745 |                   { 
 12746 |                      vi->vds()    = vds(); 
 12747 |                      src_is_ivec_ = true; 
 12748 |                   } 
 12749 |                   else 
 12750 |                      vds_t::match_sizes(vds(),vi->vds()); 
 12751 |                } 
 12752 |             } 
 12753 |  
 12754 |             initialised_ = 
 12755 |                vec0_node_ptr_               && 
 12756 |                vec1_node_ptr_               && 
 12757 |                (size() <= base_size())      && 
 12758 |                (vds_.size() <= base_size()) && 
 12759 |                binary_node<T>::valid(); 
 12760 |  
 12761 |             assert(valid()); 
 12762 |          } 
 12763 |  
 12764 |          inline T value() const exprtk_override 
 12765 |          { 
 12766 |             branch(1)->value(); 
 12767 |  
 12768 |             if (src_is_ivec_) 
 12769 |                return vec0_node_ptr_->value(); 
 12770 |  
 12771 |             T* vec0 = vec0_node_ptr_->vds().data(); 
 12772 |             T* vec1 = vec1_node_ptr_->vds().data(); 
 12773 |  
 12774 |             loop_unroll::details lud(size()); 
 12775 |             const T* upper_bound = vec0 + lud.upper_bound; 
 12776 |  
 12777 |             while (vec0 < upper_bound) 
 12778 |             { 
 12779 |                #define exprtk_loop(N) \ 
 12780 |                vec0[N] = vec1[N];     \ 
 12781 |  
 12782 |                exprtk_loop( 0) exprtk_loop( 1) 
 12783 |                exprtk_loop( 2) exprtk_loop( 3) 
 12784 |                #ifndef exprtk_disable_superscalar_unroll 
 12785 |                exprtk_loop( 4) exprtk_loop( 5) 
 12786 |                exprtk_loop( 6) exprtk_loop( 7) 
 12787 |                exprtk_loop( 8) exprtk_loop( 9) 
 12788 |                exprtk_loop(10) exprtk_loop(11) 
 12789 |                exprtk_loop(12) exprtk_loop(13) 
 12790 |                exprtk_loop(14) exprtk_loop(15) 
 12791 |                #endif 
 12792 |  
 12793 |                vec0 += lud.batch_size; 
 12794 |                vec1 += lud.batch_size; 
 12795 |             } 
 12796 |  
 12797 |             switch (lud.remainder) 
 12798 |             { 
 12799 |                #define case_stmt(N,fall_through) \ 
 12800 |                case N : *vec0++ = *vec1++;       \ 
 12801 |                fall_through                      \ 
 12802 |  
 12803 |                #ifndef exprtk_disable_superscalar_unroll 
 12804 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 12805 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 12806 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 12807 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 12808 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 12809 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 12810 |                #endif 
 12811 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 12812 |                case_stmt( 1, (void)0;) 
 12813 |             } 
 12814 |  
 12815 |             #undef exprtk_loop 
 12816 |             #undef case_stmt 
 12817 |  
 12818 |             return vec0_node_ptr_->value(); 
 12819 |          } 
 12820 |  
 12821 |          vector_node_ptr vec() exprtk_override 
 12822 |          { 
 12823 |             return vec0_node_ptr_; 
 12824 |          } 
 12825 |  
 12826 |          vector_node_ptr vec() const exprtk_override 
 12827 |          { 
 12828 |             return vec0_node_ptr_; 
 12829 |          } 
 12830 |  
 12831 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12832 |          { 
 12833 |             return expression_node<T>::e_vecvecass; 
 12834 |          } 
 12835 |  
 12836 |          inline bool valid() const exprtk_override 
 12837 |          { 
 12838 |             return initialised_; 
 12839 |          } 
 12840 |  
 12841 |          std::size_t size() const exprtk_override 
 12842 |          { 
 12843 |             return std::min( 
 12844 |                vec0_node_ptr_->vec_holder().size(), 
 12845 |                vec1_node_ptr_->vec_holder().size()); 
 12846 |          } 
 12847 |  
 12848 |          std::size_t base_size() const exprtk_override 
 12849 |          { 
 12850 |             return std::min( 
 12851 |                vec0_node_ptr_->vec_holder().base_size(), 
 12852 |                vec1_node_ptr_->vec_holder().base_size()); 
 12853 |          } 
 12854 |  
 12855 |          vds_t& vds() exprtk_override 
 12856 |          { 
 12857 |             return vds_; 
 12858 |          } 
 12859 |  
 12860 |          const vds_t& vds() const exprtk_override 
 12861 |          { 
 12862 |             return vds_; 
 12863 |          } 
 12864 |  
 12865 |       private: 
 12866 |  
 12867 |          vector_node<T>* vec0_node_ptr_; 
 12868 |          vector_node<T>* vec1_node_ptr_; 
 12869 |          bool            initialised_; 
 12870 |          bool            src_is_ivec_; 
 12871 |          vds_t           vds_; 
 12872 |       }; 
 12873 |  
 12874 |       template <typename T, typename Operation> 
 12875 |       class assignment_op_node exprtk_final : public binary_node<T> 
 12876 |       { 
 12877 |       public: 
 12878 |  
 12879 |          typedef expression_node<T>* expression_ptr; 
 12880 |          using binary_node<T>::branch; 
 12881 |  
 12882 |          assignment_op_node(const operator_type& opr, 
 12883 |                             expression_ptr branch0, 
 12884 |                             expression_ptr branch1) 
 12885 |          : binary_node<T>(opr, branch0, branch1) 
 12886 |          , var_node_ptr_(0) 
 12887 |          { 
 12888 |             if (is_variable_node(branch(0))) 
 12889 |             { 
 12890 |                var_node_ptr_ = static_cast<variable_node<T>*>(branch(0)); 
 12891 |             } 
 12892 |  
 12893 |             assert(valid()); 
 12894 |          } 
 12895 |  
 12896 |          inline T value() const exprtk_override 
 12897 |          { 
 12898 |             T& v = var_node_ptr_->ref(); 
 12899 |             v = Operation::process(v,branch(1)->value()); 
 12900 |  
 12901 |             return v; 
 12902 |          } 
 12903 |  
 12904 |          inline bool valid() const exprtk_override 
 12905 |          { 
 12906 |             return var_node_ptr_ && binary_node<T>::valid(); 
 12907 |          } 
 12908 |  
 12909 |       private: 
 12910 |  
 12911 |          variable_node<T>* var_node_ptr_; 
 12912 |       }; 
 12913 |  
 12914 |       template <typename T, typename Operation> 
 12915 |       class assignment_vec_elem_op_node exprtk_final : public binary_node<T> 
 12916 |       { 
 12917 |       public: 
 12918 |  
 12919 |          typedef expression_node<T>* expression_ptr; 
 12920 |          using binary_node<T>::branch; 
 12921 |  
 12922 |          assignment_vec_elem_op_node(const operator_type& opr, 
 12923 |                                      expression_ptr branch0, 
 12924 |                                      expression_ptr branch1) 
 12925 |          : binary_node<T>(opr, branch0, branch1) 
 12926 |          , vec_node_ptr_(0) 
 12927 |          { 
 12928 |             if (is_vector_elem_node(branch(0))) 
 12929 |             { 
 12930 |                vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0)); 
 12931 |             } 
 12932 |  
 12933 |             assert(valid()); 
 12934 |          } 
 12935 |  
 12936 |          inline T value() const exprtk_override 
 12937 |          { 
 12938 |             T& v = vec_node_ptr_->ref(); 
 12939 |                v = Operation::process(v,branch(1)->value()); 
 12940 |  
 12941 |             return v; 
 12942 |          } 
 12943 |  
 12944 |          inline bool valid() const exprtk_override 
 12945 |          { 
 12946 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12947 |          } 
 12948 |  
 12949 |       private: 
 12950 |  
 12951 |          vector_elem_node<T>* vec_node_ptr_; 
 12952 |       }; 
 12953 |  
 12954 |       template <typename T, typename Operation> 
 12955 |       class assignment_vec_elem_op_rtc_node exprtk_final : public binary_node<T> 
 12956 |       { 
 12957 |       public: 
 12958 |  
 12959 |          typedef expression_node<T>* expression_ptr; 
 12960 |          using binary_node<T>::branch; 
 12961 |  
 12962 |          assignment_vec_elem_op_rtc_node(const operator_type& opr, 
 12963 |                                          expression_ptr branch0, 
 12964 |                                          expression_ptr branch1) 
 12965 |          : binary_node<T>(opr, branch0, branch1) 
 12966 |          , vec_node_ptr_(0) 
 12967 |          { 
 12968 |             if (is_vector_elem_rtc_node(branch(0))) 
 12969 |             { 
 12970 |                vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0)); 
 12971 |             } 
 12972 |  
 12973 |             assert(valid()); 
 12974 |          } 
 12975 |  
 12976 |          inline T value() const exprtk_override 
 12977 |          { 
 12978 |             T& v = vec_node_ptr_->ref(); 
 12979 |                v = Operation::process(v,branch(1)->value()); 
 12980 |  
 12981 |             return v; 
 12982 |          } 
 12983 |  
 12984 |          inline bool valid() const exprtk_override 
 12985 |          { 
 12986 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12987 |          } 
 12988 |  
 12989 |       private: 
 12990 |  
 12991 |          vector_elem_rtc_node<T>* vec_node_ptr_; 
 12992 |       }; 
 12993 |  
 12994 |       template <typename T, typename Operation> 
 12995 |       class assignment_vec_celem_op_rtc_node exprtk_final : public binary_node<T> 
 12996 |       { 
 12997 |       public: 
 12998 |  
 12999 |          typedef expression_node<T>* expression_ptr; 
 13000 |          using binary_node<T>::branch; 
 13001 |  
 13002 |          assignment_vec_celem_op_rtc_node(const operator_type& opr, 
 13003 |                                           expression_ptr branch0, 
 13004 |                                           expression_ptr branch1) 
 13005 |          : binary_node<T>(opr, branch0, branch1) 
 13006 |          , vec_node_ptr_(0) 
 13007 |          { 
 13008 |             if (is_vector_celem_rtc_node(branch(0))) 
 13009 |             { 
 13010 |                vec_node_ptr_ = static_cast<vector_celem_rtc_node<T>*>(branch(0)); 
 13011 |             } 
 13012 |  
 13013 |             assert(valid()); 
 13014 |          } 
 13015 |  
 13016 |          inline T value() const exprtk_override 
 13017 |          { 
 13018 |             T& v = vec_node_ptr_->ref(); 
 13019 |                v = Operation::process(v,branch(1)->value()); 
 13020 |  
 13021 |             return v; 
 13022 |          } 
 13023 |  
 13024 |          inline bool valid() const exprtk_override 
 13025 |          { 
 13026 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 13027 |          } 
 13028 |  
 13029 |       private: 
 13030 |  
 13031 |          vector_celem_rtc_node<T>* vec_node_ptr_; 
 13032 |       }; 
 13033 |  
 13034 |       template <typename T, typename Operation> 
 13035 |       class assignment_rebasevec_elem_op_node exprtk_final : public binary_node<T> 
 13036 |       { 
 13037 |       public: 
 13038 |  
 13039 |          typedef expression_node<T>* expression_ptr; 
 13040 |          using binary_node<T>::branch; 
 13041 |  
 13042 |          assignment_rebasevec_elem_op_node(const operator_type& opr, 
 13043 |                                            expression_ptr branch0, 
 13044 |                                            expression_ptr branch1) 
 13045 |          : binary_node<T>(opr, branch0, branch1) 
 13046 |          , rbvec_node_ptr_(0) 
 13047 |          { 
 13048 |             if (is_rebasevector_elem_node(branch(0))) 
 13049 |             { 
 13050 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0)); 
 13051 |             } 
 13052 |  
 13053 |             assert(valid()); 
 13054 |          } 
 13055 |  
 13056 |          inline T value() const exprtk_override 
 13057 |          { 
 13058 |             T& v = rbvec_node_ptr_->ref(); 
 13059 |                v = Operation::process(v,branch(1)->value()); 
 13060 |  
 13061 |             return v; 
 13062 |          } 
 13063 |  
 13064 |          inline bool valid() const exprtk_override 
 13065 |          { 
 13066 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13067 |          } 
 13068 |  
 13069 |       private: 
 13070 |  
 13071 |          rebasevector_elem_node<T>* rbvec_node_ptr_; 
 13072 |       }; 
 13073 |  
 13074 |       template <typename T, typename Operation> 
 13075 |       class assignment_rebasevec_celem_op_node exprtk_final : public binary_node<T> 
 13076 |       { 
 13077 |       public: 
 13078 |  
 13079 |          typedef expression_node<T>* expression_ptr; 
 13080 |          using binary_node<T>::branch; 
 13081 |  
 13082 |          assignment_rebasevec_celem_op_node(const operator_type& opr, 
 13083 |                                             expression_ptr branch0, 
 13084 |                                             expression_ptr branch1) 
 13085 |          : binary_node<T>(opr, branch0, branch1) 
 13086 |          , rbvec_node_ptr_(0) 
 13087 |          { 
 13088 |             if (is_rebasevector_celem_node(branch(0))) 
 13089 |             { 
 13090 |                rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0)); 
 13091 |             } 
 13092 |  
 13093 |             assert(valid()); 
 13094 |          } 
 13095 |  
 13096 |          inline T value() const exprtk_override 
 13097 |          { 
 13098 |             T& v = rbvec_node_ptr_->ref(); 
 13099 |                v = Operation::process(v,branch(1)->value()); 
 13100 |  
 13101 |             return v; 
 13102 |          } 
 13103 |  
 13104 |          inline bool valid() const exprtk_override 
 13105 |          { 
 13106 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13107 |          } 
 13108 |  
 13109 |       private: 
 13110 |  
 13111 |          rebasevector_celem_node<T>* rbvec_node_ptr_; 
 13112 |       }; 
 13113 |  
 13114 |       template <typename T, typename Operation> 
 13115 |       class assignment_rebasevec_elem_op_rtc_node exprtk_final : public binary_node<T> 
 13116 |       { 
 13117 |       public: 
 13118 |  
 13119 |          typedef expression_node<T>* expression_ptr; 
 13120 |          using binary_node<T>::branch; 
 13121 |  
 13122 |          assignment_rebasevec_elem_op_rtc_node(const operator_type& opr, 
 13123 |                                                expression_ptr branch0, 
 13124 |                                                expression_ptr branch1) 
 13125 |          : binary_node<T>(opr, branch0, branch1) 
 13126 |          , rbvec_node_ptr_(0) 
 13127 |          { 
 13128 |             if (is_rebasevector_elem_rtc_node(branch(0))) 
 13129 |             { 
 13130 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0)); 
 13131 |             } 
 13132 |  
 13133 |             assert(valid()); 
 13134 |          } 
 13135 |  
 13136 |          inline T value() const exprtk_override 
 13137 |          { 
 13138 |             T& v = rbvec_node_ptr_->ref(); 
 13139 |                v = Operation::process(v,branch(1)->value()); 
 13140 |  
 13141 |             return v; 
 13142 |          } 
 13143 |  
 13144 |          inline bool valid() const exprtk_override 
 13145 |          { 
 13146 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13147 |          } 
 13148 |  
 13149 |       private: 
 13150 |  
 13151 |          rebasevector_elem_rtc_node<T>* rbvec_node_ptr_; 
 13152 |       }; 
 13153 |  
 13154 |       template <typename T, typename Operation> 
 13155 |       class assignment_rebasevec_celem_op_rtc_node exprtk_final : public binary_node<T> 
 13156 |       { 
 13157 |       public: 
 13158 |  
 13159 |          typedef expression_node<T>* expression_ptr; 
 13160 |          using binary_node<T>::branch; 
 13161 |  
 13162 |          assignment_rebasevec_celem_op_rtc_node(const operator_type& opr, 
 13163 |                                                 expression_ptr branch0, 
 13164 |                                                 expression_ptr branch1) 
 13165 |          : binary_node<T>(opr, branch0, branch1) 
 13166 |          , rbvec_node_ptr_(0) 
 13167 |          { 
 13168 |             if (is_rebasevector_celem_rtc_node(branch(0))) 
 13169 |             { 
 13170 |                rbvec_node_ptr_ = static_cast<rebasevector_celem_rtc_node<T>*>(branch(0)); 
 13171 |             } 
 13172 |  
 13173 |             assert(valid()); 
 13174 |          } 
 13175 |  
 13176 |          inline T value() const exprtk_override 
 13177 |          { 
 13178 |             T& v = rbvec_node_ptr_->ref(); 
 13179 |                v = Operation::process(v,branch(1)->value()); 
 13180 |  
 13181 |             return v; 
 13182 |          } 
 13183 |  
 13184 |          inline bool valid() const exprtk_override 
 13185 |          { 
 13186 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13187 |          } 
 13188 |  
 13189 |       private: 
 13190 |  
 13191 |          rebasevector_celem_rtc_node<T>* rbvec_node_ptr_; 
 13192 |       }; 
 13193 |  
 13194 |       template <typename T, typename Operation> 
 13195 |       class assignment_vec_op_node exprtk_final 
 13196 |                                    : public binary_node     <T> 
 13197 |                                    , public vector_interface<T> 
 13198 |       { 
 13199 |       public: 
 13200 |  
 13201 |          typedef expression_node<T>* expression_ptr; 
 13202 |          typedef vector_node<T>*     vector_node_ptr; 
 13203 |          typedef vec_data_store<T>   vds_t; 
 13204 |  
 13205 |          using binary_node<T>::branch; 
 13206 |  
 13207 |          assignment_vec_op_node(const operator_type& opr, 
 13208 |                                 expression_ptr branch0, 
 13209 |                                 expression_ptr branch1) 
 13210 |          : binary_node<T>(opr, branch0, branch1) 
 13211 |          , vec_node_ptr_(0) 
 13212 |          { 
 13213 |             if (is_vector_node(branch(0))) 
 13214 |             { 
 13215 |                vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 13216 |                vds()         = vec_node_ptr_->vds(); 
 13217 |             } 
 13218 |  
 13219 |             assert(valid()); 
 13220 |          } 
 13221 |  
 13222 |          inline T value() const exprtk_override 
 13223 |          { 
 13224 |             const T v = branch(1)->value(); 
 13225 |  
 13226 |             T* vec = vds().data(); 
 13227 |  
 13228 |             loop_unroll::details lud(size()); 
 13229 |             const T* upper_bound = vec + lud.upper_bound; 
 13230 |  
 13231 |             while (vec < upper_bound) 
 13232 |             { 
 13233 |                #define exprtk_loop(N)       \ 
 13234 |                Operation::assign(vec[N],v); \ 
 13235 |  
 13236 |                exprtk_loop( 0) exprtk_loop( 1) 
 13237 |                exprtk_loop( 2) exprtk_loop( 3) 
 13238 |                #ifndef exprtk_disable_superscalar_unroll 
 13239 |                exprtk_loop( 4) exprtk_loop( 5) 
 13240 |                exprtk_loop( 6) exprtk_loop( 7) 
 13241 |                exprtk_loop( 8) exprtk_loop( 9) 
 13242 |                exprtk_loop(10) exprtk_loop(11) 
 13243 |                exprtk_loop(12) exprtk_loop(13) 
 13244 |                exprtk_loop(14) exprtk_loop(15) 
 13245 |                #endif 
 13246 |  
 13247 |                vec += lud.batch_size; 
 13248 |             } 
 13249 |  
 13250 |             switch (lud.remainder) 
 13251 |             { 
 13252 |                #define case_stmt(N,fall_through)     \ 
 13253 |                case N : Operation::assign(*vec++,v); \ 
 13254 |                fall_through                          \ 
 13255 |  
 13256 |                #ifndef exprtk_disable_superscalar_unroll 
 13257 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 13258 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 13259 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 13260 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 13261 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 13262 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 13263 |                #endif 
 13264 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 13265 |                case_stmt( 1, (void)0;) 
 13266 |             } 
 13267 |  
 13268 |             #undef exprtk_loop 
 13269 |             #undef case_stmt 
 13270 |  
 13271 |             return vec_node_ptr_->value(); 
 13272 |          } 
 13273 |  
 13274 |          vector_node_ptr vec() const exprtk_override 
 13275 |          { 
 13276 |             return vec_node_ptr_; 
 13277 |          } 
 13278 |  
 13279 |          vector_node_ptr vec() exprtk_override 
 13280 |          { 
 13281 |             return vec_node_ptr_; 
 13282 |          } 
 13283 |  
 13284 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13285 |          { 
 13286 |             return expression_node<T>::e_vecopvalass; 
 13287 |          } 
 13288 |  
 13289 |          inline bool valid() const exprtk_override 
 13290 |          { 
 13291 |             return 
 13292 |                vec_node_ptr_           && 
 13293 |                (size() <= base_size()) && 
 13294 |                binary_node<T>::valid() ; 
 13295 |          } 
 13296 |  
 13297 |          std::size_t size() const exprtk_override 
 13298 |          { 
 13299 |             return vec_node_ptr_->vec_holder().size(); 
 13300 |          } 
 13301 |  
 13302 |          std::size_t base_size() const exprtk_override 
 13303 |          { 
 13304 |             return vec_node_ptr_->vec_holder().base_size(); 
 13305 |          } 
 13306 |  
 13307 |          vds_t& vds() exprtk_override 
 13308 |          { 
 13309 |             return vds_; 
 13310 |          } 
 13311 |  
 13312 |          const vds_t& vds() const exprtk_override 
 13313 |          { 
 13314 |             return vds_; 
 13315 |          } 
 13316 |  
 13317 |          bool side_effect() const exprtk_override 
 13318 |          { 
 13319 |             return true; 
 13320 |          } 
 13321 |  
 13322 |       private: 
 13323 |  
 13324 |          vector_node<T>* vec_node_ptr_; 
 13325 |          vds_t           vds_; 
 13326 |       }; 
 13327 |  
 13328 |       template <typename T, typename Operation> 
 13329 |       class assignment_vecvec_op_node exprtk_final 
 13330 |                                       : public binary_node     <T> 
 13331 |                                       , public vector_interface<T> 
 13332 |       { 
 13333 |       public: 
 13334 |  
 13335 |          typedef expression_node<T>* expression_ptr; 
 13336 |          typedef vector_node<T>*     vector_node_ptr; 
 13337 |          typedef vec_data_store<T>   vds_t; 
 13338 |  
 13339 |          using binary_node<T>::branch; 
 13340 |  
 13341 |          assignment_vecvec_op_node(const operator_type& opr, 
 13342 |                                    expression_ptr branch0, 
 13343 |                                    expression_ptr branch1) 
 13344 |          : binary_node<T>(opr, branch0, branch1) 
 13345 |          , vec0_node_ptr_(0) 
 13346 |          , vec1_node_ptr_(0) 
 13347 |          , initialised_(false) 
 13348 |          { 
 13349 |             if (is_vector_node(branch(0))) 
 13350 |             { 
 13351 |                vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 13352 |                vds()          = vec0_node_ptr_->vds(); 
 13353 |             } 
 13354 |  
 13355 |             if (is_vector_node(branch(1))) 
 13356 |             { 
 13357 |                vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1)); 
 13358 |                vec1_node_ptr_->vds() = vds(); 
 13359 |             } 
 13360 |             else if (is_ivector_node(branch(1))) 
 13361 |             { 
 13362 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13363 |  
 13364 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 13365 |                { 
 13366 |                   vec1_node_ptr_ = vi->vec(); 
 13367 |                   vec1_node_ptr_->vds() = vi->vds(); 
 13368 |                } 
 13369 |                else 
 13370 |                   vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); 
 13371 |             } 
 13372 |  
 13373 |             initialised_ = 
 13374 |                vec0_node_ptr_          && 
 13375 |                vec1_node_ptr_          && 
 13376 |                (size() <= base_size()) && 
 13377 |                binary_node<T>::valid(); 
 13378 |  
 13379 |             assert(valid()); 
 13380 |          } 
 13381 |  
 13382 |          inline T value() const exprtk_override 
 13383 |          { 
 13384 |             branch(0)->value(); 
 13385 |             branch(1)->value(); 
 13386 |  
 13387 |                   T* vec0 = vec0_node_ptr_->vds().data(); 
 13388 |             const T* vec1 = vec1_node_ptr_->vds().data(); 
 13389 |  
 13390 |             loop_unroll::details lud(size()); 
 13391 |             const T* upper_bound = vec0 + lud.upper_bound; 
 13392 |  
 13393 |             while (vec0 < upper_bound) 
 13394 |             { 
 13395 |                #define exprtk_loop(N)                          \ 
 13396 |                vec0[N] = Operation::process(vec0[N], vec1[N]); \ 
 13397 |  
 13398 |                exprtk_loop( 0) exprtk_loop( 1) 
 13399 |                exprtk_loop( 2) exprtk_loop( 3) 
 13400 |                #ifndef exprtk_disable_superscalar_unroll 
 13401 |                exprtk_loop( 4) exprtk_loop( 5) 
 13402 |                exprtk_loop( 6) exprtk_loop( 7) 
 13403 |                exprtk_loop( 8) exprtk_loop( 9) 
 13404 |                exprtk_loop(10) exprtk_loop(11) 
 13405 |                exprtk_loop(12) exprtk_loop(13) 
 13406 |                exprtk_loop(14) exprtk_loop(15) 
 13407 |                #endif 
 13408 |  
 13409 |                vec0 += lud.batch_size; 
 13410 |                vec1 += lud.batch_size; 
 13411 |             } 
 13412 |  
 13413 |             int i = 0; 
 13414 |  
 13415 |             switch (lud.remainder) 
 13416 |             { 
 13417 |                #define case_stmt(N,fall_through)                                 \ 
 13418 |                case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ 
 13419 |                fall_through                                                      \ 
 13420 |  
 13421 |                #ifndef exprtk_disable_superscalar_unroll 
 13422 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 13423 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 13424 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 13425 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 13426 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 13427 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 13428 |                #endif 
 13429 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 13430 |                case_stmt( 1, (void)0;) 
 13431 |             } 
 13432 |  
 13433 |             #undef exprtk_loop 
 13434 |             #undef case_stmt 
 13435 |  
 13436 |             return vec0_node_ptr_->value(); 
 13437 |          } 
 13438 |  
 13439 |          vector_node_ptr vec() const exprtk_override 
 13440 |          { 
 13441 |             return vec0_node_ptr_; 
 13442 |          } 
 13443 |  
 13444 |          vector_node_ptr vec() exprtk_override 
 13445 |          { 
 13446 |             return vec0_node_ptr_; 
 13447 |          } 
 13448 |  
 13449 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13450 |          { 
 13451 |             return expression_node<T>::e_vecopvecass; 
 13452 |          } 
 13453 |  
 13454 |          inline bool valid() const exprtk_override 
 13455 |          { 
 13456 |             return initialised_; 
 13457 |          } 
 13458 |  
 13459 |          std::size_t size() const exprtk_override 
 13460 |          { 
 13461 |             return std::min( 
 13462 |                vec0_node_ptr_->vec_holder().size(), 
 13463 |                vec1_node_ptr_->vec_holder().size()); 
 13464 |          } 
 13465 |  
 13466 |          std::size_t base_size() const exprtk_override 
 13467 |          { 
 13468 |             return std::min( 
 13469 |                vec0_node_ptr_->vec_holder().base_size(), 
 13470 |                vec1_node_ptr_->vec_holder().base_size()); 
 13471 |          } 
 13472 |  
 13473 |          vds_t& vds() exprtk_override 
 13474 |          { 
 13475 |             return vds_; 
 13476 |          } 
 13477 |  
 13478 |          const vds_t& vds() const exprtk_override 
 13479 |          { 
 13480 |             return vds_; 
 13481 |          } 
 13482 |  
 13483 |          bool side_effect() const exprtk_override 
 13484 |          { 
 13485 |             return true; 
 13486 |          } 
 13487 |  
 13488 |       private: 
 13489 |  
 13490 |          vector_node<T>* vec0_node_ptr_; 
 13491 |          vector_node<T>* vec1_node_ptr_; 
 13492 |          bool            initialised_; 
 13493 |          vds_t           vds_; 
 13494 |       }; 
 13495 |  
 13496 |       template <typename T> 
 13497 |       struct memory_context_t 
 13498 |       { 
 13499 |          typedef vector_node<T>*  vector_node_ptr; 
 13500 |          typedef vector_holder<T> vector_holder_t; 
 13501 |          typedef vector_holder_t* vector_holder_ptr; 
 13502 |  
 13503 |          memory_context_t() 
 13504 |          : temp_(0) 
 13505 |          , temp_vec_node_(0) 
 13506 |          {} 
 13507 |  
 13508 |          void clear() 
 13509 |          { 
 13510 |             delete temp_vec_node_; 
 13511 |             delete temp_; 
 13512 |          } 
 13513 |  
 13514 |          vector_holder_ptr temp_; 
 13515 |          vector_node_ptr   temp_vec_node_; 
 13516 |       }; 
 13517 |  
 13518 |       template <typename T> 
 13519 |       inline memory_context_t<T> make_memory_context(vector_holder<T>& vec_holder, 
 13520 |                                                      vec_data_store<T>& vds) 
 13521 |       { 
 13522 |          memory_context_t<T> result_ctxt; 
 13523 |          result_ctxt.temp_  = (vec_holder.rebaseable()) ? 
 13524 |                               new vector_holder<T>(vec_holder,vds) : 
 13525 |                               new vector_holder<T>(vds) ; 
 13526 |          result_ctxt.temp_vec_node_ = new vector_node  <T>(vds,result_ctxt.temp_); 
 13527 |          return result_ctxt; 
 13528 |       } 
 13529 |  
 13530 |       template <typename T> 
 13531 |       inline memory_context_t<T> make_memory_context(vector_holder<T>& vec_holder0, 
 13532 |                                                      vector_holder<T>& vec_holder1, 
 13533 |                                                      vec_data_store<T>& vds) 
 13534 |       { 
 13535 |          memory_context_t<T> result_ctxt; 
 13536 |  
 13537 |          if (!vec_holder0.rebaseable() && !vec_holder1.rebaseable()) 
 13538 |             result_ctxt.temp_ = new vector_holder<T>(vds); 
 13539 |          else if (vec_holder0.rebaseable() && !vec_holder1.rebaseable()) 
 13540 |             result_ctxt.temp_ = new vector_holder<T>(vec_holder0,vds); 
 13541 |          else if (!vec_holder0.rebaseable() && vec_holder1.rebaseable()) 
 13542 |             result_ctxt.temp_ = new vector_holder<T>(vec_holder1,vds); 
 13543 |          else 
 13544 |          { 
 13545 |             result_ctxt.temp_ = (vec_holder0.base_size() >= vec_holder1.base_size()) ? 
 13546 |                                 new vector_holder<T>(vec_holder0, vds) : 
 13547 |                                 new vector_holder<T>(vec_holder1, vds) ; 
 13548 |          } 
 13549 |  
 13550 |          result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_); 
 13551 |          return result_ctxt; 
 13552 |       } 
 13553 |  
 13554 |       template <typename T, typename Operation> 
 13555 |       class vec_binop_vecvec_node exprtk_final 
 13556 |                                   : public binary_node     <T> 
 13557 |                                   , public vector_interface<T> 
 13558 |       { 
 13559 |       public: 
 13560 |  
 13561 |          typedef expression_node<T>* expression_ptr; 
 13562 |          typedef vector_node<T>*     vector_node_ptr; 
 13563 |          typedef vector_holder<T>    vector_holder_t; 
 13564 |          typedef vector_holder_t*    vector_holder_ptr; 
 13565 |          typedef vec_data_store<T>   vds_t; 
 13566 |          typedef memory_context_t<T> memory_context; 
 13567 |  
 13568 |          using binary_node<T>::branch; 
 13569 |  
 13570 |          vec_binop_vecvec_node(const operator_type& opr, 
 13571 |                                expression_ptr branch0, 
 13572 |                                expression_ptr branch1) 
 13573 |          : binary_node<T>(opr, branch0, branch1) 
 13574 |          , vec0_node_ptr_(0) 
 13575 |          , vec1_node_ptr_(0) 
 13576 |          , initialised_(false) 
 13577 |          { 
 13578 |             bool v0_is_ivec = false; 
 13579 |             bool v1_is_ivec = false; 
 13580 |  
 13581 |             if (is_vector_node(branch(0))) 
 13582 |             { 
 13583 |                vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); 
 13584 |             } 
 13585 |             else if (is_ivector_node(branch(0))) 
 13586 |             { 
 13587 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13588 |  
 13589 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 13590 |                { 
 13591 |                   vec0_node_ptr_ = vi->vec(); 
 13592 |                   v0_is_ivec     = true; 
 13593 |                } 
 13594 |             } 
 13595 |  
 13596 |             if (is_vector_node(branch(1))) 
 13597 |             { 
 13598 |                vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1)); 
 13599 |             } 
 13600 |             else if (is_ivector_node(branch(1))) 
 13601 |             { 
 13602 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13603 |  
 13604 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 13605 |                { 
 13606 |                   vec1_node_ptr_ = vi->vec(); 
 13607 |                   v1_is_ivec     = true; 
 13608 |                } 
 13609 |             } 
 13610 |  
 13611 |             if (vec0_node_ptr_ && vec1_node_ptr_) 
 13612 |             { 
 13613 |                vector_holder<T>& vec0 = vec0_node_ptr_->vec_holder(); 
 13614 |                vector_holder<T>& vec1 = vec1_node_ptr_->vec_holder(); 
 13615 |  
 13616 |                if (v0_is_ivec && (vec0.base_size() <= vec1.base_size())) 
 13617 |                { 
 13618 |                   vds_ = vds_t(vec0_node_ptr_->vds()); 
 13619 |                } 
 13620 |                else if (v1_is_ivec && (vec1.base_size() <= vec0.base_size())) 
 13621 |                { 
 13622 |                   vds_ = vds_t(vec1_node_ptr_->vds()); 
 13623 |                } 
 13624 |                else 
 13625 |                { 
 13626 |                   vds_ = vds_t(std::min(vec0.base_size(),vec1.base_size())); 
 13627 |                } 
 13628 |  
 13629 |                memory_context_ = make_memory_context(vec0, vec1, vds()); 
 13630 |  
 13631 |                initialised_ = 
 13632 |                   (size() <= base_size()) && 
 13633 |                   binary_node<T>::valid(); 
 13634 |             } 
 13635 |  
 13636 |             assert(valid()); 
 13637 |          } 
 13638 |  
 13639 |         ~vec_binop_vecvec_node() 
 13640 |          { 
 13641 |             memory_context_.clear(); 
 13642 |          } 
 13643 |  
 13644 |          inline T value() const exprtk_override 
 13645 |          { 
 13646 |             branch(0)->value(); 
 13647 |             branch(1)->value(); 
 13648 |  
 13649 |             const T* vec0 = vec0_node_ptr_->vds().data(); 
 13650 |             const T* vec1 = vec1_node_ptr_->vds().data(); 
 13651 |                   T* vec2 = vds().data(); 
 13652 |  
 13653 |             loop_unroll::details lud(size()); 
 13654 |             const T* upper_bound = vec2 + lud.upper_bound; 
 13655 |  
 13656 |             while (vec2 < upper_bound) 
 13657 |             { 
 13658 |                #define exprtk_loop(N)                          \ 
 13659 |                vec2[N] = Operation::process(vec0[N], vec1[N]); \ 
 13660 |  
 13661 |                exprtk_loop( 0) exprtk_loop( 1) 
 13662 |                exprtk_loop( 2) exprtk_loop( 3) 
 13663 |                #ifndef exprtk_disable_superscalar_unroll 
 13664 |                exprtk_loop( 4) exprtk_loop( 5) 
 13665 |                exprtk_loop( 6) exprtk_loop( 7) 
 13666 |                exprtk_loop( 8) exprtk_loop( 9) 
 13667 |                exprtk_loop(10) exprtk_loop(11) 
 13668 |                exprtk_loop(12) exprtk_loop(13) 
 13669 |                exprtk_loop(14) exprtk_loop(15) 
 13670 |                #endif 
 13671 |  
 13672 |                vec0 += lud.batch_size; 
 13673 |                vec1 += lud.batch_size; 
 13674 |                vec2 += lud.batch_size; 
 13675 |             } 
 13676 |  
 13677 |             int i = 0; 
 13678 |  
 13679 |             switch (lud.remainder) 
 13680 |             { 
 13681 |                #define case_stmt(N)                                              \ 
 13682 |                case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ 
 13683 |                exprtk_fallthrough                                                \ 
 13684 |  
 13685 |                #ifndef exprtk_disable_superscalar_unroll 
 13686 |                case_stmt(15) case_stmt(14) 
 13687 |                case_stmt(13) case_stmt(12) 
 13688 |                case_stmt(11) case_stmt(10) 
 13689 |                case_stmt( 9) case_stmt( 8) 
 13690 |                case_stmt( 7) case_stmt( 6) 
 13691 |                case_stmt( 5) case_stmt( 4) 
 13692 |                #endif 
 13693 |                case_stmt( 3) case_stmt( 2) 
 13694 |                case_stmt( 1) 
 13695 |                default: break; 
 13696 |             } 
 13697 |  
 13698 |             #undef exprtk_loop 
 13699 |             #undef case_stmt 
 13700 |  
 13701 |             return (vds().data())[0]; 
 13702 |          } 
 13703 |  
 13704 |          vector_node_ptr vec() const exprtk_override 
 13705 |          { 
 13706 |             return memory_context_.temp_vec_node_; 
 13707 |          } 
 13708 |  
 13709 |          vector_node_ptr vec() exprtk_override 
 13710 |          { 
 13711 |             return memory_context_.temp_vec_node_; 
 13712 |          } 
 13713 |  
 13714 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13715 |          { 
 13716 |             return expression_node<T>::e_vecvecarith; 
 13717 |          } 
 13718 |  
 13719 |          inline bool valid() const exprtk_override 
 13720 |          { 
 13721 |             return initialised_; 
 13722 |          } 
 13723 |  
 13724 |          std::size_t size() const exprtk_override 
 13725 |          { 
 13726 |             return std::min( 
 13727 |                vec0_node_ptr_->vec_holder().size(), 
 13728 |                vec1_node_ptr_->vec_holder().size()); 
 13729 |          } 
 13730 |  
 13731 |          std::size_t base_size() const exprtk_override 
 13732 |          { 
 13733 |             return std::min( 
 13734 |                vec0_node_ptr_->vec_holder().base_size(), 
 13735 |                vec1_node_ptr_->vec_holder().base_size()); 
 13736 |          } 
 13737 |  
 13738 |          vds_t& vds() exprtk_override 
 13739 |          { 
 13740 |             return vds_; 
 13741 |          } 
 13742 |  
 13743 |          const vds_t& vds() const exprtk_override 
 13744 |          { 
 13745 |             return vds_; 
 13746 |          } 
 13747 |  
 13748 |       private: 
 13749 |  
 13750 |          vector_node_ptr vec0_node_ptr_; 
 13751 |          vector_node_ptr vec1_node_ptr_; 
 13752 |          bool            initialised_; 
 13753 |          vds_t           vds_; 
 13754 |          memory_context  memory_context_; 
 13755 |       }; 
 13756 |  
 13757 |       template <typename T, typename Operation> 
 13758 |       class vec_binop_vecval_node exprtk_final 
 13759 |                                   : public binary_node     <T> 
 13760 |                                   , public vector_interface<T> 
 13761 |       { 
 13762 |       public: 
 13763 |  
 13764 |          typedef expression_node<T>* expression_ptr; 
 13765 |          typedef vector_node<T>*     vector_node_ptr; 
 13766 |          typedef vector_holder<T>    vector_holder_t; 
 13767 |          typedef vector_holder_t*    vector_holder_ptr; 
 13768 |          typedef vec_data_store<T>   vds_t; 
 13769 |          typedef memory_context_t<T> memory_context; 
 13770 |  
 13771 |          using binary_node<T>::branch; 
 13772 |  
 13773 |          vec_binop_vecval_node(const operator_type& opr, 
 13774 |                                expression_ptr branch0, 
 13775 |                                expression_ptr branch1) 
 13776 |          : binary_node<T>(opr, branch0, branch1) 
 13777 |          , vec0_node_ptr_(0) 
 13778 |          { 
 13779 |             bool v0_is_ivec = false; 
 13780 |  
 13781 |             if (is_vector_node(branch(0))) 
 13782 |             { 
 13783 |                vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); 
 13784 |             } 
 13785 |             else if (is_ivector_node(branch(0))) 
 13786 |             { 
 13787 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13788 |  
 13789 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 13790 |                { 
 13791 |                   vec0_node_ptr_ = vi->vec(); 
 13792 |                   v0_is_ivec     = true; 
 13793 |                } 
 13794 |             } 
 13795 |  
 13796 |             if (vec0_node_ptr_) 
 13797 |             { 
 13798 |                if (v0_is_ivec) 
 13799 |                   vds() = vec0_node_ptr_->vds(); 
 13800 |                else 
 13801 |                   vds() = vds_t(vec0_node_ptr_->base_size()); 
 13802 |  
 13803 |                memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds()); 
 13804 |             } 
 13805 |  
 13806 |             assert(valid()); 
 13807 |          } 
 13808 |  
 13809 |         ~vec_binop_vecval_node() 
 13810 |          { 
 13811 |             memory_context_.clear(); 
 13812 |          } 
 13813 |  
 13814 |          inline T value() const exprtk_override 
 13815 |          { 
 13816 |                         branch(0)->value(); 
 13817 |             const T v = branch(1)->value(); 
 13818 |  
 13819 |             const T* vec0 = vec0_node_ptr_->vds().data(); 
 13820 |                   T* vec1 = vds().data(); 
 13821 |  
 13822 |             loop_unroll::details lud(size()); 
 13823 |             const T* upper_bound = vec0 + lud.upper_bound; 
 13824 |  
 13825 |             while (vec0 < upper_bound) 
 13826 |             { 
 13827 |                #define exprtk_loop(N)                    \ 
 13828 |                vec1[N] = Operation::process(vec0[N], v); \ 
 13829 |  
 13830 |                exprtk_loop( 0) exprtk_loop( 1) 
 13831 |                exprtk_loop( 2) exprtk_loop( 3) 
 13832 |                #ifndef exprtk_disable_superscalar_unroll 
 13833 |                exprtk_loop( 4) exprtk_loop( 5) 
 13834 |                exprtk_loop( 6) exprtk_loop( 7) 
 13835 |                exprtk_loop( 8) exprtk_loop( 9) 
 13836 |                exprtk_loop(10) exprtk_loop(11) 
 13837 |                exprtk_loop(12) exprtk_loop(13) 
 13838 |                exprtk_loop(14) exprtk_loop(15) 
 13839 |                #endif 
 13840 |  
 13841 |                vec0 += lud.batch_size; 
 13842 |                vec1 += lud.batch_size; 
 13843 |             } 
 13844 |  
 13845 |             int i = 0; 
 13846 |  
 13847 |             switch (lud.remainder) 
 13848 |             { 
 13849 |                #define case_stmt(N,fall_through)                           \ 
 13850 |                case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \ 
 13851 |                fall_through                                                \ 
 13852 |  
 13853 |                #ifndef exprtk_disable_superscalar_unroll 
 13854 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 13855 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 13856 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 13857 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 13858 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 13859 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 13860 |                #endif 
 13861 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 13862 |                case_stmt( 1, (void)0;) 
 13863 |             } 
 13864 |  
 13865 |             #undef exprtk_loop 
 13866 |             #undef case_stmt 
 13867 |  
 13868 |             return (vds().data())[0]; 
 13869 |          } 
 13870 |  
 13871 |          vector_node_ptr vec() const exprtk_override 
 13872 |          { 
 13873 |             return memory_context_.temp_vec_node_; 
 13874 |          } 
 13875 |  
 13876 |          vector_node_ptr vec() exprtk_override 
 13877 |          { 
 13878 |             return memory_context_.temp_vec_node_; 
 13879 |          } 
 13880 |  
 13881 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13882 |          { 
 13883 |             return expression_node<T>::e_vecvalarith; 
 13884 |          } 
 13885 |  
 13886 |          inline bool valid() const exprtk_override 
 13887 |          { 
 13888 |             return 
 13889 |                vec0_node_ptr_          && 
 13890 |                (size() <= base_size()) && 
 13891 |                binary_node<T>::valid(); 
 13892 |          } 
 13893 |  
 13894 |          std::size_t size() const exprtk_override 
 13895 |          { 
 13896 |             return vec0_node_ptr_->size(); 
 13897 |          } 
 13898 |  
 13899 |          std::size_t base_size() const exprtk_override 
 13900 |          { 
 13901 |             return vec0_node_ptr_->vec_holder().base_size(); 
 13902 |          } 
 13903 |  
 13904 |          vds_t& vds() exprtk_override 
 13905 |          { 
 13906 |             return vds_; 
 13907 |          } 
 13908 |  
 13909 |          const vds_t& vds() const exprtk_override 
 13910 |          { 
 13911 |             return vds_; 
 13912 |          } 
 13913 |  
 13914 |       private: 
 13915 |  
 13916 |          vector_node_ptr   vec0_node_ptr_; 
 13917 |          vds_t             vds_; 
 13918 |          memory_context    memory_context_; 
 13919 |       }; 
 13920 |  
 13921 |       template <typename T, typename Operation> 
 13922 |       class vec_binop_valvec_node exprtk_final 
 13923 |                                   : public binary_node     <T> 
 13924 |                                   , public vector_interface<T> 
 13925 |       { 
 13926 |       public: 
 13927 |  
 13928 |          typedef expression_node<T>* expression_ptr; 
 13929 |          typedef vector_node<T>*     vector_node_ptr; 
 13930 |          typedef vector_holder<T>    vector_holder_t; 
 13931 |          typedef vector_holder_t*    vector_holder_ptr; 
 13932 |          typedef vec_data_store<T>   vds_t; 
 13933 |          typedef memory_context_t<T> memory_context; 
 13934 |  
 13935 |          using binary_node<T>::branch; 
 13936 |  
 13937 |          vec_binop_valvec_node(const operator_type& opr, 
 13938 |                                expression_ptr branch0, 
 13939 |                                expression_ptr branch1) 
 13940 |          : binary_node<T>(opr, branch0, branch1) 
 13941 |          , vec1_node_ptr_(0) 
 13942 |          { 
 13943 |             bool v1_is_ivec = false; 
 13944 |  
 13945 |             if (is_vector_node(branch(1))) 
 13946 |             { 
 13947 |                vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1)); 
 13948 |             } 
 13949 |             else if (is_ivector_node(branch(1))) 
 13950 |             { 
 13951 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13952 |  
 13953 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 13954 |                { 
 13955 |                   vec1_node_ptr_ = vi->vec(); 
 13956 |                   v1_is_ivec     = true; 
 13957 |                } 
 13958 |             } 
 13959 |  
 13960 |             if (vec1_node_ptr_) 
 13961 |             { 
 13962 |                if (v1_is_ivec) 
 13963 |                   vds() = vec1_node_ptr_->vds(); 
 13964 |                else 
 13965 |                   vds() = vds_t(vec1_node_ptr_->base_size()); 
 13966 |  
 13967 |                memory_context_ = make_memory_context(vec1_node_ptr_->vec_holder(), vds()); 
 13968 |             } 
 13969 |  
 13970 |             assert(valid()); 
 13971 |          } 
 13972 |  
 13973 |         ~vec_binop_valvec_node() 
 13974 |          { 
 13975 |             memory_context_.clear(); 
 13976 |          } 
 13977 |  
 13978 |          inline T value() const exprtk_override 
 13979 |          { 
 13980 |             const T v = branch(0)->value(); 
 13981 |                         branch(1)->value(); 
 13982 |  
 13983 |                   T* vec0 = vds().data(); 
 13984 |             const T* vec1 = vec1_node_ptr_->vds().data(); 
 13985 |  
 13986 |             loop_unroll::details lud(size()); 
 13987 |             const T* upper_bound = vec0 + lud.upper_bound; 
 13988 |  
 13989 |             while (vec0 < upper_bound) 
 13990 |             { 
 13991 |                #define exprtk_loop(N)                    \ 
 13992 |                vec0[N] = Operation::process(v, vec1[N]); \ 
 13993 |  
 13994 |                exprtk_loop( 0) exprtk_loop( 1) 
 13995 |                exprtk_loop( 2) exprtk_loop( 3) 
 13996 |                #ifndef exprtk_disable_superscalar_unroll 
 13997 |                exprtk_loop( 4) exprtk_loop( 5) 
 13998 |                exprtk_loop( 6) exprtk_loop( 7) 
 13999 |                exprtk_loop( 8) exprtk_loop( 9) 
 14000 |                exprtk_loop(10) exprtk_loop(11) 
 14001 |                exprtk_loop(12) exprtk_loop(13) 
 14002 |                exprtk_loop(14) exprtk_loop(15) 
 14003 |                #endif 
 14004 |  
 14005 |                vec0 += lud.batch_size; 
 14006 |                vec1 += lud.batch_size; 
 14007 |             } 
 14008 |  
 14009 |             int i = 0; 
 14010 |  
 14011 |             switch (lud.remainder) 
 14012 |             { 
 14013 |                #define case_stmt(N,fall_through)                           \ 
 14014 |                case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \ 
 14015 |                fall_through                                                \ 
 14016 |  
 14017 |                #ifndef exprtk_disable_superscalar_unroll 
 14018 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 14019 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 14020 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 14021 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 14022 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 14023 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 14024 |                #endif 
 14025 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 14026 |                case_stmt( 1, (void)0;) 
 14027 |             } 
 14028 |  
 14029 |             #undef exprtk_loop 
 14030 |             #undef case_stmt 
 14031 |  
 14032 |             return (vds().data())[0]; 
 14033 |          } 
 14034 |  
 14035 |          vector_node_ptr vec() const exprtk_override 
 14036 |          { 
 14037 |             return memory_context_.temp_vec_node_; 
 14038 |          } 
 14039 |  
 14040 |          vector_node_ptr vec() exprtk_override 
 14041 |          { 
 14042 |             return memory_context_.temp_vec_node_; 
 14043 |          } 
 14044 |  
 14045 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14046 |          { 
 14047 |             return expression_node<T>::e_vecvalarith; 
 14048 |          } 
 14049 |  
 14050 |          inline bool valid() const exprtk_override 
 14051 |          { 
 14052 |             return 
 14053 |                vec1_node_ptr_               && 
 14054 |                (size() <= base_size())      && 
 14055 |                (vds_.size() <= base_size()) && 
 14056 |                binary_node<T>::valid(); 
 14057 |          } 
 14058 |  
 14059 |          std::size_t size() const exprtk_override 
 14060 |          { 
 14061 |             return vec1_node_ptr_->vec_holder().size(); 
 14062 |          } 
 14063 |  
 14064 |          std::size_t base_size() const exprtk_override 
 14065 |          { 
 14066 |             return vec1_node_ptr_->vec_holder().base_size(); 
 14067 |          } 
 14068 |  
 14069 |          vds_t& vds() exprtk_override 
 14070 |          { 
 14071 |             return vds_; 
 14072 |          } 
 14073 |  
 14074 |          const vds_t& vds() const exprtk_override 
 14075 |          { 
 14076 |             return vds_; 
 14077 |          } 
 14078 |  
 14079 |       private: 
 14080 |  
 14081 |          vector_node_ptr   vec1_node_ptr_; 
 14082 |          vds_t             vds_; 
 14083 |          memory_context    memory_context_; 
 14084 |       }; 
 14085 |  
 14086 |       template <typename T, typename Operation> 
 14087 |       class unary_vector_node exprtk_final 
 14088 |                               : public unary_node      <T> 
 14089 |                               , public vector_interface<T> 
 14090 |       { 
 14091 |       public: 
 14092 |  
 14093 |          typedef expression_node<T>* expression_ptr; 
 14094 |          typedef vector_node<T>*     vector_node_ptr; 
 14095 |          typedef vector_holder<T>    vector_holder_t; 
 14096 |          typedef vector_holder_t*    vector_holder_ptr; 
 14097 |          typedef vec_data_store<T>   vds_t; 
 14098 |          typedef memory_context_t<T> memory_context; 
 14099 |  
 14100 |          using expression_node<T>::branch; 
 14101 |  
 14102 |          unary_vector_node(const operator_type& opr, expression_ptr branch0) 
 14103 |          : unary_node<T>(opr, branch0) 
 14104 |          , vec0_node_ptr_(0) 
 14105 |          { 
 14106 |             bool vec0_is_ivec = false; 
 14107 |  
 14108 |             if (is_vector_node(branch(0))) 
 14109 |             { 
 14110 |                vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); 
 14111 |             } 
 14112 |             else if (is_ivector_node(branch(0))) 
 14113 |             { 
 14114 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 14115 |  
 14116 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 14117 |                { 
 14118 |                   vec0_node_ptr_ = vi->vec(); 
 14119 |                   vec0_is_ivec   = true; 
 14120 |                } 
 14121 |             } 
 14122 |  
 14123 |             if (vec0_node_ptr_) 
 14124 |             { 
 14125 |                if (vec0_is_ivec) 
 14126 |                   vds_ = vec0_node_ptr_->vds(); 
 14127 |                else 
 14128 |                   vds_ = vds_t(vec0_node_ptr_->base_size()); 
 14129 |  
 14130 |                memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds()); 
 14131 |             } 
 14132 |  
 14133 |             assert(valid()); 
 14134 |          } 
 14135 |  
 14136 |         ~unary_vector_node() 
 14137 |          { 
 14138 |             memory_context_.clear(); 
 14139 |          } 
 14140 |  
 14141 |          inline T value() const exprtk_override 
 14142 |          { 
 14143 |             branch()->value(); 
 14144 |  
 14145 |             const T* vec0 = vec0_node_ptr_->vds().data(); 
 14146 |                   T* vec1 = vds().data(); 
 14147 |  
 14148 |             loop_unroll::details lud(size()); 
 14149 |             const T* upper_bound = vec0 + lud.upper_bound; 
 14150 |  
 14151 |             while (vec0 < upper_bound) 
 14152 |             { 
 14153 |                #define exprtk_loop(N)                 \ 
 14154 |                vec1[N] = Operation::process(vec0[N]); \ 
 14155 |  
 14156 |                exprtk_loop( 0) exprtk_loop( 1) 
 14157 |                exprtk_loop( 2) exprtk_loop( 3) 
 14158 |                #ifndef exprtk_disable_superscalar_unroll 
 14159 |                exprtk_loop( 4) exprtk_loop( 5) 
 14160 |                exprtk_loop( 6) exprtk_loop( 7) 
 14161 |                exprtk_loop( 8) exprtk_loop( 9) 
 14162 |                exprtk_loop(10) exprtk_loop(11) 
 14163 |                exprtk_loop(12) exprtk_loop(13) 
 14164 |                exprtk_loop(14) exprtk_loop(15) 
 14165 |                #endif 
 14166 |  
 14167 |                vec0 += lud.batch_size; 
 14168 |                vec1 += lud.batch_size; 
 14169 |             } 
 14170 |  
 14171 |             int i = 0; 
 14172 |  
 14173 |             switch (lud.remainder) 
 14174 |             { 
 14175 |                #define case_stmt(N)                                     \ 
 14176 |                case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \ 
 14177 |                exprtk_fallthrough                                       \ 
 14178 |  
 14179 |                #ifndef exprtk_disable_superscalar_unroll 
 14180 |                case_stmt(15) case_stmt(14) 
 14181 |                case_stmt(13) case_stmt(12) 
 14182 |                case_stmt(11) case_stmt(10) 
 14183 |                case_stmt( 9) case_stmt( 8) 
 14184 |                case_stmt( 7) case_stmt( 6) 
 14185 |                case_stmt( 5) case_stmt( 4) 
 14186 |                #endif 
 14187 |                case_stmt( 3) case_stmt( 2) 
 14188 |                case_stmt( 1) 
 14189 |                default: break; 
 14190 |             } 
 14191 |  
 14192 |             #undef exprtk_loop 
 14193 |             #undef case_stmt 
 14194 |  
 14195 |             return (vds().data())[0]; 
 14196 |          } 
 14197 |  
 14198 |          vector_node_ptr vec() const exprtk_override 
 14199 |          { 
 14200 |             return memory_context_.temp_vec_node_; 
 14201 |          } 
 14202 |  
 14203 |          vector_node_ptr vec() exprtk_override 
 14204 |          { 
 14205 |             return memory_context_.temp_vec_node_; 
 14206 |          } 
 14207 |  
 14208 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14209 |          { 
 14210 |             return expression_node<T>::e_vecunaryop; 
 14211 |          } 
 14212 |  
 14213 |          inline bool valid() const exprtk_override 
 14214 |          { 
 14215 |             return vec0_node_ptr_ && unary_node<T>::valid(); 
 14216 |          } 
 14217 |  
 14218 |          std::size_t size() const exprtk_override 
 14219 |          { 
 14220 |             return vec0_node_ptr_->vec_holder().size(); 
 14221 |          } 
 14222 |  
 14223 |          std::size_t base_size() const exprtk_override 
 14224 |          { 
 14225 |             return vec0_node_ptr_->vec_holder().base_size(); 
 14226 |          } 
 14227 |  
 14228 |          vds_t& vds() exprtk_override 
 14229 |          { 
 14230 |             return vds_; 
 14231 |          } 
 14232 |  
 14233 |          const vds_t& vds() const exprtk_override 
 14234 |          { 
 14235 |             return vds_; 
 14236 |          } 
 14237 |  
 14238 |       private: 
 14239 |  
 14240 |          vector_node_ptr vec0_node_ptr_; 
 14241 |          vds_t           vds_; 
 14242 |          memory_context  memory_context_; 
 14243 |       }; 
 14244 |  
 14245 |       template <typename T> 
 14246 |       class conditional_vector_node exprtk_final 
 14247 |                                     : public expression_node <T> 
 14248 |                                     , public vector_interface<T> 
 14249 |       { 
 14250 |       public: 
 14251 |  
 14252 |          typedef expression_node <T>* expression_ptr; 
 14253 |          typedef vector_interface<T>* vec_interface_ptr; 
 14254 |          typedef vector_node     <T>* vector_node_ptr; 
 14255 |          typedef vector_holder   <T>  vector_holder_t; 
 14256 |          typedef vector_holder_t*     vector_holder_ptr; 
 14257 |          typedef vec_data_store  <T>  vds_t; 
 14258 |          typedef memory_context_t<T> memory_context; 
 14259 |          typedef std::pair<expression_ptr,bool> branch_t; 
 14260 |  
 14261 |          conditional_vector_node(expression_ptr condition, 
 14262 |                                  expression_ptr consequent, 
 14263 |                                  expression_ptr alternative) 
 14264 |          : consequent_node_ptr_ (0) 
 14265 |          , alternative_node_ptr_(0) 
 14266 |          , temp_vec_node_       (0) 
 14267 |          , temp_                (0) 
 14268 |          , result_vec_size_     (0) 
 14269 |          , initialised_         (false) 
 14270 |          { 
 14271 |             construct_branch_pair(condition_  , condition  ); 
 14272 |             construct_branch_pair(consequent_ , consequent ); 
 14273 |             construct_branch_pair(alternative_, alternative); 
 14274 |  
 14275 |             if (details::is_ivector_node(consequent_.first)) 
 14276 |             { 
 14277 |                vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(consequent_.first); 
 14278 |  
 14279 |                if (0 != ivec_ptr) 
 14280 |                { 
 14281 |                   consequent_node_ptr_ = ivec_ptr->vec(); 
 14282 |                } 
 14283 |             } 
 14284 |  
 14285 |             if (details::is_ivector_node(alternative_.first)) 
 14286 |             { 
 14287 |                vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(alternative_.first); 
 14288 |  
 14289 |                if (0 != ivec_ptr) 
 14290 |                { 
 14291 |                   alternative_node_ptr_ = ivec_ptr->vec(); 
 14292 |                } 
 14293 |             } 
 14294 |  
 14295 |             if (consequent_node_ptr_ && alternative_node_ptr_) 
 14296 |             { 
 14297 |                const std::size_t vec_size = 
 14298 |                   std::max(consequent_node_ptr_ ->vec_holder().base_size(), 
 14299 |                            alternative_node_ptr_->vec_holder().base_size()); 
 14300 |  
 14301 |                vds_            = vds_t(vec_size); 
 14302 |                memory_context_ = make_memory_context( 
 14303 |                   consequent_node_ptr_ ->vec_holder(), 
 14304 |                   alternative_node_ptr_->vec_holder(), 
 14305 |                   vds()); 
 14306 |  
 14307 |                initialised_ = (vec_size > 0); 
 14308 |             } 
 14309 |  
 14310 |             assert(initialised_); 
 14311 |          } 
 14312 |  
 14313 |         ~conditional_vector_node() 
 14314 |          { 
 14315 |             memory_context_.clear(); 
 14316 |          } 
 14317 |  
 14318 |          inline T value() const exprtk_override 
 14319 |          { 
 14320 |             T result = T(0); 
 14321 |             T* source_vector = 0; 
 14322 |             T* result_vector = vds().data(); 
 14323 |  
 14324 |             if (is_true(condition_)) 
 14325 |             { 
 14326 |                result           = consequent_.first->value(); 
 14327 |                source_vector    = consequent_node_ptr_->vds().data(); 
 14328 |                result_vec_size_ = consequent_node_ptr_->size(); 
 14329 |             } 
 14330 |             else 
 14331 |             { 
 14332 |                result           = alternative_.first->value(); 
 14333 |                source_vector    = alternative_node_ptr_->vds().data(); 
 14334 |                result_vec_size_ = alternative_node_ptr_->size(); 
 14335 |             } 
 14336 |  
 14337 |             for (std::size_t i = 0; i < result_vec_size_; ++i) 
 14338 |             { 
 14339 |                result_vector[i] = source_vector[i]; 
 14340 |             } 
 14341 |  
 14342 |             return result; 
 14343 |          } 
 14344 |  
 14345 |          vector_node_ptr vec() const exprtk_override 
 14346 |          { 
 14347 |             return memory_context_.temp_vec_node_; 
 14348 |          } 
 14349 |  
 14350 |          vector_node_ptr vec() exprtk_override 
 14351 |          { 
 14352 |             return memory_context_.temp_vec_node_; 
 14353 |          } 
 14354 |  
 14355 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14356 |          { 
 14357 |             return expression_node<T>::e_vecondition; 
 14358 |          } 
 14359 |  
 14360 |          inline bool valid() const exprtk_override 
 14361 |          { 
 14362 |             return 
 14363 |                initialised_                                      && 
 14364 |                condition_  .first && condition_  .first->valid() && 
 14365 |                consequent_ .first && consequent_ .first->valid() && 
 14366 |                alternative_.first && alternative_.first->valid() && 
 14367 |                size() <= base_size(); 
 14368 |          } 
 14369 |  
 14370 |          std::size_t size() const exprtk_override 
 14371 |          { 
 14372 |             return result_vec_size_; 
 14373 |          } 
 14374 |  
 14375 |          std::size_t base_size() const exprtk_override 
 14376 |          { 
 14377 |             return std::min( 
 14378 |                consequent_node_ptr_ ->vec_holder().base_size(), 
 14379 |                alternative_node_ptr_->vec_holder().base_size()); 
 14380 |          } 
 14381 |  
 14382 |          vds_t& vds() exprtk_override 
 14383 |          { 
 14384 |             return vds_; 
 14385 |          } 
 14386 |  
 14387 |          const vds_t& vds() const exprtk_override 
 14388 |          { 
 14389 |             return vds_; 
 14390 |          } 
 14391 |  
 14392 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14393 |          { 
 14394 |             expression_node<T>::ndb_t::collect(condition_   , node_delete_list); 
 14395 |             expression_node<T>::ndb_t::collect(consequent_  , node_delete_list); 
 14396 |             expression_node<T>::ndb_t::collect(alternative_ , node_delete_list); 
 14397 |          } 
 14398 |  
 14399 |          std::size_t node_depth() const exprtk_override 
 14400 |          { 
 14401 |             return expression_node<T>::ndb_t::compute_node_depth 
 14402 |                (condition_, consequent_, alternative_); 
 14403 |          } 
 14404 |  
 14405 |       private: 
 14406 |  
 14407 |          branch_t            condition_; 
 14408 |          branch_t            consequent_; 
 14409 |          branch_t            alternative_; 
 14410 |          vector_node_ptr     consequent_node_ptr_; 
 14411 |          vector_node_ptr     alternative_node_ptr_; 
 14412 |          vector_node_ptr     temp_vec_node_; 
 14413 |          vector_holder_ptr   temp_; 
 14414 |          vds_t               vds_; 
 14415 |          mutable std::size_t result_vec_size_; 
 14416 |          bool                initialised_; 
 14417 |          memory_context      memory_context_; 
 14418 |       }; 
 14419 |  
 14420 |       template <typename T> 
 14421 |       class scand_node exprtk_final : public binary_node<T> 
 14422 |       { 
 14423 |       public: 
 14424 |  
 14425 |          typedef expression_node<T>* expression_ptr; 
 14426 |          using binary_node<T>::branch; 
 14427 |  
 14428 |          scand_node(const operator_type& opr, 
 14429 |                     expression_ptr branch0, 
 14430 |                     expression_ptr branch1) 
 14431 |          : binary_node<T>(opr, branch0, branch1) 
 14432 |          { 
 14433 |             assert(binary_node<T>::valid()); 
 14434 |          } 
 14435 |  
 14436 |          inline T value() const exprtk_override 
 14437 |          { 
 14438 |             return ( 
 14439 |                      std::not_equal_to<T>() 
 14440 |                         (T(0),branch(0)->value()) && 
 14441 |                      std::not_equal_to<T>() 
 14442 |                         (T(0),branch(1)->value()) 
 14443 |                    ) ? T(1) : T(0); 
 14444 |          } 
 14445 |       }; 
 14446 |  
 14447 |       template <typename T> 
 14448 |       class scor_node exprtk_final : public binary_node<T> 
 14449 |       { 
 14450 |       public: 
 14451 |  
 14452 |          typedef expression_node<T>* expression_ptr; 
 14453 |          using binary_node<T>::branch; 
 14454 |  
 14455 |          scor_node(const operator_type& opr, 
 14456 |                    expression_ptr branch0, 
 14457 |                    expression_ptr branch1) 
 14458 |          : binary_node<T>(opr, branch0, branch1) 
 14459 |          { 
 14460 |             assert(binary_node<T>::valid()); 
 14461 |          } 
 14462 |  
 14463 |          inline T value() const exprtk_override 
 14464 |          { 
 14465 |             return ( 
 14466 |                      std::not_equal_to<T>() 
 14467 |                         (T(0),branch(0)->value()) || 
 14468 |                      std::not_equal_to<T>() 
 14469 |                         (T(0),branch(1)->value()) 
 14470 |                    ) ? T(1) : T(0); 
 14471 |          } 
 14472 |       }; 
 14473 |  
 14474 |       template <typename T, typename IFunction, std::size_t N> 
 14475 |       class function_N_node exprtk_final : public expression_node<T> 
 14476 |       { 
 14477 |       public: 
 14478 |  
 14479 |          // Function of N parameters. 
 14480 |          typedef expression_node<T>* expression_ptr; 
 14481 |          typedef std::pair<expression_ptr,bool> branch_t; 
 14482 |          typedef IFunction ifunction; 
 14483 |  
 14484 |          explicit function_N_node(ifunction* func) 
 14485 |          : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)) 
 14486 |          , parameter_count_(func->param_count) 
 14487 |          , initialised_(false) 
 14488 |          {} 
 14489 |  
 14490 |          template <std::size_t NumBranches> 
 14491 |          bool init_branches(expression_ptr (&b)[NumBranches]) 
 14492 |          { 
 14493 |             // Needed for incompetent and broken msvc compiler versions 
 14494 |             #ifdef _MSC_VER 
 14495 |              #pragma warning(push) 
 14496 |              #pragma warning(disable: 4127) 
 14497 |             #endif 
 14498 |  
 14499 |             if (N != NumBranches) 
 14500 |             { 
 14501 |                return false; 
 14502 |             } 
 14503 |  
 14504 |             for (std::size_t i = 0; i < NumBranches; ++i) 
 14505 |             { 
 14506 |                if (b[i] && b[i]->valid()) 
 14507 |                   branch_[i] = std::make_pair(b[i],branch_deletable(b[i])); 
 14508 |                else 
 14509 |                   return false; 
 14510 |             } 
 14511 |  
 14512 |             initialised_ = function_; 
 14513 |             assert(valid()); 
 14514 |             return initialised_; 
 14515 |  
 14516 |             #ifdef _MSC_VER 
 14517 |              #pragma warning(pop) 
 14518 |             #endif 
 14519 |          } 
 14520 |  
 14521 |          inline bool operator <(const function_N_node<T,IFunction,N>& fn) const 
 14522 |          { 
 14523 |             return this < (&fn); 
 14524 |          } 
 14525 |  
 14526 |          inline T value() const exprtk_override 
 14527 |          { 
 14528 |             // Needed for incompetent and broken msvc compiler versions 
 14529 |             #ifdef _MSC_VER 
 14530 |              #pragma warning(push) 
 14531 |              #pragma warning(disable: 4127) 
 14532 |             #endif 
 14533 |  
 14534 |             T v[N]; 
 14535 |             evaluate_branches<T,N>::execute(v,branch_); 
 14536 |             return invoke<T,N>::execute(*function_,v); 
 14537 |  
 14538 |             #ifdef _MSC_VER 
 14539 |              #pragma warning(pop) 
 14540 |             #endif 
 14541 |          } 
 14542 |  
 14543 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14544 |          { 
 14545 |             return expression_node<T>::e_function; 
 14546 |          } 
 14547 |  
 14548 |          inline bool valid() const exprtk_override 
 14549 |          { 
 14550 |             return initialised_; 
 14551 |          } 
 14552 |  
 14553 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14554 |          { 
 14555 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 14556 |          } 
 14557 |  
 14558 |          std::size_t node_depth() const exprtk_override 
 14559 |          { 
 14560 |             return expression_node<T>::ndb_t::template compute_node_depth<N>(branch_); 
 14561 |          } 
 14562 |  
 14563 |          template <typename T_, std::size_t BranchCount> 
 14564 |          struct evaluate_branches 
 14565 |          { 
 14566 |             static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount]) 
 14567 |             { 
 14568 |                for (std::size_t i = 0; i < BranchCount; ++i) 
 14569 |                { 
 14570 |                   v[i] = b[i].first->value(); 
 14571 |                } 
 14572 |             } 
 14573 |          }; 
 14574 |  
 14575 |          template <typename T_> 
 14576 |          struct evaluate_branches <T_,6> 
 14577 |          { 
 14578 |             static inline void execute(T_ (&v)[6], const branch_t (&b)[6]) 
 14579 |             { 
 14580 |                v[0] = b[0].first->value(); 
 14581 |                v[1] = b[1].first->value(); 
 14582 |                v[2] = b[2].first->value(); 
 14583 |                v[3] = b[3].first->value(); 
 14584 |                v[4] = b[4].first->value(); 
 14585 |                v[5] = b[5].first->value(); 
 14586 |             } 
 14587 |          }; 
 14588 |  
 14589 |          template <typename T_> 
 14590 |          struct evaluate_branches <T_,5> 
 14591 |          { 
 14592 |             static inline void execute(T_ (&v)[5], const branch_t (&b)[5]) 
 14593 |             { 
 14594 |                v[0] = b[0].first->value(); 
 14595 |                v[1] = b[1].first->value(); 
 14596 |                v[2] = b[2].first->value(); 
 14597 |                v[3] = b[3].first->value(); 
 14598 |                v[4] = b[4].first->value(); 
 14599 |             } 
 14600 |          }; 
 14601 |  
 14602 |          template <typename T_> 
 14603 |          struct evaluate_branches <T_,4> 
 14604 |          { 
 14605 |             static inline void execute(T_ (&v)[4], const branch_t (&b)[4]) 
 14606 |             { 
 14607 |                v[0] = b[0].first->value(); 
 14608 |                v[1] = b[1].first->value(); 
 14609 |                v[2] = b[2].first->value(); 
 14610 |                v[3] = b[3].first->value(); 
 14611 |             } 
 14612 |          }; 
 14613 |  
 14614 |          template <typename T_> 
 14615 |          struct evaluate_branches <T_,3> 
 14616 |          { 
 14617 |             static inline void execute(T_ (&v)[3], const branch_t (&b)[3]) 
 14618 |             { 
 14619 |                v[0] = b[0].first->value(); 
 14620 |                v[1] = b[1].first->value(); 
 14621 |                v[2] = b[2].first->value(); 
 14622 |             } 
 14623 |          }; 
 14624 |  
 14625 |          template <typename T_> 
 14626 |          struct evaluate_branches <T_,2> 
 14627 |          { 
 14628 |             static inline void execute(T_ (&v)[2], const branch_t (&b)[2]) 
 14629 |             { 
 14630 |                v[0] = b[0].first->value(); 
 14631 |                v[1] = b[1].first->value(); 
 14632 |             } 
 14633 |          }; 
 14634 |  
 14635 |          template <typename T_> 
 14636 |          struct evaluate_branches <T_,1> 
 14637 |          { 
 14638 |             static inline void execute(T_ (&v)[1], const branch_t (&b)[1]) 
 14639 |             { 
 14640 |                v[0] = b[0].first->value(); 
 14641 |             } 
 14642 |          }; 
 14643 |  
 14644 |          template <typename T_, std::size_t ParamCount> 
 14645 |          struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } }; 
 14646 |  
 14647 |          template <typename T_> 
 14648 |          struct invoke<T_,20> 
 14649 |          { 
 14650 |             static inline T_ execute(ifunction& f, T_ (&v)[20]) 
 14651 |             { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18],v[19]); } 
 14652 |          }; 
 14653 |  
 14654 |          template <typename T_> 
 14655 |          struct invoke<T_,19> 
 14656 |          { 
 14657 |             static inline T_ execute(ifunction& f, T_ (&v)[19]) 
 14658 |             { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18]); } 
 14659 |          }; 
 14660 |  
 14661 |          template <typename T_> 
 14662 |          struct invoke<T_,18> 
 14663 |          { 
 14664 |             static inline T_ execute(ifunction& f, T_ (&v)[18]) 
 14665 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15], v[16], v[17]); } 
 14666 |          }; 
 14667 |  
 14668 |          template <typename T_> 
 14669 |          struct invoke<T_,17> 
 14670 |          { 
 14671 |             static inline T_ execute(ifunction& f, T_ (&v)[17]) 
 14672 |             { 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]); } 
 14673 |          }; 
 14674 |  
 14675 |          template <typename T_> 
 14676 |          struct invoke<T_,16> 
 14677 |          { 
 14678 |             static inline T_ execute(ifunction& f, T_ (&v)[16]) 
 14679 |             { 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]); } 
 14680 |          }; 
 14681 |  
 14682 |          template <typename T_> 
 14683 |          struct invoke<T_,15> 
 14684 |          { 
 14685 |             static inline T_ execute(ifunction& f, T_ (&v)[15]) 
 14686 |             { 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]); } 
 14687 |          }; 
 14688 |  
 14689 |          template <typename T_> 
 14690 |          struct invoke<T_,14> 
 14691 |          { 
 14692 |             static inline T_ execute(ifunction& f, T_ (&v)[14]) 
 14693 |             { 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]); } 
 14694 |          }; 
 14695 |  
 14696 |          template <typename T_> 
 14697 |          struct invoke<T_,13> 
 14698 |          { 
 14699 |             static inline T_ execute(ifunction& f, T_ (&v)[13]) 
 14700 |             { 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]); } 
 14701 |          }; 
 14702 |  
 14703 |          template <typename T_> 
 14704 |          struct invoke<T_,12> 
 14705 |          { 
 14706 |             static inline T_ execute(ifunction& f, T_ (&v)[12]) 
 14707 |             { 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]); } 
 14708 |          }; 
 14709 |  
 14710 |          template <typename T_> 
 14711 |          struct invoke<T_,11> 
 14712 |          { 
 14713 |             static inline T_ execute(ifunction& f, T_ (&v)[11]) 
 14714 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10]); } 
 14715 |          }; 
 14716 |  
 14717 |          template <typename T_> 
 14718 |          struct invoke<T_,10> 
 14719 |          { 
 14720 |             static inline T_ execute(ifunction& f, T_ (&v)[10]) 
 14721 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]); } 
 14722 |          }; 
 14723 |  
 14724 |          template <typename T_> 
 14725 |          struct invoke<T_,9> 
 14726 |          { 
 14727 |             static inline T_ execute(ifunction& f, T_ (&v)[9]) 
 14728 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); } 
 14729 |          }; 
 14730 |  
 14731 |          template <typename T_> 
 14732 |          struct invoke<T_,8> 
 14733 |          { 
 14734 |             static inline T_ execute(ifunction& f, T_ (&v)[8]) 
 14735 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); } 
 14736 |          }; 
 14737 |  
 14738 |          template <typename T_> 
 14739 |          struct invoke<T_,7> 
 14740 |          { 
 14741 |             static inline T_ execute(ifunction& f, T_ (&v)[7]) 
 14742 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6]); } 
 14743 |          }; 
 14744 |  
 14745 |          template <typename T_> 
 14746 |          struct invoke<T_,6> 
 14747 |          { 
 14748 |             static inline T_ execute(ifunction& f, T_ (&v)[6]) 
 14749 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5]); } 
 14750 |          }; 
 14751 |  
 14752 |          template <typename T_> 
 14753 |          struct invoke<T_,5> 
 14754 |          { 
 14755 |             static inline T_ execute(ifunction& f, T_ (&v)[5]) 
 14756 |             { return f(v[0], v[1], v[2], v[3], v[4]); } 
 14757 |          }; 
 14758 |  
 14759 |          template <typename T_> 
 14760 |          struct invoke<T_,4> 
 14761 |          { 
 14762 |             static inline T_ execute(ifunction& f, T_ (&v)[4]) 
 14763 |             { return f(v[0], v[1], v[2], v[3]); } 
 14764 |          }; 
 14765 |  
 14766 |          template <typename T_> 
 14767 |          struct invoke<T_,3> 
 14768 |          { 
 14769 |             static inline T_ execute(ifunction& f, T_ (&v)[3]) 
 14770 |             { return f(v[0], v[1], v[2]); } 
 14771 |          }; 
 14772 |  
 14773 |          template <typename T_> 
 14774 |          struct invoke<T_,2> 
 14775 |          { 
 14776 |             static inline T_ execute(ifunction& f, T_ (&v)[2]) 
 14777 |             { return f(v[0], v[1]); } 
 14778 |          }; 
 14779 |  
 14780 |          template <typename T_> 
 14781 |          struct invoke<T_,1> 
 14782 |          { 
 14783 |             static inline T_ execute(ifunction& f, T_ (&v)[1]) 
 14784 |             { return f(v[0]); } 
 14785 |          }; 
 14786 |  
 14787 |       private: 
 14788 |  
 14789 |          ifunction*  function_; 
 14790 |          std::size_t parameter_count_; 
 14791 |          branch_t    branch_[N]; 
 14792 |          bool        initialised_; 
 14793 |       }; 
 14794 |  
 14795 |       template <typename T, typename IFunction> 
 14796 |       class function_N_node<T,IFunction,0> exprtk_final : public expression_node<T> 
 14797 |       { 
 14798 |       public: 
 14799 |  
 14800 |          typedef expression_node<T>* expression_ptr; 
 14801 |          typedef IFunction ifunction; 
 14802 |  
 14803 |          explicit function_N_node(ifunction* func) 
 14804 |          : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0)) 
 14805 |          { 
 14806 |             assert(valid()); 
 14807 |          } 
 14808 |  
 14809 |          inline bool operator <(const function_N_node<T,IFunction,0>& fn) const 
 14810 |          { 
 14811 |             return this < (&fn); 
 14812 |          } 
 14813 |  
 14814 |          inline T value() const exprtk_override 
 14815 |          { 
 14816 |             return (*function_)(); 
 14817 |          } 
 14818 |  
 14819 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14820 |          { 
 14821 |             return expression_node<T>::e_function; 
 14822 |          } 
 14823 |  
 14824 |          inline bool valid() const exprtk_override 
 14825 |          { 
 14826 |             return function_; 
 14827 |          } 
 14828 |  
 14829 |       private: 
 14830 |  
 14831 |          ifunction* function_; 
 14832 |       }; 
 14833 |  
 14834 |       template <typename T, typename VarArgFunction> 
 14835 |       class vararg_function_node exprtk_final : public expression_node<T> 
 14836 |       { 
 14837 |       public: 
 14838 |  
 14839 |          typedef expression_node<T>* expression_ptr; 
 14840 |  
 14841 |          vararg_function_node(VarArgFunction*  func, 
 14842 |                               const std::vector<expression_ptr>& arg_list) 
 14843 |          : function_(func) 
 14844 |          , arg_list_(arg_list) 
 14845 |          { 
 14846 |             value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN()); 
 14847 |             assert(valid()); 
 14848 |          } 
 14849 |  
 14850 |          inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const 
 14851 |          { 
 14852 |             return this < (&fn); 
 14853 |          } 
 14854 |  
 14855 |          inline T value() const exprtk_override 
 14856 |          { 
 14857 |             populate_value_list(); 
 14858 |             return (*function_)(value_list_); 
 14859 |          } 
 14860 |  
 14861 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14862 |          { 
 14863 |             return expression_node<T>::e_vafunction; 
 14864 |          } 
 14865 |  
 14866 |          inline bool valid() const exprtk_override 
 14867 |          { 
 14868 |             return function_; 
 14869 |          } 
 14870 |  
 14871 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14872 |          { 
 14873 |             for (std::size_t i = 0; i < arg_list_.size(); ++i) 
 14874 |             { 
 14875 |                if (arg_list_[i] && !details::is_variable_node(arg_list_[i])) 
 14876 |                { 
 14877 |                   node_delete_list.push_back(&arg_list_[i]); 
 14878 |                } 
 14879 |             } 
 14880 |          } 
 14881 |  
 14882 |          std::size_t node_depth() const exprtk_override 
 14883 |          { 
 14884 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 14885 |          } 
 14886 |  
 14887 |       private: 
 14888 |  
 14889 |          inline void populate_value_list() const 
 14890 |          { 
 14891 |             for (std::size_t i = 0; i < arg_list_.size(); ++i) 
 14892 |             { 
 14893 |                value_list_[i] = arg_list_[i]->value(); 
 14894 |             } 
 14895 |          } 
 14896 |  
 14897 |          VarArgFunction* function_; 
 14898 |          std::vector<expression_ptr> arg_list_; 
 14899 |          mutable std::vector<T> value_list_; 
 14900 |       }; 
 14901 |  
 14902 |       template <typename T, typename GenericFunction> 
 14903 |       class generic_function_node : public expression_node<T> 
 14904 |       { 
 14905 |       public: 
 14906 |  
 14907 |          typedef type_store<T>       type_store_t; 
 14908 |          typedef expression_node<T>* expression_ptr; 
 14909 |          typedef variable_node<T>    variable_node_t; 
 14910 |          typedef vector_node<T>      vector_node_t; 
 14911 |          typedef variable_node_t*    variable_node_ptr_t; 
 14912 |          typedef vector_node_t*      vector_node_ptr_t; 
 14913 |          typedef range_interface<T>  range_interface_t; 
 14914 |          typedef range_data_type<T>  range_data_type_t; 
 14915 |          typedef typename range_interface<T>::range_t range_t; 
 14916 |  
 14917 |          typedef std::pair<expression_ptr,bool> branch_t; 
 14918 |          typedef vector_holder<T>* vh_t; 
 14919 |          typedef vector_view<T>*   vecview_t; 
 14920 |  
 14921 |          typedef std::vector<T>                 tmp_vs_t; 
 14922 |          typedef std::vector<type_store_t>      typestore_list_t; 
 14923 |          typedef std::vector<range_data_type_t> range_list_t; 
 14924 |  
 14925 |          explicit generic_function_node(const std::vector<expression_ptr>& arg_list, 
 14926 |                                         GenericFunction* func = reinterpret_cast<GenericFunction*>(0)) 
 14927 |          : function_(func) 
 14928 |          , arg_list_(arg_list) 
 14929 |          {} 
 14930 |  
 14931 |          virtual ~generic_function_node() 
 14932 |          { 
 14933 |             for (std::size_t i = 0; i < vv_list_.size(); ++i) 
 14934 |             { 
 14935 |                vecview_t& vv = vv_list_[i]; 
 14936 |                if (vv && typestore_list_[i].vec_data) 
 14937 |                { 
 14938 |                   vv->remove_ref(&typestore_list_[i].vec_data); 
 14939 |                   typestore_list_[i].vec_data = 0; 
 14940 |                } 
 14941 |             } 
 14942 |          } 
 14943 |  
 14944 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14945 |          { 
 14946 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 14947 |          } 
 14948 |  
 14949 |          std::size_t node_depth() const exprtk_override exprtk_final 
 14950 |          { 
 14951 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 14952 |          } 
 14953 |  
 14954 |          virtual bool init_branches() 
 14955 |          { 
 14956 |             expr_as_vec1_store_.resize(arg_list_.size(), T(0)               ); 
 14957 |             typestore_list_    .resize(arg_list_.size(), type_store_t()     ); 
 14958 |             range_list_        .resize(arg_list_.size(), range_data_type_t()); 
 14959 |             branch_            .resize(arg_list_.size(), branch_t(reinterpret_cast<expression_ptr>(0),false)); 
 14960 |             vv_list_           .resize(arg_list_.size(), vecview_t(0)); 
 14961 |  
 14962 |             for (std::size_t i = 0; i < arg_list_.size(); ++i) 
 14963 |             { 
 14964 |                type_store_t& ts = typestore_list_[i]; 
 14965 |  
 14966 |                if (0 == arg_list_[i]) 
 14967 |                   return false; 
 14968 |                else if (is_ivector_node(arg_list_[i])) 
 14969 |                { 
 14970 |                   vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 14971 |  
 14972 |                   if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i]))) 
 14973 |                      return false; 
 14974 |  
 14975 |                   ts.size = vi->size(); 
 14976 |                   ts.data = vi->vds().data(); 
 14977 |                   ts.type = type_store_t::e_vector; 
 14978 |  
 14979 |                   if ( 
 14980 |                        vi->vec()->vec_holder().rebaseable() && 
 14981 |                        vi->vec()->vec_holder().rebaseable_instance() 
 14982 |                      ) 
 14983 |                   { 
 14984 |                      vv_list_[i] = vi->vec()->vec_holder().rebaseable_instance(); 
 14985 |                      vv_list_[i]->set_ref(&ts.vec_data); 
 14986 |                   } 
 14987 |                } 
 14988 |                #ifndef exprtk_disable_string_capabilities 
 14989 |                else if (is_generally_string_node(arg_list_[i])) 
 14990 |                { 
 14991 |                   string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0); 
 14992 |  
 14993 |                   if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i]))) 
 14994 |                      return false; 
 14995 |  
 14996 |                   ts.size = sbn->size(); 
 14997 |                   ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base())); 
 14998 |                   ts.type = type_store_t::e_string; 
 14999 |  
 15000 |                   range_list_[i].data      = ts.data; 
 15001 |                   range_list_[i].size      = ts.size; 
 15002 |                   range_list_[i].type_size = sizeof(char); 
 15003 |                   range_list_[i].str_node  = sbn; 
 15004 |  
 15005 |                   range_interface_t* ri = reinterpret_cast<range_interface_t*>(0); 
 15006 |  
 15007 |                   if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i]))) 
 15008 |                      return false; 
 15009 |  
 15010 |                   const range_t& rp = ri->range_ref(); 
 15011 |  
 15012 |                   if ( 
 15013 |                        rp.const_range() && 
 15014 |                        is_const_string_range_node(arg_list_[i]) 
 15015 |                      ) 
 15016 |                   { 
 15017 |                      ts.size = rp.const_size(); 
 15018 |                      ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second; 
 15019 |                      range_list_[i].range = reinterpret_cast<range_t*>(0); 
 15020 |                   } 
 15021 |                   else 
 15022 |                   { 
 15023 |                      range_list_[i].range = &(ri->range_ref()); 
 15024 |                      range_param_list_.push_back(i); 
 15025 |                   } 
 15026 |                } 
 15027 |                #endif 
 15028 |                else if (is_variable_node(arg_list_[i])) 
 15029 |                { 
 15030 |                   variable_node_ptr_t var = variable_node_ptr_t(0); 
 15031 |  
 15032 |                   if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i]))) 
 15033 |                      return false; 
 15034 |  
 15035 |                   ts.size = 1; 
 15036 |                   ts.data = &var->ref(); 
 15037 |                   ts.type = type_store_t::e_scalar; 
 15038 |                } 
 15039 |                else 
 15040 |                { 
 15041 |                   ts.size = 1; 
 15042 |                   ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]); 
 15043 |                   ts.type = type_store_t::e_scalar; 
 15044 |                } 
 15045 |  
 15046 |                branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i])); 
 15047 |             } 
 15048 |  
 15049 |             return true; 
 15050 |          } 
 15051 |  
 15052 |          inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const 
 15053 |          { 
 15054 |             return this < (&fn); 
 15055 |          } 
 15056 |  
 15057 |          inline T value() const exprtk_override 
 15058 |          { 
 15059 |             if (populate_value_list()) 
 15060 |             { 
 15061 |                typedef typename GenericFunction::parameter_list_t parameter_list_t; 
 15062 |  
 15063 |                return (*function_)(parameter_list_t(typestore_list_)); 
 15064 |             } 
 15065 |  
 15066 |             return std::numeric_limits<T>::quiet_NaN(); 
 15067 |          } 
 15068 |  
 15069 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15070 |          { 
 15071 |             return expression_node<T>::e_genfunction; 
 15072 |          } 
 15073 |  
 15074 |          inline bool valid() const exprtk_override 
 15075 |          { 
 15076 |             return function_; 
 15077 |          } 
 15078 |  
 15079 |       protected: 
 15080 |  
 15081 |          inline virtual bool populate_value_list() const 
 15082 |          { 
 15083 |             for (std::size_t i = 0; i < branch_.size(); ++i) 
 15084 |             { 
 15085 |                expr_as_vec1_store_[i] = branch_[i].first->value(); 
 15086 |             } 
 15087 |  
 15088 |             if (!range_param_list_.empty()) 
 15089 |             { 
 15090 |                assert(range_param_list_.size() <= branch_.size()); 
 15091 |  
 15092 |                for (std::size_t i = 0; i < range_param_list_.size(); ++i) 
 15093 |                { 
 15094 |                   const std::size_t  index = range_param_list_[i]; 
 15095 |                   range_data_type_t& rdt   = range_list_[index]; 
 15096 |  
 15097 |                   const range_t& rp = (*rdt.range); 
 15098 |                   std::size_t r0    = 0; 
 15099 |                   std::size_t r1    = 0; 
 15100 |  
 15101 |                   const std::size_t data_size = 
 15102 |                   #ifndef exprtk_disable_string_capabilities 
 15103 |                      rdt.str_node ? rdt.str_node->size() : rdt.size; 
 15104 |                   #else 
 15105 |                      rdt.size; 
 15106 |                   #endif 
 15107 |  
 15108 |                   if (!rp(r0, r1, data_size)) 
 15109 |                   { 
 15110 |                      return false; 
 15111 |                   } 
 15112 |  
 15113 |                   type_store_t& ts = typestore_list_[index]; 
 15114 |  
 15115 |                   ts.size = rp.cache_size(); 
 15116 |                   #ifndef exprtk_disable_string_capabilities 
 15117 |                   if (ts.type == type_store_t::e_string) 
 15118 |                      ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first; 
 15119 |                   else 
 15120 |                   #endif 
 15121 |                      ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size); 
 15122 |                } 
 15123 |             } 
 15124 |  
 15125 |             return true; 
 15126 |          } 
 15127 |  
 15128 |          GenericFunction* function_; 
 15129 |          mutable typestore_list_t typestore_list_; 
 15130 |  
 15131 |       private: 
 15132 |  
 15133 |          std::vector<expression_ptr> arg_list_; 
 15134 |          std::vector<branch_t>       branch_; 
 15135 |          std::vector<vecview_t>      vv_list_; 
 15136 |          mutable tmp_vs_t            expr_as_vec1_store_; 
 15137 |          mutable range_list_t        range_list_; 
 15138 |          std::vector<std::size_t>    range_param_list_; 
 15139 |       }; 
 15140 |  
 15141 |       #ifndef exprtk_disable_string_capabilities 
 15142 |       template <typename T, typename StringFunction> 
 15143 |       class string_function_node : public generic_function_node<T,StringFunction> 
 15144 |                                  , public string_base_node<T> 
 15145 |                                  , public range_interface <T> 
 15146 |       { 
 15147 |       public: 
 15148 |  
 15149 |          typedef generic_function_node<T,StringFunction> gen_function_t; 
 15150 |          typedef typename range_interface<T>::range_t range_t; 
 15151 |  
 15152 |          string_function_node(StringFunction* func, 
 15153 |                               const std::vector<typename gen_function_t::expression_ptr>& arg_list) 
 15154 |          : gen_function_t(arg_list,func) 
 15155 |          { 
 15156 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 15157 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 15158 |             range_.cache.first  = range_.n0_c.second; 
 15159 |             range_.cache.second = range_.n1_c.second; 
 15160 |             assert(valid()); 
 15161 |          } 
 15162 |  
 15163 |          inline bool operator <(const string_function_node<T,StringFunction>& fn) const 
 15164 |          { 
 15165 |             return this < (&fn); 
 15166 |          } 
 15167 |  
 15168 |          inline T value() const exprtk_override 
 15169 |          { 
 15170 |             if (gen_function_t::populate_value_list()) 
 15171 |             { 
 15172 |                typedef typename StringFunction::parameter_list_t parameter_list_t; 
 15173 |  
 15174 |                const T result = 
 15175 |                   (*gen_function_t::function_) 
 15176 |                   ( 
 15177 |                      ret_string_, 
 15178 |                      parameter_list_t(gen_function_t::typestore_list_) 
 15179 |                   ); 
 15180 |  
 15181 |                range_.n1_c.second  = ret_string_.size(); 
 15182 |                range_.cache.second = range_.n1_c.second; 
 15183 |  
 15184 |                return result; 
 15185 |             } 
 15186 |  
 15187 |             return std::numeric_limits<T>::quiet_NaN(); 
 15188 |          } 
 15189 |  
 15190 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15191 |          { 
 15192 |             return expression_node<T>::e_strfunction; 
 15193 |          } 
 15194 |  
 15195 |          inline bool valid() const exprtk_override 
 15196 |          { 
 15197 |             return gen_function_t::function_; 
 15198 |          } 
 15199 |  
 15200 |          std::string str() const exprtk_override 
 15201 |          { 
 15202 |             return ret_string_; 
 15203 |          } 
 15204 |  
 15205 |          char_cptr base() const exprtk_override 
 15206 |          { 
 15207 |            return &ret_string_[0]; 
 15208 |          } 
 15209 |  
 15210 |          std::size_t size() const exprtk_override 
 15211 |          { 
 15212 |             return ret_string_.size(); 
 15213 |          } 
 15214 |  
 15215 |          range_t& range_ref() exprtk_override 
 15216 |          { 
 15217 |             return range_; 
 15218 |          } 
 15219 |  
 15220 |          const range_t& range_ref() const exprtk_override 
 15221 |          { 
 15222 |             return range_; 
 15223 |          } 
 15224 |  
 15225 |       protected: 
 15226 |  
 15227 |          mutable range_t     range_; 
 15228 |          mutable std::string ret_string_; 
 15229 |       }; 
 15230 |       #endif 
 15231 |  
 15232 |       template <typename T, typename GenericFunction> 
 15233 |       class multimode_genfunction_node : public generic_function_node<T,GenericFunction> 
 15234 |       { 
 15235 |       public: 
 15236 |  
 15237 |          typedef generic_function_node<T,GenericFunction> gen_function_t; 
 15238 |          typedef typename gen_function_t::range_t         range_t; 
 15239 |  
 15240 |          multimode_genfunction_node(GenericFunction* func, 
 15241 |                                     const std::size_t& param_seq_index, 
 15242 |                                     const std::vector<typename gen_function_t::expression_ptr>& arg_list) 
 15243 |          : gen_function_t(arg_list,func) 
 15244 |          , param_seq_index_(param_seq_index) 
 15245 |          {} 
 15246 |  
 15247 |          inline T value() const exprtk_override 
 15248 |          { 
 15249 |             assert(gen_function_t::valid()); 
 15250 |  
 15251 |             if (gen_function_t::populate_value_list()) 
 15252 |             { 
 15253 |                typedef typename GenericFunction::parameter_list_t parameter_list_t; 
 15254 |  
 15255 |                return 
 15256 |                   (*gen_function_t::function_) 
 15257 |                   ( 
 15258 |                      param_seq_index_, 
 15259 |                      parameter_list_t(gen_function_t::typestore_list_) 
 15260 |                   ); 
 15261 |             } 
 15262 |  
 15263 |             return std::numeric_limits<T>::quiet_NaN(); 
 15264 |          } 
 15265 |  
 15266 |          inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final 
 15267 |          { 
 15268 |             return expression_node<T>::e_genfunction; 
 15269 |          } 
 15270 |  
 15271 |       private: 
 15272 |  
 15273 |          std::size_t param_seq_index_; 
 15274 |       }; 
 15275 |  
 15276 |       #ifndef exprtk_disable_string_capabilities 
 15277 |       template <typename T, typename StringFunction> 
 15278 |       class multimode_strfunction_node exprtk_final : public string_function_node<T,StringFunction> 
 15279 |       { 
 15280 |       public: 
 15281 |  
 15282 |          typedef string_function_node<T,StringFunction> str_function_t; 
 15283 |          typedef typename str_function_t::range_t range_t; 
 15284 |  
 15285 |          multimode_strfunction_node(StringFunction* func, 
 15286 |                                     const std::size_t& param_seq_index, 
 15287 |                                     const std::vector<typename str_function_t::expression_ptr>& arg_list) 
 15288 |          : str_function_t(func,arg_list) 
 15289 |          , param_seq_index_(param_seq_index) 
 15290 |          {} 
 15291 |  
 15292 |          inline T value() const exprtk_override 
 15293 |          { 
 15294 |             if (str_function_t::populate_value_list()) 
 15295 |             { 
 15296 |                typedef typename StringFunction::parameter_list_t parameter_list_t; 
 15297 |  
 15298 |                const T result = 
 15299 |                   (*str_function_t::function_) 
 15300 |                   ( 
 15301 |                      param_seq_index_, 
 15302 |                      str_function_t::ret_string_, 
 15303 |                      parameter_list_t(str_function_t::typestore_list_) 
 15304 |                   ); 
 15305 |  
 15306 |                str_function_t::range_.n1_c.second  = str_function_t::ret_string_.size(); 
 15307 |                str_function_t::range_.cache.second = str_function_t::range_.n1_c.second; 
 15308 |  
 15309 |                return result; 
 15310 |             } 
 15311 |  
 15312 |             return std::numeric_limits<T>::quiet_NaN(); 
 15313 |          } 
 15314 |  
 15315 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15316 |          { 
 15317 |             return expression_node<T>::e_strfunction; 
 15318 |          } 
 15319 |  
 15320 |       private: 
 15321 |  
 15322 |          const std::size_t param_seq_index_; 
 15323 |       }; 
 15324 |       #endif 
 15325 |  
 15326 |       class return_exception {}; 
 15327 |  
 15328 |       template <typename T> 
 15329 |       class null_igenfunc 
 15330 |       { 
 15331 |       public: 
 15332 |  
 15333 |          virtual ~null_igenfunc() 
 15334 |          {} 
 15335 |  
 15336 |          typedef type_store<T> generic_type; 
 15337 |          typedef typename generic_type::parameter_list parameter_list_t; 
 15338 |  
 15339 |          inline virtual T operator() (parameter_list_t) 
 15340 |          { 
 15341 |             return std::numeric_limits<T>::quiet_NaN(); 
 15342 |          } 
 15343 |       }; 
 15344 |  
 15345 |       #ifndef exprtk_disable_return_statement 
 15346 |       template <typename T> 
 15347 |       class return_node exprtk_final : public generic_function_node<T,null_igenfunc<T> > 
 15348 |       { 
 15349 |       public: 
 15350 |  
 15351 |          typedef results_context<T>   results_context_t; 
 15352 |          typedef null_igenfunc<T>     igeneric_function_t; 
 15353 |          typedef igeneric_function_t* igeneric_function_ptr; 
 15354 |          typedef generic_function_node<T,igeneric_function_t> gen_function_t; 
 15355 |  
 15356 |          return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list, 
 15357 |                      results_context_t& rc) 
 15358 |          : gen_function_t  (arg_list) 
 15359 |          , results_context_(&rc) 
 15360 |          { 
 15361 |             assert(valid()); 
 15362 |          } 
 15363 |  
 15364 |          inline T value() const exprtk_override 
 15365 |          { 
 15366 |             if (gen_function_t::populate_value_list()) 
 15367 |             { 
 15368 |                typedef typename type_store<T>::parameter_list parameter_list_t; 
 15369 |  
 15370 |                results_context_-> 
 15371 |                   assign(parameter_list_t(gen_function_t::typestore_list_)); 
 15372 |  
 15373 |                throw return_exception(); 
 15374 |             } 
 15375 |  
 15376 |             return std::numeric_limits<T>::quiet_NaN(); 
 15377 |          } 
 15378 |  
 15379 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15380 |          { 
 15381 |             return expression_node<T>::e_return; 
 15382 |          } 
 15383 |  
 15384 |          inline bool valid() const exprtk_override 
 15385 |          { 
 15386 |             return results_context_; 
 15387 |          } 
 15388 |  
 15389 |       private: 
 15390 |  
 15391 |          results_context_t* results_context_; 
 15392 |       }; 
 15393 |  
 15394 |       template <typename T> 
 15395 |       class return_envelope_node exprtk_final : public expression_node<T> 
 15396 |       { 
 15397 |       public: 
 15398 |  
 15399 |          typedef expression_node<T>* expression_ptr; 
 15400 |          typedef results_context<T>  results_context_t; 
 15401 |          typedef std::pair<expression_ptr,bool> branch_t; 
 15402 |  
 15403 |          return_envelope_node(expression_ptr body, results_context_t& rc) 
 15404 |          : results_context_(&rc  ) 
 15405 |          , return_invoked_ (false) 
 15406 |          { 
 15407 |             construct_branch_pair(body_, body); 
 15408 |             assert(valid()); 
 15409 |          } 
 15410 |  
 15411 |          inline T value() const exprtk_override 
 15412 |          { 
 15413 |             try 
 15414 |             { 
 15415 |                return_invoked_ = false; 
 15416 |                results_context_->clear(); 
 15417 |  
 15418 |                return body_.first->value(); 
 15419 |             } 
 15420 |             catch(const return_exception&) 
 15421 |             { 
 15422 |                return_invoked_ = true; 
 15423 |  
 15424 |                return std::numeric_limits<T>::quiet_NaN(); 
 15425 |             } 
 15426 |          } 
 15427 |  
 15428 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15429 |          { 
 15430 |             return expression_node<T>::e_retenv; 
 15431 |          } 
 15432 |  
 15433 |          inline bool valid() const exprtk_override 
 15434 |          { 
 15435 |             return results_context_ && body_.first; 
 15436 |          } 
 15437 |  
 15438 |          inline bool* retinvk_ptr() 
 15439 |          { 
 15440 |             return &return_invoked_; 
 15441 |          } 
 15442 |  
 15443 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 15444 |          { 
 15445 |             expression_node<T>::ndb_t::collect(body_, node_delete_list); 
 15446 |          } 
 15447 |  
 15448 |          std::size_t node_depth() const exprtk_override 
 15449 |          { 
 15450 |             return expression_node<T>::ndb_t::compute_node_depth(body_); 
 15451 |          } 
 15452 |  
 15453 |       private: 
 15454 |  
 15455 |          results_context_t* results_context_; 
 15456 |          mutable bool        return_invoked_; 
 15457 |          branch_t                      body_; 
 15458 |       }; 
 15459 |       #endif 
 15460 |  
 15461 |       #define exprtk_define_unary_op(OpName)                    \ 
 15462 |       template <typename T>                                     \ 
 15463 |       struct OpName##_op                                        \ 
 15464 |       {                                                         \ 
 15465 |          typedef typename functor_t<T>::Type Type;              \ 
 15466 |          typedef typename expression_node<T>::node_type node_t; \ 
 15467 |                                                                 \ 
 15468 |          static inline T process(Type v)                        \ 
 15469 |          {                                                      \ 
 15470 |             return numeric:: OpName (v);                        \ 
 15471 |          }                                                      \ 
 15472 |                                                                 \ 
 15473 |          static inline node_t type()                            \ 
 15474 |          {                                                      \ 
 15475 |             return expression_node<T>::e_##OpName;              \ 
 15476 |          }                                                      \ 
 15477 |                                                                 \ 
 15478 |          static inline details::operator_type operation()       \ 
 15479 |          {                                                      \ 
 15480 |             return details::e_##OpName;                         \ 
 15481 |          }                                                      \ 
 15482 |       };                                                        \ 
 15483 |  
 15484 |       exprtk_define_unary_op(abs  ) 
 15485 |       exprtk_define_unary_op(acos ) 
 15486 |       exprtk_define_unary_op(acosh) 
 15487 |       exprtk_define_unary_op(asin ) 
 15488 |       exprtk_define_unary_op(asinh) 
 15489 |       exprtk_define_unary_op(atan ) 
 15490 |       exprtk_define_unary_op(atanh) 
 15491 |       exprtk_define_unary_op(ceil ) 
 15492 |       exprtk_define_unary_op(cos  ) 
 15493 |       exprtk_define_unary_op(cosh ) 
 15494 |       exprtk_define_unary_op(cot  ) 
 15495 |       exprtk_define_unary_op(csc  ) 
 15496 |       exprtk_define_unary_op(d2g  ) 
 15497 |       exprtk_define_unary_op(d2r  ) 
 15498 |       exprtk_define_unary_op(erf  ) 
 15499 |       exprtk_define_unary_op(erfc ) 
 15500 |       exprtk_define_unary_op(exp  ) 
 15501 |       exprtk_define_unary_op(expm1) 
 15502 |       exprtk_define_unary_op(floor) 
 15503 |       exprtk_define_unary_op(frac ) 
 15504 |       exprtk_define_unary_op(g2d  ) 
 15505 |       exprtk_define_unary_op(log  ) 
 15506 |       exprtk_define_unary_op(log10) 
 15507 |       exprtk_define_unary_op(log2 ) 
 15508 |       exprtk_define_unary_op(log1p) 
 15509 |       exprtk_define_unary_op(ncdf ) 
 15510 |       exprtk_define_unary_op(neg  ) 
 15511 |       exprtk_define_unary_op(notl ) 
 15512 |       exprtk_define_unary_op(pos  ) 
 15513 |       exprtk_define_unary_op(r2d  ) 
 15514 |       exprtk_define_unary_op(round) 
 15515 |       exprtk_define_unary_op(sec  ) 
 15516 |       exprtk_define_unary_op(sgn  ) 
 15517 |       exprtk_define_unary_op(sin  ) 
 15518 |       exprtk_define_unary_op(sinc ) 
 15519 |       exprtk_define_unary_op(sinh ) 
 15520 |       exprtk_define_unary_op(sqrt ) 
 15521 |       exprtk_define_unary_op(tan  ) 
 15522 |       exprtk_define_unary_op(tanh ) 
 15523 |       exprtk_define_unary_op(trunc) 
 15524 |       #undef exprtk_define_unary_op 
 15525 |  
 15526 |       template <typename T> 
 15527 |       struct opr_base 
 15528 |       { 
 15529 |          typedef typename details::functor_t<T>::Type    Type; 
 15530 |          typedef typename details::functor_t<T>::RefType RefType; 
 15531 |          typedef typename details::functor_t<T> functor_t; 
 15532 |          typedef typename functor_t::qfunc_t    quaternary_functor_t; 
 15533 |          typedef typename functor_t::tfunc_t    trinary_functor_t; 
 15534 |          typedef typename functor_t::bfunc_t    binary_functor_t; 
 15535 |          typedef typename functor_t::ufunc_t    unary_functor_t; 
 15536 |       }; 
 15537 |  
 15538 |       template <typename T> 
 15539 |       struct add_op : public opr_base<T> 
 15540 |       { 
 15541 |          typedef typename opr_base<T>::Type    Type; 
 15542 |          typedef typename opr_base<T>::RefType RefType; 
 15543 |  
 15544 |          static inline T process(Type t1, Type t2) { return t1 + t2; } 
 15545 |          static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; } 
 15546 |          static inline void assign(RefType t1, Type t2) { t1 += t2; } 
 15547 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; } 
 15548 |          static inline details::operator_type operation() { return details::e_add; } 
 15549 |       }; 
 15550 |  
 15551 |       template <typename T> 
 15552 |       struct mul_op : public opr_base<T> 
 15553 |       { 
 15554 |          typedef typename opr_base<T>::Type    Type; 
 15555 |          typedef typename opr_base<T>::RefType RefType; 
 15556 |  
 15557 |          static inline T process(Type t1, Type t2) { return t1 * t2; } 
 15558 |          static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; } 
 15559 |          static inline void assign(RefType t1, Type t2) { t1 *= t2; } 
 15560 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; } 
 15561 |          static inline details::operator_type operation() { return details::e_mul; } 
 15562 |       }; 
 15563 |  
 15564 |       template <typename T> 
 15565 |       struct sub_op : public opr_base<T> 
 15566 |       { 
 15567 |          typedef typename opr_base<T>::Type    Type; 
 15568 |          typedef typename opr_base<T>::RefType RefType; 
 15569 |  
 15570 |          static inline T process(Type t1, Type t2) { return t1 - t2; } 
 15571 |          static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; } 
 15572 |          static inline void assign(RefType t1, Type t2) { t1 -= t2; } 
 15573 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; } 
 15574 |          static inline details::operator_type operation() { return details::e_sub; } 
 15575 |       }; 
 15576 |  
 15577 |       template <typename T> 
 15578 |       struct div_op : public opr_base<T> 
 15579 |       { 
 15580 |          typedef typename opr_base<T>::Type    Type; 
 15581 |          typedef typename opr_base<T>::RefType RefType; 
 15582 |  
 15583 |          static inline T process(Type t1, Type t2) { return t1 / t2; } 
 15584 |          static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; } 
 15585 |          static inline void assign(RefType t1, Type t2) { t1 /= t2; } 
 15586 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; } 
 15587 |          static inline details::operator_type operation() { return details::e_div; } 
 15588 |       }; 
 15589 |  
 15590 |       template <typename T> 
 15591 |       struct mod_op : public opr_base<T> 
 15592 |       { 
 15593 |          typedef typename opr_base<T>::Type    Type; 
 15594 |          typedef typename opr_base<T>::RefType RefType; 
 15595 |  
 15596 |          static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); } 
 15597 |          static inline void assign(RefType t1, Type t2) { t1 = numeric::modulus<T>(t1,t2); } 
 15598 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; } 
 15599 |          static inline details::operator_type operation() { return details::e_mod; } 
 15600 |       }; 
 15601 |  
 15602 |       template <typename T> 
 15603 |       struct pow_op : public opr_base<T> 
 15604 |       { 
 15605 |          typedef typename opr_base<T>::Type    Type; 
 15606 |          typedef typename opr_base<T>::RefType RefType; 
 15607 |  
 15608 |          static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); } 
 15609 |          static inline void assign(RefType t1, Type t2) { t1 = numeric::pow<T>(t1,t2); } 
 15610 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; } 
 15611 |          static inline details::operator_type operation() { return details::e_pow; } 
 15612 |       }; 
 15613 |  
 15614 |       template <typename T> 
 15615 |       struct lt_op : public opr_base<T> 
 15616 |       { 
 15617 |          typedef typename opr_base<T>::Type Type; 
 15618 |  
 15619 |          static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); } 
 15620 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); } 
 15621 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; } 
 15622 |          static inline details::operator_type operation() { return details::e_lt; } 
 15623 |       }; 
 15624 |  
 15625 |       template <typename T> 
 15626 |       struct lte_op : public opr_base<T> 
 15627 |       { 
 15628 |          typedef typename opr_base<T>::Type Type; 
 15629 |  
 15630 |          static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); } 
 15631 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); } 
 15632 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; } 
 15633 |          static inline details::operator_type operation() { return details::e_lte; } 
 15634 |       }; 
 15635 |  
 15636 |       template <typename T> 
 15637 |       struct gt_op : public opr_base<T> 
 15638 |       { 
 15639 |          typedef typename opr_base<T>::Type Type; 
 15640 |  
 15641 |          static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); } 
 15642 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); } 
 15643 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; } 
 15644 |          static inline details::operator_type operation() { return details::e_gt; } 
 15645 |       }; 
 15646 |  
 15647 |       template <typename T> 
 15648 |       struct gte_op : public opr_base<T> 
 15649 |       { 
 15650 |          typedef typename opr_base<T>::Type Type; 
 15651 |  
 15652 |          static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); } 
 15653 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); } 
 15654 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; } 
 15655 |          static inline details::operator_type operation() { return details::e_gte; } 
 15656 |       }; 
 15657 |  
 15658 |       template <typename T> 
 15659 |       struct eq_op : public opr_base<T> 
 15660 |       { 
 15661 |          typedef typename opr_base<T>::Type Type; 
 15662 |          static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); } 
 15663 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); } 
 15664 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; } 
 15665 |          static inline details::operator_type operation() { return details::e_eq; } 
 15666 |       }; 
 15667 |  
 15668 |       template <typename T> 
 15669 |       struct equal_op : public opr_base<T> 
 15670 |       { 
 15671 |          typedef typename opr_base<T>::Type Type; 
 15672 |  
 15673 |          static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); } 
 15674 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); } 
 15675 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; } 
 15676 |          static inline details::operator_type operation() { return details::e_equal; } 
 15677 |       }; 
 15678 |  
 15679 |       template <typename T> 
 15680 |       struct ne_op : public opr_base<T> 
 15681 |       { 
 15682 |          typedef typename opr_base<T>::Type Type; 
 15683 |  
 15684 |          static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); } 
 15685 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); } 
 15686 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; } 
 15687 |          static inline details::operator_type operation() { return details::e_ne; } 
 15688 |       }; 
 15689 |  
 15690 |       template <typename T> 
 15691 |       struct and_op : public opr_base<T> 
 15692 |       { 
 15693 |          typedef typename opr_base<T>::Type Type; 
 15694 |  
 15695 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); } 
 15696 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; } 
 15697 |          static inline details::operator_type operation() { return details::e_and; } 
 15698 |       }; 
 15699 |  
 15700 |       template <typename T> 
 15701 |       struct nand_op : public opr_base<T> 
 15702 |       { 
 15703 |          typedef typename opr_base<T>::Type Type; 
 15704 |  
 15705 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); } 
 15706 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; } 
 15707 |          static inline details::operator_type operation() { return details::e_nand; } 
 15708 |       }; 
 15709 |  
 15710 |       template <typename T> 
 15711 |       struct or_op : public opr_base<T> 
 15712 |       { 
 15713 |          typedef typename opr_base<T>::Type Type; 
 15714 |  
 15715 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); } 
 15716 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; } 
 15717 |          static inline details::operator_type operation() { return details::e_or; } 
 15718 |       }; 
 15719 |  
 15720 |       template <typename T> 
 15721 |       struct nor_op : public opr_base<T> 
 15722 |       { 
 15723 |          typedef typename opr_base<T>::Type Type; 
 15724 |  
 15725 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); } 
 15726 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; } 
 15727 |          static inline details::operator_type operation() { return details::e_nor; } 
 15728 |       }; 
 15729 |  
 15730 |       template <typename T> 
 15731 |       struct xor_op : public opr_base<T> 
 15732 |       { 
 15733 |          typedef typename opr_base<T>::Type Type; 
 15734 |  
 15735 |          static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); } 
 15736 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; } 
 15737 |          static inline details::operator_type operation() { return details::e_xor; } 
 15738 |       }; 
 15739 |  
 15740 |       template <typename T> 
 15741 |       struct xnor_op : public opr_base<T> 
 15742 |       { 
 15743 |          typedef typename opr_base<T>::Type Type; 
 15744 |  
 15745 |          static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); } 
 15746 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; } 
 15747 |          static inline details::operator_type operation() { return details::e_xnor; } 
 15748 |       }; 
 15749 |  
 15750 |       template <typename T> 
 15751 |       struct in_op : public opr_base<T> 
 15752 |       { 
 15753 |          typedef typename opr_base<T>::Type Type; 
 15754 |  
 15755 |          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); } 
 15756 |          static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); } 
 15757 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; } 
 15758 |          static inline details::operator_type operation() { return details::e_in; } 
 15759 |       }; 
 15760 |  
 15761 |       template <typename T> 
 15762 |       struct like_op : public opr_base<T> 
 15763 |       { 
 15764 |          typedef typename opr_base<T>::Type Type; 
 15765 |  
 15766 |          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); } 
 15767 |          static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); } 
 15768 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; } 
 15769 |          static inline details::operator_type operation() { return details::e_like; } 
 15770 |       }; 
 15771 |  
 15772 |       template <typename T> 
 15773 |       struct ilike_op : public opr_base<T> 
 15774 |       { 
 15775 |          typedef typename opr_base<T>::Type Type; 
 15776 |  
 15777 |          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); } 
 15778 |          static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); } 
 15779 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; } 
 15780 |          static inline details::operator_type operation() { return details::e_ilike; } 
 15781 |       }; 
 15782 |  
 15783 |       template <typename T> 
 15784 |       struct inrange_op : public opr_base<T> 
 15785 |       { 
 15786 |          typedef typename opr_base<T>::Type Type; 
 15787 |  
 15788 |          static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); } 
 15789 |          static inline T process(const std::string& t0, const std::string& t1, const std::string& t2) 
 15790 |          { 
 15791 |             return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); 
 15792 |          } 
 15793 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_inranges; } 
 15794 |          static inline details::operator_type operation() { return details::e_inrange; } 
 15795 |       }; 
 15796 |  
 15797 |       template <typename T> 
 15798 |       inline T value(details::expression_node<T>* n) 
 15799 |       { 
 15800 |          return n->value(); 
 15801 |       } 
 15802 |  
 15803 |       template <typename T> 
 15804 |       inline T value(std::pair<details::expression_node<T>*,bool> n) 
 15805 |       { 
 15806 |          return n.first->value(); 
 15807 |       } 
 15808 |  
 15809 |       template <typename T> 
 15810 |       inline T value(const T* t) 
 15811 |       { 
 15812 |          return (*t); 
 15813 |       } 
 15814 |  
 15815 |       template <typename T> 
 15816 |       inline T value(const T& t) 
 15817 |       { 
 15818 |          return t; 
 15819 |       } 
 15820 |  
 15821 |       template <typename T> 
 15822 |       struct vararg_add_op exprtk_final : public opr_base<T> 
 15823 |       { 
 15824 |          typedef typename opr_base<T>::Type Type; 
 15825 |  
 15826 |          template <typename Type, 
 15827 |                    typename Allocator, 
 15828 |                    template <typename, typename> class Sequence> 
 15829 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 15830 |          { 
 15831 |             switch (arg_list.size()) 
 15832 |             { 
 15833 |                case 0  : return T(0); 
 15834 |                case 1  : return process_1(arg_list); 
 15835 |                case 2  : return process_2(arg_list); 
 15836 |                case 3  : return process_3(arg_list); 
 15837 |                case 4  : return process_4(arg_list); 
 15838 |                case 5  : return process_5(arg_list); 
 15839 |                default : 
 15840 |                          { 
 15841 |                             T result = T(0); 
 15842 |  
 15843 |                             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 15844 |                             { 
 15845 |                                result += value(arg_list[i]); 
 15846 |                             } 
 15847 |  
 15848 |                             return result; 
 15849 |                          } 
 15850 |             } 
 15851 |          } 
 15852 |  
 15853 |          template <typename Sequence> 
 15854 |          static inline T process_1(const Sequence& arg_list) 
 15855 |          { 
 15856 |             return value(arg_list[0]); 
 15857 |          } 
 15858 |  
 15859 |          template <typename Sequence> 
 15860 |          static inline T process_2(const Sequence& arg_list) 
 15861 |          { 
 15862 |             return value(arg_list[0]) + value(arg_list[1]); 
 15863 |          } 
 15864 |  
 15865 |          template <typename Sequence> 
 15866 |          static inline T process_3(const Sequence& arg_list) 
 15867 |          { 
 15868 |             return value(arg_list[0]) + value(arg_list[1]) + 
 15869 |                    value(arg_list[2]) ; 
 15870 |          } 
 15871 |  
 15872 |          template <typename Sequence> 
 15873 |          static inline T process_4(const Sequence& arg_list) 
 15874 |          { 
 15875 |             return value(arg_list[0]) + value(arg_list[1]) + 
 15876 |                    value(arg_list[2]) + value(arg_list[3]) ; 
 15877 |          } 
 15878 |  
 15879 |          template <typename Sequence> 
 15880 |          static inline T process_5(const Sequence& arg_list) 
 15881 |          { 
 15882 |             return value(arg_list[0]) + value(arg_list[1]) + 
 15883 |                    value(arg_list[2]) + value(arg_list[3]) + 
 15884 |                    value(arg_list[4]) ; 
 15885 |          } 
 15886 |       }; 
 15887 |  
 15888 |       template <typename T> 
 15889 |       struct vararg_mul_op exprtk_final : public opr_base<T> 
 15890 |       { 
 15891 |          typedef typename opr_base<T>::Type Type; 
 15892 |  
 15893 |          template <typename Type, 
 15894 |                    typename Allocator, 
 15895 |                    template <typename, typename> class Sequence> 
 15896 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 15897 |          { 
 15898 |             switch (arg_list.size()) 
 15899 |             { 
 15900 |                case 0  : return T(0); 
 15901 |                case 1  : return process_1(arg_list); 
 15902 |                case 2  : return process_2(arg_list); 
 15903 |                case 3  : return process_3(arg_list); 
 15904 |                case 4  : return process_4(arg_list); 
 15905 |                case 5  : return process_5(arg_list); 
 15906 |                default : 
 15907 |                          { 
 15908 |                             T result = T(value(arg_list[0])); 
 15909 |  
 15910 |                             for (std::size_t i = 1; i < arg_list.size(); ++i) 
 15911 |                             { 
 15912 |                                result *= value(arg_list[i]); 
 15913 |                             } 
 15914 |  
 15915 |                             return result; 
 15916 |                          } 
 15917 |             } 
 15918 |          } 
 15919 |  
 15920 |          template <typename Sequence> 
 15921 |          static inline T process_1(const Sequence& arg_list) 
 15922 |          { 
 15923 |             return value(arg_list[0]); 
 15924 |          } 
 15925 |  
 15926 |          template <typename Sequence> 
 15927 |          static inline T process_2(const Sequence& arg_list) 
 15928 |          { 
 15929 |             return value(arg_list[0]) * value(arg_list[1]); 
 15930 |          } 
 15931 |  
 15932 |          template <typename Sequence> 
 15933 |          static inline T process_3(const Sequence& arg_list) 
 15934 |          { 
 15935 |             return value(arg_list[0]) * value(arg_list[1]) * 
 15936 |                    value(arg_list[2]) ; 
 15937 |          } 
 15938 |  
 15939 |          template <typename Sequence> 
 15940 |          static inline T process_4(const Sequence& arg_list) 
 15941 |          { 
 15942 |             return value(arg_list[0]) * value(arg_list[1]) * 
 15943 |                    value(arg_list[2]) * value(arg_list[3]) ; 
 15944 |          } 
 15945 |  
 15946 |          template <typename Sequence> 
 15947 |          static inline T process_5(const Sequence& arg_list) 
 15948 |          { 
 15949 |             return value(arg_list[0]) * value(arg_list[1]) * 
 15950 |                    value(arg_list[2]) * value(arg_list[3]) * 
 15951 |                    value(arg_list[4]) ; 
 15952 |          } 
 15953 |       }; 
 15954 |  
 15955 |       template <typename T> 
 15956 |       struct vararg_avg_op exprtk_final : public opr_base<T> 
 15957 |       { 
 15958 |          typedef typename opr_base<T>::Type Type; 
 15959 |  
 15960 |          template <typename Type, 
 15961 |                    typename Allocator, 
 15962 |                    template <typename, typename> class Sequence> 
 15963 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 15964 |          { 
 15965 |             switch (arg_list.size()) 
 15966 |             { 
 15967 |                case 0  : return T(0); 
 15968 |                case 1  : return process_1(arg_list); 
 15969 |                case 2  : return process_2(arg_list); 
 15970 |                case 3  : return process_3(arg_list); 
 15971 |                case 4  : return process_4(arg_list); 
 15972 |                case 5  : return process_5(arg_list); 
 15973 |                default : return vararg_add_op<T>::process(arg_list) / T(arg_list.size()); 
 15974 |             } 
 15975 |          } 
 15976 |  
 15977 |          template <typename Sequence> 
 15978 |          static inline T process_1(const Sequence& arg_list) 
 15979 |          { 
 15980 |             return value(arg_list[0]); 
 15981 |          } 
 15982 |  
 15983 |          template <typename Sequence> 
 15984 |          static inline T process_2(const Sequence& arg_list) 
 15985 |          { 
 15986 |             return (value(arg_list[0]) + value(arg_list[1])) / T(2); 
 15987 |          } 
 15988 |  
 15989 |          template <typename Sequence> 
 15990 |          static inline T process_3(const Sequence& arg_list) 
 15991 |          { 
 15992 |             return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3); 
 15993 |          } 
 15994 |  
 15995 |          template <typename Sequence> 
 15996 |          static inline T process_4(const Sequence& arg_list) 
 15997 |          { 
 15998 |             return (value(arg_list[0]) + value(arg_list[1]) + 
 15999 |                     value(arg_list[2]) + value(arg_list[3])) / T(4); 
 16000 |          } 
 16001 |  
 16002 |          template <typename Sequence> 
 16003 |          static inline T process_5(const Sequence& arg_list) 
 16004 |          { 
 16005 |             return (value(arg_list[0]) + value(arg_list[1]) + 
 16006 |                     value(arg_list[2]) + value(arg_list[3]) + 
 16007 |                     value(arg_list[4])) / T(5); 
 16008 |          } 
 16009 |       }; 
 16010 |  
 16011 |       template <typename T> 
 16012 |       struct vararg_min_op exprtk_final : public opr_base<T> 
 16013 |       { 
 16014 |          typedef typename opr_base<T>::Type Type; 
 16015 |  
 16016 |          template <typename Type, 
 16017 |                    typename Allocator, 
 16018 |                    template <typename, typename> class Sequence> 
 16019 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16020 |          { 
 16021 |             switch (arg_list.size()) 
 16022 |             { 
 16023 |                case 0  : return T(0); 
 16024 |                case 1  : return process_1(arg_list); 
 16025 |                case 2  : return process_2(arg_list); 
 16026 |                case 3  : return process_3(arg_list); 
 16027 |                case 4  : return process_4(arg_list); 
 16028 |                case 5  : return process_5(arg_list); 
 16029 |                default : 
 16030 |                          { 
 16031 |                             T result = T(value(arg_list[0])); 
 16032 |  
 16033 |                             for (std::size_t i = 1; i < arg_list.size(); ++i) 
 16034 |                             { 
 16035 |                                const T v = value(arg_list[i]); 
 16036 |  
 16037 |                                if (v < result) 
 16038 |                                   result = v; 
 16039 |                             } 
 16040 |  
 16041 |                             return result; 
 16042 |                          } 
 16043 |             } 
 16044 |          } 
 16045 |  
 16046 |          template <typename Sequence> 
 16047 |          static inline T process_1(const Sequence& arg_list) 
 16048 |          { 
 16049 |             return value(arg_list[0]); 
 16050 |          } 
 16051 |  
 16052 |          template <typename Sequence> 
 16053 |          static inline T process_2(const Sequence& arg_list) 
 16054 |          { 
 16055 |             return std::min<T>(value(arg_list[0]),value(arg_list[1])); 
 16056 |          } 
 16057 |  
 16058 |          template <typename Sequence> 
 16059 |          static inline T process_3(const Sequence& arg_list) 
 16060 |          { 
 16061 |             return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2])); 
 16062 |          } 
 16063 |  
 16064 |          template <typename Sequence> 
 16065 |          static inline T process_4(const Sequence& arg_list) 
 16066 |          { 
 16067 |             return std::min<T>( 
 16068 |                         std::min<T>(value(arg_list[0]), value(arg_list[1])), 
 16069 |                         std::min<T>(value(arg_list[2]), value(arg_list[3]))); 
 16070 |          } 
 16071 |  
 16072 |          template <typename Sequence> 
 16073 |          static inline T process_5(const Sequence& arg_list) 
 16074 |          { 
 16075 |             return std::min<T>( 
 16076 |                    std::min<T>(std::min<T>(value(arg_list[0]), value(arg_list[1])), 
 16077 |                                std::min<T>(value(arg_list[2]), value(arg_list[3]))), 
 16078 |                                value(arg_list[4])); 
 16079 |          } 
 16080 |       }; 
 16081 |  
 16082 |       template <typename T> 
 16083 |       struct vararg_max_op exprtk_final : public opr_base<T> 
 16084 |       { 
 16085 |          typedef typename opr_base<T>::Type Type; 
 16086 |  
 16087 |          template <typename Type, 
 16088 |                    typename Allocator, 
 16089 |                    template <typename, typename> class Sequence> 
 16090 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16091 |          { 
 16092 |             switch (arg_list.size()) 
 16093 |             { 
 16094 |                case 0  : return T(0); 
 16095 |                case 1  : return process_1(arg_list); 
 16096 |                case 2  : return process_2(arg_list); 
 16097 |                case 3  : return process_3(arg_list); 
 16098 |                case 4  : return process_4(arg_list); 
 16099 |                case 5  : return process_5(arg_list); 
 16100 |                default : 
 16101 |                          { 
 16102 |                             T result = T(value(arg_list[0])); 
 16103 |  
 16104 |                             for (std::size_t i = 1; i < arg_list.size(); ++i) 
 16105 |                             { 
 16106 |                                const T v = value(arg_list[i]); 
 16107 |  
 16108 |                                if (v > result) 
 16109 |                                   result = v; 
 16110 |                             } 
 16111 |  
 16112 |                             return result; 
 16113 |                          } 
 16114 |             } 
 16115 |          } 
 16116 |  
 16117 |          template <typename Sequence> 
 16118 |          static inline T process_1(const Sequence& arg_list) 
 16119 |          { 
 16120 |             return value(arg_list[0]); 
 16121 |          } 
 16122 |  
 16123 |          template <typename Sequence> 
 16124 |          static inline T process_2(const Sequence& arg_list) 
 16125 |          { 
 16126 |             return std::max<T>(value(arg_list[0]),value(arg_list[1])); 
 16127 |          } 
 16128 |  
 16129 |          template <typename Sequence> 
 16130 |          static inline T process_3(const Sequence& arg_list) 
 16131 |          { 
 16132 |             return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2])); 
 16133 |          } 
 16134 |  
 16135 |          template <typename Sequence> 
 16136 |          static inline T process_4(const Sequence& arg_list) 
 16137 |          { 
 16138 |             return std::max<T>( 
 16139 |                         std::max<T>(value(arg_list[0]), value(arg_list[1])), 
 16140 |                         std::max<T>(value(arg_list[2]), value(arg_list[3]))); 
 16141 |          } 
 16142 |  
 16143 |          template <typename Sequence> 
 16144 |          static inline T process_5(const Sequence& arg_list) 
 16145 |          { 
 16146 |             return std::max<T>( 
 16147 |                    std::max<T>(std::max<T>(value(arg_list[0]), value(arg_list[1])), 
 16148 |                                std::max<T>(value(arg_list[2]), value(arg_list[3]))), 
 16149 |                                value(arg_list[4])); 
 16150 |          } 
 16151 |       }; 
 16152 |  
 16153 |       template <typename T> 
 16154 |       struct vararg_mand_op exprtk_final : public opr_base<T> 
 16155 |       { 
 16156 |          typedef typename opr_base<T>::Type Type; 
 16157 |  
 16158 |          template <typename Type, 
 16159 |                    typename Allocator, 
 16160 |                    template <typename, typename> class Sequence> 
 16161 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16162 |          { 
 16163 |             switch (arg_list.size()) 
 16164 |             { 
 16165 |                case 1  : return process_1(arg_list); 
 16166 |                case 2  : return process_2(arg_list); 
 16167 |                case 3  : return process_3(arg_list); 
 16168 |                case 4  : return process_4(arg_list); 
 16169 |                case 5  : return process_5(arg_list); 
 16170 |                default : 
 16171 |                          { 
 16172 |                             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 16173 |                             { 
 16174 |                                if (std::equal_to<T>()(T(0), value(arg_list[i]))) 
 16175 |                                   return T(0); 
 16176 |                             } 
 16177 |  
 16178 |                             return T(1); 
 16179 |                          } 
 16180 |             } 
 16181 |          } 
 16182 |  
 16183 |          template <typename Sequence> 
 16184 |          static inline T process_1(const Sequence& arg_list) 
 16185 |          { 
 16186 |             return std::not_equal_to<T>() 
 16187 |                       (T(0), value(arg_list[0])) ? T(1) : T(0); 
 16188 |          } 
 16189 |  
 16190 |          template <typename Sequence> 
 16191 |          static inline T process_2(const Sequence& arg_list) 
 16192 |          { 
 16193 |             return ( 
 16194 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16195 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) 
 16196 |                    ) ? T(1) : T(0); 
 16197 |          } 
 16198 |  
 16199 |          template <typename Sequence> 
 16200 |          static inline T process_3(const Sequence& arg_list) 
 16201 |          { 
 16202 |             return ( 
 16203 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16204 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) && 
 16205 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) 
 16206 |                    ) ? T(1) : T(0); 
 16207 |          } 
 16208 |  
 16209 |          template <typename Sequence> 
 16210 |          static inline T process_4(const Sequence& arg_list) 
 16211 |          { 
 16212 |             return ( 
 16213 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16214 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) && 
 16215 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) && 
 16216 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) 
 16217 |                    ) ? T(1) : T(0); 
 16218 |          } 
 16219 |  
 16220 |          template <typename Sequence> 
 16221 |          static inline T process_5(const Sequence& arg_list) 
 16222 |          { 
 16223 |             return ( 
 16224 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16225 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) && 
 16226 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) && 
 16227 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) && 
 16228 |                      std::not_equal_to<T>()(T(0), value(arg_list[4])) 
 16229 |                    ) ? T(1) : T(0); 
 16230 |          } 
 16231 |       }; 
 16232 |  
 16233 |       template <typename T> 
 16234 |       struct vararg_mor_op exprtk_final : public opr_base<T> 
 16235 |       { 
 16236 |          typedef typename opr_base<T>::Type Type; 
 16237 |  
 16238 |          template <typename Type, 
 16239 |                    typename Allocator, 
 16240 |                    template <typename, typename> class Sequence> 
 16241 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16242 |          { 
 16243 |             switch (arg_list.size()) 
 16244 |             { 
 16245 |                case 1  : return process_1(arg_list); 
 16246 |                case 2  : return process_2(arg_list); 
 16247 |                case 3  : return process_3(arg_list); 
 16248 |                case 4  : return process_4(arg_list); 
 16249 |                case 5  : return process_5(arg_list); 
 16250 |                default : 
 16251 |                          { 
 16252 |                             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 16253 |                             { 
 16254 |                                if (std::not_equal_to<T>()(T(0), value(arg_list[i]))) 
 16255 |                                   return T(1); 
 16256 |                             } 
 16257 |  
 16258 |                             return T(0); 
 16259 |                          } 
 16260 |             } 
 16261 |          } 
 16262 |  
 16263 |          template <typename Sequence> 
 16264 |          static inline T process_1(const Sequence& arg_list) 
 16265 |          { 
 16266 |             return std::not_equal_to<T>() 
 16267 |                       (T(0), value(arg_list[0])) ? T(1) : T(0); 
 16268 |          } 
 16269 |  
 16270 |          template <typename Sequence> 
 16271 |          static inline T process_2(const Sequence& arg_list) 
 16272 |          { 
 16273 |             return ( 
 16274 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16275 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) 
 16276 |                    ) ? T(1) : T(0); 
 16277 |          } 
 16278 |  
 16279 |          template <typename Sequence> 
 16280 |          static inline T process_3(const Sequence& arg_list) 
 16281 |          { 
 16282 |             return ( 
 16283 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16284 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) || 
 16285 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) 
 16286 |                    ) ? T(1) : T(0); 
 16287 |          } 
 16288 |  
 16289 |          template <typename Sequence> 
 16290 |          static inline T process_4(const Sequence& arg_list) 
 16291 |          { 
 16292 |             return ( 
 16293 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16294 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) || 
 16295 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) || 
 16296 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) 
 16297 |                    ) ? T(1) : T(0); 
 16298 |          } 
 16299 |  
 16300 |          template <typename Sequence> 
 16301 |          static inline T process_5(const Sequence& arg_list) 
 16302 |          { 
 16303 |             return ( 
 16304 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16305 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) || 
 16306 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) || 
 16307 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) || 
 16308 |                      std::not_equal_to<T>()(T(0), value(arg_list[4])) 
 16309 |                    ) ? T(1) : T(0); 
 16310 |          } 
 16311 |       }; 
 16312 |  
 16313 |       template <typename T> 
 16314 |       struct vararg_multi_op exprtk_final : public opr_base<T> 
 16315 |       { 
 16316 |          typedef typename opr_base<T>::Type Type; 
 16317 |  
 16318 |          template <typename Type, 
 16319 |                    typename Allocator, 
 16320 |                    template <typename, typename> class Sequence> 
 16321 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16322 |          { 
 16323 |             switch (arg_list.size()) 
 16324 |             { 
 16325 |                case 0  : return std::numeric_limits<T>::quiet_NaN(); 
 16326 |                case 1  : return process_1(arg_list); 
 16327 |                case 2  : return process_2(arg_list); 
 16328 |                case 3  : return process_3(arg_list); 
 16329 |                case 4  : return process_4(arg_list); 
 16330 |                case 5  : return process_5(arg_list); 
 16331 |                case 6  : return process_6(arg_list); 
 16332 |                case 7  : return process_7(arg_list); 
 16333 |                case 8  : return process_8(arg_list); 
 16334 |                default : 
 16335 |                         { 
 16336 |                            for (std::size_t i = 0; i < (arg_list.size() - 1); ++i) 
 16337 |                            { 
 16338 |                               value(arg_list[i]); 
 16339 |                            } 
 16340 |                            return value(arg_list.back()); 
 16341 |                         } 
 16342 |             } 
 16343 |          } 
 16344 |  
 16345 |          template <typename Sequence> 
 16346 |          static inline T process_1(const Sequence& arg_list) 
 16347 |          { 
 16348 |             return value(arg_list[0]); 
 16349 |          } 
 16350 |  
 16351 |          template <typename Sequence> 
 16352 |          static inline T process_2(const Sequence& arg_list) 
 16353 |          { 
 16354 |                    value(arg_list[0]); 
 16355 |             return value(arg_list[1]); 
 16356 |          } 
 16357 |  
 16358 |          template <typename Sequence> 
 16359 |          static inline T process_3(const Sequence& arg_list) 
 16360 |          { 
 16361 |                    value(arg_list[0]); 
 16362 |                    value(arg_list[1]); 
 16363 |             return value(arg_list[2]); 
 16364 |          } 
 16365 |  
 16366 |          template <typename Sequence> 
 16367 |          static inline T process_4(const Sequence& arg_list) 
 16368 |          { 
 16369 |                    value(arg_list[0]); 
 16370 |                    value(arg_list[1]); 
 16371 |                    value(arg_list[2]); 
 16372 |             return value(arg_list[3]); 
 16373 |          } 
 16374 |  
 16375 |          template <typename Sequence> 
 16376 |          static inline T process_5(const Sequence& arg_list) 
 16377 |          { 
 16378 |                    value(arg_list[0]); 
 16379 |                    value(arg_list[1]); 
 16380 |                    value(arg_list[2]); 
 16381 |                    value(arg_list[3]); 
 16382 |             return value(arg_list[4]); 
 16383 |          } 
 16384 |  
 16385 |          template <typename Sequence> 
 16386 |          static inline T process_6(const Sequence& arg_list) 
 16387 |          { 
 16388 |                    value(arg_list[0]); 
 16389 |                    value(arg_list[1]); 
 16390 |                    value(arg_list[2]); 
 16391 |                    value(arg_list[3]); 
 16392 |                    value(arg_list[4]); 
 16393 |             return value(arg_list[5]); 
 16394 |          } 
 16395 |  
 16396 |          template <typename Sequence> 
 16397 |          static inline T process_7(const Sequence& arg_list) 
 16398 |          { 
 16399 |                    value(arg_list[0]); 
 16400 |                    value(arg_list[1]); 
 16401 |                    value(arg_list[2]); 
 16402 |                    value(arg_list[3]); 
 16403 |                    value(arg_list[4]); 
 16404 |                    value(arg_list[5]); 
 16405 |             return value(arg_list[6]); 
 16406 |          } 
 16407 |  
 16408 |          template <typename Sequence> 
 16409 |          static inline T process_8(const Sequence& arg_list) 
 16410 |          { 
 16411 |                    value(arg_list[0]); 
 16412 |                    value(arg_list[1]); 
 16413 |                    value(arg_list[2]); 
 16414 |                    value(arg_list[3]); 
 16415 |                    value(arg_list[4]); 
 16416 |                    value(arg_list[5]); 
 16417 |                    value(arg_list[6]); 
 16418 |             return value(arg_list[7]); 
 16419 |          } 
 16420 |       }; 
 16421 |  
 16422 |       template <typename T> 
 16423 |       struct vec_add_op 
 16424 |       { 
 16425 |          typedef vector_interface<T>* ivector_ptr; 
 16426 |  
 16427 |          static inline T process(const ivector_ptr v) 
 16428 |          { 
 16429 |             const T* vec = v->vec()->vds().data(); 
 16430 |             const std::size_t vec_size = v->size(); 
 16431 |  
 16432 |             loop_unroll::details lud(vec_size); 
 16433 |  
 16434 |             if (vec_size <= static_cast<std::size_t>(lud.batch_size)) 
 16435 |             { 
 16436 |                T result = T(0); 
 16437 |                int i    = 0; 
 16438 |  
 16439 |                switch (vec_size) 
 16440 |                { 
 16441 |                   #define case_stmt(N,fall_through) \ 
 16442 |                   case N : result += vec[i++];      \ 
 16443 |                   fall_through                      \ 
 16444 |  
 16445 |                   #ifndef exprtk_disable_superscalar_unroll 
 16446 |                   case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough) 
 16447 |                   case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough) 
 16448 |                   case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough) 
 16449 |                   case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough) 
 16450 |                   case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough) 
 16451 |                   case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough) 
 16452 |  
 16453 |                   #endif 
 16454 |                   case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough) 
 16455 |                   case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;) 
 16456 |                } 
 16457 |  
 16458 |                #undef case_stmt 
 16459 |  
 16460 |                return result; 
 16461 |             } 
 16462 |  
 16463 |             T r[] = { 
 16464 |                       T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0), 
 16465 |                       T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0) 
 16466 |                     }; 
 16467 |  
 16468 |             const T* upper_bound = vec + lud.upper_bound; 
 16469 |  
 16470 |             while (vec < upper_bound) 
 16471 |             { 
 16472 |                #define exprtk_loop(N) \ 
 16473 |                r[N] += vec[N];        \ 
 16474 |  
 16475 |                exprtk_loop( 0) exprtk_loop( 1) 
 16476 |                exprtk_loop( 2) exprtk_loop( 3) 
 16477 |                #ifndef exprtk_disable_superscalar_unroll 
 16478 |                exprtk_loop( 4) exprtk_loop( 5) 
 16479 |                exprtk_loop( 6) exprtk_loop( 7) 
 16480 |                exprtk_loop( 8) exprtk_loop( 9) 
 16481 |                exprtk_loop(10) exprtk_loop(11) 
 16482 |                exprtk_loop(12) exprtk_loop(13) 
 16483 |                exprtk_loop(14) exprtk_loop(15) 
 16484 |                #endif 
 16485 |  
 16486 |                vec += lud.batch_size; 
 16487 |             } 
 16488 |  
 16489 |             int i = 0; 
 16490 |  
 16491 |             switch (lud.remainder) 
 16492 |             { 
 16493 |                #define case_stmt(N,fall_through) \ 
 16494 |                case N : r[0] += vec[i++];        \ 
 16495 |                fall_through                      \ 
 16496 |  
 16497 |                #ifndef exprtk_disable_superscalar_unroll 
 16498 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 16499 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 16500 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 16501 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 16502 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 16503 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 16504 |                #endif 
 16505 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 16506 |                case_stmt( 1, (void)0;) 
 16507 |             } 
 16508 |  
 16509 |             #undef exprtk_loop 
 16510 |             #undef case_stmt 
 16511 |  
 16512 |             return (r[ 0] + r[ 1] + r[ 2] + r[ 3]) 
 16513 |                    #ifndef exprtk_disable_superscalar_unroll 
 16514 |                  + (r[ 4] + r[ 5] + r[ 6] + r[ 7]) 
 16515 |                  + (r[ 8] + r[ 9] + r[10] + r[11]) 
 16516 |                  + (r[12] + r[13] + r[14] + r[15]) 
 16517 |                    #endif 
 16518 |                    ; 
 16519 |          } 
 16520 |       }; 
 16521 |  
 16522 |       template <typename T> 
 16523 |       struct vec_mul_op 
 16524 |       { 
 16525 |          typedef vector_interface<T>* ivector_ptr; 
 16526 |  
 16527 |          static inline T process(const ivector_ptr v) 
 16528 |          { 
 16529 |             const T* vec = v->vec()->vds().data(); 
 16530 |             const std::size_t vec_size = v->vec()->size(); 
 16531 |  
 16532 |             loop_unroll::details lud(vec_size); 
 16533 |  
 16534 |             if (vec_size <= static_cast<std::size_t>(lud.batch_size)) 
 16535 |             { 
 16536 |                T result = T(1); 
 16537 |                int i    = 0; 
 16538 |  
 16539 |                switch (vec_size) 
 16540 |                { 
 16541 |                   #define case_stmt(N,fall_through) \ 
 16542 |                   case N : result *= vec[i++];      \ 
 16543 |                   fall_through                      \ 
 16544 |  
 16545 |                   #ifndef exprtk_disable_superscalar_unroll 
 16546 |                   case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough) 
 16547 |                   case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough) 
 16548 |                   case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough) 
 16549 |                   case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough) 
 16550 |                   case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough) 
 16551 |                   case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough) 
 16552 |                   #endif 
 16553 |                   case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough) 
 16554 |                   case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;) 
 16555 |                } 
 16556 |  
 16557 |                #undef case_stmt 
 16558 |  
 16559 |                return result; 
 16560 |             } 
 16561 |  
 16562 |             T r[] = { 
 16563 |                       T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1), 
 16564 |                       T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1) 
 16565 |                     }; 
 16566 |  
 16567 |             const T* upper_bound = vec + lud.upper_bound; 
 16568 |  
 16569 |             while (vec < upper_bound) 
 16570 |             { 
 16571 |                #define exprtk_loop(N) \ 
 16572 |                r[N] *= vec[N];        \ 
 16573 |  
 16574 |                exprtk_loop( 0) exprtk_loop( 1) 
 16575 |                exprtk_loop( 2) exprtk_loop( 3) 
 16576 |                #ifndef exprtk_disable_superscalar_unroll 
 16577 |                exprtk_loop( 4) exprtk_loop( 5) 
 16578 |                exprtk_loop( 6) exprtk_loop( 7) 
 16579 |                exprtk_loop( 8) exprtk_loop( 9) 
 16580 |                exprtk_loop(10) exprtk_loop(11) 
 16581 |                exprtk_loop(12) exprtk_loop(13) 
 16582 |                exprtk_loop(14) exprtk_loop(15) 
 16583 |                #endif 
 16584 |  
 16585 |                vec += lud.batch_size; 
 16586 |             } 
 16587 |  
 16588 |             int i = 0; 
 16589 |  
 16590 |             switch (lud.remainder) 
 16591 |             { 
 16592 |                #define case_stmt(N,fall_through) \ 
 16593 |                case N : r[0] *= vec[i++];        \ 
 16594 |                fall_through                      \ 
 16595 |  
 16596 |                #ifndef exprtk_disable_superscalar_unroll 
 16597 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 16598 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 16599 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 16600 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 16601 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 16602 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 16603 |                #endif 
 16604 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 16605 |                case_stmt( 1, (void)0;) 
 16606 |             } 
 16607 |  
 16608 |             #undef exprtk_loop 
 16609 |             #undef case_stmt 
 16610 |  
 16611 |             return (r[ 0] * r[ 1] * r[ 2] * r[ 3]) 
 16612 |                    #ifndef exprtk_disable_superscalar_unroll 
 16613 |                  * (r[ 4] * r[ 5] * r[ 6] * r[ 7]) 
 16614 |                  * (r[ 8] * r[ 9] * r[10] * r[11]) 
 16615 |                  * (r[12] * r[13] * r[14] * r[15]) 
 16616 |                    #endif 
 16617 |                    ; 
 16618 |          } 
 16619 |       }; 
 16620 |  
 16621 |       template <typename T> 
 16622 |       struct vec_avg_op 
 16623 |       { 
 16624 |          typedef vector_interface<T>* ivector_ptr; 
 16625 |  
 16626 |          static inline T process(const ivector_ptr v) 
 16627 |          { 
 16628 |             const T vec_size = T(v->vec()->size()); 
 16629 |             return vec_add_op<T>::process(v) / vec_size; 
 16630 |          } 
 16631 |       }; 
 16632 |  
 16633 |       template <typename T> 
 16634 |       struct vec_min_op 
 16635 |       { 
 16636 |          typedef vector_interface<T>* ivector_ptr; 
 16637 |  
 16638 |          static inline T process(const ivector_ptr v) 
 16639 |          { 
 16640 |             const T* vec = v->vec()->vds().data(); 
 16641 |             const std::size_t vec_size = v->vec()->size(); 
 16642 |  
 16643 |             T result = vec[0]; 
 16644 |  
 16645 |             for (std::size_t i = 1; i < vec_size; ++i) 
 16646 |             { 
 16647 |                const T v_i = vec[i]; 
 16648 |  
 16649 |                if (v_i < result) 
 16650 |                   result = v_i; 
 16651 |             } 
 16652 |  
 16653 |             return result; 
 16654 |          } 
 16655 |       }; 
 16656 |  
 16657 |       template <typename T> 
 16658 |       struct vec_max_op 
 16659 |       { 
 16660 |          typedef vector_interface<T>* ivector_ptr; 
 16661 |  
 16662 |          static inline T process(const ivector_ptr v) 
 16663 |          { 
 16664 |             const T* vec = v->vec()->vds().data(); 
 16665 |             const std::size_t vec_size = v->vec()->size(); 
 16666 |  
 16667 |             T result = vec[0]; 
 16668 |  
 16669 |             for (std::size_t i = 1; i < vec_size; ++i) 
 16670 |             { 
 16671 |                const T v_i = vec[i]; 
 16672 |  
 16673 |                if (v_i > result) 
 16674 |                   result = v_i; 
 16675 |             } 
 16676 |  
 16677 |             return result; 
 16678 |          } 
 16679 |       }; 
 16680 |  
 16681 |       template <typename T> 
 16682 |       class vov_base_node : public expression_node<T> 
 16683 |       { 
 16684 |       public: 
 16685 |  
 16686 |          virtual ~vov_base_node() 
 16687 |          {} 
 16688 |  
 16689 |          inline virtual operator_type operation() const 
 16690 |          { 
 16691 |             return details::e_default; 
 16692 |          } 
 16693 |  
 16694 |          virtual const T& v0() const = 0; 
 16695 |  
 16696 |          virtual const T& v1() const = 0; 
 16697 |       }; 
 16698 |  
 16699 |       template <typename T> 
 16700 |       class cov_base_node : public expression_node<T> 
 16701 |       { 
 16702 |       public: 
 16703 |  
 16704 |          virtual ~cov_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 voc_base_node : public expression_node<T> 
 16719 |       { 
 16720 |       public: 
 16721 |  
 16722 |          virtual ~voc_base_node() 
 16723 |          {} 
 16724 |  
 16725 |          inline virtual operator_type operation() const 
 16726 |          { 
 16727 |             return details::e_default; 
 16728 |          } 
 16729 |  
 16730 |          virtual const T c() const = 0; 
 16731 |  
 16732 |          virtual const T& v() const = 0; 
 16733 |       }; 
 16734 |  
 16735 |       template <typename T> 
 16736 |       class vob_base_node : public expression_node<T> 
 16737 |       { 
 16738 |       public: 
 16739 |  
 16740 |          virtual ~vob_base_node() 
 16741 |          {} 
 16742 |  
 16743 |          virtual const T& v() const = 0; 
 16744 |       }; 
 16745 |  
 16746 |       template <typename T> 
 16747 |       class bov_base_node : public expression_node<T> 
 16748 |       { 
 16749 |       public: 
 16750 |  
 16751 |          virtual ~bov_base_node() 
 16752 |          {} 
 16753 |  
 16754 |          virtual const T& v() const = 0; 
 16755 |       }; 
 16756 |  
 16757 |       template <typename T> 
 16758 |       class cob_base_node : public expression_node<T> 
 16759 |       { 
 16760 |       public: 
 16761 |  
 16762 |          virtual ~cob_base_node() 
 16763 |          {} 
 16764 |  
 16765 |          inline virtual operator_type operation() const 
 16766 |          { 
 16767 |             return details::e_default; 
 16768 |          } 
 16769 |  
 16770 |          virtual const T c() const = 0; 
 16771 |  
 16772 |          virtual void set_c(const T) = 0; 
 16773 |  
 16774 |          virtual expression_node<T>* move_branch(const std::size_t& index) = 0; 
 16775 |       }; 
 16776 |  
 16777 |       template <typename T> 
 16778 |       class boc_base_node : public expression_node<T> 
 16779 |       { 
 16780 |       public: 
 16781 |  
 16782 |          virtual ~boc_base_node() 
 16783 |          {} 
 16784 |  
 16785 |          inline virtual operator_type operation() const 
 16786 |          { 
 16787 |             return details::e_default; 
 16788 |          } 
 16789 |  
 16790 |          virtual const T c() const = 0; 
 16791 |  
 16792 |          virtual void set_c(const T) = 0; 
 16793 |  
 16794 |          virtual expression_node<T>* move_branch(const std::size_t& index) = 0; 
 16795 |       }; 
 16796 |  
 16797 |       template <typename T> 
 16798 |       class uv_base_node : public expression_node<T> 
 16799 |       { 
 16800 |       public: 
 16801 |  
 16802 |          virtual ~uv_base_node() 
 16803 |          {} 
 16804 |  
 16805 |          inline virtual operator_type operation() const 
 16806 |          { 
 16807 |             return details::e_default; 
 16808 |          } 
 16809 |  
 16810 |          virtual const T& v() const = 0; 
 16811 |       }; 
 16812 |  
 16813 |       template <typename T> 
 16814 |       class sos_base_node : public expression_node<T> 
 16815 |       { 
 16816 |       public: 
 16817 |  
 16818 |          virtual ~sos_base_node() 
 16819 |          {} 
 16820 |  
 16821 |          inline virtual operator_type operation() const 
 16822 |          { 
 16823 |             return details::e_default; 
 16824 |          } 
 16825 |       }; 
 16826 |  
 16827 |       template <typename T> 
 16828 |       class sosos_base_node : public expression_node<T> 
 16829 |       { 
 16830 |       public: 
 16831 |  
 16832 |          virtual ~sosos_base_node() 
 16833 |          {} 
 16834 |  
 16835 |          inline virtual operator_type operation() const 
 16836 |          { 
 16837 |             return details::e_default; 
 16838 |          } 
 16839 |       }; 
 16840 |  
 16841 |       template <typename T> 
 16842 |       class T0oT1oT2_base_node : public expression_node<T> 
 16843 |       { 
 16844 |       public: 
 16845 |  
 16846 |          virtual ~T0oT1oT2_base_node() 
 16847 |          {} 
 16848 |  
 16849 |          virtual std::string type_id() const = 0; 
 16850 |       }; 
 16851 |  
 16852 |       template <typename T> 
 16853 |       class T0oT1oT2oT3_base_node : public expression_node<T> 
 16854 |       { 
 16855 |       public: 
 16856 |  
 16857 |          virtual ~T0oT1oT2oT3_base_node() 
 16858 |          {} 
 16859 |  
 16860 |          virtual std::string type_id() const = 0; 
 16861 |       }; 
 16862 |  
 16863 |       template <typename T, typename Operation> 
 16864 |       class unary_variable_node exprtk_final : public uv_base_node<T> 
 16865 |       { 
 16866 |       public: 
 16867 |  
 16868 |          typedef expression_node<T>* expression_ptr; 
 16869 |          typedef Operation operation_t; 
 16870 |  
 16871 |          explicit unary_variable_node(const T& var) 
 16872 |          : v_(var) 
 16873 |          {} 
 16874 |  
 16875 |          inline T value() const exprtk_override 
 16876 |          { 
 16877 |             return Operation::process(v_); 
 16878 |          } 
 16879 |  
 16880 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 16881 |          { 
 16882 |             return Operation::type(); 
 16883 |          } 
 16884 |  
 16885 |          inline operator_type operation() const exprtk_override 
 16886 |          { 
 16887 |             return Operation::operation(); 
 16888 |          } 
 16889 |  
 16890 |          inline const T& v() const exprtk_override 
 16891 |          { 
 16892 |             return v_; 
 16893 |          } 
 16894 |  
 16895 |       private: 
 16896 |  
 16897 |          unary_variable_node(const unary_variable_node<T,Operation>&) exprtk_delete; 
 16898 |          unary_variable_node<T,Operation>& operator=(const unary_variable_node<T,Operation>&) exprtk_delete; 
 16899 |  
 16900 |          const T& v_; 
 16901 |       }; 
 16902 |  
 16903 |       template <typename T> 
 16904 |       class uvouv_node exprtk_final : public expression_node<T> 
 16905 |       { 
 16906 |       public: 
 16907 |  
 16908 |          // UOpr1(v0) Op UOpr2(v1) 
 16909 |          typedef typename details::functor_t<T> functor_t; 
 16910 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 16911 |          typedef typename functor_t::ufunc_t    ufunc_t; 
 16912 |          typedef expression_node<T>*            expression_ptr; 
 16913 |  
 16914 |          explicit uvouv_node(const T& var0,const T& var1, 
 16915 |                              ufunc_t uf0, ufunc_t uf1, bfunc_t bf) 
 16916 |          : v0_(var0) 
 16917 |          , v1_(var1) 
 16918 |          , u0_(uf0 ) 
 16919 |          , u1_(uf1 ) 
 16920 |          , f_ (bf  ) 
 16921 |          {} 
 16922 |  
 16923 |          inline T value() const exprtk_override 
 16924 |          { 
 16925 |             return f_(u0_(v0_),u1_(v1_)); 
 16926 |          } 
 16927 |  
 16928 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 16929 |          { 
 16930 |             return expression_node<T>::e_uvouv; 
 16931 |          } 
 16932 |  
 16933 |          inline const T& v0() 
 16934 |          { 
 16935 |             return v0_; 
 16936 |          } 
 16937 |  
 16938 |          inline const T& v1() 
 16939 |          { 
 16940 |             return v1_; 
 16941 |          } 
 16942 |  
 16943 |          inline ufunc_t u0() 
 16944 |          { 
 16945 |             return u0_; 
 16946 |          } 
 16947 |  
 16948 |          inline ufunc_t u1() 
 16949 |          { 
 16950 |             return u1_; 
 16951 |          } 
 16952 |  
 16953 |          inline ufunc_t f() 
 16954 |          { 
 16955 |             return f_; 
 16956 |          } 
 16957 |  
 16958 |       private: 
 16959 |  
 16960 |          uvouv_node(const uvouv_node<T>&) exprtk_delete; 
 16961 |          uvouv_node<T>& operator=(const uvouv_node<T>&) exprtk_delete; 
 16962 |  
 16963 |          const T& v0_; 
 16964 |          const T& v1_; 
 16965 |          const ufunc_t u0_; 
 16966 |          const ufunc_t u1_; 
 16967 |          const bfunc_t f_; 
 16968 |       }; 
 16969 |  
 16970 |       template <typename T, typename Operation> 
 16971 |       class unary_branch_node exprtk_final : public expression_node<T> 
 16972 |       { 
 16973 |       public: 
 16974 |  
 16975 |          typedef Operation                      operation_t; 
 16976 |          typedef expression_node<T>*            expression_ptr; 
 16977 |          typedef std::pair<expression_ptr,bool> branch_t; 
 16978 |  
 16979 |          explicit unary_branch_node(expression_ptr branch) 
 16980 |          { 
 16981 |             construct_branch_pair(branch_, branch); 
 16982 |          } 
 16983 |  
 16984 |          inline T value() const exprtk_override 
 16985 |          { 
 16986 |             return Operation::process(branch_.first->value()); 
 16987 |          } 
 16988 |  
 16989 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 16990 |          { 
 16991 |             return Operation::type(); 
 16992 |          } 
 16993 |  
 16994 |          inline bool valid() const exprtk_override 
 16995 |          { 
 16996 |             return branch_.first && branch_.first->valid(); 
 16997 |          } 
 16998 |  
 16999 |          inline operator_type operation() 
 17000 |          { 
 17001 |             return Operation::operation(); 
 17002 |          } 
 17003 |  
 17004 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 17005 |          { 
 17006 |             return branch_.first; 
 17007 |          } 
 17008 |  
 17009 |          inline void release() 
 17010 |          { 
 17011 |             branch_.second = false; 
 17012 |          } 
 17013 |  
 17014 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 17015 |          { 
 17016 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 17017 |          } 
 17018 |  
 17019 |          std::size_t node_depth() const exprtk_override 
 17020 |          { 
 17021 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 17022 |          } 
 17023 |  
 17024 |       private: 
 17025 |  
 17026 |          unary_branch_node(const unary_branch_node<T,Operation>&) exprtk_delete; 
 17027 |          unary_branch_node<T,Operation>& operator=(const unary_branch_node<T,Operation>&) exprtk_delete; 
 17028 |  
 17029 |          branch_t branch_; 
 17030 |       }; 
 17031 |  
 17032 |       template <typename T> struct is_const                { enum {result = 0}; }; 
 17033 |       template <typename T> struct is_const <const T>      { enum {result = 1}; }; 
 17034 |       template <typename T> struct is_const_ref            { enum {result = 0}; }; 
 17035 |       template <typename T> struct is_const_ref <const T&> { enum {result = 1}; }; 
 17036 |       template <typename T> struct is_ref                  { enum {result = 0}; }; 
 17037 |       template <typename T> struct is_ref<T&>              { enum {result = 1}; }; 
 17038 |       template <typename T> struct is_ref<const T&>        { enum {result = 0}; }; 
 17039 |  
 17040 |       template <std::size_t State> 
 17041 |       struct param_to_str { static std::string result() { static const std::string r("v"); return r; } }; 
 17042 |  
 17043 |       template <> 
 17044 |       struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } }; 
 17045 |  
 17046 |       #define exprtk_crtype(Type)                          \ 
 17047 |       param_to_str<is_const_ref< Type >::result>::result() \ 
 17048 |  
 17049 |       template <typename T> 
 17050 |       struct T0oT1oT2process 
 17051 |       { 
 17052 |          typedef typename details::functor_t<T> functor_t; 
 17053 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17054 |  
 17055 |          struct mode0 
 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 bf1(bf0(t0,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 |          struct mode1 
 17074 |          { 
 17075 |             static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1) 
 17076 |             { 
 17077 |                // T0 o0 (T1 o1 T2) 
 17078 |                return bf0(t0,bf1(t1,t2)); 
 17079 |             } 
 17080 |  
 17081 |             template <typename T0, typename T1, typename T2> 
 17082 |             static inline std::string id() 
 17083 |             { 
 17084 |                static const std::string result = "(" + exprtk_crtype(T0) + ")o(" + 
 17085 |                                                        exprtk_crtype(T1) + "o"   + 
 17086 |                                                        exprtk_crtype(T2) + ")"   ; 
 17087 |                return result; 
 17088 |             } 
 17089 |          }; 
 17090 |       }; 
 17091 |  
 17092 |       template <typename T> 
 17093 |       struct T0oT1oT20T3process 
 17094 |       { 
 17095 |          typedef typename details::functor_t<T> functor_t; 
 17096 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17097 |  
 17098 |          struct mode0 
 17099 |          { 
 17100 |             static inline T process(const T& t0, const T& t1, 
 17101 |                                     const T& t2, const T& t3, 
 17102 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17103 |             { 
 17104 |                // (T0 o0 T1) o1 (T2 o2 T3) 
 17105 |                return bf1(bf0(t0,t1),bf2(t2,t3)); 
 17106 |             } 
 17107 |  
 17108 |             template <typename T0, typename T1, typename T2, typename T3> 
 17109 |             static inline std::string id() 
 17110 |             { 
 17111 |                static const std::string result = "(" + exprtk_crtype(T0) + "o"  + 
 17112 |                                                        exprtk_crtype(T1) + ")o" + 
 17113 |                                                  "(" + exprtk_crtype(T2) + "o"  + 
 17114 |                                                        exprtk_crtype(T3) + ")"  ; 
 17115 |                return result; 
 17116 |             } 
 17117 |          }; 
 17118 |  
 17119 |          struct mode1 
 17120 |          { 
 17121 |             static inline T process(const T& t0, const T& t1, 
 17122 |                                     const T& t2, const T& t3, 
 17123 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17124 |             { 
 17125 |                // (T0 o0 (T1 o1 (T2 o2 T3)) 
 17126 |                return bf0(t0,bf1(t1,bf2(t2,t3))); 
 17127 |             } 
 17128 |             template <typename T0, typename T1, typename T2, typename T3> 
 17129 |             static inline std::string id() 
 17130 |             { 
 17131 |                static const std::string result = "(" + exprtk_crtype(T0) +  ")o((" + 
 17132 |                                                        exprtk_crtype(T1) +  ")o("  + 
 17133 |                                                        exprtk_crtype(T2) +  "o"    + 
 17134 |                                                        exprtk_crtype(T3) +  "))"   ; 
 17135 |                return result; 
 17136 |             } 
 17137 |          }; 
 17138 |  
 17139 |          struct mode2 
 17140 |          { 
 17141 |             static inline T process(const T& t0, const T& t1, 
 17142 |                                     const T& t2, const T& t3, 
 17143 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17144 |             { 
 17145 |                // (T0 o0 ((T1 o1 T2) o2 T3) 
 17146 |                return bf0(t0,bf2(bf1(t1,t2),t3)); 
 17147 |             } 
 17148 |  
 17149 |             template <typename T0, typename T1, typename T2, typename T3> 
 17150 |             static inline std::string id() 
 17151 |             { 
 17152 |                static const std::string result = "(" + exprtk_crtype(T0) + ")o((" + 
 17153 |                                                        exprtk_crtype(T1) + "o"    + 
 17154 |                                                        exprtk_crtype(T2) + ")o("  + 
 17155 |                                                        exprtk_crtype(T3) + "))"   ; 
 17156 |                return result; 
 17157 |             } 
 17158 |          }; 
 17159 |  
 17160 |          struct mode3 
 17161 |          { 
 17162 |             static inline T process(const T& t0, const T& t1, 
 17163 |                                     const T& t2, const T& t3, 
 17164 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17165 |             { 
 17166 |                // (((T0 o0 T1) o1 T2) o2 T3) 
 17167 |                return bf2(bf1(bf0(t0,t1),t2),t3); 
 17168 |             } 
 17169 |  
 17170 |             template <typename T0, typename T1, typename T2, typename T3> 
 17171 |             static inline std::string id() 
 17172 |             { 
 17173 |                static const std::string result = "((" + exprtk_crtype(T0) + "o"    + 
 17174 |                                                         exprtk_crtype(T1) + ")o("  + 
 17175 |                                                         exprtk_crtype(T2) + "))o(" + 
 17176 |                                                         exprtk_crtype(T3) + ")" 
 17177 |                return result; 
 17178 |             } 
 17179 |          }; 
 17180 |  
 17181 |          struct mode4 
 17182 |          { 
 17183 |             static inline T process(const T& t0, const T& t1, 
 17184 |                                     const T& t2, const T& t3, 
 17185 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17186 |             { 
 17187 |                // ((T0 o0 (T1 o1 T2)) o2 T3 
 17188 |                return bf2(bf0(t0,bf1(t1,t2)),t3); 
 17189 |             } 
 17190 |  
 17191 |             template <typename T0, typename T1, typename T2, typename T3> 
 17192 |             static inline std::string id() 
 17193 |             { 
 17194 |                static const std::string result = "((" + exprtk_crtype(T0) + ")o("  + 
 17195 |                                                         exprtk_crtype(T1) + "o"    + 
 17196 |                                                         exprtk_crtype(T2) + "))o(" + 
 17197 |                                                         exprtk_crtype(T3) + ")"    ; 
 17198 |                return result; 
 17199 |             } 
 17200 |          }; 
 17201 |       }; 
 17202 |  
 17203 |       #undef exprtk_crtype 
 17204 |  
 17205 |       template <typename T, typename T0, typename T1> 
 17206 |       struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; }; 
 17207 |       template <typename T, typename T0, typename T1> 
 17208 |       const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none; 
 17209 |  
 17210 |       #define synthesis_node_type_define(T0_, T1_, v_)                                                          \ 
 17211 |       template <typename T, typename T0, typename T1>                                                           \ 
 17212 |       struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; };         \ 
 17213 |       template <typename T, typename T0, typename T1>                                                           \ 
 17214 |       const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \ 
 17215 |  
 17216 |       synthesis_node_type_define(const T0&, const T1&,  e_vov) 
 17217 |       synthesis_node_type_define(const T0&, const T1 ,  e_voc) 
 17218 |       synthesis_node_type_define(const T0 , const T1&,  e_cov) 
 17219 |       synthesis_node_type_define(      T0&,       T1&, e_none) 
 17220 |       synthesis_node_type_define(const T0 , const T1 , e_none) 
 17221 |       synthesis_node_type_define(      T0&, const T1 , e_none) 
 17222 |       synthesis_node_type_define(const T0 ,       T1&, e_none) 
 17223 |       synthesis_node_type_define(const T0&,       T1&, e_none) 
 17224 |       synthesis_node_type_define(      T0&, const T1&, e_none) 
 17225 |       #undef synthesis_node_type_define 
 17226 |  
 17227 |       template <typename T, typename T0, typename T1, typename T2> 
 17228 |       struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; }; 
 17229 |       template <typename T, typename T0, typename T1, typename T2> 
 17230 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none; 
 17231 |  
 17232 |       #define synthesis_node_type_define(T0_, T1_, T2_, v_)                                                            \ 
 17233 |       template <typename T, typename T0, typename T1, typename T2>                                                     \ 
 17234 |       struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; };         \ 
 17235 |       template <typename T, typename T0, typename T1, typename T2>                                                     \ 
 17236 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \ 
 17237 |  
 17238 |       synthesis_node_type_define(const T0&, const T1&, const T2&, e_vovov) 
 17239 |       synthesis_node_type_define(const T0&, const T1&, const T2 , e_vovoc) 
 17240 |       synthesis_node_type_define(const T0&, const T1 , const T2&, e_vocov) 
 17241 |       synthesis_node_type_define(const T0 , const T1&, const T2&, e_covov) 
 17242 |       synthesis_node_type_define(const T0 , const T1&, const T2 , e_covoc) 
 17243 |       synthesis_node_type_define(const T0 , const T1 , const T2 , e_none ) 
 17244 |       synthesis_node_type_define(const T0 , const T1 , const T2&, e_none ) 
 17245 |       synthesis_node_type_define(const T0&, const T1 , const T2 , e_none ) 
 17246 |       synthesis_node_type_define(      T0&,       T1&,       T2&, e_none ) 
 17247 |       #undef synthesis_node_type_define 
 17248 |  
 17249 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17250 |       struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; }; 
 17251 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17252 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none; 
 17253 |  
 17254 |       #define synthesis_node_type_define(T0_, T1_, T2_, T3_, v_)                                                              \ 
 17255 |       template <typename T, typename T0, typename T1, typename T2, typename T3>                                               \ 
 17256 |       struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; };         \ 
 17257 |       template <typename T, typename T0, typename T1, typename T2, typename T3>                                               \ 
 17258 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \ 
 17259 |  
 17260 |       synthesis_node_type_define(const T0&, const T1&, const T2&, const T3&, e_vovovov) 
 17261 |       synthesis_node_type_define(const T0&, const T1&, const T2&, const T3 , e_vovovoc) 
 17262 |       synthesis_node_type_define(const T0&, const T1&, const T2 , const T3&, e_vovocov) 
 17263 |       synthesis_node_type_define(const T0&, const T1 , const T2&, const T3&, e_vocovov) 
 17264 |       synthesis_node_type_define(const T0 , const T1&, const T2&, const T3&, e_covovov) 
 17265 |       synthesis_node_type_define(const T0 , const T1&, const T2 , const T3&, e_covocov) 
 17266 |       synthesis_node_type_define(const T0&, const T1 , const T2&, const T3 , e_vocovoc) 
 17267 |       synthesis_node_type_define(const T0 , const T1&, const T2&, const T3 , e_covovoc) 
 17268 |       synthesis_node_type_define(const T0&, const T1 , const T2 , const T3&, e_vococov) 
 17269 |       synthesis_node_type_define(const T0 , const T1 , const T2 , const T3 , e_none   ) 
 17270 |       synthesis_node_type_define(const T0 , const T1 , const T2 , const T3&, e_none   ) 
 17271 |       synthesis_node_type_define(const T0 , const T1 , const T2&, const T3 , e_none   ) 
 17272 |       synthesis_node_type_define(const T0 , const T1&, const T2 , const T3 , e_none   ) 
 17273 |       synthesis_node_type_define(const T0&, const T1 , const T2 , const T3 , e_none   ) 
 17274 |       synthesis_node_type_define(const T0 , const T1 , const T2&, const T3&, e_none   ) 
 17275 |       synthesis_node_type_define(const T0&, const T1&, const T2 , const T3 , e_none   ) 
 17276 |       #undef synthesis_node_type_define 
 17277 |  
 17278 |       template <typename T, typename T0, typename T1> 
 17279 |       class T0oT1 exprtk_final : public expression_node<T> 
 17280 |       { 
 17281 |       public: 
 17282 |  
 17283 |          typedef typename details::functor_t<T> functor_t; 
 17284 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17285 |          typedef T value_type; 
 17286 |          typedef T0oT1<T,T0,T1> node_type; 
 17287 |  
 17288 |          T0oT1(T0 p0, T1 p1, const bfunc_t p2) 
 17289 |          : t0_(p0) 
 17290 |          , t1_(p1) 
 17291 |          , f_ (p2) 
 17292 |          {} 
 17293 |  
 17294 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17295 |          { 
 17296 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result; 
 17297 |             return result; 
 17298 |          } 
 17299 |  
 17300 |          inline operator_type operation() const exprtk_override 
 17301 |          { 
 17302 |             return e_default; 
 17303 |          } 
 17304 |  
 17305 |          inline T value() const exprtk_override 
 17306 |          { 
 17307 |             return f_(t0_,t1_); 
 17308 |          } 
 17309 |  
 17310 |          inline T0 t0() const 
 17311 |          { 
 17312 |             return t0_; 
 17313 |          } 
 17314 |  
 17315 |          inline T1 t1() const 
 17316 |          { 
 17317 |             return t1_; 
 17318 |          } 
 17319 |  
 17320 |          inline bfunc_t f() const 
 17321 |          { 
 17322 |             return f_; 
 17323 |          } 
 17324 |  
 17325 |          template <typename Allocator> 
 17326 |          static inline expression_node<T>* allocate(Allocator& allocator, 
 17327 |                                                     T0 p0, T1 p1, 
 17328 |                                                     bfunc_t p2) 
 17329 |          { 
 17330 |             return allocator 
 17331 |                      .template allocate_type<node_type, T0, T1, bfunc_t&> 
 17332 |                         (p0, p1, p2); 
 17333 |          } 
 17334 |  
 17335 |       private: 
 17336 |  
 17337 |          T0oT1(const T0oT1<T,T0,T1>&) exprtk_delete; 
 17338 |          T0oT1<T,T0,T1>& operator=(const T0oT1<T,T0,T1>&) { return (*this); } 
 17339 |  
 17340 |          T0 t0_; 
 17341 |          T1 t1_; 
 17342 |          const bfunc_t f_; 
 17343 |       }; 
 17344 |  
 17345 |       template <typename T, typename T0, typename T1, typename T2, typename ProcessMode> 
 17346 |       class T0oT1oT2 exprtk_final : public T0oT1oT2_base_node<T> 
 17347 |       { 
 17348 |       public: 
 17349 |  
 17350 |          typedef typename details::functor_t<T> functor_t; 
 17351 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17352 |          typedef T value_type; 
 17353 |          typedef T0oT1oT2<T,T0,T1,T2,ProcessMode> node_type; 
 17354 |          typedef ProcessMode process_mode_t; 
 17355 |  
 17356 |          T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4) 
 17357 |          : t0_(p0) 
 17358 |          , t1_(p1) 
 17359 |          , t2_(p2) 
 17360 |          , f0_(p3) 
 17361 |          , f1_(p4) 
 17362 |          {} 
 17363 |  
 17364 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17365 |          { 
 17366 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result; 
 17367 |             return result; 
 17368 |          } 
 17369 |  
 17370 |          inline operator_type operation() 
 17371 |          { 
 17372 |             return e_default; 
 17373 |          } 
 17374 |  
 17375 |          inline T value() const exprtk_override 
 17376 |          { 
 17377 |             return ProcessMode::process(t0_, t1_, t2_, f0_, f1_); 
 17378 |          } 
 17379 |  
 17380 |          inline T0 t0() const 
 17381 |          { 
 17382 |             return t0_; 
 17383 |          } 
 17384 |  
 17385 |          inline T1 t1() const 
 17386 |          { 
 17387 |             return t1_; 
 17388 |          } 
 17389 |  
 17390 |          inline T2 t2() const 
 17391 |          { 
 17392 |             return t2_; 
 17393 |          } 
 17394 |  
 17395 |          bfunc_t f0() const 
 17396 |          { 
 17397 |             return f0_; 
 17398 |          } 
 17399 |  
 17400 |          bfunc_t f1() const 
 17401 |          { 
 17402 |             return f1_; 
 17403 |          } 
 17404 |  
 17405 |          std::string type_id() const exprtk_override 
 17406 |          { 
 17407 |             return id(); 
 17408 |          } 
 17409 |  
 17410 |          static inline std::string id() 
 17411 |          { 
 17412 |             return process_mode_t::template id<T0,T1,T2>(); 
 17413 |          } 
 17414 |  
 17415 |          template <typename Allocator> 
 17416 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4) 
 17417 |          { 
 17418 |             return allocator 
 17419 |                       .template allocate_type<node_type, T0, T1, T2, bfunc_t, bfunc_t> 
 17420 |                          (p0, p1, p2, p3, p4); 
 17421 |          } 
 17422 |  
 17423 |       private: 
 17424 |  
 17425 |          T0oT1oT2(const node_type&) exprtk_delete; 
 17426 |          node_type& operator=(const node_type&) exprtk_delete; 
 17427 |  
 17428 |          T0 t0_; 
 17429 |          T1 t1_; 
 17430 |          T2 t2_; 
 17431 |          const bfunc_t f0_; 
 17432 |          const bfunc_t f1_; 
 17433 |       }; 
 17434 |  
 17435 |       template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode> 
 17436 |       class T0oT1oT2oT3 exprtk_final : public T0oT1oT2oT3_base_node<T> 
 17437 |       { 
 17438 |       public: 
 17439 |  
 17440 |          typedef typename details::functor_t<T> functor_t; 
 17441 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17442 |          typedef T value_type; 
 17443 |          typedef T0_ T0; 
 17444 |          typedef T1_ T1; 
 17445 |          typedef T2_ T2; 
 17446 |          typedef T3_ T3; 
 17447 |          typedef T0oT1oT2oT3<T,T0,T1,T2,T3,ProcessMode> node_type; 
 17448 |          typedef ProcessMode process_mode_t; 
 17449 |  
 17450 |          T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6) 
 17451 |          : t0_(p0) 
 17452 |          , t1_(p1) 
 17453 |          , t2_(p2) 
 17454 |          , t3_(p3) 
 17455 |          , f0_(p4) 
 17456 |          , f1_(p5) 
 17457 |          , f2_(p6) 
 17458 |          {} 
 17459 |  
 17460 |          inline T value() const exprtk_override 
 17461 |          { 
 17462 |             return ProcessMode::process(t0_, t1_, t2_, t3_, f0_, f1_, f2_); 
 17463 |          } 
 17464 |  
 17465 |          inline T0 t0() const 
 17466 |          { 
 17467 |             return t0_; 
 17468 |          } 
 17469 |  
 17470 |          inline T1 t1() const 
 17471 |          { 
 17472 |             return t1_; 
 17473 |          } 
 17474 |  
 17475 |          inline T2 t2() const 
 17476 |          { 
 17477 |             return t2_; 
 17478 |          } 
 17479 |  
 17480 |          inline T3 t3() const 
 17481 |          { 
 17482 |             return t3_; 
 17483 |          } 
 17484 |  
 17485 |          inline bfunc_t f0() const 
 17486 |          { 
 17487 |             return f0_; 
 17488 |          } 
 17489 |  
 17490 |          inline bfunc_t f1() const 
 17491 |          { 
 17492 |             return f1_; 
 17493 |          } 
 17494 |  
 17495 |          inline bfunc_t f2() const 
 17496 |          { 
 17497 |             return f2_; 
 17498 |          } 
 17499 |  
 17500 |          inline std::string type_id() const exprtk_override 
 17501 |          { 
 17502 |             return id(); 
 17503 |          } 
 17504 |  
 17505 |          static inline std::string id() 
 17506 |          { 
 17507 |             return process_mode_t::template id<T0, T1, T2, T3>(); 
 17508 |          } 
 17509 |  
 17510 |          template <typename Allocator> 
 17511 |          static inline expression_node<T>* allocate(Allocator& allocator, 
 17512 |                                                     T0 p0, T1 p1, T2 p2, T3 p3, 
 17513 |                                                     bfunc_t p4, bfunc_t p5, bfunc_t p6) 
 17514 |          { 
 17515 |             return allocator 
 17516 |                       .template allocate_type<node_type, T0, T1, T2, T3, bfunc_t, bfunc_t> 
 17517 |                          (p0, p1, p2, p3, p4, p5, p6); 
 17518 |          } 
 17519 |  
 17520 |       private: 
 17521 |  
 17522 |          T0oT1oT2oT3(const node_type&) exprtk_delete; 
 17523 |          node_type& operator=(const node_type&) exprtk_delete; 
 17524 |  
 17525 |          T0 t0_; 
 17526 |          T1 t1_; 
 17527 |          T2 t2_; 
 17528 |          T3 t3_; 
 17529 |          const bfunc_t f0_; 
 17530 |          const bfunc_t f1_; 
 17531 |          const bfunc_t f2_; 
 17532 |       }; 
 17533 |  
 17534 |       template <typename T, typename T0, typename T1, typename T2> 
 17535 |       class T0oT1oT2_sf3 exprtk_final : public T0oT1oT2_base_node<T> 
 17536 |       { 
 17537 |       public: 
 17538 |  
 17539 |          typedef typename details::functor_t<T> functor_t; 
 17540 |          typedef typename functor_t::tfunc_t    tfunc_t; 
 17541 |          typedef T value_type; 
 17542 |          typedef T0oT1oT2_sf3<T,T0,T1,T2> node_type; 
 17543 |  
 17544 |          T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3) 
 17545 |          : t0_(p0) 
 17546 |          , t1_(p1) 
 17547 |          , t2_(p2) 
 17548 |          , f_ (p3) 
 17549 |          {} 
 17550 |  
 17551 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17552 |          { 
 17553 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result; 
 17554 |             return result; 
 17555 |          } 
 17556 |  
 17557 |          inline operator_type operation() const exprtk_override 
 17558 |          { 
 17559 |             return e_default; 
 17560 |          } 
 17561 |  
 17562 |          inline T value() const exprtk_override 
 17563 |          { 
 17564 |             return f_(t0_, t1_, t2_); 
 17565 |          } 
 17566 |  
 17567 |          inline T0 t0() const 
 17568 |          { 
 17569 |             return t0_; 
 17570 |          } 
 17571 |  
 17572 |          inline T1 t1() const 
 17573 |          { 
 17574 |             return t1_; 
 17575 |          } 
 17576 |  
 17577 |          inline T2 t2() const 
 17578 |          { 
 17579 |             return t2_; 
 17580 |          } 
 17581 |  
 17582 |          tfunc_t f() const 
 17583 |          { 
 17584 |             return f_; 
 17585 |          } 
 17586 |  
 17587 |          std::string type_id() const 
 17588 |          { 
 17589 |             return id(); 
 17590 |          } 
 17591 |  
 17592 |          static inline std::string id() 
 17593 |          { 
 17594 |             return "sf3" 
 17595 |          } 
 17596 |  
 17597 |          template <typename Allocator> 
 17598 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3) 
 17599 |          { 
 17600 |             return allocator 
 17601 |                      .template allocate_type<node_type, T0, T1, T2, tfunc_t> 
 17602 |                         (p0, p1, p2, p3); 
 17603 |          } 
 17604 |  
 17605 |       private: 
 17606 |  
 17607 |          T0oT1oT2_sf3(const node_type&) exprtk_delete; 
 17608 |          node_type& operator=(const node_type&) exprtk_delete; 
 17609 |  
 17610 |          T0 t0_; 
 17611 |          T1 t1_; 
 17612 |          T2 t2_; 
 17613 |          const tfunc_t f_; 
 17614 |       }; 
 17615 |  
 17616 |       template <typename T, typename T0, typename T1, typename T2> 
 17617 |       class sf3ext_type_node : public T0oT1oT2_base_node<T> 
 17618 |       { 
 17619 |       public: 
 17620 |  
 17621 |          virtual ~sf3ext_type_node() 
 17622 |          {} 
 17623 |  
 17624 |          virtual T0 t0() const = 0; 
 17625 |  
 17626 |          virtual T1 t1() const = 0; 
 17627 |  
 17628 |          virtual T2 t2() const = 0; 
 17629 |       }; 
 17630 |  
 17631 |       template <typename T, typename T0, typename T1, typename T2, typename SF3Operation> 
 17632 |       class T0oT1oT2_sf3ext exprtk_final : public sf3ext_type_node<T,T0,T1,T2> 
 17633 |       { 
 17634 |       public: 
 17635 |  
 17636 |          typedef T value_type; 
 17637 |          typedef T0oT1oT2_sf3ext<T, T0, T1, T2, SF3Operation> node_type; 
 17638 |  
 17639 |          T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2) 
 17640 |          : t0_(p0) 
 17641 |          , t1_(p1) 
 17642 |          , t2_(p2) 
 17643 |          {} 
 17644 |  
 17645 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17646 |          { 
 17647 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result; 
 17648 |             return result; 
 17649 |          } 
 17650 |  
 17651 |          inline operator_type operation() 
 17652 |          { 
 17653 |             return e_default; 
 17654 |          } 
 17655 |  
 17656 |          inline T value() const exprtk_override 
 17657 |          { 
 17658 |             return SF3Operation::process(t0_, t1_, t2_); 
 17659 |          } 
 17660 |  
 17661 |          T0 t0() const exprtk_override 
 17662 |          { 
 17663 |             return t0_; 
 17664 |          } 
 17665 |  
 17666 |          T1 t1() const exprtk_override 
 17667 |          { 
 17668 |             return t1_; 
 17669 |          } 
 17670 |  
 17671 |          T2 t2() const exprtk_override 
 17672 |          { 
 17673 |             return t2_; 
 17674 |          } 
 17675 |  
 17676 |          std::string type_id() const exprtk_override 
 17677 |          { 
 17678 |             return id(); 
 17679 |          } 
 17680 |  
 17681 |          static inline std::string id() 
 17682 |          { 
 17683 |             return SF3Operation::id(); 
 17684 |          } 
 17685 |  
 17686 |          template <typename Allocator> 
 17687 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2) 
 17688 |          { 
 17689 |             return allocator 
 17690 |                      .template allocate_type<node_type, T0, T1, T2> 
 17691 |                         (p0, p1, p2); 
 17692 |          } 
 17693 |  
 17694 |       private: 
 17695 |  
 17696 |          T0oT1oT2_sf3ext(const node_type&) exprtk_delete; 
 17697 |          node_type& operator=(const node_type&) exprtk_delete; 
 17698 |  
 17699 |          T0 t0_; 
 17700 |          T1 t1_; 
 17701 |          T2 t2_; 
 17702 |       }; 
 17703 |  
 17704 |       template <typename T> 
 17705 |       inline bool is_sf3ext_node(const expression_node<T>* n) 
 17706 |       { 
 17707 |          switch (n->type()) 
 17708 |          { 
 17709 |             case expression_node<T>::e_vovov : return true; 
 17710 |             case expression_node<T>::e_vovoc : return true; 
 17711 |             case expression_node<T>::e_vocov : return true; 
 17712 |             case expression_node<T>::e_covov : return true; 
 17713 |             case expression_node<T>::e_covoc : return true; 
 17714 |             default                          : return false; 
 17715 |          } 
 17716 |       } 
 17717 |  
 17718 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17719 |       class T0oT1oT2oT3_sf4 exprtk_final : public T0oT1oT2_base_node<T> 
 17720 |       { 
 17721 |       public: 
 17722 |  
 17723 |          typedef typename details::functor_t<T> functor_t; 
 17724 |          typedef typename functor_t::qfunc_t    qfunc_t; 
 17725 |          typedef T value_type; 
 17726 |          typedef T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> node_type; 
 17727 |  
 17728 |          T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4) 
 17729 |          : t0_(p0) 
 17730 |          , t1_(p1) 
 17731 |          , t2_(p2) 
 17732 |          , t3_(p3) 
 17733 |          , f_ (p4) 
 17734 |          {} 
 17735 |  
 17736 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17737 |          { 
 17738 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result; 
 17739 |             return result; 
 17740 |          } 
 17741 |  
 17742 |          inline operator_type operation() const exprtk_override 
 17743 |          { 
 17744 |             return e_default; 
 17745 |          } 
 17746 |  
 17747 |          inline T value() const exprtk_override 
 17748 |          { 
 17749 |             return f_(t0_, t1_, t2_, t3_); 
 17750 |          } 
 17751 |  
 17752 |          inline T0 t0() const 
 17753 |          { 
 17754 |             return t0_; 
 17755 |          } 
 17756 |  
 17757 |          inline T1 t1() const 
 17758 |          { 
 17759 |             return t1_; 
 17760 |          } 
 17761 |  
 17762 |          inline T2 t2() const 
 17763 |          { 
 17764 |             return t2_; 
 17765 |          } 
 17766 |  
 17767 |          inline T3 t3() const 
 17768 |          { 
 17769 |             return t3_; 
 17770 |          } 
 17771 |  
 17772 |          qfunc_t f() const 
 17773 |          { 
 17774 |             return f_; 
 17775 |          } 
 17776 |  
 17777 |          std::string type_id() const 
 17778 |          { 
 17779 |             return id(); 
 17780 |          } 
 17781 |  
 17782 |          static inline std::string id() 
 17783 |          { 
 17784 |             return "sf4" 
 17785 |          } 
 17786 |  
 17787 |          template <typename Allocator> 
 17788 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4) 
 17789 |          { 
 17790 |             return allocator 
 17791 |                      .template allocate_type<node_type, T0, T1, T2, T3, qfunc_t> 
 17792 |                         (p0, p1, p2, p3, p4); 
 17793 |          } 
 17794 |  
 17795 |       private: 
 17796 |  
 17797 |          T0oT1oT2oT3_sf4(const node_type&) exprtk_delete; 
 17798 |          node_type& operator=(const node_type&) exprtk_delete; 
 17799 |  
 17800 |          T0 t0_; 
 17801 |          T1 t1_; 
 17802 |          T2 t2_; 
 17803 |          T3 t3_; 
 17804 |          const qfunc_t f_; 
 17805 |       }; 
 17806 |  
 17807 |       template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation> 
 17808 |       class T0oT1oT2oT3_sf4ext exprtk_final : public T0oT1oT2oT3_base_node<T> 
 17809 |       { 
 17810 |       public: 
 17811 |  
 17812 |          typedef T value_type; 
 17813 |          typedef T0oT1oT2oT3_sf4ext<T, T0, T1, T2, T3, SF4Operation> node_type; 
 17814 |  
 17815 |          T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3) 
 17816 |          : t0_(p0) 
 17817 |          , t1_(p1) 
 17818 |          , t2_(p2) 
 17819 |          , t3_(p3) 
 17820 |          {} 
 17821 |  
 17822 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17823 |          { 
 17824 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result; 
 17825 |             return result; 
 17826 |          } 
 17827 |  
 17828 |          inline T value() const exprtk_override 
 17829 |          { 
 17830 |             return SF4Operation::process(t0_, t1_, t2_, t3_); 
 17831 |          } 
 17832 |  
 17833 |          inline T0 t0() const 
 17834 |          { 
 17835 |             return t0_; 
 17836 |          } 
 17837 |  
 17838 |          inline T1 t1() const 
 17839 |          { 
 17840 |             return t1_; 
 17841 |          } 
 17842 |  
 17843 |          inline T2 t2() const 
 17844 |          { 
 17845 |             return t2_; 
 17846 |          } 
 17847 |  
 17848 |          inline T3 t3() const 
 17849 |          { 
 17850 |             return t3_; 
 17851 |          } 
 17852 |  
 17853 |          std::string type_id() const exprtk_override 
 17854 |          { 
 17855 |             return id(); 
 17856 |          } 
 17857 |  
 17858 |          static inline std::string id() 
 17859 |          { 
 17860 |             return SF4Operation::id(); 
 17861 |          } 
 17862 |  
 17863 |          template <typename Allocator> 
 17864 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3) 
 17865 |          { 
 17866 |             return allocator 
 17867 |                      .template allocate_type<node_type, T0, T1, T2, T3> 
 17868 |                         (p0, p1, p2, p3); 
 17869 |          } 
 17870 |  
 17871 |       private: 
 17872 |  
 17873 |          T0oT1oT2oT3_sf4ext(const node_type&) exprtk_delete; 
 17874 |          node_type& operator=(const node_type&) exprtk_delete; 
 17875 |  
 17876 |          T0 t0_; 
 17877 |          T1 t1_; 
 17878 |          T2 t2_; 
 17879 |          T3 t3_; 
 17880 |       }; 
 17881 |  
 17882 |       template <typename T> 
 17883 |       inline bool is_sf4ext_node(const expression_node<T>* n) 
 17884 |       { 
 17885 |          switch (n->type()) 
 17886 |          { 
 17887 |             case expression_node<T>::e_vovovov : return true; 
 17888 |             case expression_node<T>::e_vovovoc : return true; 
 17889 |             case expression_node<T>::e_vovocov : return true; 
 17890 |             case expression_node<T>::e_vocovov : return true; 
 17891 |             case expression_node<T>::e_covovov : return true; 
 17892 |             case expression_node<T>::e_covocov : return true; 
 17893 |             case expression_node<T>::e_vocovoc : return true; 
 17894 |             case expression_node<T>::e_covovoc : return true; 
 17895 |             case expression_node<T>::e_vococov : return true; 
 17896 |             default                            : return false; 
 17897 |          } 
 17898 |       } 
 17899 |  
 17900 |       template <typename T, typename T0, typename T1> 
 17901 |       struct T0oT1_define 
 17902 |       { 
 17903 |          typedef details::T0oT1<T, T0, T1> type0; 
 17904 |       }; 
 17905 |  
 17906 |       template <typename T, typename T0, typename T1, typename T2> 
 17907 |       struct T0oT1oT2_define 
 17908 |       { 
 17909 |          typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode0> type0; 
 17910 |          typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode1> type1; 
 17911 |          typedef details::T0oT1oT2_sf3<T, T0, T1, T2> sf3_type; 
 17912 |          typedef details::sf3ext_type_node<T, T0, T1, T2> sf3_type_node; 
 17913 |       }; 
 17914 |  
 17915 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17916 |       struct T0oT1oT2oT3_define 
 17917 |       { 
 17918 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode0> type0; 
 17919 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode1> type1; 
 17920 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode2> type2; 
 17921 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode3> type3; 
 17922 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode4> type4; 
 17923 |          typedef details::T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> sf4_type; 
 17924 |       }; 
 17925 |  
 17926 |       template <typename T, typename Operation> 
 17927 |       class vov_node exprtk_final : public vov_base_node<T> 
 17928 |       { 
 17929 |       public: 
 17930 |  
 17931 |          typedef expression_node<T>* expression_ptr; 
 17932 |          typedef Operation operation_t; 
 17933 |  
 17934 |          // variable op variable node 
 17935 |          explicit vov_node(const T& var0, const T& var1) 
 17936 |          : v0_(var0) 
 17937 |          , v1_(var1) 
 17938 |          {} 
 17939 |  
 17940 |          inline T value() const exprtk_override 
 17941 |          { 
 17942 |             return Operation::process(v0_,v1_); 
 17943 |          } 
 17944 |  
 17945 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17946 |          { 
 17947 |             return Operation::type(); 
 17948 |          } 
 17949 |  
 17950 |          inline operator_type operation() const exprtk_override 
 17951 |          { 
 17952 |             return Operation::operation(); 
 17953 |          } 
 17954 |  
 17955 |          inline const T& v0() const exprtk_override 
 17956 |          { 
 17957 |             return v0_; 
 17958 |          } 
 17959 |  
 17960 |          inline const T& v1() const exprtk_override 
 17961 |          { 
 17962 |             return v1_; 
 17963 |          } 
 17964 |  
 17965 |       protected: 
 17966 |  
 17967 |          const T& v0_; 
 17968 |          const T& v1_; 
 17969 |  
 17970 |       private: 
 17971 |  
 17972 |          vov_node(const vov_node<T,Operation>&) exprtk_delete; 
 17973 |          vov_node<T,Operation>& operator=(const vov_node<T,Operation>&) exprtk_delete; 
 17974 |       }; 
 17975 |  
 17976 |       template <typename T, typename Operation> 
 17977 |       class cov_node exprtk_final : public cov_base_node<T> 
 17978 |       { 
 17979 |       public: 
 17980 |  
 17981 |          typedef expression_node<T>* expression_ptr; 
 17982 |          typedef Operation operation_t; 
 17983 |  
 17984 |          // constant op variable node 
 17985 |          explicit cov_node(const T& const_var, const T& var) 
 17986 |          : c_(const_var) 
 17987 |          , v_(var) 
 17988 |          {} 
 17989 |  
 17990 |          inline T value() const exprtk_override 
 17991 |          { 
 17992 |             return Operation::process(c_,v_); 
 17993 |          } 
 17994 |  
 17995 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17996 |          { 
 17997 |             return Operation::type(); 
 17998 |          } 
 17999 |  
 18000 |          inline operator_type operation() const exprtk_override 
 18001 |          { 
 18002 |             return Operation::operation(); 
 18003 |          } 
 18004 |  
 18005 |          inline const T c() const exprtk_override 
 18006 |          { 
 18007 |             return c_; 
 18008 |          } 
 18009 |  
 18010 |          inline const T& v() const exprtk_override 
 18011 |          { 
 18012 |             return v_; 
 18013 |          } 
 18014 |  
 18015 |       protected: 
 18016 |  
 18017 |          const T  c_; 
 18018 |          const T& v_; 
 18019 |  
 18020 |       private: 
 18021 |  
 18022 |          cov_node(const cov_node<T,Operation>&) exprtk_delete; 
 18023 |          cov_node<T,Operation>& operator=(const cov_node<T,Operation>&) exprtk_delete; 
 18024 |       }; 
 18025 |  
 18026 |       template <typename T, typename Operation> 
 18027 |       class voc_node exprtk_final : public voc_base_node<T> 
 18028 |       { 
 18029 |       public: 
 18030 |  
 18031 |          typedef expression_node<T>* expression_ptr; 
 18032 |          typedef Operation operation_t; 
 18033 |  
 18034 |          // variable op constant node 
 18035 |          explicit voc_node(const T& var, const T& const_var) 
 18036 |          : v_(var) 
 18037 |          , c_(const_var) 
 18038 |          {} 
 18039 |  
 18040 |          inline T value() const exprtk_override 
 18041 |          { 
 18042 |             return Operation::process(v_,c_); 
 18043 |          } 
 18044 |  
 18045 |          inline operator_type operation() const exprtk_override 
 18046 |          { 
 18047 |             return Operation::operation(); 
 18048 |          } 
 18049 |  
 18050 |          inline const T c() const exprtk_override 
 18051 |          { 
 18052 |             return c_; 
 18053 |          } 
 18054 |  
 18055 |          inline const T& v() const exprtk_override 
 18056 |          { 
 18057 |             return v_; 
 18058 |          } 
 18059 |  
 18060 |       protected: 
 18061 |  
 18062 |          const T& v_; 
 18063 |          const T  c_; 
 18064 |  
 18065 |       private: 
 18066 |  
 18067 |          voc_node(const voc_node<T,Operation>&) exprtk_delete; 
 18068 |          voc_node<T,Operation>& operator=(const voc_node<T,Operation>&) exprtk_delete; 
 18069 |       }; 
 18070 |  
 18071 |       template <typename T, typename Operation> 
 18072 |       class vob_node exprtk_final : public vob_base_node<T> 
 18073 |       { 
 18074 |       public: 
 18075 |  
 18076 |          typedef expression_node<T>* expression_ptr; 
 18077 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18078 |          typedef Operation operation_t; 
 18079 |  
 18080 |          // variable op binary node 
 18081 |          explicit vob_node(const T& var, const expression_ptr branch) 
 18082 |          : v_(var) 
 18083 |          { 
 18084 |             construct_branch_pair(branch_, branch); 
 18085 |             assert(valid()); 
 18086 |          } 
 18087 |  
 18088 |          inline T value() const exprtk_override 
 18089 |          { 
 18090 |             return Operation::process(v_,branch_.first->value()); 
 18091 |          } 
 18092 |  
 18093 |          inline const T& v() const exprtk_override 
 18094 |          { 
 18095 |             return v_; 
 18096 |          } 
 18097 |  
 18098 |          inline bool valid() const exprtk_override 
 18099 |          { 
 18100 |             return branch_.first && branch_.first->valid(); 
 18101 |          } 
 18102 |  
 18103 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18104 |          { 
 18105 |             return branch_.first; 
 18106 |          } 
 18107 |  
 18108 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18109 |          { 
 18110 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18111 |          } 
 18112 |  
 18113 |          std::size_t node_depth() const exprtk_override 
 18114 |          { 
 18115 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18116 |          } 
 18117 |  
 18118 |       private: 
 18119 |  
 18120 |          vob_node(const vob_node<T,Operation>&) exprtk_delete; 
 18121 |          vob_node<T,Operation>& operator=(const vob_node<T,Operation>&) exprtk_delete; 
 18122 |  
 18123 |          const T& v_; 
 18124 |          branch_t branch_; 
 18125 |       }; 
 18126 |  
 18127 |       template <typename T, typename Operation> 
 18128 |       class bov_node exprtk_final : public bov_base_node<T> 
 18129 |       { 
 18130 |       public: 
 18131 |  
 18132 |          typedef expression_node<T>* expression_ptr; 
 18133 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18134 |          typedef Operation operation_t; 
 18135 |  
 18136 |          // binary node op variable node 
 18137 |          explicit bov_node(const expression_ptr branch, const T& var) 
 18138 |          : v_(var) 
 18139 |          { 
 18140 |             construct_branch_pair(branch_, branch); 
 18141 |             assert(valid()); 
 18142 |          } 
 18143 |  
 18144 |          inline T value() const exprtk_override 
 18145 |          { 
 18146 |             return Operation::process(branch_.first->value(),v_); 
 18147 |          } 
 18148 |  
 18149 |          inline const T& v() const exprtk_override 
 18150 |          { 
 18151 |             return v_; 
 18152 |          } 
 18153 |  
 18154 |          inline bool valid() const exprtk_override 
 18155 |          { 
 18156 |             return branch_.first && branch_.first->valid(); 
 18157 |          } 
 18158 |  
 18159 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18160 |          { 
 18161 |             return branch_.first; 
 18162 |          } 
 18163 |  
 18164 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18165 |          { 
 18166 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18167 |          } 
 18168 |  
 18169 |          std::size_t node_depth() const exprtk_override 
 18170 |          { 
 18171 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18172 |          } 
 18173 |  
 18174 |       private: 
 18175 |  
 18176 |          bov_node(const bov_node<T,Operation>&) exprtk_delete; 
 18177 |          bov_node<T,Operation>& operator=(const bov_node<T,Operation>&) exprtk_delete; 
 18178 |  
 18179 |          const T& v_; 
 18180 |          branch_t branch_; 
 18181 |       }; 
 18182 |  
 18183 |       template <typename T, typename Operation> 
 18184 |       class cob_node exprtk_final : public cob_base_node<T> 
 18185 |       { 
 18186 |       public: 
 18187 |  
 18188 |          typedef expression_node<T>* expression_ptr; 
 18189 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18190 |          typedef Operation operation_t; 
 18191 |  
 18192 |          // constant op variable node 
 18193 |          explicit cob_node(const T const_var, const expression_ptr branch) 
 18194 |          : c_(const_var) 
 18195 |          { 
 18196 |             construct_branch_pair(branch_, branch); 
 18197 |             assert(valid()); 
 18198 |          } 
 18199 |  
 18200 |          inline T value() const exprtk_override 
 18201 |          { 
 18202 |             return Operation::process(c_,branch_.first->value()); 
 18203 |          } 
 18204 |  
 18205 |          inline operator_type operation() const exprtk_override 
 18206 |          { 
 18207 |             return Operation::operation(); 
 18208 |          } 
 18209 |  
 18210 |          inline const T c() const exprtk_override 
 18211 |          { 
 18212 |             return c_; 
 18213 |          } 
 18214 |  
 18215 |          inline void set_c(const T new_c) exprtk_override 
 18216 |          { 
 18217 |             (*const_cast<T*>(&c_)) = new_c; 
 18218 |          } 
 18219 |  
 18220 |          inline bool valid() const exprtk_override 
 18221 |          { 
 18222 |             return branch_.first && branch_.first->valid(); 
 18223 |          } 
 18224 |  
 18225 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18226 |          { 
 18227 |             return branch_.first; 
 18228 |          } 
 18229 |  
 18230 |          inline expression_node<T>* move_branch(const std::size_t&) exprtk_override 
 18231 |          { 
 18232 |             branch_.second = false; 
 18233 |             return branch_.first; 
 18234 |          } 
 18235 |  
 18236 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18237 |          { 
 18238 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18239 |          } 
 18240 |  
 18241 |          std::size_t node_depth() const exprtk_override 
 18242 |          { 
 18243 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18244 |          } 
 18245 |  
 18246 |       private: 
 18247 |  
 18248 |          cob_node(const cob_node<T,Operation>&) exprtk_delete; 
 18249 |          cob_node<T,Operation>& operator=(const cob_node<T,Operation>&) exprtk_delete; 
 18250 |  
 18251 |          const T  c_; 
 18252 |          branch_t branch_; 
 18253 |       }; 
 18254 |  
 18255 |       template <typename T, typename Operation> 
 18256 |       class boc_node exprtk_final : public boc_base_node<T> 
 18257 |       { 
 18258 |       public: 
 18259 |  
 18260 |          typedef expression_node<T>* expression_ptr; 
 18261 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18262 |          typedef Operation operation_t; 
 18263 |  
 18264 |          // binary node op constant node 
 18265 |          explicit boc_node(const expression_ptr branch, const T const_var) 
 18266 |          : c_(const_var) 
 18267 |          { 
 18268 |             construct_branch_pair(branch_, branch); 
 18269 |             assert(valid()); 
 18270 |          } 
 18271 |  
 18272 |          inline T value() const exprtk_override 
 18273 |          { 
 18274 |             return Operation::process(branch_.first->value(),c_); 
 18275 |          } 
 18276 |  
 18277 |          inline operator_type operation() const exprtk_override 
 18278 |          { 
 18279 |             return Operation::operation(); 
 18280 |          } 
 18281 |  
 18282 |          inline const T c() const exprtk_override 
 18283 |          { 
 18284 |             return c_; 
 18285 |          } 
 18286 |  
 18287 |          inline void set_c(const T new_c) exprtk_override 
 18288 |          { 
 18289 |             (*const_cast<T*>(&c_)) = new_c; 
 18290 |          } 
 18291 |  
 18292 |          inline bool valid() const exprtk_override 
 18293 |          { 
 18294 |             return branch_.first && branch_.first->valid(); 
 18295 |          } 
 18296 |  
 18297 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18298 |          { 
 18299 |             return branch_.first; 
 18300 |          } 
 18301 |  
 18302 |          inline expression_node<T>* move_branch(const std::size_t&) exprtk_override 
 18303 |          { 
 18304 |             branch_.second = false; 
 18305 |             return branch_.first; 
 18306 |          } 
 18307 |  
 18308 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18309 |          { 
 18310 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18311 |          } 
 18312 |  
 18313 |          std::size_t node_depth() const exprtk_override 
 18314 |          { 
 18315 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18316 |          } 
 18317 |  
 18318 |       private: 
 18319 |  
 18320 |          boc_node(const boc_node<T,Operation>&) exprtk_delete; 
 18321 |          boc_node<T,Operation>& operator=(const boc_node<T,Operation>&) exprtk_delete; 
 18322 |  
 18323 |          const T  c_; 
 18324 |          branch_t branch_; 
 18325 |       }; 
 18326 |  
 18327 |       #ifndef exprtk_disable_string_capabilities 
 18328 |       template <typename T, typename SType0, typename SType1, typename Operation> 
 18329 |       class sos_node exprtk_final : public sos_base_node<T> 
 18330 |       { 
 18331 |       public: 
 18332 |  
 18333 |          typedef expression_node<T>* expression_ptr; 
 18334 |          typedef Operation operation_t; 
 18335 |  
 18336 |          // string op string node 
 18337 |          explicit sos_node(SType0 p0, SType1 p1) 
 18338 |          : s0_(p0) 
 18339 |          , s1_(p1) 
 18340 |          {} 
 18341 |  
 18342 |          inline T value() const exprtk_override 
 18343 |          { 
 18344 |             return Operation::process(s0_,s1_); 
 18345 |          } 
 18346 |  
 18347 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18348 |          { 
 18349 |             return Operation::type(); 
 18350 |          } 
 18351 |  
 18352 |          inline operator_type operation() const exprtk_override 
 18353 |          { 
 18354 |             return Operation::operation(); 
 18355 |          } 
 18356 |  
 18357 |          inline std::string& s0() 
 18358 |          { 
 18359 |             return s0_; 
 18360 |          } 
 18361 |  
 18362 |          inline std::string& s1() 
 18363 |          { 
 18364 |             return s1_; 
 18365 |          } 
 18366 |  
 18367 |       protected: 
 18368 |  
 18369 |          SType0 s0_; 
 18370 |          SType1 s1_; 
 18371 |  
 18372 |       private: 
 18373 |  
 18374 |          sos_node(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete; 
 18375 |          sos_node<T,SType0,SType1,Operation>& operator=(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete; 
 18376 |       }; 
 18377 |  
 18378 |       template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation> 
 18379 |       class str_xrox_node exprtk_final : public sos_base_node<T> 
 18380 |       { 
 18381 |       public: 
 18382 |  
 18383 |          typedef expression_node<T>* expression_ptr; 
 18384 |          typedef Operation operation_t; 
 18385 |          typedef str_xrox_node<T,SType0,SType1,RangePack,Operation> node_type; 
 18386 |  
 18387 |          // string-range op string node 
 18388 |          explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0) 
 18389 |          : s0_ (p0 ) 
 18390 |          , s1_ (p1 ) 
 18391 |          , rp0_(rp0) 
 18392 |          {} 
 18393 |  
 18394 |         ~str_xrox_node() exprtk_override 
 18395 |          { 
 18396 |             rp0_.free(); 
 18397 |          } 
 18398 |  
 18399 |          inline T value() const exprtk_override 
 18400 |          { 
 18401 |             std::size_t r0 = 0; 
 18402 |             std::size_t r1 = 0; 
 18403 |  
 18404 |             if (rp0_(r0, r1, s0_.size())) 
 18405 |                return Operation::process(s0_.substr(r0, (r1 - r0) + 1), s1_); 
 18406 |             else 
 18407 |                return T(0); 
 18408 |          } 
 18409 |  
 18410 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18411 |          { 
 18412 |             return Operation::type(); 
 18413 |          } 
 18414 |  
 18415 |          inline operator_type operation() const exprtk_override 
 18416 |          { 
 18417 |             return Operation::operation(); 
 18418 |          } 
 18419 |  
 18420 |          inline std::string& s0() 
 18421 |          { 
 18422 |             return s0_; 
 18423 |          } 
 18424 |  
 18425 |          inline std::string& s1() 
 18426 |          { 
 18427 |             return s1_; 
 18428 |          } 
 18429 |  
 18430 |       protected: 
 18431 |  
 18432 |          SType0    s0_; 
 18433 |          SType1    s1_; 
 18434 |          RangePack rp0_; 
 18435 |  
 18436 |       private: 
 18437 |  
 18438 |          str_xrox_node(const node_type&) exprtk_delete; 
 18439 |          node_type& operator=(const node_type&) exprtk_delete; 
 18440 |       }; 
 18441 |  
 18442 |       template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation> 
 18443 |       class str_xoxr_node exprtk_final : public sos_base_node<T> 
 18444 |       { 
 18445 |       public: 
 18446 |  
 18447 |          typedef expression_node<T>* expression_ptr; 
 18448 |          typedef Operation operation_t; 
 18449 |          typedef str_xoxr_node<T,SType0,SType1,RangePack,Operation> node_type; 
 18450 |  
 18451 |          // string op string range node 
 18452 |          explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1) 
 18453 |          : s0_ (p0 ) 
 18454 |          , s1_ (p1 ) 
 18455 |          , rp1_(rp1) 
 18456 |          {} 
 18457 |  
 18458 |         ~str_xoxr_node() 
 18459 |          { 
 18460 |             rp1_.free(); 
 18461 |          } 
 18462 |  
 18463 |          inline T value() const exprtk_override 
 18464 |          { 
 18465 |             std::size_t r0 = 0; 
 18466 |             std::size_t r1 = 0; 
 18467 |  
 18468 |             if (rp1_(r0, r1, s1_.size())) 
 18469 |             { 
 18470 |                return Operation::process 
 18471 |                       ( 
 18472 |                          s0_, 
 18473 |                          s1_.substr(r0, (r1 - r0) + 1) 
 18474 |                       ); 
 18475 |             } 
 18476 |             else 
 18477 |                return T(0); 
 18478 |          } 
 18479 |  
 18480 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18481 |          { 
 18482 |             return Operation::type(); 
 18483 |          } 
 18484 |  
 18485 |          inline operator_type operation() const exprtk_override 
 18486 |          { 
 18487 |             return Operation::operation(); 
 18488 |          } 
 18489 |  
 18490 |          inline std::string& s0() 
 18491 |          { 
 18492 |             return s0_; 
 18493 |          } 
 18494 |  
 18495 |          inline std::string& s1() 
 18496 |          { 
 18497 |             return s1_; 
 18498 |          } 
 18499 |  
 18500 |       protected: 
 18501 |  
 18502 |          SType0    s0_; 
 18503 |          SType1    s1_; 
 18504 |          RangePack rp1_; 
 18505 |  
 18506 |       private: 
 18507 |  
 18508 |          str_xoxr_node(const node_type&) exprtk_delete; 
 18509 |          node_type& operator=(const node_type&) exprtk_delete; 
 18510 |       }; 
 18511 |  
 18512 |       template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation> 
 18513 |       class str_xroxr_node exprtk_final : public sos_base_node<T> 
 18514 |       { 
 18515 |       public: 
 18516 |  
 18517 |          typedef expression_node<T>* expression_ptr; 
 18518 |          typedef Operation operation_t; 
 18519 |          typedef str_xroxr_node<T,SType0,SType1,RangePack,Operation> node_type; 
 18520 |  
 18521 |          // string-range op string-range node 
 18522 |          explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1) 
 18523 |          : s0_ (p0 ) 
 18524 |          , s1_ (p1 ) 
 18525 |          , rp0_(rp0) 
 18526 |          , rp1_(rp1) 
 18527 |          {} 
 18528 |  
 18529 |         ~str_xroxr_node() exprtk_override 
 18530 |          { 
 18531 |             rp0_.free(); 
 18532 |             rp1_.free(); 
 18533 |          } 
 18534 |  
 18535 |          inline T value() const exprtk_override 
 18536 |          { 
 18537 |             std::size_t r0_0 = 0; 
 18538 |             std::size_t r0_1 = 0; 
 18539 |             std::size_t r1_0 = 0; 
 18540 |             std::size_t r1_1 = 0; 
 18541 |  
 18542 |             if ( 
 18543 |                  rp0_(r0_0, r1_0, s0_.size()) && 
 18544 |                  rp1_(r0_1, r1_1, s1_.size()) 
 18545 |                ) 
 18546 |             { 
 18547 |                return Operation::process 
 18548 |                       ( 
 18549 |                          s0_.substr(r0_0, (r1_0 - r0_0) + 1), 
 18550 |                          s1_.substr(r0_1, (r1_1 - r0_1) + 1) 
 18551 |                       ); 
 18552 |             } 
 18553 |             else 
 18554 |                return T(0); 
 18555 |          } 
 18556 |  
 18557 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18558 |          { 
 18559 |             return Operation::type(); 
 18560 |          } 
 18561 |  
 18562 |          inline operator_type operation() const exprtk_override 
 18563 |          { 
 18564 |             return Operation::operation(); 
 18565 |          } 
 18566 |  
 18567 |          inline std::string& s0() 
 18568 |          { 
 18569 |             return s0_; 
 18570 |          } 
 18571 |  
 18572 |          inline std::string& s1() 
 18573 |          { 
 18574 |             return s1_; 
 18575 |          } 
 18576 |  
 18577 |       protected: 
 18578 |  
 18579 |          SType0    s0_; 
 18580 |          SType1    s1_; 
 18581 |          RangePack rp0_; 
 18582 |          RangePack rp1_; 
 18583 |  
 18584 |       private: 
 18585 |  
 18586 |          str_xroxr_node(const node_type&) exprtk_delete; 
 18587 |          node_type& operator=(const node_type&) exprtk_delete; 
 18588 |       }; 
 18589 |  
 18590 |       template <typename T, typename Operation> 
 18591 |       class str_sogens_node exprtk_final : public binary_node<T> 
 18592 |       { 
 18593 |       public: 
 18594 |  
 18595 |          typedef expression_node <T>* expression_ptr; 
 18596 |          typedef string_base_node<T>* str_base_ptr; 
 18597 |          typedef range_pack      <T>  range_t; 
 18598 |          typedef range_t*             range_ptr; 
 18599 |          typedef range_interface <T>  irange_t; 
 18600 |          typedef irange_t*            irange_ptr; 
 18601 |  
 18602 |          using binary_node<T>::branch; 
 18603 |  
 18604 |          str_sogens_node(const operator_type& opr, 
 18605 |                          expression_ptr branch0, 
 18606 |                          expression_ptr branch1) 
 18607 |          : binary_node<T>(opr, branch0, branch1) 
 18608 |          , str0_base_ptr_ (0) 
 18609 |          , str1_base_ptr_ (0) 
 18610 |          , str0_range_ptr_(0) 
 18611 |          , str1_range_ptr_(0) 
 18612 |          , initialised_   (false) 
 18613 |          { 
 18614 |             if (is_generally_string_node(branch(0))) 
 18615 |             { 
 18616 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 18617 |  
 18618 |                if (0 == str0_base_ptr_) 
 18619 |                   return; 
 18620 |  
 18621 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); 
 18622 |  
 18623 |                if (0 == range) 
 18624 |                   return; 
 18625 |  
 18626 |                str0_range_ptr_ = &(range->range_ref()); 
 18627 |             } 
 18628 |  
 18629 |             if (is_generally_string_node(branch(1))) 
 18630 |             { 
 18631 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 18632 |  
 18633 |                if (0 == str1_base_ptr_) 
 18634 |                   return; 
 18635 |  
 18636 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 18637 |  
 18638 |                if (0 == range) 
 18639 |                   return; 
 18640 |  
 18641 |                str1_range_ptr_ = &(range->range_ref()); 
 18642 |             } 
 18643 |  
 18644 |             initialised_ = 
 18645 |                str0_base_ptr_  && 
 18646 |                str1_base_ptr_  && 
 18647 |                str0_range_ptr_ && 
 18648 |                str1_range_ptr_; 
 18649 |  
 18650 |             assert(valid()); 
 18651 |          } 
 18652 |  
 18653 |          inline T value() const exprtk_override 
 18654 |          { 
 18655 |             branch(0)->value(); 
 18656 |             branch(1)->value(); 
 18657 |  
 18658 |             std::size_t str0_r0 = 0; 
 18659 |             std::size_t str0_r1 = 0; 
 18660 |  
 18661 |             std::size_t str1_r0 = 0; 
 18662 |             std::size_t str1_r1 = 0; 
 18663 |  
 18664 |             const range_t& range0 = (*str0_range_ptr_); 
 18665 |             const range_t& range1 = (*str1_range_ptr_); 
 18666 |  
 18667 |             if ( 
 18668 |                  range0(str0_r0, str0_r1, str0_base_ptr_->size()) && 
 18669 |                  range1(str1_r0, str1_r1, str1_base_ptr_->size()) 
 18670 |                ) 
 18671 |             { 
 18672 |                return Operation::process 
 18673 |                       ( 
 18674 |                          str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0)), 
 18675 |                          str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0)) 
 18676 |                       ); 
 18677 |             } 
 18678 |  
 18679 |             return std::numeric_limits<T>::quiet_NaN(); 
 18680 |          } 
 18681 |  
 18682 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18683 |          { 
 18684 |             return Operation::type(); 
 18685 |          } 
 18686 |  
 18687 |          inline bool valid() const exprtk_override 
 18688 |          { 
 18689 |             return initialised_; 
 18690 |          } 
 18691 |  
 18692 |       private: 
 18693 |  
 18694 |          str_sogens_node(const str_sogens_node<T,Operation>&) exprtk_delete; 
 18695 |          str_sogens_node<T,Operation>& operator=(const str_sogens_node<T,Operation>&) exprtk_delete; 
 18696 |  
 18697 |          str_base_ptr str0_base_ptr_; 
 18698 |          str_base_ptr str1_base_ptr_; 
 18699 |          range_ptr    str0_range_ptr_; 
 18700 |          range_ptr    str1_range_ptr_; 
 18701 |          bool         initialised_; 
 18702 |       }; 
 18703 |  
 18704 |       template <typename T, typename SType0, typename SType1, typename SType2, typename Operation> 
 18705 |       class sosos_node exprtk_final : public sosos_base_node<T> 
 18706 |       { 
 18707 |       public: 
 18708 |  
 18709 |          typedef expression_node<T>* expression_ptr; 
 18710 |          typedef Operation operation_t; 
 18711 |          typedef sosos_node<T, SType0, SType1, SType2, Operation> node_type; 
 18712 |  
 18713 |          // string op string op string node 
 18714 |          explicit sosos_node(SType0 p0, SType1 p1, SType2 p2) 
 18715 |          : s0_(p0) 
 18716 |          , s1_(p1) 
 18717 |          , s2_(p2) 
 18718 |          {} 
 18719 |  
 18720 |          inline T value() const exprtk_override 
 18721 |          { 
 18722 |             return Operation::process(s0_, s1_, s2_); 
 18723 |          } 
 18724 |  
 18725 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18726 |          { 
 18727 |             return Operation::type(); 
 18728 |          } 
 18729 |  
 18730 |          inline operator_type operation() const exprtk_override 
 18731 |          { 
 18732 |             return Operation::operation(); 
 18733 |          } 
 18734 |  
 18735 |          inline std::string& s0() 
 18736 |          { 
 18737 |             return s0_; 
 18738 |          } 
 18739 |  
 18740 |          inline std::string& s1() 
 18741 |          { 
 18742 |             return s1_; 
 18743 |          } 
 18744 |  
 18745 |          inline std::string& s2() 
 18746 |          { 
 18747 |             return s2_; 
 18748 |          } 
 18749 |  
 18750 |       protected: 
 18751 |  
 18752 |          SType0 s0_; 
 18753 |          SType1 s1_; 
 18754 |          SType2 s2_; 
 18755 |  
 18756 |       private: 
 18757 |  
 18758 |          sosos_node(const node_type&) exprtk_delete; 
 18759 |          node_type& operator=(const node_type&) exprtk_delete; 
 18760 |       }; 
 18761 |       #endif 
 18762 |  
 18763 |       template <typename T, typename PowOp> 
 18764 |       class ipow_node exprtk_final: public expression_node<T> 
 18765 |       { 
 18766 |       public: 
 18767 |  
 18768 |          typedef expression_node<T>* expression_ptr; 
 18769 |          typedef PowOp operation_t; 
 18770 |  
 18771 |          explicit ipow_node(const T& v) 
 18772 |          : v_(v) 
 18773 |          {} 
 18774 |  
 18775 |          inline T value() const exprtk_override 
 18776 |          { 
 18777 |             return PowOp::result(v_); 
 18778 |          } 
 18779 |  
 18780 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18781 |          { 
 18782 |             return expression_node<T>::e_ipow; 
 18783 |          } 
 18784 |  
 18785 |       private: 
 18786 |  
 18787 |          ipow_node(const ipow_node<T,PowOp>&) exprtk_delete; 
 18788 |          ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&) exprtk_delete; 
 18789 |  
 18790 |          const T& v_; 
 18791 |       }; 
 18792 |  
 18793 |       template <typename T, typename PowOp> 
 18794 |       class bipow_node exprtk_final : public expression_node<T> 
 18795 |       { 
 18796 |       public: 
 18797 |  
 18798 |          typedef expression_node<T>* expression_ptr; 
 18799 |          typedef std::pair<expression_ptr, bool> branch_t; 
 18800 |          typedef PowOp operation_t; 
 18801 |  
 18802 |          explicit bipow_node(expression_ptr branch) 
 18803 |          { 
 18804 |             construct_branch_pair(branch_, branch); 
 18805 |             assert(valid()); 
 18806 |          } 
 18807 |  
 18808 |          inline T value() const exprtk_override 
 18809 |          { 
 18810 |             return PowOp::result(branch_.first->value()); 
 18811 |          } 
 18812 |  
 18813 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18814 |          { 
 18815 |             return expression_node<T>::e_ipow; 
 18816 |          } 
 18817 |  
 18818 |          inline bool valid() const exprtk_override 
 18819 |          { 
 18820 |             return branch_.first && branch_.first->valid(); 
 18821 |          } 
 18822 |  
 18823 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18824 |          { 
 18825 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18826 |          } 
 18827 |  
 18828 |          std::size_t node_depth() const exprtk_override 
 18829 |          { 
 18830 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18831 |          } 
 18832 |  
 18833 |       private: 
 18834 |  
 18835 |          bipow_node(const bipow_node<T,PowOp>&) exprtk_delete; 
 18836 |          bipow_node<T,PowOp>& operator=(const bipow_node<T,PowOp>&) exprtk_delete; 
 18837 |  
 18838 |          branch_t branch_; 
 18839 |       }; 
 18840 |  
 18841 |       template <typename T, typename PowOp> 
 18842 |       class ipowinv_node exprtk_final : public expression_node<T> 
 18843 |       { 
 18844 |       public: 
 18845 |  
 18846 |          typedef expression_node<T>* expression_ptr; 
 18847 |          typedef PowOp operation_t; 
 18848 |  
 18849 |          explicit ipowinv_node(const T& v) 
 18850 |          : v_(v) 
 18851 |          {} 
 18852 |  
 18853 |          inline T value() const exprtk_override 
 18854 |          { 
 18855 |             return (T(1) / PowOp::result(v_)); 
 18856 |          } 
 18857 |  
 18858 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18859 |          { 
 18860 |             return expression_node<T>::e_ipowinv; 
 18861 |          } 
 18862 |  
 18863 |       private: 
 18864 |  
 18865 |          ipowinv_node(const ipowinv_node<T,PowOp>&) exprtk_delete; 
 18866 |          ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&) exprtk_delete; 
 18867 |  
 18868 |          const T& v_; 
 18869 |       }; 
 18870 |  
 18871 |       template <typename T, typename PowOp> 
 18872 |       class bipowinv_node exprtk_final : public expression_node<T> 
 18873 |       { 
 18874 |       public: 
 18875 |  
 18876 |          typedef expression_node<T>* expression_ptr; 
 18877 |          typedef std::pair<expression_ptr, bool> branch_t; 
 18878 |          typedef PowOp operation_t; 
 18879 |  
 18880 |          explicit bipowinv_node(expression_ptr branch) 
 18881 |          { 
 18882 |             construct_branch_pair(branch_, branch); 
 18883 |             assert(valid()); 
 18884 |          } 
 18885 |  
 18886 |          inline T value() const exprtk_override 
 18887 |          { 
 18888 |             return (T(1) / PowOp::result(branch_.first->value())); 
 18889 |          } 
 18890 |  
 18891 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18892 |          { 
 18893 |             return expression_node<T>::e_ipowinv; 
 18894 |          } 
 18895 |  
 18896 |          inline bool valid() const exprtk_override 
 18897 |          { 
 18898 |             return branch_.first && branch_.first->valid(); 
 18899 |          } 
 18900 |  
 18901 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18902 |          { 
 18903 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18904 |          } 
 18905 |  
 18906 |          std::size_t node_depth() const exprtk_override 
 18907 |          { 
 18908 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18909 |          } 
 18910 |  
 18911 |       private: 
 18912 |  
 18913 |          bipowinv_node(const bipowinv_node<T,PowOp>&) exprtk_delete; 
 18914 |          bipowinv_node<T,PowOp>& operator=(const bipowinv_node<T,PowOp>&) exprtk_delete; 
 18915 |  
 18916 |          branch_t branch_; 
 18917 |       }; 
 18918 |  
 18919 |       template <typename T> 
 18920 |       inline bool is_vov_node(const expression_node<T>* node) 
 18921 |       { 
 18922 |          return (0 != dynamic_cast<const vov_base_node<T>*>(node)); 
 18923 |       } 
 18924 |  
 18925 |       template <typename T> 
 18926 |       inline bool is_cov_node(const expression_node<T>* node) 
 18927 |       { 
 18928 |          return (0 != dynamic_cast<const cov_base_node<T>*>(node)); 
 18929 |       } 
 18930 |  
 18931 |       template <typename T> 
 18932 |       inline bool is_voc_node(const expression_node<T>* node) 
 18933 |       { 
 18934 |          return (0 != dynamic_cast<const voc_base_node<T>*>(node)); 
 18935 |       } 
 18936 |  
 18937 |       template <typename T> 
 18938 |       inline bool is_cob_node(const expression_node<T>* node) 
 18939 |       { 
 18940 |          return (0 != dynamic_cast<const cob_base_node<T>*>(node)); 
 18941 |       } 
 18942 |  
 18943 |       template <typename T> 
 18944 |       inline bool is_boc_node(const expression_node<T>* node) 
 18945 |       { 
 18946 |          return (0 != dynamic_cast<const boc_base_node<T>*>(node)); 
 18947 |       } 
 18948 |  
 18949 |       template <typename T> 
 18950 |       inline bool is_t0ot1ot2_node(const expression_node<T>* node) 
 18951 |       { 
 18952 |          return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node)); 
 18953 |       } 
 18954 |  
 18955 |       template <typename T> 
 18956 |       inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node) 
 18957 |       { 
 18958 |          return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node)); 
 18959 |       } 
 18960 |  
 18961 |       template <typename T> 
 18962 |       inline bool is_uv_node(const expression_node<T>* node) 
 18963 |       { 
 18964 |          return (0 != dynamic_cast<const uv_base_node<T>*>(node)); 
 18965 |       } 
 18966 |  
 18967 |       template <typename T> 
 18968 |       inline bool is_string_node(const expression_node<T>* node) 
 18969 |       { 
 18970 |          return node && (expression_node<T>::e_stringvar == node->type()); 
 18971 |       } 
 18972 |  
 18973 |       template <typename T> 
 18974 |       inline bool is_string_range_node(const expression_node<T>* node) 
 18975 |       { 
 18976 |          return node && (expression_node<T>::e_stringvarrng == node->type()); 
 18977 |       } 
 18978 |  
 18979 |       template <typename T> 
 18980 |       inline bool is_const_string_node(const expression_node<T>* node) 
 18981 |       { 
 18982 |          return node && (expression_node<T>::e_stringconst == node->type()); 
 18983 |       } 
 18984 |  
 18985 |       template <typename T> 
 18986 |       inline bool is_const_string_range_node(const expression_node<T>* node) 
 18987 |       { 
 18988 |          return node && (expression_node<T>::e_cstringvarrng == node->type()); 
 18989 |       } 
 18990 |  
 18991 |       template <typename T> 
 18992 |       inline bool is_string_assignment_node(const expression_node<T>* node) 
 18993 |       { 
 18994 |          return node && (expression_node<T>::e_strass == node->type()); 
 18995 |       } 
 18996 |  
 18997 |       template <typename T> 
 18998 |       inline bool is_string_concat_node(const expression_node<T>* node) 
 18999 |       { 
 19000 |          return node && (expression_node<T>::e_strconcat == node->type()); 
 19001 |       } 
 19002 |  
 19003 |       template <typename T> 
 19004 |       inline bool is_string_function_node(const expression_node<T>* node) 
 19005 |       { 
 19006 |          return node && (expression_node<T>::e_strfunction == node->type()); 
 19007 |       } 
 19008 |  
 19009 |       template <typename T> 
 19010 |       inline bool is_string_condition_node(const expression_node<T>* node) 
 19011 |       { 
 19012 |          return node && (expression_node<T>::e_strcondition == node->type()); 
 19013 |       } 
 19014 |  
 19015 |       template <typename T> 
 19016 |       inline bool is_string_ccondition_node(const expression_node<T>* node) 
 19017 |       { 
 19018 |          return node && (expression_node<T>::e_strccondition == node->type()); 
 19019 |       } 
 19020 |  
 19021 |       template <typename T> 
 19022 |       inline bool is_string_vararg_node(const expression_node<T>* node) 
 19023 |       { 
 19024 |          return node && (expression_node<T>::e_stringvararg == node->type()); 
 19025 |       } 
 19026 |  
 19027 |       template <typename T> 
 19028 |       inline bool is_genricstring_range_node(const expression_node<T>* node) 
 19029 |       { 
 19030 |          return node && (expression_node<T>::e_strgenrange == node->type()); 
 19031 |       } 
 19032 |  
 19033 |       template <typename T> 
 19034 |       inline bool is_generally_string_node(const expression_node<T>* node) 
 19035 |       { 
 19036 |          if (node) 
 19037 |          { 
 19038 |             switch (node->type()) 
 19039 |             { 
 19040 |                case expression_node<T>::e_stringvar     : 
 19041 |                case expression_node<T>::e_stringconst   : 
 19042 |                case expression_node<T>::e_stringvarrng  : 
 19043 |                case expression_node<T>::e_cstringvarrng : 
 19044 |                case expression_node<T>::e_strgenrange   : 
 19045 |                case expression_node<T>::e_strass        : 
 19046 |                case expression_node<T>::e_strconcat     : 
 19047 |                case expression_node<T>::e_strfunction   : 
 19048 |                case expression_node<T>::e_strcondition  : 
 19049 |                case expression_node<T>::e_strccondition : 
 19050 |                case expression_node<T>::e_stringvararg  : return true; 
 19051 |                default                                  : return false; 
 19052 |             } 
 19053 |          } 
 19054 |  
 19055 |          return false; 
 19056 |       } 
 19057 |  
 19058 |       template <typename T> 
 19059 |       inline bool is_loop_node(const expression_node<T>* node) 
 19060 |       { 
 19061 |          if (node) 
 19062 |          { 
 19063 |             switch (node->type()) 
 19064 |             { 
 19065 |                case expression_node<T>::e_for    : 
 19066 |                case expression_node<T>::e_repeat : 
 19067 |                case expression_node<T>::e_while  : return true; 
 19068 |                default                           : return false; 
 19069 |             } 
 19070 |          } 
 19071 |  
 19072 |          return false; 
 19073 |       } 
 19074 |  
 19075 |       template <typename T> 
 19076 |       inline bool is_block_node(const expression_node<T>* node) 
 19077 |       { 
 19078 |          if (node) 
 19079 |          { 
 19080 |             if (is_loop_node(node)) 
 19081 |             { 
 19082 |                return true; 
 19083 |             } 
 19084 |  
 19085 |             switch (node->type()) 
 19086 |             { 
 19087 |                case expression_node<T>::e_conditional : 
 19088 |                case expression_node<T>::e_mswitch     : 
 19089 |                case expression_node<T>::e_switch      : 
 19090 |                case expression_node<T>::e_vararg      : return true; 
 19091 |                default                                : return false; 
 19092 |             } 
 19093 |          } 
 19094 |  
 19095 |          return false; 
 19096 |       } 
 19097 |  
 19098 |       class node_allocator 
 19099 |       { 
 19100 |       public: 
 19101 |  
 19102 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19103 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1]) 
 19104 |          { 
 19105 |             expression_node<typename ResultNode::value_type>* result = 
 19106 |                allocate<ResultNode>(operation, branch[0]); 
 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)[2]) 
 19113 |          { 
 19114 |             expression_node<typename ResultNode::value_type>* result = 
 19115 |                allocate<ResultNode>(operation, branch[0], branch[1]); 
 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)[3]) 
 19122 |          { 
 19123 |             expression_node<typename ResultNode::value_type>* result = 
 19124 |                allocate<ResultNode>(operation, branch[0], branch[1], branch[2]); 
 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)[4]) 
 19131 |          { 
 19132 |             expression_node<typename ResultNode::value_type>* result = 
 19133 |                allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3]); 
 19134 |             result->node_depth(); 
 19135 |             return result; 
 19136 |          } 
 19137 |  
 19138 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19139 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5]) 
 19140 |          { 
 19141 |             expression_node<typename ResultNode::value_type>* result = 
 19142 |                allocate<ResultNode>(operation, branch[0],branch[1], branch[2], branch[3], branch[4]); 
 19143 |             result->node_depth(); 
 19144 |             return result; 
 19145 |          } 
 19146 |  
 19147 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19148 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6]) 
 19149 |          { 
 19150 |             expression_node<typename ResultNode::value_type>* result = 
 19151 |                allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3], branch[4], branch[5]); 
 19152 |             result->node_depth(); 
 19153 |             return result; 
 19154 |          } 
 19155 |  
 19156 |          template <typename node_type> 
 19157 |          inline expression_node<typename node_type::value_type>* allocate() const 
 19158 |          { 
 19159 |             return (new node_type()); 
 19160 |          } 
 19161 |  
 19162 |          template <typename node_type, 
 19163 |                    typename Type, 
 19164 |                    typename Allocator, 
 19165 |                    template <typename, typename> class Sequence> 
 19166 |          inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const 
 19167 |          { 
 19168 |             expression_node<typename node_type::value_type>* 
 19169 |             result = (new node_type(seq)); 
 19170 |             result->node_depth(); 
 19171 |             return result; 
 19172 |          } 
 19173 |  
 19174 |          template <typename node_type, typename T1> 
 19175 |          inline expression_node<typename node_type::value_type>* allocate(T1& t1) const 
 19176 |          { 
 19177 |             expression_node<typename node_type::value_type>* 
 19178 |             result = (new node_type(t1)); 
 19179 |             result->node_depth(); 
 19180 |             return result; 
 19181 |          } 
 19182 |  
 19183 |          template <typename node_type, typename T1> 
 19184 |          inline expression_node<typename node_type::value_type>* allocate_c(const T1& t1) const 
 19185 |          { 
 19186 |             expression_node<typename node_type::value_type>* 
 19187 |             result = (new node_type(t1)); 
 19188 |             result->node_depth(); 
 19189 |             return result; 
 19190 |          } 
 19191 |  
 19192 |          template <typename node_type, 
 19193 |                    typename T1, typename T2> 
 19194 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const 
 19195 |          { 
 19196 |             expression_node<typename node_type::value_type>* 
 19197 |             result = (new node_type(t1, t2)); 
 19198 |             result->node_depth(); 
 19199 |             return result; 
 19200 |          } 
 19201 |  
 19202 |          template <typename node_type, 
 19203 |                    typename T1, typename T2> 
 19204 |          inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const 
 19205 |          { 
 19206 |             expression_node<typename node_type::value_type>* 
 19207 |             result = (new node_type(t1, t2)); 
 19208 |             result->node_depth(); 
 19209 |             return result; 
 19210 |          } 
 19211 |  
 19212 |          template <typename node_type, 
 19213 |                    typename T1, typename T2> 
 19214 |          inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const 
 19215 |          { 
 19216 |             expression_node<typename node_type::value_type>* 
 19217 |             result = (new node_type(t1, t2)); 
 19218 |             result->node_depth(); 
 19219 |             return result; 
 19220 |          } 
 19221 |  
 19222 |          template <typename node_type, 
 19223 |                    typename T1, typename T2> 
 19224 |          inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const 
 19225 |          { 
 19226 |             expression_node<typename node_type::value_type>* 
 19227 |             result = (new node_type(t1, t2)); 
 19228 |             result->node_depth(); 
 19229 |             return result; 
 19230 |          } 
 19231 |  
 19232 |          template <typename node_type, 
 19233 |                    typename T1, typename T2> 
 19234 |          inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const 
 19235 |          { 
 19236 |             expression_node<typename node_type::value_type>* 
 19237 |             result = (new node_type(t1, t2)); 
 19238 |             result->node_depth(); 
 19239 |             return result; 
 19240 |          } 
 19241 |  
 19242 |          template <typename node_type, 
 19243 |                    typename T1, typename T2, typename T3> 
 19244 |          inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const 
 19245 |          { 
 19246 |             expression_node<typename node_type::value_type>* 
 19247 |             result = (new node_type(t1, t2, t3)); 
 19248 |             result->node_depth(); 
 19249 |             return result; 
 19250 |          } 
 19251 |  
 19252 |          template <typename node_type, 
 19253 |                    typename T1, typename T2, typename T3, typename T4> 
 19254 |          inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const 
 19255 |          { 
 19256 |             expression_node<typename node_type::value_type>* 
 19257 |             result = (new node_type(t1, t2, t3, t4)); 
 19258 |             result->node_depth(); 
 19259 |             return result; 
 19260 |          } 
 19261 |  
 19262 |          template <typename node_type, 
 19263 |                    typename T1, typename T2, typename T3> 
 19264 |          inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const 
 19265 |          { 
 19266 |             expression_node<typename node_type::value_type>* 
 19267 |             result = (new node_type(t1, t2, t3)); 
 19268 |             result->node_depth(); 
 19269 |             return result; 
 19270 |          } 
 19271 |  
 19272 |          template <typename node_type, 
 19273 |                    typename T1, typename T2, typename T3, typename T4> 
 19274 |          inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const 
 19275 |          { 
 19276 |             expression_node<typename node_type::value_type>* 
 19277 |             result = (new node_type(t1, t2, t3, t4)); 
 19278 |             result->node_depth(); 
 19279 |             return result; 
 19280 |          } 
 19281 |  
 19282 |          template <typename node_type, 
 19283 |                    typename T1, typename T2, typename T3, typename T4, typename T5> 
 19284 |          inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const 
 19285 |          { 
 19286 |             expression_node<typename node_type::value_type>* 
 19287 |             result = (new node_type(t1, t2, t3, t4, t5)); 
 19288 |             result->node_depth(); 
 19289 |             return result; 
 19290 |          } 
 19291 |  
 19292 |          template <typename node_type, 
 19293 |                    typename T1, typename T2, typename T3> 
 19294 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19295 |                                                                           const T3& t3) const 
 19296 |          { 
 19297 |             expression_node<typename node_type::value_type>* 
 19298 |             result = (new node_type(t1, t2, t3)); 
 19299 |             result->node_depth(); 
 19300 |             return result; 
 19301 |          } 
 19302 |  
 19303 |          template <typename node_type, 
 19304 |                    typename T1, typename T2, 
 19305 |                    typename T3, typename T4> 
 19306 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19307 |                                                                           const T3& t3, const T4& t4) const 
 19308 |          { 
 19309 |             expression_node<typename node_type::value_type>* 
 19310 |             result = (new node_type(t1, t2, t3, t4)); 
 19311 |             result->node_depth(); 
 19312 |             return result; 
 19313 |          } 
 19314 |  
 19315 |          template <typename node_type, 
 19316 |                    typename T1, typename T2, 
 19317 |                    typename T3, typename T4, typename T5> 
 19318 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19319 |                                                                           const T3& t3, const T4& t4, 
 19320 |                                                                           const T5& t5) const 
 19321 |          { 
 19322 |             expression_node<typename node_type::value_type>* 
 19323 |             result = (new node_type(t1, t2, t3, t4, t5)); 
 19324 |             result->node_depth(); 
 19325 |             return result; 
 19326 |          } 
 19327 |  
 19328 |          template <typename node_type, 
 19329 |                    typename T1, typename T2, 
 19330 |                    typename T3, typename T4, typename T5, typename T6> 
 19331 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19332 |                                                                           const T3& t3, const T4& t4, 
 19333 |                                                                           const T5& t5, const T6& t6) const 
 19334 |          { 
 19335 |             expression_node<typename node_type::value_type>* 
 19336 |             result = (new node_type(t1, t2, t3, t4, t5, t6)); 
 19337 |             result->node_depth(); 
 19338 |             return result; 
 19339 |          } 
 19340 |  
 19341 |          template <typename node_type, 
 19342 |                    typename T1, typename T2, 
 19343 |                    typename T3, typename T4, 
 19344 |                    typename T5, typename T6, typename T7> 
 19345 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19346 |                                                                           const T3& t3, const T4& t4, 
 19347 |                                                                           const T5& t5, const T6& t6, 
 19348 |                                                                           const T7& t7) const 
 19349 |          { 
 19350 |             expression_node<typename node_type::value_type>* 
 19351 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7)); 
 19352 |             result->node_depth(); 
 19353 |             return result; 
 19354 |          } 
 19355 |  
 19356 |          template <typename node_type, 
 19357 |                    typename T1, typename T2, 
 19358 |                    typename T3, typename T4, 
 19359 |                    typename T5, typename T6, 
 19360 |                    typename T7, typename T8> 
 19361 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19362 |                                                                           const T3& t3, const T4& t4, 
 19363 |                                                                           const T5& t5, const T6& t6, 
 19364 |                                                                           const T7& t7, const T8& t8) const 
 19365 |          { 
 19366 |             expression_node<typename node_type::value_type>* 
 19367 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8)); 
 19368 |             result->node_depth(); 
 19369 |             return result; 
 19370 |          } 
 19371 |  
 19372 |          template <typename node_type, 
 19373 |                    typename T1, typename T2, 
 19374 |                    typename T3, typename T4, 
 19375 |                    typename T5, typename T6, 
 19376 |                    typename T7, typename T8, typename T9> 
 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 
 19382 |          { 
 19383 |             expression_node<typename node_type::value_type>* 
 19384 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9)); 
 19385 |             result->node_depth(); 
 19386 |             return result; 
 19387 |          } 
 19388 |  
 19389 |          template <typename node_type, 
 19390 |                    typename T1, typename T2, 
 19391 |                    typename T3, typename T4, 
 19392 |                    typename T5, typename T6, 
 19393 |                    typename T7, typename T8, 
 19394 |                    typename T9, typename T10> 
 19395 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const  T2&  t2, 
 19396 |                                                                           const T3& t3, const  T4&  t4, 
 19397 |                                                                           const T5& t5, const  T6&  t6, 
 19398 |                                                                           const T7& t7, const  T8&  t8, 
 19399 |                                                                           const T9& t9, const T10& t10) const 
 19400 |          { 
 19401 |             expression_node<typename node_type::value_type>* 
 19402 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)); 
 19403 |             result->node_depth(); 
 19404 |             return result; 
 19405 |          } 
 19406 |  
 19407 |          template <typename node_type, 
 19408 |                    typename T1, typename T2, typename T3> 
 19409 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const 
 19410 |          { 
 19411 |             expression_node<typename node_type::value_type>* 
 19412 |             result = (new node_type(t1, t2, t3)); 
 19413 |             result->node_depth(); 
 19414 |             return result; 
 19415 |          } 
 19416 |  
 19417 |          template <typename node_type, 
 19418 |                    typename T1, typename T2, 
 19419 |                    typename T3, typename T4> 
 19420 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19421 |                                                                                T3 t3, T4 t4) const 
 19422 |          { 
 19423 |             expression_node<typename node_type::value_type>* 
 19424 |             result = (new node_type(t1, t2, t3, t4)); 
 19425 |             result->node_depth(); 
 19426 |             return result; 
 19427 |          } 
 19428 |  
 19429 |          template <typename node_type, 
 19430 |                    typename T1, typename T2, 
 19431 |                    typename T3, typename T4, 
 19432 |                    typename T5> 
 19433 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19434 |                                                                                T3 t3, T4 t4, 
 19435 |                                                                                T5 t5) const 
 19436 |          { 
 19437 |             expression_node<typename node_type::value_type>* 
 19438 |             result = (new node_type(t1, t2, t3, t4, t5)); 
 19439 |             result->node_depth(); 
 19440 |             return result; 
 19441 |          } 
 19442 |  
 19443 |          template <typename node_type, 
 19444 |                    typename T1, typename T2, 
 19445 |                    typename T3, typename T4, 
 19446 |                    typename T5, typename T6> 
 19447 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19448 |                                                                                T3 t3, T4 t4, 
 19449 |                                                                                T5 t5, T6 t6) const 
 19450 |          { 
 19451 |             expression_node<typename node_type::value_type>* 
 19452 |             result = (new node_type(t1, t2, t3, t4, t5, t6)); 
 19453 |             result->node_depth(); 
 19454 |             return result; 
 19455 |          } 
 19456 |  
 19457 |          template <typename node_type, 
 19458 |                    typename T1, typename T2, 
 19459 |                    typename T3, typename T4, 
 19460 |                    typename T5, typename T6, typename T7> 
 19461 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19462 |                                                                                T3 t3, T4 t4, 
 19463 |                                                                                T5 t5, T6 t6, 
 19464 |                                                                                T7 t7) const 
 19465 |          { 
 19466 |             expression_node<typename node_type::value_type>* 
 19467 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7)); 
 19468 |             result->node_depth(); 
 19469 |             return result; 
 19470 |          } 
 19471 |  
 19472 |          template <typename T> 
 19473 |          void inline free(expression_node<T>*& e) const 
 19474 |          { 
 19475 |             exprtk_debug(("node_allocator::free() - deleting expression_node " 
 19476 |                           "type: %03d addr: %p\n", 
 19477 |                           static_cast<int>(e->type()), 
 19478 |                           reinterpret_cast<void*>(e))); 
 19479 |             delete e; 
 19480 |             e = 0; 
 19481 |          } 
 19482 |       }; 
 19483 |  
 19484 |       inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m) 
 19485 |       { 
 19486 |          #define register_op(Symbol, Type, Args)                                             \ 
 19487 |          m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \ 
 19488 |  
 19489 |          register_op("abs"       , e_abs     , 1) 
 19490 |          register_op("acos"      , e_acos    , 1) 
 19491 |          register_op("acosh"     , e_acosh   , 1) 
 19492 |          register_op("asin"      , e_asin    , 1) 
 19493 |          register_op("asinh"     , e_asinh   , 1) 
 19494 |          register_op("atan"      , e_atan    , 1) 
 19495 |          register_op("atanh"     , e_atanh   , 1) 
 19496 |          register_op("ceil"      , e_ceil    , 1) 
 19497 |          register_op("cos"       , e_cos     , 1) 
 19498 |          register_op("cosh"      , e_cosh    , 1) 
 19499 |          register_op("exp"       , e_exp     , 1) 
 19500 |          register_op("expm1"     , e_expm1   , 1) 
 19501 |          register_op("floor"     , e_floor   , 1) 
 19502 |          register_op("log"       , e_log     , 1) 
 19503 |          register_op("log10"     , e_log10   , 1) 
 19504 |          register_op("log2"      , e_log2    , 1) 
 19505 |          register_op("log1p"     , e_log1p   , 1) 
 19506 |          register_op("round"     , e_round   , 1) 
 19507 |          register_op("sin"       , e_sin     , 1) 
 19508 |          register_op("sinc"      , e_sinc    , 1) 
 19509 |          register_op("sinh"      , e_sinh    , 1) 
 19510 |          register_op("sec"       , e_sec     , 1) 
 19511 |          register_op("csc"       , e_csc     , 1) 
 19512 |          register_op("sqrt"      , e_sqrt    , 1) 
 19513 |          register_op("tan"       , e_tan     , 1) 
 19514 |          register_op("tanh"      , e_tanh    , 1) 
 19515 |          register_op("cot"       , e_cot     , 1) 
 19516 |          register_op("rad2deg"   , e_r2d     , 1) 
 19517 |          register_op("deg2rad"   , e_d2r     , 1) 
 19518 |          register_op("deg2grad"  , e_d2g     , 1) 
 19519 |          register_op("grad2deg"  , e_g2d     , 1) 
 19520 |          register_op("sgn"       , e_sgn     , 1) 
 19521 |          register_op("not"       , e_notl    , 1) 
 19522 |          register_op("erf"       , e_erf     , 1) 
 19523 |          register_op("erfc"      , e_erfc    , 1) 
 19524 |          register_op("ncdf"      , e_ncdf    , 1) 
 19525 |          register_op("frac"      , e_frac    , 1) 
 19526 |          register_op("trunc"     , e_trunc   , 1) 
 19527 |          register_op("atan2"     , e_atan2   , 2) 
 19528 |          register_op("mod"       , e_mod     , 2) 
 19529 |          register_op("logn"      , e_logn    , 2) 
 19530 |          register_op("pow"       , e_pow     , 2) 
 19531 |          register_op("root"      , e_root    , 2) 
 19532 |          register_op("roundn"    , e_roundn  , 2) 
 19533 |          register_op("equal"     , e_equal   , 2) 
 19534 |          register_op("not_equal" , e_nequal  , 2) 
 19535 |          register_op("hypot"     , e_hypot   , 2) 
 19536 |          register_op("shr"       , e_shr     , 2) 
 19537 |          register_op("shl"       , e_shl     , 2) 
 19538 |          register_op("clamp"     , e_clamp   , 3) 
 19539 |          register_op("iclamp"    , e_iclamp  , 3) 
 19540 |          register_op("inrange"   , e_inrange , 3) 
 19541 |          #undef register_op 
 19542 |       } 
 19543 |  
 19544 |    } // namespace details 
 19545 |  
 19546 |    class function_traits 
 19547 |    { 
 19548 |    public: 
 19549 |  
 19550 |       function_traits() 
 19551 |       : allow_zero_parameters_(false) 
 19552 |       , has_side_effects_(true) 
 19553 |       , min_num_args_(0) 
 19554 |       , max_num_args_(std::numeric_limits<std::size_t>::max()) 
 19555 |       {} 
 19556 |  
 19557 |       inline bool& allow_zero_parameters() 
 19558 |       { 
 19559 |          return allow_zero_parameters_; 
 19560 |       } 
 19561 |  
 19562 |       inline bool& has_side_effects() 
 19563 |       { 
 19564 |          return has_side_effects_; 
 19565 |       } 
 19566 |  
 19567 |       std::size_t& min_num_args() 
 19568 |       { 
 19569 |          return min_num_args_; 
 19570 |       } 
 19571 |  
 19572 |       std::size_t& max_num_args() 
 19573 |       { 
 19574 |          return max_num_args_; 
 19575 |       } 
 19576 |  
 19577 |    private: 
 19578 |  
 19579 |       bool allow_zero_parameters_; 
 19580 |       bool has_side_effects_; 
 19581 |       std::size_t min_num_args_; 
 19582 |       std::size_t max_num_args_; 
 19583 |    }; 
 19584 |  
 19585 |    template <typename FunctionType> 
 19586 |    void enable_zero_parameters(FunctionType& func) 
 19587 |    { 
 19588 |       func.allow_zero_parameters() = true; 
 19589 |  
 19590 |       if (0 != func.min_num_args()) 
 19591 |       { 
 19592 |          func.min_num_args() = 0; 
 19593 |       } 
 19594 |    } 
 19595 |  
 19596 |    template <typename FunctionType> 
 19597 |    void disable_zero_parameters(FunctionType& func) 
 19598 |    { 
 19599 |       func.allow_zero_parameters() = false; 
 19600 |    } 
 19601 |  
 19602 |    template <typename FunctionType> 
 19603 |    void enable_has_side_effects(FunctionType& func) 
 19604 |    { 
 19605 |       func.has_side_effects() = true; 
 19606 |    } 
 19607 |  
 19608 |    template <typename FunctionType> 
 19609 |    void disable_has_side_effects(FunctionType& func) 
 19610 |    { 
 19611 |       func.has_side_effects() = false; 
 19612 |    } 
 19613 |  
 19614 |    template <typename FunctionType> 
 19615 |    void set_min_num_args(FunctionType& func, const std::size_t& num_args) 
 19616 |    { 
 19617 |       func.min_num_args() = num_args; 
 19618 |  
 19619 |       if ((0 != func.min_num_args()) && func.allow_zero_parameters()) 
 19620 |          func.allow_zero_parameters() = false; 
 19621 |    } 
 19622 |  
 19623 |    template <typename FunctionType> 
 19624 |    void set_max_num_args(FunctionType& func, const std::size_t& num_args) 
 19625 |    { 
 19626 |       func.max_num_args() = num_args; 
 19627 |    } 
 19628 |  
 19629 |    template <typename T> 
 19630 |    class ifunction : public function_traits 
 19631 |    { 
 19632 |    public: 
 19633 |  
 19634 |       explicit ifunction(const std::size_t& pc) 
 19635 |       : param_count(pc) 
 19636 |       {} 
 19637 |  
 19638 |       virtual ~ifunction() 
 19639 |       {} 
 19640 |  
 19641 |       #define empty_method_body(N)                   \ 
 19642 |       {                                              \ 
 19643 |          exprtk_debug(("ifunction::operator() - Operator(" #N ") has not been overridden\n")); \ 
 19644 |          return std::numeric_limits<T>::quiet_NaN(); \ 
 19645 |       }                                              \ 
 19646 |  
 19647 |       inline virtual T operator() () 
 19648 |       empty_method_body(0) 
 19649 |  
 19650 |       inline virtual T operator() (const T&) 
 19651 |       empty_method_body(1) 
 19652 |  
 19653 |       inline virtual T operator() (const T&,const T&) 
 19654 |       empty_method_body(2) 
 19655 |  
 19656 |       inline virtual T operator() (const T&, const T&, const T&) 
 19657 |       empty_method_body(3) 
 19658 |  
 19659 |       inline virtual T operator() (const T&, const T&, const T&, const T&) 
 19660 |       empty_method_body(4) 
 19661 |  
 19662 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&) 
 19663 |       empty_method_body(5) 
 19664 |  
 19665 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&) 
 19666 |       empty_method_body(6) 
 19667 |  
 19668 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19669 |       empty_method_body(7) 
 19670 |  
 19671 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19672 |       empty_method_body(8) 
 19673 |  
 19674 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19675 |       empty_method_body(9) 
 19676 |  
 19677 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19678 |       empty_method_body(10) 
 19679 |  
 19680 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19681 |                                    const T&) 
 19682 |       empty_method_body(11) 
 19683 |  
 19684 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19685 |                                    const T&, const T&) 
 19686 |       empty_method_body(12) 
 19687 |  
 19688 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19689 |                                    const T&, const T&, const T&) 
 19690 |       empty_method_body(13) 
 19691 |  
 19692 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19693 |                                    const T&, const T&, const T&, const T&) 
 19694 |       empty_method_body(14) 
 19695 |  
 19696 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19697 |                                    const T&, const T&, const T&, const T&, const T&) 
 19698 |       empty_method_body(15) 
 19699 |  
 19700 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19701 |                                    const T&, const T&, const T&, const T&, const T&, const T&) 
 19702 |       empty_method_body(16) 
 19703 |  
 19704 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19705 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19706 |       empty_method_body(17) 
 19707 |  
 19708 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19709 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19710 |       empty_method_body(18) 
 19711 |  
 19712 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19713 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19714 |       empty_method_body(19) 
 19715 |  
 19716 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19717 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19718 |       empty_method_body(20) 
 19719 |  
 19720 |       #undef empty_method_body 
 19721 |  
 19722 |       std::size_t param_count; 
 19723 |    }; 
 19724 |  
 19725 |    template <typename T> 
 19726 |    class ivararg_function : public function_traits 
 19727 |    { 
 19728 |    public: 
 19729 |  
 19730 |       virtual ~ivararg_function() 
 19731 |       {} 
 19732 |  
 19733 |       inline virtual T operator() (const std::vector<T>&) 
 19734 |       { 
 19735 |          exprtk_debug(("ivararg_function::operator() - Operator has not been overridden\n")); 
 19736 |          return std::numeric_limits<T>::quiet_NaN(); 
 19737 |       } 
 19738 |    }; 
 19739 |  
 19740 |    template <typename T> 
 19741 |    class igeneric_function : public function_traits 
 19742 |    { 
 19743 |    public: 
 19744 |  
 19745 |       enum return_type 
 19746 |       { 
 19747 |          e_rtrn_scalar   = 0, 
 19748 |          e_rtrn_string   = 1, 
 19749 |          e_rtrn_overload = 2 
 19750 |       }; 
 19751 |  
 19752 |       typedef T type; 
 19753 |       typedef type_store<T> generic_type; 
 19754 |       typedef typename generic_type::parameter_list parameter_list_t; 
 19755 |  
 19756 |       explicit igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar) 
 19757 |       : parameter_sequence(param_seq) 
 19758 |       , rtrn_type(rtr_type) 
 19759 |       {} 
 19760 |  
 19761 |       virtual ~igeneric_function() 
 19762 |       {} 
 19763 |  
 19764 |       #define igeneric_function_empty_body(N)        \ 
 19765 |       {                                              \ 
 19766 |          exprtk_debug(("igeneric_function::operator() - Operator(" #N ") has not been overridden\n")); \ 
 19767 |          return std::numeric_limits<T>::quiet_NaN(); \ 
 19768 |       }                                              \ 
 19769 |  
 19770 |       // f(i_0,i_1,....,i_N) --> Scalar 
 19771 |       inline virtual T operator() (parameter_list_t) 
 19772 |       igeneric_function_empty_body(1) 
 19773 |  
 19774 |       // f(i_0,i_1,....,i_N) --> String 
 19775 |       inline virtual T operator() (std::string&, parameter_list_t) 
 19776 |       igeneric_function_empty_body(2) 
 19777 |  
 19778 |       // f(psi,i_0,i_1,....,i_N) --> Scalar 
 19779 |       inline virtual T operator() (const std::size_t&, parameter_list_t) 
 19780 |       igeneric_function_empty_body(3) 
 19781 |  
 19782 |       // f(psi,i_0,i_1,....,i_N) --> String 
 19783 |       inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t) 
 19784 |       igeneric_function_empty_body(4) 
 19785 |  
 19786 |       #undef igeneric_function_empty_body 
 19787 |  
 19788 |       std::string parameter_sequence; 
 19789 |       return_type rtrn_type; 
 19790 |    }; 
 19791 |  
 19792 |    #ifndef exprtk_disable_string_capabilities 
 19793 |    template <typename T> 
 19794 |    class stringvar_base 
 19795 |    { 
 19796 |    public: 
 19797 |  
 19798 |       typedef typename details::stringvar_node<T> stringvar_node_t; 
 19799 |  
 19800 |       stringvar_base(const std::string& name, stringvar_node_t* svn) 
 19801 |       : name_(name) 
 19802 |       , string_varnode_(svn) 
 19803 |       {} 
 19804 |  
 19805 |       bool valid() const 
 19806 |       { 
 19807 |          return !name_.empty() && (0 != string_varnode_); 
 19808 |       } 
 19809 |  
 19810 |       std::string name() const 
 19811 |       { 
 19812 |          assert(string_varnode_); 
 19813 |          return name_; 
 19814 |       } 
 19815 |  
 19816 |       void rebase(std::string& s) 
 19817 |       { 
 19818 |          assert(string_varnode_); 
 19819 |          string_varnode_->rebase(s); 
 19820 |       } 
 19821 |  
 19822 |    private: 
 19823 |  
 19824 |       std::string name_; 
 19825 |       stringvar_node_t* string_varnode_; 
 19826 |    }; 
 19827 |    #endif 
 19828 |  
 19829 |    template <typename T> class parser; 
 19830 |    template <typename T> class expression_helper; 
 19831 |  
 19832 |    template <typename T> 
 19833 |    class symbol_table 
 19834 |    { 
 19835 |    public: 
 19836 |  
 19837 |      enum symtab_mutability_type 
 19838 |      { 
 19839 |        e_unknown   = 0, 
 19840 |        e_mutable   = 1, 
 19841 |        e_immutable = 2 
 19842 |      }; 
 19843 |  
 19844 |      typedef T (*ff00_functor)(); 
 19845 |      typedef T (*ff01_functor)(T); 
 19846 |      typedef T (*ff02_functor)(T, T); 
 19847 |      typedef T (*ff03_functor)(T, T, T); 
 19848 |      typedef T (*ff04_functor)(T, T, T, T); 
 19849 |      typedef T (*ff05_functor)(T, T, T, T, T); 
 19850 |      typedef T (*ff06_functor)(T, T, T, T, T, T); 
 19851 |      typedef T (*ff07_functor)(T, T, T, T, T, T, T); 
 19852 |      typedef T (*ff08_functor)(T, T, T, T, T, T, T, T); 
 19853 |      typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T); 
 19854 |      typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T); 
 19855 |      typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T); 
 19856 |      typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T); 
 19857 |      typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T); 
 19858 |      typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T); 
 19859 |      typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T); 
 19860 |  
 19861 |    protected: 
 19862 |  
 19863 |        struct freefunc00 exprtk_final : public exprtk::ifunction<T> 
 19864 |        { 
 19865 |           using exprtk::ifunction<T>::operator(); 
 19866 |  
 19867 |           explicit freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {} 
 19868 |           inline T operator() () exprtk_override 
 19869 |           { return f(); } 
 19870 |           ff00_functor f; 
 19871 |        }; 
 19872 |  
 19873 |       struct freefunc01 exprtk_final : public exprtk::ifunction<T> 
 19874 |       { 
 19875 |          using exprtk::ifunction<T>::operator(); 
 19876 |  
 19877 |          explicit freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {} 
 19878 |          inline T operator() (const T& v0) exprtk_override 
 19879 |          { return f(v0); } 
 19880 |          ff01_functor f; 
 19881 |       }; 
 19882 |  
 19883 |       struct freefunc02 exprtk_final : public exprtk::ifunction<T> 
 19884 |       { 
 19885 |          using exprtk::ifunction<T>::operator(); 
 19886 |  
 19887 |          explicit freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {} 
 19888 |          inline T operator() (const T& v0, const T& v1) exprtk_override 
 19889 |          { return f(v0, v1); } 
 19890 |          ff02_functor f; 
 19891 |       }; 
 19892 |  
 19893 |       struct freefunc03 exprtk_final : public exprtk::ifunction<T> 
 19894 |       { 
 19895 |          using exprtk::ifunction<T>::operator(); 
 19896 |  
 19897 |          explicit freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {} 
 19898 |          inline T operator() (const T& v0, const T& v1, const T& v2) exprtk_override 
 19899 |          { return f(v0, v1, v2); } 
 19900 |          ff03_functor f; 
 19901 |       }; 
 19902 |  
 19903 |       struct freefunc04 exprtk_final : public exprtk::ifunction<T> 
 19904 |       { 
 19905 |          using exprtk::ifunction<T>::operator(); 
 19906 |  
 19907 |          explicit freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {} 
 19908 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) exprtk_override 
 19909 |          { return f(v0, v1, v2, v3); } 
 19910 |          ff04_functor f; 
 19911 |       }; 
 19912 |  
 19913 |       struct freefunc05 : public exprtk::ifunction<T> 
 19914 |       { 
 19915 |          using exprtk::ifunction<T>::operator(); 
 19916 |  
 19917 |          explicit freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {} 
 19918 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) exprtk_override 
 19919 |          { return f(v0, v1, v2, v3, v4); } 
 19920 |          ff05_functor f; 
 19921 |       }; 
 19922 |  
 19923 |       struct freefunc06 exprtk_final : public exprtk::ifunction<T> 
 19924 |       { 
 19925 |          using exprtk::ifunction<T>::operator(); 
 19926 |  
 19927 |          explicit freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {} 
 19928 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) exprtk_override 
 19929 |          { return f(v0, v1, v2, v3, v4, v5); } 
 19930 |          ff06_functor f; 
 19931 |       }; 
 19932 |  
 19933 |       struct freefunc07 exprtk_final : public exprtk::ifunction<T> 
 19934 |       { 
 19935 |          using exprtk::ifunction<T>::operator(); 
 19936 |  
 19937 |          explicit freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {} 
 19938 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19939 |                               const T& v5, const T& v6) exprtk_override 
 19940 |          { return f(v0, v1, v2, v3, v4, v5, v6); } 
 19941 |          ff07_functor f; 
 19942 |       }; 
 19943 |  
 19944 |       struct freefunc08 exprtk_final : public exprtk::ifunction<T> 
 19945 |       { 
 19946 |          using exprtk::ifunction<T>::operator(); 
 19947 |  
 19948 |          explicit freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {} 
 19949 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19950 |                               const T& v5, const T& v6, const T& v7) exprtk_override 
 19951 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7); } 
 19952 |          ff08_functor f; 
 19953 |       }; 
 19954 |  
 19955 |       struct freefunc09 exprtk_final : public exprtk::ifunction<T> 
 19956 |       { 
 19957 |          using exprtk::ifunction<T>::operator(); 
 19958 |  
 19959 |          explicit freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {} 
 19960 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19961 |                               const T& v5, const T& v6, const T& v7, const T& v8) exprtk_override 
 19962 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); } 
 19963 |          ff09_functor f; 
 19964 |       }; 
 19965 |  
 19966 |       struct freefunc10 exprtk_final : public exprtk::ifunction<T> 
 19967 |       { 
 19968 |          using exprtk::ifunction<T>::operator(); 
 19969 |  
 19970 |          explicit freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {} 
 19971 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19972 |                               const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) exprtk_override 
 19973 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); } 
 19974 |          ff10_functor f; 
 19975 |       }; 
 19976 |  
 19977 |       struct freefunc11 exprtk_final : public exprtk::ifunction<T> 
 19978 |       { 
 19979 |          using exprtk::ifunction<T>::operator(); 
 19980 |  
 19981 |          explicit freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {} 
 19982 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19983 |                               const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) exprtk_override 
 19984 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } 
 19985 |          ff11_functor f; 
 19986 |       }; 
 19987 |  
 19988 |       struct freefunc12 exprtk_final : public exprtk::ifunction<T> 
 19989 |       { 
 19990 |          using exprtk::ifunction<T>::operator(); 
 19991 |  
 19992 |          explicit freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {} 
 19993 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 19994 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 19995 |                               const T& v10, const T& v11) exprtk_override 
 19996 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); } 
 19997 |          ff12_functor f; 
 19998 |       }; 
 19999 |  
 20000 |       struct freefunc13 exprtk_final : public exprtk::ifunction<T> 
 20001 |       { 
 20002 |          using exprtk::ifunction<T>::operator(); 
 20003 |  
 20004 |          explicit freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {} 
 20005 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 20006 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 20007 |                               const T& v10, const T& v11, const T& v12) exprtk_override 
 20008 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); } 
 20009 |          ff13_functor f; 
 20010 |       }; 
 20011 |  
 20012 |       struct freefunc14 exprtk_final : public exprtk::ifunction<T> 
 20013 |       { 
 20014 |          using exprtk::ifunction<T>::operator(); 
 20015 |  
 20016 |          explicit freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {} 
 20017 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 20018 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 20019 |                               const T& v10, const T& v11, const T& v12, const T& v13) exprtk_override 
 20020 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); } 
 20021 |          ff14_functor f; 
 20022 |       }; 
 20023 |  
 20024 |       struct freefunc15 exprtk_final : public exprtk::ifunction<T> 
 20025 |       { 
 20026 |          using exprtk::ifunction<T>::operator(); 
 20027 |  
 20028 |          explicit freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {} 
 20029 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 20030 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 20031 |                               const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) exprtk_override 
 20032 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); } 
 20033 |          ff15_functor f; 
 20034 |       }; 
 20035 |  
 20036 |       template <typename Type, typename RawType> 
 20037 |       struct type_store 
 20038 |       { 
 20039 |          typedef details::expression_node<T>*        expression_ptr; 
 20040 |          typedef typename details::variable_node<T>  variable_node_t; 
 20041 |          typedef ifunction<T>                        ifunction_t; 
 20042 |          typedef ivararg_function<T>                 ivararg_function_t; 
 20043 |          typedef igeneric_function<T>                igeneric_function_t; 
 20044 |          typedef details::vector_holder<T>           vector_t; 
 20045 |          #ifndef exprtk_disable_string_capabilities 
 20046 |          typedef typename details::stringvar_node<T> stringvar_node_t; 
 20047 |          #endif 
 20048 |  
 20049 |          typedef Type type_t; 
 20050 |          typedef type_t* type_ptr; 
 20051 |          typedef std::pair<bool,type_ptr> type_pair_t; 
 20052 |          typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t; 
 20053 |          typedef typename type_map_t::iterator tm_itr_t; 
 20054 |          typedef typename type_map_t::const_iterator tm_const_itr_t; 
 20055 |  
 20056 |          enum { lut_size = 256 }; 
 20057 |  
 20058 |          type_map_t  map; 
 20059 |          std::size_t size; 
 20060 |  
 20061 |          type_store() 
 20062 |          : size(0) 
 20063 |          {} 
 20064 |  
 20065 |          struct deleter 
 20066 |          { 
 20067 |             #define exprtk_define_process(Type)                  \ 
 20068 |             static inline void process(std::pair<bool,Type*>& n) \ 
 20069 |             {                                                    \ 
 20070 |                delete n.second;                                  \ 
 20071 |             }                                                    \ 
 20072 |  
 20073 |             exprtk_define_process(variable_node_t ) 
 20074 |             exprtk_define_process(vector_t        ) 
 20075 |             #ifndef exprtk_disable_string_capabilities 
 20076 |             exprtk_define_process(stringvar_node_t) 
 20077 |             #endif 
 20078 |  
 20079 |             #undef exprtk_define_process 
 20080 |  
 20081 |             template <typename DeleteType> 
 20082 |             static inline void process(std::pair<bool,DeleteType*>&) 
 20083 |             {} 
 20084 |          }; 
 20085 |  
 20086 |          inline bool symbol_exists(const std::string& symbol_name) const 
 20087 |          { 
 20088 |             if (symbol_name.empty()) 
 20089 |                return false; 
 20090 |             else if (map.end() != map.find(symbol_name)) 
 20091 |                return true; 
 20092 |             else 
 20093 |                return false; 
 20094 |          } 
 20095 |  
 20096 |          template <typename PtrType> 
 20097 |          inline std::string entity_name(const PtrType& ptr) const 
 20098 |          { 
 20099 |             if (map.empty()) 
 20100 |                return std::string(); 
 20101 |  
 20102 |             tm_const_itr_t itr = map.begin(); 
 20103 |  
 20104 |             while (map.end() != itr) 
 20105 |             { 
 20106 |                if (itr->second.second == ptr) 
 20107 |                { 
 20108 |                   return itr->first; 
 20109 |                } 
 20110 |                else 
 20111 |                   ++itr; 
 20112 |             } 
 20113 |  
 20114 |             return std::string(); 
 20115 |          } 
 20116 |  
 20117 |          inline bool is_constant(const std::string& symbol_name) const 
 20118 |          { 
 20119 |             if (symbol_name.empty()) 
 20120 |                return false; 
 20121 |             else 
 20122 |             { 
 20123 |                const tm_const_itr_t itr = map.find(symbol_name); 
 20124 |  
 20125 |                if (map.end() == itr) 
 20126 |                   return false; 
 20127 |                else 
 20128 |                   return (*itr).second.first; 
 20129 |             } 
 20130 |          } 
 20131 |  
 20132 |          template <typename Tie, typename RType> 
 20133 |          inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const) 
 20134 |          { 
 20135 |             if (symbol_name.size() > 1) 
 20136 |             { 
 20137 |                for (std::size_t i = 0; i < details::reserved_symbols_size; ++i) 
 20138 |                { 
 20139 |                   if (details::imatch(symbol_name, details::reserved_symbols[i])) 
 20140 |                   { 
 20141 |                      return false; 
 20142 |                   } 
 20143 |                } 
 20144 |             } 
 20145 |  
 20146 |             const tm_itr_t itr = map.find(symbol_name); 
 20147 |  
 20148 |             if (map.end() == itr) 
 20149 |             { 
 20150 |                map[symbol_name] = Tie::make(t,is_const); 
 20151 |                ++size; 
 20152 |             } 
 20153 |  
 20154 |             return true; 
 20155 |          } 
 20156 |  
 20157 |          struct tie_array 
 20158 |          { 
 20159 |             static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false) 
 20160 |             { 
 20161 |                return std::make_pair(is_const, new vector_t(v.first, v.second)); 
 20162 |             } 
 20163 |          }; 
 20164 |  
 20165 |          struct tie_stdvec 
 20166 |          { 
 20167 |             template <typename Allocator> 
 20168 |             static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false) 
 20169 |             { 
 20170 |                return std::make_pair(is_const, new vector_t(v)); 
 20171 |             } 
 20172 |          }; 
 20173 |  
 20174 |          struct tie_vecview 
 20175 |          { 
 20176 |             static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false) 
 20177 |             { 
 20178 |                return std::make_pair(is_const, new vector_t(v)); 
 20179 |             } 
 20180 |          }; 
 20181 |  
 20182 |          struct tie_stddeq 
 20183 |          { 
 20184 |             template <typename Allocator> 
 20185 |             static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false) 
 20186 |             { 
 20187 |                return std::make_pair(is_const, new vector_t(v)); 
 20188 |             } 
 20189 |          }; 
 20190 |  
 20191 |          template <std::size_t v_size> 
 20192 |          inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false) 
 20193 |          { 
 20194 |             return add_impl<tie_array,std::pair<T*,std::size_t> > 
 20195 |                       (symbol_name, std::make_pair(v,v_size), is_const); 
 20196 |          } 
 20197 |  
 20198 |          inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false) 
 20199 |          { 
 20200 |             return add_impl<tie_array,std::pair<T*,std::size_t> > 
 20201 |                      (symbol_name, std::make_pair(v,v_size), is_const); 
 20202 |          } 
 20203 |  
 20204 |          template <typename Allocator> 
 20205 |          inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false) 
 20206 |          { 
 20207 |             return add_impl<tie_stdvec,std::vector<T,Allocator>&> 
 20208 |                       (symbol_name, v, is_const); 
 20209 |          } 
 20210 |  
 20211 |          inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false) 
 20212 |          { 
 20213 |             return add_impl<tie_vecview,exprtk::vector_view<T>&> 
 20214 |                       (symbol_name, v, is_const); 
 20215 |          } 
 20216 |  
 20217 |          template <typename Allocator> 
 20218 |          inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false) 
 20219 |          { 
 20220 |             return add_impl<tie_stddeq,std::deque<T,Allocator>&> 
 20221 |                       (symbol_name, v, is_const); 
 20222 |          } 
 20223 |  
 20224 |          inline bool add(const std::string& symbol_name, RawType& t_, const bool is_const = false) 
 20225 |          { 
 20226 |             struct tie 
 20227 |             { 
 20228 |                static inline std::pair<bool,variable_node_t*> make(T& t, const bool is_constant = false) 
 20229 |                { 
 20230 |                   return std::make_pair(is_constant, new variable_node_t(t)); 
 20231 |                } 
 20232 |  
 20233 |                #ifndef exprtk_disable_string_capabilities 
 20234 |                static inline std::pair<bool,stringvar_node_t*> make(std::string& t, const bool is_constant = false) 
 20235 |                { 
 20236 |                   return std::make_pair(is_constant, new stringvar_node_t(t)); 
 20237 |                } 
 20238 |                #endif 
 20239 |  
 20240 |                static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false) 
 20241 |                { 
 20242 |                   return std::make_pair(is_constant,&t); 
 20243 |                } 
 20244 |  
 20245 |                static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_constant = false) 
 20246 |                { 
 20247 |                   return std::make_pair(is_constant,&t); 
 20248 |                } 
 20249 |  
 20250 |                static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false) 
 20251 |                { 
 20252 |                   return std::make_pair(is_constant,&t); 
 20253 |                } 
 20254 |             }; 
 20255 |  
 20256 |             const tm_itr_t itr = map.find(symbol_name); 
 20257 |  
 20258 |             if (map.end() == itr) 
 20259 |             { 
 20260 |                map[symbol_name] = tie::make(t_,is_const); 
 20261 |                ++size; 
 20262 |             } 
 20263 |  
 20264 |             return true; 
 20265 |          } 
 20266 |  
 20267 |          inline type_ptr get(const std::string& symbol_name) const 
 20268 |          { 
 20269 |             const tm_const_itr_t itr = map.find(symbol_name); 
 20270 |  
 20271 |             if (map.end() == itr) 
 20272 |                return reinterpret_cast<type_ptr>(0); 
 20273 |             else 
 20274 |                return itr->second.second; 
 20275 |          } 
 20276 |  
 20277 |          template <typename TType, typename TRawType, typename PtrType> 
 20278 |          struct ptr_match 
 20279 |          { 
 20280 |             static inline bool test(const PtrType, const void*) 
 20281 |             { 
 20282 |                return false; 
 20283 |             } 
 20284 |          }; 
 20285 |  
 20286 |          template <typename TType, typename TRawType> 
 20287 |          struct ptr_match<TType,TRawType,variable_node_t*> 
 20288 |          { 
 20289 |             static inline bool test(const variable_node_t* p, const void* ptr) 
 20290 |             { 
 20291 |                exprtk_debug(("ptr_match::test() - %p <--> %p\n", reinterpret_cast<const void*>(&(p->ref())), ptr)); 
 20292 |                return (&(p->ref()) == ptr); 
 20293 |             } 
 20294 |          }; 
 20295 |  
 20296 |          inline type_ptr get_from_varptr(const void* ptr) const 
 20297 |          { 
 20298 |             tm_const_itr_t itr = map.begin(); 
 20299 |  
 20300 |             while (map.end() != itr) 
 20301 |             { 
 20302 |                type_ptr ret_ptr = itr->second.second; 
 20303 |  
 20304 |                if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr)) 
 20305 |                { 
 20306 |                   return ret_ptr; 
 20307 |                } 
 20308 |  
 20309 |                ++itr; 
 20310 |             } 
 20311 |  
 20312 |             return type_ptr(0); 
 20313 |          } 
 20314 |  
 20315 |          inline bool remove(const std::string& symbol_name, const bool delete_node = true) 
 20316 |          { 
 20317 |             const tm_itr_t itr = map.find(symbol_name); 
 20318 |  
 20319 |             if (map.end() != itr) 
 20320 |             { 
 20321 |                if (delete_node) 
 20322 |                { 
 20323 |                   deleter::process((*itr).second); 
 20324 |                } 
 20325 |  
 20326 |                map.erase(itr); 
 20327 |                --size; 
 20328 |  
 20329 |                return true; 
 20330 |             } 
 20331 |             else 
 20332 |                return false; 
 20333 |          } 
 20334 |  
 20335 |          inline RawType& type_ref(const std::string& symbol_name) 
 20336 |          { 
 20337 |             struct init_type 
 20338 |             { 
 20339 |                static inline double set(double)           { return (0.0);           } 
 20340 |                static inline double set(long double)      { return (0.0);           } 
 20341 |                static inline float  set(float)            { return (0.0f);          } 
 20342 |                static inline std::string set(std::string) { return std::string(""); } 
 20343 |             }; 
 20344 |  
 20345 |             static RawType null_type = init_type::set(RawType()); 
 20346 |  
 20347 |             const tm_const_itr_t itr = map.find(symbol_name); 
 20348 |  
 20349 |             if (map.end() == itr) 
 20350 |                return null_type; 
 20351 |             else 
 20352 |                return itr->second.second->ref(); 
 20353 |          } 
 20354 |  
 20355 |          inline void clear(const bool delete_node = true) 
 20356 |          { 
 20357 |             if (!map.empty()) 
 20358 |             { 
 20359 |                if (delete_node) 
 20360 |                { 
 20361 |                   tm_itr_t itr = map.begin(); 
 20362 |                   tm_itr_t end = map.end  (); 
 20363 |  
 20364 |                   while (end != itr) 
 20365 |                   { 
 20366 |                      deleter::process((*itr).second); 
 20367 |                      ++itr; 
 20368 |                   } 
 20369 |                } 
 20370 |  
 20371 |                map.clear(); 
 20372 |             } 
 20373 |  
 20374 |             size = 0; 
 20375 |          } 
 20376 |  
 20377 |          template <typename Allocator, 
 20378 |                    template <typename, typename> class Sequence> 
 20379 |          inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const 
 20380 |          { 
 20381 |             std::size_t count = 0; 
 20382 |  
 20383 |             if (!map.empty()) 
 20384 |             { 
 20385 |                tm_const_itr_t itr = map.begin(); 
 20386 |                tm_const_itr_t end = map.end  (); 
 20387 |  
 20388 |                while (end != itr) 
 20389 |                { 
 20390 |                   list.push_back(std::make_pair((*itr).first,itr->second.second->ref())); 
 20391 |                   ++itr; 
 20392 |                   ++count; 
 20393 |                } 
 20394 |             } 
 20395 |  
 20396 |             return count; 
 20397 |          } 
 20398 |  
 20399 |          template <typename Allocator, 
 20400 |                    template <typename, typename> class Sequence> 
 20401 |          inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const 
 20402 |          { 
 20403 |             std::size_t count = 0; 
 20404 |  
 20405 |             if (!map.empty()) 
 20406 |             { 
 20407 |                tm_const_itr_t itr = map.begin(); 
 20408 |                tm_const_itr_t end = map.end  (); 
 20409 |  
 20410 |                while (end != itr) 
 20411 |                { 
 20412 |                   vlist.push_back((*itr).first); 
 20413 |                   ++itr; 
 20414 |                   ++count; 
 20415 |                } 
 20416 |             } 
 20417 |  
 20418 |             return count; 
 20419 |          } 
 20420 |       }; 
 20421 |  
 20422 |       typedef details::expression_node<T>*        expression_ptr; 
 20423 |       typedef typename details::variable_node<T>  variable_t; 
 20424 |       typedef typename details::vector_holder<T>  vector_holder_t; 
 20425 |       typedef variable_t*                         variable_ptr; 
 20426 |       #ifndef exprtk_disable_string_capabilities 
 20427 |       typedef typename details::stringvar_node<T> stringvar_t; 
 20428 |       typedef stringvar_t*                        stringvar_ptr; 
 20429 |       #endif 
 20430 |       typedef ifunction        <T>                function_t; 
 20431 |       typedef ivararg_function <T>                vararg_function_t; 
 20432 |       typedef igeneric_function<T>                generic_function_t; 
 20433 |       typedef function_t*                         function_ptr; 
 20434 |       typedef vararg_function_t*                  vararg_function_ptr; 
 20435 |       typedef generic_function_t*                 generic_function_ptr; 
 20436 |  
 20437 |       static const std::size_t lut_size = 256; 
 20438 |  
 20439 |       // Symbol Table Holder 
 20440 |       struct control_block 
 20441 |       { 
 20442 |          struct st_data 
 20443 |          { 
 20444 |             type_store<variable_t        , T                 > variable_store; 
 20445 |             type_store<function_t        , function_t        > function_store; 
 20446 |             type_store<vararg_function_t , vararg_function_t > vararg_function_store; 
 20447 |             type_store<generic_function_t, generic_function_t> generic_function_store; 
 20448 |             type_store<generic_function_t, generic_function_t> string_function_store; 
 20449 |             type_store<generic_function_t, generic_function_t> overload_function_store; 
 20450 |             type_store<vector_holder_t   , vector_holder_t   > vector_store; 
 20451 |             #ifndef exprtk_disable_string_capabilities 
 20452 |             type_store<stringvar_t       , std::string       > stringvar_store; 
 20453 |             #endif 
 20454 |  
 20455 |             st_data() 
 20456 |             { 
 20457 |                for (std::size_t i = 0; i < details::reserved_words_size; ++i) 
 20458 |                { 
 20459 |                   reserved_symbol_table_.insert(details::reserved_words[i]); 
 20460 |                } 
 20461 |  
 20462 |                for (std::size_t i = 0; i < details::reserved_symbols_size; ++i) 
 20463 |                { 
 20464 |                   reserved_symbol_table_.insert(details::reserved_symbols[i]); 
 20465 |                } 
 20466 |             } 
 20467 |  
 20468 |            ~st_data() 
 20469 |             { 
 20470 |                for (std::size_t i = 0; i < free_function_list_.size(); ++i) 
 20471 |                { 
 20472 |                   delete free_function_list_[i]; 
 20473 |                } 
 20474 |             } 
 20475 |  
 20476 |             inline bool is_reserved_symbol(const std::string& symbol) const 
 20477 |             { 
 20478 |                return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol)); 
 20479 |             } 
 20480 |  
 20481 |             static inline st_data* create() 
 20482 |             { 
 20483 |                return (new st_data); 
 20484 |             } 
 20485 |  
 20486 |             static inline void destroy(st_data*& sd) 
 20487 |             { 
 20488 |                delete sd; 
 20489 |                sd = reinterpret_cast<st_data*>(0); 
 20490 |             } 
 20491 |  
 20492 |             std::list<T>               local_symbol_list_; 
 20493 |             std::list<std::string>     local_stringvar_list_; 
 20494 |             std::set<std::string>      reserved_symbol_table_; 
 20495 |             std::vector<ifunction<T>*> free_function_list_; 
 20496 |          }; 
 20497 |  
 20498 |          control_block() 
 20499 |          : ref_count(1) 
 20500 |          , data_(st_data::create()) 
 20501 |          , mutability_(e_mutable) 
 20502 |          {} 
 20503 |  
 20504 |          explicit control_block(st_data* data) 
 20505 |          : ref_count(1) 
 20506 |          , data_(data) 
 20507 |          , mutability_(e_mutable) 
 20508 |          {} 
 20509 |  
 20510 |         ~control_block() 
 20511 |          { 
 20512 |             if (data_ && (0 == ref_count)) 
 20513 |             { 
 20514 |                st_data::destroy(data_); 
 20515 |             } 
 20516 |          } 
 20517 |  
 20518 |          static inline control_block* create() 
 20519 |          { 
 20520 |             return (new control_block); 
 20521 |          } 
 20522 |  
 20523 |          template <typename SymTab> 
 20524 |          static inline void destroy(control_block*& cntrl_blck, SymTab* sym_tab) 
 20525 |          { 
 20526 |             if (cntrl_blck) 
 20527 |             { 
 20528 |                if ( 
 20529 |                     (0 !=   cntrl_blck->ref_count) && 
 20530 |                     (0 == --cntrl_blck->ref_count) 
 20531 |                   ) 
 20532 |                { 
 20533 |                   if (sym_tab) 
 20534 |                      sym_tab->clear(); 
 20535 |  
 20536 |                   delete cntrl_blck; 
 20537 |                } 
 20538 |  
 20539 |                cntrl_blck = 0; 
 20540 |             } 
 20541 |          } 
 20542 |  
 20543 |          void set_mutability(const symtab_mutability_type mutability) 
 20544 |          { 
 20545 |             mutability_ = mutability; 
 20546 |          } 
 20547 |  
 20548 |          std::size_t ref_count; 
 20549 |          st_data* data_; 
 20550 |          symtab_mutability_type mutability_; 
 20551 |       }; 
 20552 |  
 20553 |    public: 
 20554 |  
 20555 |       explicit symbol_table(const symtab_mutability_type mutability = e_mutable) 
 20556 |       : control_block_(control_block::create()) 
 20557 |       { 
 20558 |          control_block_->set_mutability(mutability); 
 20559 |          clear(); 
 20560 |       } 
 20561 |  
 20562 |      ~symbol_table() 
 20563 |       { 
 20564 |          exprtk::details::dump_ptr("~symbol_table", this); 
 20565 |          control_block::destroy(control_block_, this); 
 20566 |       } 
 20567 |  
 20568 |       symbol_table(const symbol_table<T>& st) 
 20569 |       { 
 20570 |          control_block_ = st.control_block_; 
 20571 |          control_block_->ref_count++; 
 20572 |       } 
 20573 |  
 20574 |       inline symbol_table<T>& operator=(const symbol_table<T>& st) 
 20575 |       { 
 20576 |          if (this != &st) 
 20577 |          { 
 20578 |             control_block::destroy(control_block_,reinterpret_cast<symbol_table<T>*>(0)); 
 20579 |  
 20580 |             control_block_ = st.control_block_; 
 20581 |             control_block_->ref_count++; 
 20582 |          } 
 20583 |  
 20584 |          return (*this); 
 20585 |       } 
 20586 |  
 20587 |       inline bool operator==(const symbol_table<T>& st) const 
 20588 |       { 
 20589 |          return (this == &st) || (control_block_ == st.control_block_); 
 20590 |       } 
 20591 |  
 20592 |       inline symtab_mutability_type mutability() const 
 20593 |       { 
 20594 |          return valid() ? control_block_->mutability_ : e_unknown; 
 20595 |       } 
 20596 |  
 20597 |       inline void clear_variables(const bool delete_node = true) 
 20598 |       { 
 20599 |          local_data().variable_store.clear(delete_node); 
 20600 |       } 
 20601 |  
 20602 |       inline void clear_functions() 
 20603 |       { 
 20604 |          local_data().function_store.clear(); 
 20605 |       } 
 20606 |  
 20607 |       inline void clear_strings() 
 20608 |       { 
 20609 |          #ifndef exprtk_disable_string_capabilities 
 20610 |          local_data().stringvar_store.clear(); 
 20611 |          #endif 
 20612 |       } 
 20613 |  
 20614 |       inline void clear_vectors() 
 20615 |       { 
 20616 |          local_data().vector_store.clear(); 
 20617 |       } 
 20618 |  
 20619 |       inline void clear_local_constants() 
 20620 |       { 
 20621 |          local_data().local_symbol_list_.clear(); 
 20622 |       } 
 20623 |  
 20624 |       inline void clear() 
 20625 |       { 
 20626 |          if (!valid()) return; 
 20627 |          clear_variables      (); 
 20628 |          clear_functions      (); 
 20629 |          clear_strings        (); 
 20630 |          clear_vectors        (); 
 20631 |          clear_local_constants(); 
 20632 |       } 
 20633 |  
 20634 |       inline std::size_t variable_count() const 
 20635 |       { 
 20636 |          if (valid()) 
 20637 |             return local_data().variable_store.size; 
 20638 |          else 
 20639 |             return 0; 
 20640 |       } 
 20641 |  
 20642 |       #ifndef exprtk_disable_string_capabilities 
 20643 |       inline std::size_t stringvar_count() const 
 20644 |       { 
 20645 |          if (valid()) 
 20646 |             return local_data().stringvar_store.size; 
 20647 |          else 
 20648 |             return 0; 
 20649 |       } 
 20650 |       #endif 
 20651 |  
 20652 |       inline std::size_t function_count() const 
 20653 |       { 
 20654 |          if (valid()) 
 20655 |             return local_data().function_store.size; 
 20656 |          else 
 20657 |             return 0; 
 20658 |       } 
 20659 |  
 20660 |       inline std::size_t vector_count() const 
 20661 |       { 
 20662 |          if (valid()) 
 20663 |             return local_data().vector_store.size; 
 20664 |          else 
 20665 |             return 0; 
 20666 |       } 
 20667 |  
 20668 |       inline variable_ptr get_variable(const std::string& variable_name) const 
 20669 |       { 
 20670 |          if (!valid()) 
 20671 |             return reinterpret_cast<variable_ptr>(0); 
 20672 |          else if (!valid_symbol(variable_name)) 
 20673 |             return reinterpret_cast<variable_ptr>(0); 
 20674 |          else 
 20675 |             return local_data().variable_store.get(variable_name); 
 20676 |       } 
 20677 |  
 20678 |       inline variable_ptr get_variable(const T& var_ref) const 
 20679 |       { 
 20680 |          if (!valid()) 
 20681 |             return reinterpret_cast<variable_ptr>(0); 
 20682 |          else 
 20683 |             return local_data().variable_store.get_from_varptr( 
 20684 |                                                   reinterpret_cast<const void*>(&var_ref)); 
 20685 |       } 
 20686 |  
 20687 |       #ifndef exprtk_disable_string_capabilities 
 20688 |       inline stringvar_ptr get_stringvar(const std::string& string_name) const 
 20689 |       { 
 20690 |          if (!valid()) 
 20691 |             return reinterpret_cast<stringvar_ptr>(0); 
 20692 |          else if (!valid_symbol(string_name)) 
 20693 |             return reinterpret_cast<stringvar_ptr>(0); 
 20694 |          else 
 20695 |             return local_data().stringvar_store.get(string_name); 
 20696 |       } 
 20697 |  
 20698 |       inline stringvar_base<T> get_stringvar_base(const std::string& string_name) const 
 20699 |       { 
 20700 |          static stringvar_base<T> null_stringvar_base("",reinterpret_cast<stringvar_ptr>(0)); 
 20701 |          if (!valid()) 
 20702 |             return null_stringvar_base; 
 20703 |          else if (!valid_symbol(string_name)) 
 20704 |             return null_stringvar_base; 
 20705 |  
 20706 |          stringvar_ptr stringvar = local_data().stringvar_store.get(string_name); 
 20707 |  
 20708 |          if (0 == stringvar) 
 20709 |          { 
 20710 |             return null_stringvar_base; 
 20711 |          } 
 20712 |  
 20713 |          return stringvar_base<T>(string_name,stringvar); 
 20714 |       } 
 20715 |       #endif 
 20716 |  
 20717 |       inline function_ptr get_function(const std::string& function_name) const 
 20718 |       { 
 20719 |          if (!valid()) 
 20720 |             return reinterpret_cast<function_ptr>(0); 
 20721 |          else if (!valid_symbol(function_name)) 
 20722 |             return reinterpret_cast<function_ptr>(0); 
 20723 |          else 
 20724 |             return local_data().function_store.get(function_name); 
 20725 |       } 
 20726 |  
 20727 |       inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const 
 20728 |       { 
 20729 |          if (!valid()) 
 20730 |             return reinterpret_cast<vararg_function_ptr>(0); 
 20731 |          else if (!valid_symbol(vararg_function_name)) 
 20732 |             return reinterpret_cast<vararg_function_ptr>(0); 
 20733 |          else 
 20734 |             return local_data().vararg_function_store.get(vararg_function_name); 
 20735 |       } 
 20736 |  
 20737 |       inline generic_function_ptr get_generic_function(const std::string& function_name) const 
 20738 |       { 
 20739 |          if (!valid()) 
 20740 |             return reinterpret_cast<generic_function_ptr>(0); 
 20741 |          else if (!valid_symbol(function_name)) 
 20742 |             return reinterpret_cast<generic_function_ptr>(0); 
 20743 |          else 
 20744 |             return local_data().generic_function_store.get(function_name); 
 20745 |       } 
 20746 |  
 20747 |       inline generic_function_ptr get_string_function(const std::string& function_name) const 
 20748 |       { 
 20749 |          if (!valid()) 
 20750 |             return reinterpret_cast<generic_function_ptr>(0); 
 20751 |          else if (!valid_symbol(function_name)) 
 20752 |             return reinterpret_cast<generic_function_ptr>(0); 
 20753 |          else 
 20754 |             return local_data().string_function_store.get(function_name); 
 20755 |       } 
 20756 |  
 20757 |       inline generic_function_ptr get_overload_function(const std::string& function_name) const 
 20758 |       { 
 20759 |          if (!valid()) 
 20760 |             return reinterpret_cast<generic_function_ptr>(0); 
 20761 |          else if (!valid_symbol(function_name)) 
 20762 |             return reinterpret_cast<generic_function_ptr>(0); 
 20763 |          else 
 20764 |             return local_data().overload_function_store.get(function_name); 
 20765 |       } 
 20766 |  
 20767 |       typedef vector_holder_t* vector_holder_ptr; 
 20768 |  
 20769 |       inline vector_holder_ptr get_vector(const std::string& vector_name) const 
 20770 |       { 
 20771 |          if (!valid()) 
 20772 |             return reinterpret_cast<vector_holder_ptr>(0); 
 20773 |          else if (!valid_symbol(vector_name)) 
 20774 |             return reinterpret_cast<vector_holder_ptr>(0); 
 20775 |          else 
 20776 |             return local_data().vector_store.get(vector_name); 
 20777 |       } 
 20778 |  
 20779 |       inline T& variable_ref(const std::string& symbol_name) 
 20780 |       { 
 20781 |          static T null_var = T(0); 
 20782 |          if (!valid()) 
 20783 |             return null_var; 
 20784 |          else if (!valid_symbol(symbol_name)) 
 20785 |             return null_var; 
 20786 |          else 
 20787 |             return local_data().variable_store.type_ref(symbol_name); 
 20788 |       } 
 20789 |  
 20790 |       #ifndef exprtk_disable_string_capabilities 
 20791 |       inline std::string& stringvar_ref(const std::string& symbol_name) 
 20792 |       { 
 20793 |          static std::string null_stringvar; 
 20794 |          if (!valid()) 
 20795 |             return null_stringvar; 
 20796 |          else if (!valid_symbol(symbol_name)) 
 20797 |             return null_stringvar; 
 20798 |          else 
 20799 |             return local_data().stringvar_store.type_ref(symbol_name); 
 20800 |       } 
 20801 |       #endif 
 20802 |  
 20803 |       inline bool is_constant_node(const std::string& symbol_name) const 
 20804 |       { 
 20805 |          if (!valid()) 
 20806 |             return false; 
 20807 |          else if (!valid_symbol(symbol_name)) 
 20808 |             return false; 
 20809 |          else 
 20810 |             return local_data().variable_store.is_constant(symbol_name); 
 20811 |       } 
 20812 |  
 20813 |       #ifndef exprtk_disable_string_capabilities 
 20814 |       inline bool is_constant_string(const std::string& symbol_name) const 
 20815 |       { 
 20816 |          if (!valid()) 
 20817 |             return false; 
 20818 |          else if (!valid_symbol(symbol_name)) 
 20819 |             return false; 
 20820 |          else if (!local_data().stringvar_store.symbol_exists(symbol_name)) 
 20821 |             return false; 
 20822 |          else 
 20823 |             return local_data().stringvar_store.is_constant(symbol_name); 
 20824 |       } 
 20825 |       #endif 
 20826 |  
 20827 |       inline bool create_variable(const std::string& variable_name, const T& value = T(0)) 
 20828 |       { 
 20829 |          if (!valid()) 
 20830 |             return false; 
 20831 |          else if (!valid_symbol(variable_name)) 
 20832 |             return false; 
 20833 |          else if (symbol_exists(variable_name)) 
 20834 |             return false; 
 20835 |  
 20836 |          local_data().local_symbol_list_.push_back(value); 
 20837 |          T& t = local_data().local_symbol_list_.back(); 
 20838 |  
 20839 |          return add_variable(variable_name,t); 
 20840 |       } 
 20841 |  
 20842 |       #ifndef exprtk_disable_string_capabilities 
 20843 |       inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string("")) 
 20844 |       { 
 20845 |          if (!valid()) 
 20846 |             return false; 
 20847 |          else if (!valid_symbol(stringvar_name)) 
 20848 |             return false; 
 20849 |          else if (symbol_exists(stringvar_name)) 
 20850 |             return false; 
 20851 |  
 20852 |          local_data().local_stringvar_list_.push_back(value); 
 20853 |          std::string& s = local_data().local_stringvar_list_.back(); 
 20854 |  
 20855 |          return add_stringvar(stringvar_name,s); 
 20856 |       } 
 20857 |       #endif 
 20858 |  
 20859 |       inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false) 
 20860 |       { 
 20861 |          if (!valid()) 
 20862 |             return false; 
 20863 |          else if (!valid_symbol(variable_name)) 
 20864 |             return false; 
 20865 |          else if (symbol_exists(variable_name)) 
 20866 |             return false; 
 20867 |          else 
 20868 |             return local_data().variable_store.add(variable_name, t, is_constant); 
 20869 |       } 
 20870 |  
 20871 |       inline bool add_constant(const std::string& constant_name, const T& value) 
 20872 |       { 
 20873 |          if (!valid()) 
 20874 |             return false; 
 20875 |          else if (!valid_symbol(constant_name)) 
 20876 |             return false; 
 20877 |          else if (symbol_exists(constant_name)) 
 20878 |             return false; 
 20879 |  
 20880 |          local_data().local_symbol_list_.push_back(value); 
 20881 |          T& t = local_data().local_symbol_list_.back(); 
 20882 |  
 20883 |          return add_variable(constant_name, t, true); 
 20884 |       } 
 20885 |  
 20886 |       #ifndef exprtk_disable_string_capabilities 
 20887 |       inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false) 
 20888 |       { 
 20889 |          if (!valid()) 
 20890 |             return false; 
 20891 |          else if (!valid_symbol(stringvar_name)) 
 20892 |             return false; 
 20893 |          else if (symbol_exists(stringvar_name)) 
 20894 |             return false; 
 20895 |          else 
 20896 |             return local_data().stringvar_store.add(stringvar_name, s, is_constant); 
 20897 |       } 
 20898 |       #endif 
 20899 |  
 20900 |       inline bool add_function(const std::string& function_name, function_t& function) 
 20901 |       { 
 20902 |          if (!valid()) 
 20903 |             return false; 
 20904 |          else if (!valid_symbol(function_name)) 
 20905 |             return false; 
 20906 |          else if (symbol_exists(function_name)) 
 20907 |             return false; 
 20908 |          else 
 20909 |             return local_data().function_store.add(function_name,function); 
 20910 |       } 
 20911 |  
 20912 |       inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function) 
 20913 |       { 
 20914 |          if (!valid()) 
 20915 |             return false; 
 20916 |          else if (!valid_symbol(vararg_function_name)) 
 20917 |             return false; 
 20918 |          else if (symbol_exists(vararg_function_name)) 
 20919 |             return false; 
 20920 |          else 
 20921 |             return local_data().vararg_function_store.add(vararg_function_name,vararg_function); 
 20922 |       } 
 20923 |  
 20924 |       inline bool add_function(const std::string& function_name, generic_function_t& function) 
 20925 |       { 
 20926 |          if (!valid()) 
 20927 |             return false; 
 20928 |          else if (!valid_symbol(function_name)) 
 20929 |             return false; 
 20930 |          else if (symbol_exists(function_name)) 
 20931 |             return false; 
 20932 |          else 
 20933 |          { 
 20934 |             switch (function.rtrn_type) 
 20935 |             { 
 20936 |                case generic_function_t::e_rtrn_scalar : 
 20937 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 20938 |                          local_data().generic_function_store.add(function_name,function) : false; 
 20939 |  
 20940 |                case generic_function_t::e_rtrn_string : 
 20941 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 20942 |                          local_data().string_function_store.add(function_name,function)  : false; 
 20943 |  
 20944 |                case generic_function_t::e_rtrn_overload : 
 20945 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ? 
 20946 |                          local_data().overload_function_store.add(function_name,function) : false; 
 20947 |             } 
 20948 |          } 
 20949 |  
 20950 |          return false; 
 20951 |       } 
 20952 |  
 20953 |       #define exprtk_define_freefunction(NN)                                                \ 
 20954 |       inline bool add_function(const std::string& function_name, ff##NN##_functor function) \ 
 20955 |       {                                                                                     \ 
 20956 |          if (!valid())                                                                      \ 
 20957 |          { return false; }                                                                  \ 
 20958 |          if (!valid_symbol(function_name))                                                  \ 
 20959 |          { return false; }                                                                  \ 
 20960 |          if (symbol_exists(function_name))                                                  \ 
 20961 |          { return false; }                                                                  \ 
 20962 |                                                                                             \ 
 20963 |          exprtk::ifunction<T>* ifunc = new freefunc##NN(function);                          \ 
 20964 |                                                                                             \ 
 20965 |          local_data().free_function_list_.push_back(ifunc);                                 \ 
 20966 |                                                                                             \ 
 20967 |          return add_function(function_name,(*local_data().free_function_list_.back()));     \ 
 20968 |       }                                                                                     \ 
 20969 |  
 20970 |       exprtk_define_freefunction(00) exprtk_define_freefunction(01) 
 20971 |       exprtk_define_freefunction(02) exprtk_define_freefunction(03) 
 20972 |       exprtk_define_freefunction(04) exprtk_define_freefunction(05) 
 20973 |       exprtk_define_freefunction(06) exprtk_define_freefunction(07) 
 20974 |       exprtk_define_freefunction(08) exprtk_define_freefunction(09) 
 20975 |       exprtk_define_freefunction(10) exprtk_define_freefunction(11) 
 20976 |       exprtk_define_freefunction(12) exprtk_define_freefunction(13) 
 20977 |       exprtk_define_freefunction(14) exprtk_define_freefunction(15) 
 20978 |  
 20979 |       #undef exprtk_define_freefunction 
 20980 |  
 20981 |       inline bool add_reserved_function(const std::string& function_name, function_t& function) 
 20982 |       { 
 20983 |          if (!valid()) 
 20984 |             return false; 
 20985 |          else if (!valid_symbol(function_name,false)) 
 20986 |             return false; 
 20987 |          else if (symbol_exists(function_name,false)) 
 20988 |             return false; 
 20989 |          else 
 20990 |             return local_data().function_store.add(function_name,function); 
 20991 |       } 
 20992 |  
 20993 |       inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function) 
 20994 |       { 
 20995 |          if (!valid()) 
 20996 |             return false; 
 20997 |          else if (!valid_symbol(vararg_function_name,false)) 
 20998 |             return false; 
 20999 |          else if (symbol_exists(vararg_function_name,false)) 
 21000 |             return false; 
 21001 |          else 
 21002 |             return local_data().vararg_function_store.add(vararg_function_name,vararg_function); 
 21003 |       } 
 21004 |  
 21005 |       inline bool add_reserved_function(const std::string& function_name, generic_function_t& function) 
 21006 |       { 
 21007 |          if (!valid()) 
 21008 |             return false; 
 21009 |          else if (!valid_symbol(function_name,false)) 
 21010 |             return false; 
 21011 |          else if (symbol_exists(function_name,false)) 
 21012 |             return false; 
 21013 |          else 
 21014 |          { 
 21015 |             switch (function.rtrn_type) 
 21016 |             { 
 21017 |                case generic_function_t::e_rtrn_scalar : 
 21018 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 21019 |                          local_data().generic_function_store.add(function_name,function) : false; 
 21020 |  
 21021 |                case generic_function_t::e_rtrn_string : 
 21022 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 21023 |                          local_data().string_function_store.add(function_name,function)  : false; 
 21024 |  
 21025 |                case generic_function_t::e_rtrn_overload : 
 21026 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ? 
 21027 |                          local_data().overload_function_store.add(function_name,function) : false; 
 21028 |             } 
 21029 |          } 
 21030 |  
 21031 |          return false; 
 21032 |       } 
 21033 |  
 21034 |       #define exprtk_define_reserved_function(NN)                                                    \ 
 21035 |       inline bool add_reserved_function(const std::string& function_name, ff##NN##_functor function) \ 
 21036 |       {                                                                                              \ 
 21037 |          if (!valid())                                                                               \ 
 21038 |          { return false; }                                                                           \ 
 21039 |          if (!valid_symbol(function_name,false))                                                     \ 
 21040 |          { return false; }                                                                           \ 
 21041 |          if (symbol_exists(function_name,false))                                                     \ 
 21042 |          { return false; }                                                                           \ 
 21043 |                                                                                                      \ 
 21044 |          exprtk::ifunction<T>* ifunc = new freefunc##NN(function);                                   \ 
 21045 |                                                                                                      \ 
 21046 |          local_data().free_function_list_.push_back(ifunc);                                          \ 
 21047 |                                                                                                      \ 
 21048 |          return add_reserved_function(function_name,(*local_data().free_function_list_.back()));     \ 
 21049 |       }                                                                                              \ 
 21050 |  
 21051 |       exprtk_define_reserved_function(00) exprtk_define_reserved_function(01) 
 21052 |       exprtk_define_reserved_function(02) exprtk_define_reserved_function(03) 
 21053 |       exprtk_define_reserved_function(04) exprtk_define_reserved_function(05) 
 21054 |       exprtk_define_reserved_function(06) exprtk_define_reserved_function(07) 
 21055 |       exprtk_define_reserved_function(08) exprtk_define_reserved_function(09) 
 21056 |       exprtk_define_reserved_function(10) exprtk_define_reserved_function(11) 
 21057 |       exprtk_define_reserved_function(12) exprtk_define_reserved_function(13) 
 21058 |       exprtk_define_reserved_function(14) exprtk_define_reserved_function(15) 
 21059 |  
 21060 |       #undef exprtk_define_reserved_function 
 21061 |  
 21062 |       template <std::size_t N> 
 21063 |       inline bool add_vector(const std::string& vector_name, T (&v)[N]) 
 21064 |       { 
 21065 |          if (!valid()) 
 21066 |             return false; 
 21067 |          else if (!valid_symbol(vector_name)) 
 21068 |             return false; 
 21069 |          else if (symbol_exists(vector_name)) 
 21070 |             return false; 
 21071 |          else 
 21072 |             return local_data().vector_store.add(vector_name,v); 
 21073 |       } 
 21074 |  
 21075 |       inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size) 
 21076 |       { 
 21077 |          if (!valid()) 
 21078 |             return false; 
 21079 |          else if (!valid_symbol(vector_name)) 
 21080 |             return false; 
 21081 |          else if (symbol_exists(vector_name)) 
 21082 |             return false; 
 21083 |          else if (0 == v_size) 
 21084 |             return false; 
 21085 |          else 
 21086 |             return local_data().vector_store.add(vector_name, v, v_size); 
 21087 |       } 
 21088 |  
 21089 |       template <typename Allocator> 
 21090 |       inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v) 
 21091 |       { 
 21092 |          if (!valid()) 
 21093 |             return false; 
 21094 |          else if (!valid_symbol(vector_name)) 
 21095 |             return false; 
 21096 |          else if (symbol_exists(vector_name)) 
 21097 |             return false; 
 21098 |          else if (0 == v.size()) 
 21099 |             return false; 
 21100 |          else 
 21101 |             return local_data().vector_store.add(vector_name,v); 
 21102 |       } 
 21103 |  
 21104 |       inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v) 
 21105 |       { 
 21106 |          if (!valid()) 
 21107 |             return false; 
 21108 |          else if (!valid_symbol(vector_name)) 
 21109 |             return false; 
 21110 |          else if (symbol_exists(vector_name)) 
 21111 |             return false; 
 21112 |          else if (0 == v.size()) 
 21113 |             return false; 
 21114 |          else 
 21115 |             return local_data().vector_store.add(vector_name,v); 
 21116 |       } 
 21117 |  
 21118 |       inline bool remove_variable(const std::string& variable_name, const bool delete_node = true) 
 21119 |       { 
 21120 |          if (!valid()) 
 21121 |             return false; 
 21122 |          else 
 21123 |             return local_data().variable_store.remove(variable_name, delete_node); 
 21124 |       } 
 21125 |  
 21126 |       #ifndef exprtk_disable_string_capabilities 
 21127 |       inline bool remove_stringvar(const std::string& string_name) 
 21128 |       { 
 21129 |          if (!valid()) 
 21130 |             return false; 
 21131 |          else 
 21132 |             return local_data().stringvar_store.remove(string_name); 
 21133 |       } 
 21134 |       #endif 
 21135 |  
 21136 |       inline bool remove_function(const std::string& function_name) 
 21137 |       { 
 21138 |          if (!valid()) 
 21139 |             return false; 
 21140 |          else 
 21141 |             return local_data().function_store.remove(function_name); 
 21142 |       } 
 21143 |  
 21144 |       inline bool remove_vararg_function(const std::string& vararg_function_name) 
 21145 |       { 
 21146 |          if (!valid()) 
 21147 |             return false; 
 21148 |          else 
 21149 |             return local_data().vararg_function_store.remove(vararg_function_name); 
 21150 |       } 
 21151 |  
 21152 |       inline bool remove_vector(const std::string& vector_name) 
 21153 |       { 
 21154 |          if (!valid()) 
 21155 |             return false; 
 21156 |          else 
 21157 |             return local_data().vector_store.remove(vector_name); 
 21158 |       } 
 21159 |  
 21160 |       inline bool add_constants() 
 21161 |       { 
 21162 |          return add_pi      () && 
 21163 |                 add_epsilon () && 
 21164 |                 add_infinity() ; 
 21165 |       } 
 21166 |  
 21167 |       inline bool add_pi() 
 21168 |       { 
 21169 |          const typename details::numeric::details::number_type<T>::type num_type; 
 21170 |          static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type); 
 21171 |          return add_constant("pi",local_pi); 
 21172 |       } 
 21173 |  
 21174 |       inline bool add_epsilon() 
 21175 |       { 
 21176 |          static const T local_epsilon = details::numeric::details::epsilon_type<T>::value(); 
 21177 |          return add_constant("epsilon",local_epsilon); 
 21178 |       } 
 21179 |  
 21180 |       inline bool add_infinity() 
 21181 |       { 
 21182 |          static const T local_infinity = std::numeric_limits<T>::infinity(); 
 21183 |          return add_constant("inf",local_infinity); 
 21184 |       } 
 21185 |  
 21186 |       template <typename Package> 
 21187 |       inline bool add_package(Package& package) 
 21188 |       { 
 21189 |          return package.register_package(*this); 
 21190 |       } 
 21191 |  
 21192 |       template <typename Allocator, 
 21193 |                 template <typename, typename> class Sequence> 
 21194 |       inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const 
 21195 |       { 
 21196 |          if (!valid()) 
 21197 |             return 0; 
 21198 |          else 
 21199 |             return local_data().variable_store.get_list(vlist); 
 21200 |       } 
 21201 |  
 21202 |       template <typename Allocator, 
 21203 |                 template <typename, typename> class Sequence> 
 21204 |       inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const 
 21205 |       { 
 21206 |          if (!valid()) 
 21207 |             return 0; 
 21208 |          else 
 21209 |             return local_data().variable_store.get_list(vlist); 
 21210 |       } 
 21211 |  
 21212 |       #ifndef exprtk_disable_string_capabilities 
 21213 |       template <typename Allocator, 
 21214 |                 template <typename, typename> class Sequence> 
 21215 |       inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const 
 21216 |       { 
 21217 |          if (!valid()) 
 21218 |             return 0; 
 21219 |          else 
 21220 |             return local_data().stringvar_store.get_list(svlist); 
 21221 |       } 
 21222 |  
 21223 |       template <typename Allocator, 
 21224 |                 template <typename, typename> class Sequence> 
 21225 |       inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const 
 21226 |       { 
 21227 |          if (!valid()) 
 21228 |             return 0; 
 21229 |          else 
 21230 |             return local_data().stringvar_store.get_list(svlist); 
 21231 |       } 
 21232 |       #endif 
 21233 |  
 21234 |       template <typename Allocator, 
 21235 |                 template <typename, typename> class Sequence> 
 21236 |       inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vec_list) const 
 21237 |       { 
 21238 |          if (!valid()) 
 21239 |             return 0; 
 21240 |          else 
 21241 |             return local_data().vector_store.get_list(vec_list); 
 21242 |       } 
 21243 |  
 21244 |       template <typename Allocator, 
 21245 |                 template <typename, typename> class Sequence> 
 21246 |       inline std::size_t get_function_list(Sequence<std::string,Allocator>& function_list) const 
 21247 |       { 
 21248 |          if (!valid()) 
 21249 |             return 0; 
 21250 |  
 21251 |          std::vector<std::string> function_names; 
 21252 |          std::size_t count = 0; 
 21253 |  
 21254 |          count += local_data().function_store         .get_list(function_names); 
 21255 |          count += local_data().vararg_function_store  .get_list(function_names); 
 21256 |          count += local_data().generic_function_store .get_list(function_names); 
 21257 |          count += local_data().string_function_store  .get_list(function_names); 
 21258 |          count += local_data().overload_function_store.get_list(function_names); 
 21259 |  
 21260 |          std::set<std::string> function_set; 
 21261 |  
 21262 |          for (std::size_t i = 0; i < function_names.size(); ++i) 
 21263 |          { 
 21264 |             function_set.insert(function_names[i]); 
 21265 |          } 
 21266 |  
 21267 |          std::copy(function_set.begin(), function_set.end(), 
 21268 |                    std::back_inserter(function_list)); 
 21269 |  
 21270 |          return count; 
 21271 |       } 
 21272 |  
 21273 |       inline std::vector<std::string> get_function_list() const 
 21274 |       { 
 21275 |          std::vector<std::string> result; 
 21276 |          get_function_list(result); 
 21277 |          return result; 
 21278 |       } 
 21279 |  
 21280 |       inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const 
 21281 |       { 
 21282 |          /* 
 21283 |             Function will return true if symbol_name exists as either a 
 21284 |             reserved symbol, variable, stringvar, vector or function name 
 21285 |             in any of the type stores. 
 21286 |          */ 
 21287 |          if (!valid()) 
 21288 |             return false; 
 21289 |          else if (local_data().variable_store.symbol_exists(symbol_name)) 
 21290 |             return true; 
 21291 |          #ifndef exprtk_disable_string_capabilities 
 21292 |          else if (local_data().stringvar_store.symbol_exists(symbol_name)) 
 21293 |             return true; 
 21294 |          #endif 
 21295 |          else if (local_data().vector_store.symbol_exists(symbol_name)) 
 21296 |             return true; 
 21297 |          else if (local_data().function_store.symbol_exists(symbol_name)) 
 21298 |             return true; 
 21299 |          else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name)) 
 21300 |             return true; 
 21301 |          else 
 21302 |             return false; 
 21303 |       } 
 21304 |  
 21305 |       inline bool is_variable(const std::string& variable_name) const 
 21306 |       { 
 21307 |          if (!valid()) 
 21308 |             return false; 
 21309 |          else 
 21310 |             return local_data().variable_store.symbol_exists(variable_name); 
 21311 |       } 
 21312 |  
 21313 |       #ifndef exprtk_disable_string_capabilities 
 21314 |       inline bool is_stringvar(const std::string& stringvar_name) const 
 21315 |       { 
 21316 |          if (!valid()) 
 21317 |             return false; 
 21318 |          else 
 21319 |             return local_data().stringvar_store.symbol_exists(stringvar_name); 
 21320 |       } 
 21321 |  
 21322 |       inline bool is_conststr_stringvar(const std::string& symbol_name) const 
 21323 |       { 
 21324 |          if (!valid()) 
 21325 |             return false; 
 21326 |          else if (!valid_symbol(symbol_name)) 
 21327 |             return false; 
 21328 |          else if (!local_data().stringvar_store.symbol_exists(symbol_name)) 
 21329 |             return false; 
 21330 |  
 21331 |          return ( 
 21332 |                   local_data().stringvar_store.symbol_exists(symbol_name) || 
 21333 |                   local_data().stringvar_store.is_constant  (symbol_name) 
 21334 |                 ); 
 21335 |       } 
 21336 |       #endif 
 21337 |  
 21338 |       inline bool is_function(const std::string& function_name) const 
 21339 |       { 
 21340 |          if (!valid()) 
 21341 |             return false; 
 21342 |          else 
 21343 |             return local_data().function_store.symbol_exists(function_name); 
 21344 |       } 
 21345 |  
 21346 |       inline bool is_vararg_function(const std::string& vararg_function_name) const 
 21347 |       { 
 21348 |          if (!valid()) 
 21349 |             return false; 
 21350 |          else 
 21351 |             return local_data().vararg_function_store.symbol_exists(vararg_function_name); 
 21352 |       } 
 21353 |  
 21354 |       inline bool is_vector(const std::string& vector_name) const 
 21355 |       { 
 21356 |          if (!valid()) 
 21357 |             return false; 
 21358 |          else 
 21359 |             return local_data().vector_store.symbol_exists(vector_name); 
 21360 |       } 
 21361 |  
 21362 |       inline std::string get_variable_name(const expression_ptr& ptr) const 
 21363 |       { 
 21364 |          return local_data().variable_store.entity_name(ptr); 
 21365 |       } 
 21366 |  
 21367 |       inline std::string get_vector_name(const vector_holder_ptr& ptr) const 
 21368 |       { 
 21369 |          return local_data().vector_store.entity_name(ptr); 
 21370 |       } 
 21371 |  
 21372 |       #ifndef exprtk_disable_string_capabilities 
 21373 |       inline std::string get_stringvar_name(const expression_ptr& ptr) const 
 21374 |       { 
 21375 |          return local_data().stringvar_store.entity_name(ptr); 
 21376 |       } 
 21377 |  
 21378 |       inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const 
 21379 |       { 
 21380 |          return local_data().stringvar_store.entity_name(ptr); 
 21381 |       } 
 21382 |       #endif 
 21383 |  
 21384 |       inline bool valid() const 
 21385 |       { 
 21386 |          // Symbol table sanity check. 
 21387 |          return control_block_ && control_block_->data_; 
 21388 |       } 
 21389 |  
 21390 |       inline void load_from(const symbol_table<T>& st) 
 21391 |       { 
 21392 |          { 
 21393 |             std::vector<std::string> name_list; 
 21394 |  
 21395 |             st.local_data().function_store.get_list(name_list); 
 21396 |  
 21397 |             if (!name_list.empty()) 
 21398 |             { 
 21399 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21400 |                { 
 21401 |                   exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]); 
 21402 |                   add_function(name_list[i],ifunc); 
 21403 |                } 
 21404 |             } 
 21405 |          } 
 21406 |  
 21407 |          { 
 21408 |             std::vector<std::string> name_list; 
 21409 |  
 21410 |             st.local_data().vararg_function_store.get_list(name_list); 
 21411 |  
 21412 |             if (!name_list.empty()) 
 21413 |             { 
 21414 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21415 |                { 
 21416 |                   exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]); 
 21417 |                   add_function(name_list[i],ivafunc); 
 21418 |                } 
 21419 |             } 
 21420 |          } 
 21421 |  
 21422 |          { 
 21423 |             std::vector<std::string> name_list; 
 21424 |  
 21425 |             st.local_data().generic_function_store.get_list(name_list); 
 21426 |  
 21427 |             if (!name_list.empty()) 
 21428 |             { 
 21429 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21430 |                { 
 21431 |                   exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]); 
 21432 |                   add_function(name_list[i],ifunc); 
 21433 |                } 
 21434 |             } 
 21435 |          } 
 21436 |  
 21437 |          { 
 21438 |             std::vector<std::string> name_list; 
 21439 |  
 21440 |             st.local_data().string_function_store.get_list(name_list); 
 21441 |  
 21442 |             if (!name_list.empty()) 
 21443 |             { 
 21444 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21445 |                { 
 21446 |                   exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]); 
 21447 |                   add_function(name_list[i],ifunc); 
 21448 |                } 
 21449 |             } 
 21450 |          } 
 21451 |  
 21452 |          { 
 21453 |             std::vector<std::string> name_list; 
 21454 |  
 21455 |             st.local_data().overload_function_store.get_list(name_list); 
 21456 |  
 21457 |             if (!name_list.empty()) 
 21458 |             { 
 21459 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21460 |                { 
 21461 |                   exprtk::igeneric_function<T>& ifunc = *st.get_overload_function(name_list[i]); 
 21462 |                   add_function(name_list[i],ifunc); 
 21463 |                } 
 21464 |             } 
 21465 |          } 
 21466 |       } 
 21467 |  
 21468 |       inline void load_variables_from(const symbol_table<T>& st) 
 21469 |       { 
 21470 |          std::vector<std::string> name_list; 
 21471 |  
 21472 |          st.local_data().variable_store.get_list(name_list); 
 21473 |  
 21474 |          if (!name_list.empty()) 
 21475 |          { 
 21476 |             for (std::size_t i = 0; i < name_list.size(); ++i) 
 21477 |             { 
 21478 |                T& variable = st.get_variable(name_list[i])->ref(); 
 21479 |                add_variable(name_list[i], variable); 
 21480 |             } 
 21481 |          } 
 21482 |       } 
 21483 |  
 21484 |       inline void load_vectors_from(const symbol_table<T>& st) 
 21485 |       { 
 21486 |          std::vector<std::string> name_list; 
 21487 |  
 21488 |          st.local_data().vector_store.get_list(name_list); 
 21489 |  
 21490 |          if (!name_list.empty()) 
 21491 |          { 
 21492 |             for (std::size_t i = 0; i < name_list.size(); ++i) 
 21493 |             { 
 21494 |                vector_holder_t& vecholder = *st.get_vector(name_list[i]); 
 21495 |                add_vector(name_list[i], vecholder.data(), vecholder.size()); 
 21496 |             } 
 21497 |          } 
 21498 |       } 
 21499 |  
 21500 |    private: 
 21501 |  
 21502 |       inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const 
 21503 |       { 
 21504 |          if (symbol.empty()) 
 21505 |             return false; 
 21506 |          else if (!details::is_letter(symbol[0])) 
 21507 |             return false; 
 21508 |          else if (symbol.size() > 1) 
 21509 |          { 
 21510 |             for (std::size_t i = 1; i < symbol.size(); ++i) 
 21511 |             { 
 21512 |                if ( 
 21513 |                     !details::is_letter_or_digit(symbol[i]) && 
 21514 |                     ('_' != symbol[i]) 
 21515 |                   ) 
 21516 |                { 
 21517 |                   if ((i < (symbol.size() - 1)) && ('.' == symbol[i])) 
 21518 |                      continue; 
 21519 |                   else 
 21520 |                      return false; 
 21521 |                } 
 21522 |             } 
 21523 |          } 
 21524 |  
 21525 |          return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true; 
 21526 |       } 
 21527 |  
 21528 |       inline bool valid_function(const std::string& symbol) const 
 21529 |       { 
 21530 |          if (symbol.empty()) 
 21531 |             return false; 
 21532 |          else if (!details::is_letter(symbol[0])) 
 21533 |             return false; 
 21534 |          else if (symbol.size() > 1) 
 21535 |          { 
 21536 |             for (std::size_t i = 1; i < symbol.size(); ++i) 
 21537 |             { 
 21538 |                if ( 
 21539 |                     !details::is_letter_or_digit(symbol[i]) && 
 21540 |                     ('_' != symbol[i]) 
 21541 |                   ) 
 21542 |                { 
 21543 |                   if ((i < (symbol.size() - 1)) && ('.' == symbol[i])) 
 21544 |                      continue; 
 21545 |                   else 
 21546 |                      return false; 
 21547 |                } 
 21548 |             } 
 21549 |          } 
 21550 |  
 21551 |          return true; 
 21552 |       } 
 21553 |  
 21554 |       typedef typename control_block::st_data local_data_t; 
 21555 |  
 21556 |       inline local_data_t& local_data() 
 21557 |       { 
 21558 |          return *(control_block_->data_); 
 21559 |       } 
 21560 |  
 21561 |       inline const local_data_t& local_data() const 
 21562 |       { 
 21563 |          return *(control_block_->data_); 
 21564 |       } 
 21565 |  
 21566 |       control_block* control_block_; 
 21567 |  
 21568 |       friend class parser<T>; 
 21569 |    }; // class symbol_table 
 21570 |  
 21571 |    template <typename T> 
 21572 |    class function_compositor; 
 21573 |  
 21574 |    template <typename T> 
 21575 |    class expression 
 21576 |    { 
 21577 |    private: 
 21578 |  
 21579 |       typedef details::expression_node<T>*  expression_ptr; 
 21580 |       typedef details::vector_holder<T>*    vector_holder_ptr; 
 21581 |       typedef std::vector<symbol_table<T> > symtab_list_t; 
 21582 |  
 21583 |       struct control_block 
 21584 |       { 
 21585 |          enum data_type 
 21586 |          { 
 21587 |             e_unknown  , 
 21588 |             e_expr     , 
 21589 |             e_vecholder, 
 21590 |             e_data     , 
 21591 |             e_vecdata  , 
 21592 |             e_string 
 21593 |          }; 
 21594 |  
 21595 |          static std::string to_str(data_type dt) 
 21596 |          { 
 21597 |             switch (dt) 
 21598 |             { 
 21599 |                case e_unknown   : return "e_unknown  " 
 21600 |                case e_expr      : return "e_expr"     ; 
 21601 |                case e_vecholder : return "e_vecholder" 
 21602 |                case e_data      : return "e_data"     ; 
 21603 |                case e_vecdata   : return "e_vecdata"  ; 
 21604 |                case e_string    : return "e_string"   ; 
 21605 |             } 
 21606 |  
 21607 |             return "" 
 21608 |          } 
 21609 |  
 21610 |          struct data_pack 
 21611 |          { 
 21612 |             data_pack() 
 21613 |             : pointer(0) 
 21614 |             , type(e_unknown) 
 21615 |             , size(0) 
 21616 |             {} 
 21617 |  
 21618 |             data_pack(void* ptr, const data_type dt, const std::size_t sz = 0) 
 21619 |             : pointer(ptr) 
 21620 |             , type(dt) 
 21621 |             , size(sz) 
 21622 |             {} 
 21623 |  
 21624 |             void*       pointer; 
 21625 |             data_type   type; 
 21626 |             std::size_t size; 
 21627 |          }; 
 21628 |  
 21629 |          typedef std::vector<data_pack> local_data_list_t; 
 21630 |          typedef results_context<T>     results_context_t; 
 21631 |          typedef control_block*         cntrl_blck_ptr_t; 
 21632 |  
 21633 |          control_block() 
 21634 |          : ref_count(0) 
 21635 |          , expr     (0) 
 21636 |          , results  (0) 
 21637 |          , retinv_null(false) 
 21638 |          , return_invoked(&retinv_null) 
 21639 |          {} 
 21640 |  
 21641 |          explicit control_block(expression_ptr e) 
 21642 |          : ref_count(1) 
 21643 |          , expr     (e) 
 21644 |          , results  (0) 
 21645 |          , retinv_null(false) 
 21646 |          , return_invoked(&retinv_null) 
 21647 |          {} 
 21648 |  
 21649 |         ~control_block() 
 21650 |          { 
 21651 |             if (expr && details::branch_deletable(expr)) 
 21652 |             { 
 21653 |                destroy_node(expr); 
 21654 |             } 
 21655 |  
 21656 |             if (!local_data_list.empty()) 
 21657 |             { 
 21658 |                for (std::size_t i = 0; i < local_data_list.size(); ++i) 
 21659 |                { 
 21660 |                   switch (local_data_list[i].type) 
 21661 |                   { 
 21662 |                      case e_expr      : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer); 
 21663 |                                         break; 
 21664 |  
 21665 |                      case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer); 
 21666 |                                         break; 
 21667 |  
 21668 |                      case e_data      : delete reinterpret_cast<T*>(local_data_list[i].pointer); 
 21669 |                                         break; 
 21670 |  
 21671 |                      case e_vecdata   : delete [] reinterpret_cast<T*>(local_data_list[i].pointer); 
 21672 |                                         break; 
 21673 |  
 21674 |                      case e_string    : delete reinterpret_cast<std::string*>(local_data_list[i].pointer); 
 21675 |                                         break; 
 21676 |  
 21677 |                      default          : break; 
 21678 |                   } 
 21679 |                } 
 21680 |             } 
 21681 |  
 21682 |             if (results) 
 21683 |             { 
 21684 |                delete results; 
 21685 |             } 
 21686 |          } 
 21687 |  
 21688 |          static inline cntrl_blck_ptr_t create(expression_ptr e) 
 21689 |          { 
 21690 |             return new control_block(e); 
 21691 |          } 
 21692 |  
 21693 |          static inline void destroy(cntrl_blck_ptr_t& cntrl_blck) 
 21694 |          { 
 21695 |             if (cntrl_blck) 
 21696 |             { 
 21697 |                if ( 
 21698 |                     (0 !=   cntrl_blck->ref_count) && 
 21699 |                     (0 == --cntrl_blck->ref_count) 
 21700 |                   ) 
 21701 |                { 
 21702 |                   delete cntrl_blck; 
 21703 |                } 
 21704 |  
 21705 |                cntrl_blck = 0; 
 21706 |             } 
 21707 |          } 
 21708 |  
 21709 |          std::size_t ref_count; 
 21710 |          expression_ptr expr; 
 21711 |          local_data_list_t local_data_list; 
 21712 |          results_context_t* results; 
 21713 |          bool  retinv_null; 
 21714 |          bool* return_invoked; 
 21715 |  
 21716 |          friend class function_compositor<T>; 
 21717 |       }; 
 21718 |  
 21719 |    public: 
 21720 |  
 21721 |       expression() 
 21722 |       : control_block_(0) 
 21723 |       { 
 21724 |          set_expression(new details::null_node<T>()); 
 21725 |       } 
 21726 |  
 21727 |       expression(const expression<T>& e) 
 21728 |       : control_block_    (e.control_block_    ) 
 21729 |       , symbol_table_list_(e.symbol_table_list_) 
 21730 |       { 
 21731 |          control_block_->ref_count++; 
 21732 |       } 
 21733 |  
 21734 |       explicit expression(const symbol_table<T>& symbol_table) 
 21735 |       : control_block_(0) 
 21736 |       { 
 21737 |          set_expression(new details::null_node<T>()); 
 21738 |          symbol_table_list_.push_back(symbol_table); 
 21739 |       } 
 21740 |  
 21741 |       inline expression<T>& operator=(const expression<T>& e) 
 21742 |       { 
 21743 |          if (this != &e) 
 21744 |          { 
 21745 |             if (control_block_) 
 21746 |             { 
 21747 |                if ( 
 21748 |                     (0 !=   control_block_->ref_count) && 
 21749 |                     (0 == --control_block_->ref_count) 
 21750 |                   ) 
 21751 |                { 
 21752 |                   delete control_block_; 
 21753 |                } 
 21754 |  
 21755 |                control_block_ = 0; 
 21756 |             } 
 21757 |  
 21758 |             control_block_ = e.control_block_; 
 21759 |             control_block_->ref_count++; 
 21760 |             symbol_table_list_ = e.symbol_table_list_; 
 21761 |          } 
 21762 |  
 21763 |          return *this; 
 21764 |       } 
 21765 |  
 21766 |       inline bool operator==(const expression<T>& e) const 
 21767 |       { 
 21768 |          return (this == &e); 
 21769 |       } 
 21770 |  
 21771 |       inline bool operator!() const 
 21772 |       { 
 21773 |          return ( 
 21774 |                   (0 == control_block_      ) || 
 21775 |                   (0 == control_block_->expr) 
 21776 |                 ); 
 21777 |       } 
 21778 |  
 21779 |       inline expression<T>& release() 
 21780 |       { 
 21781 |          exprtk::details::dump_ptr("expression::release", this); 
 21782 |          control_block::destroy(control_block_); 
 21783 |  
 21784 |          return (*this); 
 21785 |       } 
 21786 |  
 21787 |      ~expression() 
 21788 |       { 
 21789 |          control_block::destroy(control_block_); 
 21790 |       } 
 21791 |  
 21792 |       inline T value() const 
 21793 |       { 
 21794 |          assert(control_block_      ); 
 21795 |          assert(control_block_->expr); 
 21796 |  
 21797 |          return control_block_->expr->value(); 
 21798 |       } 
 21799 |  
 21800 |       inline T operator() () const 
 21801 |       { 
 21802 |          return value(); 
 21803 |       } 
 21804 |  
 21805 |       inline operator T() const 
 21806 |       { 
 21807 |          return value(); 
 21808 |       } 
 21809 |  
 21810 |       inline operator bool() const 
 21811 |       { 
 21812 |          return details::is_true(value()); 
 21813 |       } 
 21814 |  
 21815 |       inline bool register_symbol_table(symbol_table<T>& st) 
 21816 |       { 
 21817 |          for (std::size_t i = 0; i < symbol_table_list_.size(); ++i) 
 21818 |          { 
 21819 |             if (st == symbol_table_list_[i]) 
 21820 |             { 
 21821 |                return false; 
 21822 |             } 
 21823 |          } 
 21824 |  
 21825 |          symbol_table_list_.push_back(st); 
 21826 |          return true; 
 21827 |       } 
 21828 |  
 21829 |       inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const 
 21830 |       { 
 21831 |          return symbol_table_list_[index]; 
 21832 |       } 
 21833 |  
 21834 |       inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0) 
 21835 |       { 
 21836 |          return symbol_table_list_[index]; 
 21837 |       } 
 21838 |  
 21839 |       std::size_t num_symbol_tables() const 
 21840 |       { 
 21841 |          return symbol_table_list_.size(); 
 21842 |       } 
 21843 |  
 21844 |       typedef results_context<T> results_context_t; 
 21845 |  
 21846 |       inline const results_context_t& results() const 
 21847 |       { 
 21848 |          if (control_block_->results) 
 21849 |             return (*control_block_->results); 
 21850 |          else 
 21851 |          { 
 21852 |             static const results_context_t null_results; 
 21853 |             return null_results; 
 21854 |          } 
 21855 |       } 
 21856 |  
 21857 |       inline bool return_invoked() const 
 21858 |       { 
 21859 |          return (*control_block_->return_invoked); 
 21860 |       } 
 21861 |  
 21862 |    private: 
 21863 |  
 21864 |       inline symtab_list_t get_symbol_table_list() const 
 21865 |       { 
 21866 |          return symbol_table_list_; 
 21867 |       } 
 21868 |  
 21869 |       inline void set_expression(const expression_ptr expr) 
 21870 |       { 
 21871 |          if (expr) 
 21872 |          { 
 21873 |             if (control_block_) 
 21874 |             { 
 21875 |                if (0 == --control_block_->ref_count) 
 21876 |                { 
 21877 |                   delete control_block_; 
 21878 |                } 
 21879 |             } 
 21880 |  
 21881 |             control_block_ = control_block::create(expr); 
 21882 |          } 
 21883 |       } 
 21884 |  
 21885 |       inline void register_local_var(expression_ptr expr) 
 21886 |       { 
 21887 |          if (expr) 
 21888 |          { 
 21889 |             if (control_block_) 
 21890 |             { 
 21891 |                control_block_-> 
 21892 |                   local_data_list.push_back( 
 21893 |                      typename expression<T>::control_block:: 
 21894 |                         data_pack(reinterpret_cast<void*>(expr), 
 21895 |                                   control_block::e_expr)); 
 21896 |             } 
 21897 |          } 
 21898 |       } 
 21899 |  
 21900 |       inline void register_local_var(vector_holder_ptr vec_holder) 
 21901 |       { 
 21902 |          if (vec_holder) 
 21903 |          { 
 21904 |             if (control_block_) 
 21905 |             { 
 21906 |                control_block_-> 
 21907 |                   local_data_list.push_back( 
 21908 |                      typename expression<T>::control_block:: 
 21909 |                         data_pack(reinterpret_cast<void*>(vec_holder), 
 21910 |                                   control_block::e_vecholder)); 
 21911 |             } 
 21912 |          } 
 21913 |       } 
 21914 |  
 21915 |       inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0) 
 21916 |       { 
 21917 |          if (data) 
 21918 |          { 
 21919 |             if (control_block_) 
 21920 |             { 
 21921 |                typename control_block::data_type dt = control_block::e_data; 
 21922 |  
 21923 |                switch (data_mode) 
 21924 |                { 
 21925 |                   case 0 : dt = control_block::e_data;    break; 
 21926 |                   case 1 : dt = control_block::e_vecdata; break; 
 21927 |                   case 2 : dt = control_block::e_string;  break; 
 21928 |                } 
 21929 |  
 21930 |                control_block_-> 
 21931 |                   local_data_list.push_back( 
 21932 |                      typename expression<T>::control_block:: 
 21933 |                         data_pack(reinterpret_cast<void*>(data), dt, size)); 
 21934 |             } 
 21935 |          } 
 21936 |       } 
 21937 |  
 21938 |       inline const typename control_block::local_data_list_t& local_data_list() 
 21939 |       { 
 21940 |          if (control_block_) 
 21941 |          { 
 21942 |             return control_block_->local_data_list; 
 21943 |          } 
 21944 |          else 
 21945 |          { 
 21946 |             static typename control_block::local_data_list_t null_local_data_list; 
 21947 |             return null_local_data_list; 
 21948 |          } 
 21949 |       } 
 21950 |  
 21951 |       inline void register_return_results(results_context_t* rc) 
 21952 |       { 
 21953 |          if (control_block_ && rc) 
 21954 |          { 
 21955 |             control_block_->results = rc; 
 21956 |          } 
 21957 |       } 
 21958 |  
 21959 |       inline void set_retinvk(bool* retinvk_ptr) 
 21960 |       { 
 21961 |          if (control_block_) 
 21962 |          { 
 21963 |             control_block_->return_invoked = retinvk_ptr; 
 21964 |          } 
 21965 |       } 
 21966 |  
 21967 |       control_block* control_block_; 
 21968 |       symtab_list_t  symbol_table_list_; 
 21969 |  
 21970 |       friend class parser<T>; 
 21971 |       friend class expression_helper<T>; 
 21972 |       friend class function_compositor<T>; 
 21973 |       template <typename TT> 
 21974 |       friend bool is_valid(const expression<TT>& expr); 
 21975 |    }; // class expression 
 21976 |  
 21977 |    template <typename T> 
 21978 |    class expression_helper 
 21979 |    { 
 21980 |    public: 
 21981 |  
 21982 |       enum node_types 
 21983 |       { 
 21984 |          e_literal, 
 21985 |          e_variable, 
 21986 |          e_string, 
 21987 |          e_unary, 
 21988 |          e_binary, 
 21989 |          e_function, 
 21990 |          e_vararg, 
 21991 |          e_null, 
 21992 |          e_assert, 
 21993 |          e_sf3ext, 
 21994 |          e_sf4ext 
 21995 |       }; 
 21996 |  
 21997 |       static inline bool is_literal(const expression<T>& expr) 
 21998 |       { 
 21999 |          return expr.control_block_ && details::is_literal_node(expr.control_block_->expr); 
 22000 |       } 
 22001 |  
 22002 |       static inline bool is_variable(const expression<T>& expr) 
 22003 |       { 
 22004 |          return expr.control_block_ && details::is_variable_node(expr.control_block_->expr); 
 22005 |       } 
 22006 |  
 22007 |       static inline bool is_string(const expression<T>& expr) 
 22008 |       { 
 22009 |          return expr.control_block_ && details::is_generally_string_node(expr.control_block_->expr); 
 22010 |       } 
 22011 |  
 22012 |       static inline bool is_unary(const expression<T>& expr) 
 22013 |       { 
 22014 |          return expr.control_block_ && details::is_unary_node(expr.control_block_->expr); 
 22015 |       } 
 22016 |  
 22017 |       static inline bool is_binary(const expression<T>& expr) 
 22018 |       { 
 22019 |          return expr.control_block_ && details::is_binary_node(expr.control_block_->expr); 
 22020 |       } 
 22021 |  
 22022 |       static inline bool is_function(const expression<T>& expr) 
 22023 |       { 
 22024 |          return expr.control_block_ && details::is_function(expr.control_block_->expr); 
 22025 |       } 
 22026 |  
 22027 |       static inline bool is_vararg(const expression<T>& expr) 
 22028 |       { 
 22029 |          return expr.control_block_ && details::is_vararg_node(expr.control_block_->expr); 
 22030 |       } 
 22031 |  
 22032 |       static inline bool is_null(const expression<T>& expr) 
 22033 |       { 
 22034 |          return expr.control_block_ && details::is_null_node(expr.control_block_->expr); 
 22035 |       } 
 22036 |  
 22037 |       static inline bool is_assert(const expression<T>& expr) 
 22038 |       { 
 22039 |          return expr.control_block_ && details::is_assert_node(expr.control_block_->expr); 
 22040 |       } 
 22041 |  
 22042 |       static inline bool is_sf3ext(const expression<T>& expr) 
 22043 |       { 
 22044 |          return expr.control_block_ && details::is_sf3ext_node(expr.control_block_->expr); 
 22045 |       } 
 22046 |  
 22047 |       static inline bool is_sf4ext(const expression<T>& expr) 
 22048 |       { 
 22049 |          return expr.control_block_ && details::is_sf4ext_node(expr.control_block_->expr); 
 22050 |       } 
 22051 |  
 22052 |       static inline bool is_type(const expression<T>& expr, const node_types node_type) 
 22053 |       { 
 22054 |          if (0 == expr.control_block_) 
 22055 |          { 
 22056 |             return false; 
 22057 |          } 
 22058 |  
 22059 |          switch (node_type) 
 22060 |          { 
 22061 |             case e_literal  : return is_literal_node(expr); 
 22062 |             case e_variable : return is_variable    (expr); 
 22063 |             case e_string   : return is_string      (expr); 
 22064 |             case e_unary    : return is_unary       (expr); 
 22065 |             case e_binary   : return is_binary      (expr); 
 22066 |             case e_function : return is_function    (expr); 
 22067 |             case e_null     : return is_null        (expr); 
 22068 |             case e_assert   : return is_assert      (expr); 
 22069 |             case e_sf3ext   : return is_sf3ext      (expr); 
 22070 |             case e_sf4ext   : return is_sf4ext      (expr); 
 22071 |          }; 
 22072 |  
 22073 |          return false; 
 22074 |       } 
 22075 |  
 22076 |       static inline bool match_type_sequence(const expression<T>& expr, const std::vector<node_types>& type_seq) 
 22077 |       { 
 22078 |          if ((0 == expr.control_block_) || !is_vararg(expr)) 
 22079 |          { 
 22080 |             return false; 
 22081 |          } 
 22082 |  
 22083 |          typedef details::vararg_node<T, exprtk::details::vararg_multi_op<T> > mo_vararg_t; 
 22084 |  
 22085 |          mo_vararg_t* vnode = dynamic_cast<mo_vararg_t*>(expr.control_block_->expr); 
 22086 |  
 22087 |          if ( 
 22088 |               (0 == vnode) || 
 22089 |               type_seq.empty() || 
 22090 |               (vnode->size() < type_seq.size()) 
 22091 |             ) 
 22092 |          { 
 22093 |             return false; 
 22094 |          } 
 22095 |  
 22096 |          for (std::size_t i = 0; i < type_seq.size(); ++i) 
 22097 |          { 
 22098 |             assert((*vnode)[i]); 
 22099 |  
 22100 |             switch (type_seq[i]) 
 22101 |             { 
 22102 |                case e_literal  : { if (details::is_literal_node         ((*vnode)[i])) continue; } break; 
 22103 |                case e_variable : { if (details::is_variable_node        ((*vnode)[i])) continue; } break; 
 22104 |                case e_string   : { if (details::is_generally_string_node((*vnode)[i])) continue; } break; 
 22105 |                case e_unary    : { if (details::is_unary_node           ((*vnode)[i])) continue; } break; 
 22106 |                case e_binary   : { if (details::is_binary_node          ((*vnode)[i])) continue; } break; 
 22107 |                case e_function : { if (details::is_function             ((*vnode)[i])) continue; } break; 
 22108 |                case e_null     : { if (details::is_null_node            ((*vnode)[i])) continue; } break; 
 22109 |                case e_assert   : { if (details::is_assert_node          ((*vnode)[i])) continue; } break; 
 22110 |                case e_sf3ext   : { if (details::is_sf3ext_node          ((*vnode)[i])) continue; } break; 
 22111 |                case e_sf4ext   : { if (details::is_sf4ext_node          ((*vnode)[i])) continue; } break; 
 22112 |                case e_vararg   : break; 
 22113 |             } 
 22114 |  
 22115 |             return false; 
 22116 |          } 
 22117 |  
 22118 |          return true; 
 22119 |       } 
 22120 |    }; 
 22121 |  
 22122 |    template <typename T> 
 22123 |    inline bool is_valid(const expression<T>& expr) 
 22124 |    { 
 22125 |       return expr.control_block_ && !expression_helper<T>::is_null(expr); 
 22126 |    } 
 22127 |  
 22128 |    namespace parser_error 
 22129 |    { 
 22130 |       enum error_mode 
 22131 |       { 
 22132 |          e_unknown   = 0, 
 22133 |          e_syntax    = 1, 
 22134 |          e_token     = 2, 
 22135 |          e_numeric   = 4, 
 22136 |          e_symtab    = 5, 
 22137 |          e_lexer     = 6, 
 22138 |          e_synthesis = 7, 
 22139 |          e_helper    = 8, 
 22140 |          e_parser    = 9 
 22141 |       }; 
 22142 |  
 22143 |       struct type 
 22144 |       { 
 22145 |          type() 
 22146 |          : mode(parser_error::e_unknown) 
 22147 |          , line_no  (0) 
 22148 |          , column_no(0) 
 22149 |          {} 
 22150 |  
 22151 |          lexer::token token; 
 22152 |          error_mode mode; 
 22153 |          std::string diagnostic; 
 22154 |          std::string src_location; 
 22155 |          std::string error_line; 
 22156 |          std::size_t line_no; 
 22157 |          std::size_t column_no; 
 22158 |       }; 
 22159 |  
 22160 |       inline type make_error(const error_mode mode, 
 22161 |                              const std::string& diagnostic   = "", 
 22162 |                              const std::string& src_location = "") 
 22163 |       { 
 22164 |          type t; 
 22165 |          t.mode         = mode; 
 22166 |          t.token.type   = lexer::token::e_error; 
 22167 |          t.diagnostic   = diagnostic; 
 22168 |          t.src_location = src_location; 
 22169 |          exprtk_debug(("%s\n", diagnostic .c_str())); 
 22170 |          return t; 
 22171 |       } 
 22172 |  
 22173 |       inline type make_error(const error_mode mode, 
 22174 |                              const lexer::token& tk, 
 22175 |                              const std::string& diagnostic   = "", 
 22176 |                              const std::string& src_location = "") 
 22177 |       { 
 22178 |          type t; 
 22179 |          t.mode         = mode; 
 22180 |          t.token        = tk; 
 22181 |          t.diagnostic   = diagnostic; 
 22182 |          t.src_location = src_location; 
 22183 |          exprtk_debug(("%s\n", diagnostic .c_str())); 
 22184 |          return t; 
 22185 |       } 
 22186 |  
 22187 |       inline std::string to_str(error_mode mode) 
 22188 |       { 
 22189 |          switch (mode) 
 22190 |          { 
 22191 |             case e_unknown : return std::string("Unknown Error"); 
 22192 |             case e_syntax  : return std::string("Syntax Error" ); 
 22193 |             case e_token   : return std::string("Token Error"  ); 
 22194 |             case e_numeric : return std::string("Numeric Error"); 
 22195 |             case e_symtab  : return std::string("Symbol Error" ); 
 22196 |             case e_lexer   : return std::string("Lexer Error"  ); 
 22197 |             case e_helper  : return std::string("Helper Error" ); 
 22198 |             case e_parser  : return std::string("Parser Error" ); 
 22199 |             default        : return std::string("Unknown Error"); 
 22200 |          } 
 22201 |       } 
 22202 |  
 22203 |       inline bool update_error(type& error, const std::string& expression) 
 22204 |       { 
 22205 |          if ( 
 22206 |               expression.empty()                         || 
 22207 |               (error.token.position > expression.size()) || 
 22208 |               (std::numeric_limits<std::size_t>::max() == error.token.position) 
 22209 |             ) 
 22210 |          { 
 22211 |             return false; 
 22212 |          } 
 22213 |  
 22214 |          std::size_t error_line_start = 0; 
 22215 |  
 22216 |          for (std::size_t i = error.token.position; i > 0; --i) 
 22217 |          { 
 22218 |             const details::char_t c = expression[i]; 
 22219 |  
 22220 |             if (('\n' == c) || ('\r' == c)) 
 22221 |             { 
 22222 |                error_line_start = i + 1; 
 22223 |                break; 
 22224 |             } 
 22225 |          } 
 22226 |  
 22227 |          std::size_t next_nl_position = std::min(expression.size(), 
 22228 |                                                  expression.find_first_of('\n',error.token.position + 1)); 
 22229 |  
 22230 |          error.column_no  = error.token.position - error_line_start; 
 22231 |          error.error_line = expression.substr(error_line_start, 
 22232 |                                               next_nl_position - error_line_start); 
 22233 |  
 22234 |          error.line_no = 0; 
 22235 |  
 22236 |          for (std::size_t i = 0; i < next_nl_position; ++i) 
 22237 |          { 
 22238 |             if ('\n' == expression[i]) 
 22239 |                ++error.line_no; 
 22240 |          } 
 22241 |  
 22242 |          return true; 
 22243 |       } 
 22244 |  
 22245 |       inline void dump_error(const type& error) 
 22246 |       { 
 22247 |          printf("Position: %02d   Type: [%s]   Msg: %s\n", 
 22248 |                 static_cast<int>(error.token.position), 
 22249 |                 exprtk::parser_error::to_str(error.mode).c_str(), 
 22250 |                 error.diagnostic.c_str()); 
 22251 |       } 
 22252 |    } 
 22253 |  
 22254 |    namespace details 
 22255 |    { 
 22256 |       template <typename Parser> 
 22257 |       inline void disable_type_checking(Parser& p) 
 22258 |       { 
 22259 |          p.state_.type_check_enabled = false; 
 22260 |       } 
 22261 |    } 
 22262 |  
 22263 |    template <typename T> 
 22264 |    class parser : public lexer::parser_helper 
 22265 |    { 
 22266 |    private: 
 22267 |  
 22268 |       enum precedence_level 
 22269 |       { 
 22270 |          e_level00, e_level01, e_level02, e_level03, e_level04, 
 22271 |          e_level05, e_level06, e_level07, e_level08, e_level09, 
 22272 |          e_level10, e_level11, e_level12, e_level13, e_level14 
 22273 |       }; 
 22274 |  
 22275 |       typedef const T&                                       cref_t; 
 22276 |       typedef const T                                        const_t; 
 22277 |       typedef ifunction<T>                                   F; 
 22278 |       typedef ivararg_function<T>                            VAF; 
 22279 |       typedef igeneric_function<T>                           GF; 
 22280 |       typedef ifunction<T>                                   ifunction_t; 
 22281 |       typedef ivararg_function<T>                            ivararg_function_t; 
 22282 |       typedef igeneric_function<T>                           igeneric_function_t; 
 22283 |       typedef details::expression_node<T>                    expression_node_t; 
 22284 |       typedef details::literal_node<T>                       literal_node_t; 
 22285 |       typedef details::unary_node<T>                         unary_node_t; 
 22286 |       typedef details::binary_node<T>                        binary_node_t; 
 22287 |       typedef details::trinary_node<T>                       trinary_node_t; 
 22288 |       typedef details::quaternary_node<T>                    quaternary_node_t; 
 22289 |       typedef details::conditional_node<T>                   conditional_node_t; 
 22290 |       typedef details::cons_conditional_node<T>              cons_conditional_node_t; 
 22291 |       typedef details::while_loop_node<T>                    while_loop_node_t; 
 22292 |       typedef details::repeat_until_loop_node<T>             repeat_until_loop_node_t; 
 22293 |       typedef details::for_loop_node<T>                      for_loop_node_t; 
 22294 |       typedef details::while_loop_rtc_node<T>                while_loop_rtc_node_t; 
 22295 |       typedef details::repeat_until_loop_rtc_node<T>         repeat_until_loop_rtc_node_t; 
 22296 |       typedef details::for_loop_rtc_node<T>                  for_loop_rtc_node_t; 
 22297 |       #ifndef exprtk_disable_break_continue 
 22298 |       typedef details::while_loop_bc_node<T>                 while_loop_bc_node_t; 
 22299 |       typedef details::repeat_until_loop_bc_node<T>          repeat_until_loop_bc_node_t; 
 22300 |       typedef details::for_loop_bc_node<T>                   for_loop_bc_node_t; 
 22301 |       typedef details::while_loop_bc_rtc_node<T>             while_loop_bc_rtc_node_t; 
 22302 |       typedef details::repeat_until_loop_bc_rtc_node<T>      repeat_until_loop_bc_rtc_node_t; 
 22303 |       typedef details::for_loop_bc_rtc_node<T>               for_loop_bc_rtc_node_t; 
 22304 |       #endif 
 22305 |       typedef details::switch_node<T>                        switch_node_t; 
 22306 |       typedef details::variable_node<T>                      variable_node_t; 
 22307 |       typedef details::vector_elem_node<T>                   vector_elem_node_t; 
 22308 |       typedef details::vector_celem_node<T>                  vector_celem_node_t; 
 22309 |       typedef details::vector_elem_rtc_node<T>               vector_elem_rtc_node_t; 
 22310 |       typedef details::vector_celem_rtc_node<T>              vector_celem_rtc_node_t; 
 22311 |       typedef details::rebasevector_elem_node<T>             rebasevector_elem_node_t; 
 22312 |       typedef details::rebasevector_celem_node<T>            rebasevector_celem_node_t; 
 22313 |       typedef details::rebasevector_elem_rtc_node<T>         rebasevector_elem_rtc_node_t; 
 22314 |       typedef details::rebasevector_celem_rtc_node<T>        rebasevector_celem_rtc_node_t; 
 22315 |       typedef details::vector_node<T>                        vector_node_t; 
 22316 |       typedef details::vector_size_node<T>                   vector_size_node_t; 
 22317 |       typedef details::range_pack<T>                         range_t; 
 22318 |       #ifndef exprtk_disable_string_capabilities 
 22319 |       typedef details::stringvar_node<T>                     stringvar_node_t; 
 22320 |       typedef details::string_literal_node<T>                string_literal_node_t; 
 22321 |       typedef details::string_range_node<T>                  string_range_node_t; 
 22322 |       typedef details::const_string_range_node<T>            const_string_range_node_t; 
 22323 |       typedef details::generic_string_range_node<T>          generic_string_range_node_t; 
 22324 |       typedef details::string_concat_node<T>                 string_concat_node_t; 
 22325 |       typedef details::assignment_string_node<T>             assignment_string_node_t; 
 22326 |       typedef details::assignment_string_range_node<T>       assignment_string_range_node_t; 
 22327 |       typedef details::conditional_string_node<T>            conditional_string_node_t; 
 22328 |       typedef details::cons_conditional_str_node<T>          cons_conditional_str_node_t; 
 22329 |       #endif 
 22330 |       typedef details::assignment_node<T>                    assignment_node_t; 
 22331 |       typedef details::assignment_vec_elem_node<T>           assignment_vec_elem_node_t; 
 22332 |       typedef details::assignment_vec_elem_rtc_node<T>       assignment_vec_elem_rtc_node_t; 
 22333 |       typedef details::assignment_rebasevec_elem_node<T>     assignment_rebasevec_elem_node_t; 
 22334 |       typedef details::assignment_rebasevec_elem_rtc_node<T> assignment_rebasevec_elem_rtc_node_t; 
 22335 |       typedef details::assignment_rebasevec_celem_node<T>    assignment_rebasevec_celem_node_t; 
 22336 |       typedef details::assignment_vec_node<T>                assignment_vec_node_t; 
 22337 |       typedef details::assignment_vecvec_node<T>             assignment_vecvec_node_t; 
 22338 |       typedef details::conditional_vector_node<T>            conditional_vector_node_t; 
 22339 |       typedef details::scand_node<T>                         scand_node_t; 
 22340 |       typedef details::scor_node<T>                          scor_node_t; 
 22341 |       typedef lexer::token                                   token_t; 
 22342 |       typedef expression_node_t*                             expression_node_ptr; 
 22343 |       typedef expression<T>                                  expression_t; 
 22344 |       typedef symbol_table<T>                                symbol_table_t; 
 22345 |       typedef typename expression<T>::symtab_list_t          symbol_table_list_t; 
 22346 |       typedef details::vector_holder<T>                      vector_holder_t; 
 22347 |       typedef vector_holder_t*                               vector_holder_ptr; 
 22348 |  
 22349 |       typedef typename details::functor_t<T> functor_t; 
 22350 |       typedef typename functor_t::qfunc_t    quaternary_functor_t; 
 22351 |       typedef typename functor_t::tfunc_t    trinary_functor_t; 
 22352 |       typedef typename functor_t::bfunc_t    binary_functor_t; 
 22353 |       typedef typename functor_t::ufunc_t    unary_functor_t; 
 22354 |  
 22355 |       typedef details::operator_type operator_t; 
 22356 |  
 22357 |       typedef std::map<operator_t, unary_functor_t  > unary_op_map_t; 
 22358 |       typedef std::map<operator_t, binary_functor_t > binary_op_map_t; 
 22359 |       typedef std::map<operator_t, trinary_functor_t> trinary_op_map_t; 
 22360 |  
 22361 |       typedef std::map<std::string,std::pair<trinary_functor_t   ,operator_t> > sf3_map_t; 
 22362 |       typedef std::map<std::string,std::pair<quaternary_functor_t,operator_t> > sf4_map_t; 
 22363 |  
 22364 |       typedef std::map<binary_functor_t,operator_t> inv_binary_op_map_t; 
 22365 |       typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_t; 
 22366 |       typedef std::set<std::string,details::ilesscompare> disabled_func_set_t; 
 22367 |  
 22368 |       typedef details::T0oT1_define<T, cref_t , cref_t > vov_t; 
 22369 |       typedef details::T0oT1_define<T, const_t, cref_t > cov_t; 
 22370 |       typedef details::T0oT1_define<T, cref_t , const_t> voc_t; 
 22371 |  
 22372 |       typedef details::T0oT1oT2_define<T, cref_t , cref_t , cref_t > vovov_t; 
 22373 |       typedef details::T0oT1oT2_define<T, cref_t , cref_t , const_t> vovoc_t; 
 22374 |       typedef details::T0oT1oT2_define<T, cref_t , const_t, cref_t > vocov_t; 
 22375 |       typedef details::T0oT1oT2_define<T, const_t, cref_t , cref_t > covov_t; 
 22376 |       typedef details::T0oT1oT2_define<T, const_t, cref_t , const_t> covoc_t; 
 22377 |       typedef details::T0oT1oT2_define<T, const_t, const_t, cref_t > cocov_t; 
 22378 |       typedef details::T0oT1oT2_define<T, cref_t , const_t, const_t> vococ_t; 
 22379 |  
 22380 |       typedef details::T0oT1oT2oT3_define<T, cref_t , cref_t , cref_t , cref_t > vovovov_t; 
 22381 |       typedef details::T0oT1oT2oT3_define<T, cref_t , cref_t , cref_t , const_t> vovovoc_t; 
 22382 |       typedef details::T0oT1oT2oT3_define<T, cref_t , cref_t , const_t, cref_t > vovocov_t; 
 22383 |       typedef details::T0oT1oT2oT3_define<T, cref_t , const_t, cref_t , cref_t > vocovov_t; 
 22384 |       typedef details::T0oT1oT2oT3_define<T, const_t, cref_t , cref_t , cref_t > covovov_t; 
 22385 |  
 22386 |       typedef details::T0oT1oT2oT3_define<T, const_t, cref_t , const_t, cref_t > covocov_t; 
 22387 |       typedef details::T0oT1oT2oT3_define<T, cref_t , const_t, cref_t , const_t> vocovoc_t; 
 22388 |       typedef details::T0oT1oT2oT3_define<T, const_t, cref_t , cref_t , const_t> covovoc_t; 
 22389 |       typedef details::T0oT1oT2oT3_define<T, cref_t , const_t, const_t, cref_t > vococov_t; 
 22390 |  
 22391 |       typedef results_context<T> results_context_t; 
 22392 |  
 22393 |       typedef parser_helper prsrhlpr_t; 
 22394 |  
 22395 |       struct scope_element 
 22396 |       { 
 22397 |          enum element_type 
 22398 |          { 
 22399 |             e_none    , 
 22400 |             e_literal , 
 22401 |             e_variable, 
 22402 |             e_vector  , 
 22403 |             e_vecelem , 
 22404 |             e_string 
 22405 |          }; 
 22406 |  
 22407 |          typedef details::vector_holder<T> vector_holder_t; 
 22408 |          typedef literal_node_t*           literal_node_ptr; 
 22409 |          typedef variable_node_t*          variable_node_ptr; 
 22410 |          typedef vector_holder_t*          vector_holder_ptr; 
 22411 |          typedef expression_node_t*        expression_node_ptr; 
 22412 |          #ifndef exprtk_disable_string_capabilities 
 22413 |          typedef stringvar_node_t*         stringvar_node_ptr; 
 22414 |          #endif 
 22415 |  
 22416 |          scope_element() 
 22417 |          : name("???") 
 22418 |          , size (std::numeric_limits<std::size_t>::max()) 
 22419 |          , index(std::numeric_limits<std::size_t>::max()) 
 22420 |          , depth(std::numeric_limits<std::size_t>::max()) 
 22421 |          , ref_count(0) 
 22422 |          , ip_index (0) 
 22423 |          , type     (e_none) 
 22424 |          , active   (false) 
 22425 |          , data     (0) 
 22426 |          , var_node (0) 
 22427 |          , vec_node (0) 
 22428 |          #ifndef exprtk_disable_string_capabilities 
 22429 |          , str_node(0) 
 22430 |          #endif 
 22431 |          {} 
 22432 |  
 22433 |          bool operator < (const scope_element& se) const 
 22434 |          { 
 22435 |             if (ip_index < se.ip_index) 
 22436 |                return true; 
 22437 |             else if (ip_index > se.ip_index) 
 22438 |                return false; 
 22439 |             else if (depth < se.depth) 
 22440 |                return true; 
 22441 |             else if (depth > se.depth) 
 22442 |                return false; 
 22443 |             else if (index < se.index) 
 22444 |                return true; 
 22445 |             else if (index > se.index) 
 22446 |                return false; 
 22447 |             else 
 22448 |                return (name < se.name); 
 22449 |          } 
 22450 |  
 22451 |          void clear() 
 22452 |          { 
 22453 |             name   = "???" 
 22454 |             size   = std::numeric_limits<std::size_t>::max(); 
 22455 |             index  = std::numeric_limits<std::size_t>::max(); 
 22456 |             depth  = std::numeric_limits<std::size_t>::max(); 
 22457 |             type   = e_none; 
 22458 |             active = false; 
 22459 |             ref_count = 0; 
 22460 |             ip_index  = 0; 
 22461 |             data      = 0; 
 22462 |             var_node  = 0; 
 22463 |             vec_node  = 0; 
 22464 |             #ifndef exprtk_disable_string_capabilities 
 22465 |             str_node  = 0; 
 22466 |             #endif 
 22467 |          } 
 22468 |  
 22469 |          std::string  name; 
 22470 |          std::size_t  size; 
 22471 |          std::size_t  index; 
 22472 |          std::size_t  depth; 
 22473 |          std::size_t  ref_count; 
 22474 |          std::size_t  ip_index; 
 22475 |          element_type type; 
 22476 |          bool         active; 
 22477 |          void*        data; 
 22478 |          expression_node_ptr var_node; 
 22479 |          vector_holder_ptr   vec_node; 
 22480 |          #ifndef exprtk_disable_string_capabilities 
 22481 |          stringvar_node_ptr str_node; 
 22482 |          #endif 
 22483 |       }; 
 22484 |  
 22485 |       class scope_element_manager 
 22486 |       { 
 22487 |       public: 
 22488 |  
 22489 |          typedef expression_node_t* expression_node_ptr; 
 22490 |          typedef variable_node_t*   variable_node_ptr; 
 22491 |          typedef parser<T>          parser_t; 
 22492 |  
 22493 |          explicit scope_element_manager(parser<T>& p) 
 22494 |          : parser_(p) 
 22495 |          , input_param_cnt_(0) 
 22496 |          , total_local_symb_size_bytes_(0) 
 22497 |          {} 
 22498 |  
 22499 |          inline std::size_t size() const 
 22500 |          { 
 22501 |             return element_.size(); 
 22502 |          } 
 22503 |  
 22504 |          inline bool empty() const 
 22505 |          { 
 22506 |             return element_.empty(); 
 22507 |          } 
 22508 |  
 22509 |          inline scope_element& get_element(const std::size_t& index) 
 22510 |          { 
 22511 |             if (index < element_.size()) 
 22512 |                return element_[index]; 
 22513 |             else 
 22514 |                return null_element_; 
 22515 |          } 
 22516 |  
 22517 |          inline scope_element& get_element(const std::string& var_name, 
 22518 |                                            const std::size_t index = std::numeric_limits<std::size_t>::max()) 
 22519 |          { 
 22520 |             const std::size_t current_depth = parser_.state_.scope_depth; 
 22521 |  
 22522 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22523 |             { 
 22524 |                scope_element& se = element_[i]; 
 22525 |  
 22526 |                if (se.depth > current_depth) 
 22527 |                   continue; 
 22528 |                else if ( 
 22529 |                          details::imatch(se.name, var_name) && 
 22530 |                          (se.index == index) 
 22531 |                        ) 
 22532 |                   return se; 
 22533 |             } 
 22534 |  
 22535 |             return null_element_; 
 22536 |          } 
 22537 |  
 22538 |          inline scope_element& get_active_element(const std::string& var_name, 
 22539 |                                                   const std::size_t index = std::numeric_limits<std::size_t>::max()) 
 22540 |          { 
 22541 |             const std::size_t current_depth = parser_.state_.scope_depth; 
 22542 |  
 22543 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22544 |             { 
 22545 |                scope_element& se = element_[i]; 
 22546 |  
 22547 |                if (se.depth > current_depth) 
 22548 |                   continue; 
 22549 |                else if ( 
 22550 |                          details::imatch(se.name, var_name) && 
 22551 |                          (se.index == index)                && 
 22552 |                          (se.active) 
 22553 |                        ) 
 22554 |                   return se; 
 22555 |             } 
 22556 |  
 22557 |             return null_element_; 
 22558 |          } 
 22559 |  
 22560 |          inline bool add_element(const scope_element& se) 
 22561 |          { 
 22562 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22563 |             { 
 22564 |                scope_element& cse = element_[i]; 
 22565 |  
 22566 |                if ( 
 22567 |                     details::imatch(cse.name, se.name) && 
 22568 |                     (cse.depth <= se.depth)            && 
 22569 |                     (cse.index == se.index)            && 
 22570 |                     (cse.size  == se.size )            && 
 22571 |                     (cse.type  == se.type )            && 
 22572 |                     (cse.active) 
 22573 |                   ) 
 22574 |                   return false; 
 22575 |             } 
 22576 |  
 22577 |             switch (se.type) 
 22578 |             { 
 22579 |                case scope_element::e_variable : total_local_symb_size_bytes_ += sizeof(T); 
 22580 |                                                 break; 
 22581 |  
 22582 |                case scope_element::e_literal  : total_local_symb_size_bytes_ += sizeof(T); 
 22583 |                                                 break; 
 22584 |  
 22585 |                case scope_element::e_vector   : total_local_symb_size_bytes_ += sizeof(T) * se.size; 
 22586 |                                                 break; 
 22587 |  
 22588 |                default                        : break; 
 22589 |             } 
 22590 |  
 22591 |             element_.push_back(se); 
 22592 |             std::sort(element_.begin(),element_.end()); 
 22593 |  
 22594 |             return true; 
 22595 |          } 
 22596 |  
 22597 |          inline void deactivate(const std::size_t& scope_depth) 
 22598 |          { 
 22599 |             exprtk_debug(("deactivate() - Scope depth: %d\n", 
 22600 |                           static_cast<int>(parser_.state_.scope_depth))); 
 22601 |  
 22602 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22603 |             { 
 22604 |                scope_element& se = element_[i]; 
 22605 |  
 22606 |                if (se.active && (se.depth >= scope_depth)) 
 22607 |                { 
 22608 |                   exprtk_debug(("deactivate() - element[%02d] '%s'\n", 
 22609 |                                 static_cast<int>(i), 
 22610 |                                 se.name.c_str())); 
 22611 |  
 22612 |                   se.active = false; 
 22613 |                } 
 22614 |             } 
 22615 |          } 
 22616 |  
 22617 |          inline void free_element(scope_element& se) 
 22618 |          { 
 22619 |             exprtk_debug(("free_element() - se[%s]\n", se.name.c_str())); 
 22620 |  
 22621 |             switch (se.type) 
 22622 |             { 
 22623 |                case scope_element::e_literal    : delete reinterpret_cast<T*>(se.data); 
 22624 |                                                   delete se.var_node; 
 22625 |                                                   break; 
 22626 |  
 22627 |                case scope_element::e_variable   : delete reinterpret_cast<T*>(se.data); 
 22628 |                                                   delete se.var_node; 
 22629 |                                                   break; 
 22630 |  
 22631 |                case scope_element::e_vector     : delete[] reinterpret_cast<T*>(se.data); 
 22632 |                                                   delete se.vec_node; 
 22633 |                                                   break; 
 22634 |  
 22635 |                case scope_element::e_vecelem    : delete se.var_node; 
 22636 |                                                   break; 
 22637 |  
 22638 |                #ifndef exprtk_disable_string_capabilities 
 22639 |                case scope_element::e_string     : delete reinterpret_cast<std::string*>(se.data); 
 22640 |                                                   delete se.str_node; 
 22641 |                                                   break; 
 22642 |                #endif 
 22643 |  
 22644 |                default                          : return; 
 22645 |             } 
 22646 |  
 22647 |             se.clear(); 
 22648 |          } 
 22649 |  
 22650 |          inline void cleanup() 
 22651 |          { 
 22652 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22653 |             { 
 22654 |                free_element(element_[i]); 
 22655 |             } 
 22656 |  
 22657 |             element_.clear(); 
 22658 |  
 22659 |             input_param_cnt_             = 0; 
 22660 |             total_local_symb_size_bytes_ = 0; 
 22661 |          } 
 22662 |  
 22663 |          inline std::size_t total_local_symb_size_bytes() const 
 22664 |          { 
 22665 |             return total_local_symb_size_bytes_; 
 22666 |          } 
 22667 |  
 22668 |          inline std::size_t next_ip_index() 
 22669 |          { 
 22670 |             return ++input_param_cnt_; 
 22671 |          } 
 22672 |  
 22673 |          inline expression_node_ptr get_variable(const T& v) 
 22674 |          { 
 22675 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22676 |             { 
 22677 |                scope_element& se = element_[i]; 
 22678 |  
 22679 |                if ( 
 22680 |                     se.active   && 
 22681 |                     se.var_node && 
 22682 |                     details::is_variable_node(se.var_node) 
 22683 |                   ) 
 22684 |                { 
 22685 |                   variable_node_ptr vn = reinterpret_cast<variable_node_ptr>(se.var_node); 
 22686 |  
 22687 |                   if (&(vn->ref()) == (&v)) 
 22688 |                   { 
 22689 |                      return se.var_node; 
 22690 |                   } 
 22691 |                } 
 22692 |             } 
 22693 |  
 22694 |             return expression_node_ptr(0); 
 22695 |          } 
 22696 |  
 22697 |          inline std::string get_vector_name(const T* data) 
 22698 |          { 
 22699 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22700 |             { 
 22701 |                scope_element& se = element_[i]; 
 22702 |  
 22703 |                if ( 
 22704 |                     se.active   && 
 22705 |                     se.vec_node && 
 22706 |                     (se.vec_node->data() == data) 
 22707 |                   ) 
 22708 |                { 
 22709 |                   return se.name; 
 22710 |                } 
 22711 |             } 
 22712 |  
 22713 |             return "neo-vector" 
 22714 |          } 
 22715 |  
 22716 |       private: 
 22717 |  
 22718 |          scope_element_manager(const scope_element_manager&) exprtk_delete; 
 22719 |          scope_element_manager& operator=(const scope_element_manager&) exprtk_delete; 
 22720 |  
 22721 |          parser_t& parser_; 
 22722 |          std::vector<scope_element> element_; 
 22723 |          scope_element null_element_; 
 22724 |          std::size_t input_param_cnt_; 
 22725 |          std::size_t total_local_symb_size_bytes_; 
 22726 |       }; 
 22727 |  
 22728 |       class scope_handler 
 22729 |       { 
 22730 |       public: 
 22731 |  
 22732 |          typedef parser<T> parser_t; 
 22733 |  
 22734 |          explicit scope_handler(parser<T>& p) 
 22735 |          : parser_(p) 
 22736 |          { 
 22737 |             parser_.state_.scope_depth++; 
 22738 |             #ifdef exprtk_enable_debugging 
 22739 |             const std::string depth(2 * parser_.state_.scope_depth,'-'); 
 22740 |             exprtk_debug(("%s> Scope Depth: %02d\n", 
 22741 |                           depth.c_str(), 
 22742 |                           static_cast<int>(parser_.state_.scope_depth))); 
 22743 |             #endif 
 22744 |          } 
 22745 |  
 22746 |         ~scope_handler() 
 22747 |          { 
 22748 |             parser_.sem_.deactivate(parser_.state_.scope_depth); 
 22749 |             parser_.state_.scope_depth--; 
 22750 |             #ifdef exprtk_enable_debugging 
 22751 |             const std::string depth(2 * parser_.state_.scope_depth,'-'); 
 22752 |             exprtk_debug(("<%s Scope Depth: %02d\n", 
 22753 |                           depth.c_str(), 
 22754 |                           static_cast<int>(parser_.state_.scope_depth))); 
 22755 |             #endif 
 22756 |          } 
 22757 |  
 22758 |       private: 
 22759 |  
 22760 |          scope_handler(const scope_handler&) exprtk_delete; 
 22761 |          scope_handler& operator=(const scope_handler&) exprtk_delete; 
 22762 |  
 22763 |          parser_t& parser_; 
 22764 |       }; 
 22765 |  
 22766 |       template <typename T_> 
 22767 |       struct halfopen_range_policy 
 22768 |       { 
 22769 |          static inline bool is_within(const T_& v, const T_& begin, const T_& end) 
 22770 |          { 
 22771 |             assert(begin <= end); 
 22772 |             return (begin <= v) && (v < end); 
 22773 |          } 
 22774 |  
 22775 |          static inline bool is_less(const T_& v, const T_& begin) 
 22776 |          { 
 22777 |             return (v < begin); 
 22778 |          } 
 22779 |  
 22780 |          static inline bool is_greater(const T_& v, const T_& end) 
 22781 |          { 
 22782 |             return (end <= v); 
 22783 |          } 
 22784 |  
 22785 |          static inline bool end_inclusive() 
 22786 |          { 
 22787 |             return false; 
 22788 |          } 
 22789 |       }; 
 22790 |  
 22791 |       template <typename T_> 
 22792 |       struct closed_range_policy 
 22793 |       { 
 22794 |          static inline bool is_within(const T_& v, const T_& begin, const T_& end) 
 22795 |          { 
 22796 |             assert(begin <= end); 
 22797 |             return (begin <= v) && (v <= end); 
 22798 |          } 
 22799 |  
 22800 |          static inline bool is_less(const T_& v, const T_& begin) 
 22801 |          { 
 22802 |             return (v < begin); 
 22803 |          } 
 22804 |  
 22805 |          static inline bool is_greater(const T_& v, const T_& end) 
 22806 |          { 
 22807 |             return (end < v); 
 22808 |          } 
 22809 |  
 22810 |          static inline bool end_inclusive() 
 22811 |          { 
 22812 |             return true; 
 22813 |          } 
 22814 |       }; 
 22815 |  
 22816 |       template <typename IntervalPointType, 
 22817 |                 typename RangePolicy = halfopen_range_policy<IntervalPointType> > 
 22818 |       class interval_container_t 
 22819 |       { 
 22820 |       public: 
 22821 |  
 22822 |          typedef IntervalPointType interval_point_t; 
 22823 |          typedef std::pair<interval_point_t, interval_point_t> interval_t; 
 22824 |          typedef std::map<interval_point_t, interval_t> interval_map_t; 
 22825 |          typedef typename interval_map_t::const_iterator interval_map_citr_t; 
 22826 |  
 22827 |          std::size_t size() const 
 22828 |          { 
 22829 |             return interval_map_.size(); 
 22830 |          } 
 22831 |  
 22832 |          void reset() 
 22833 |          { 
 22834 |             interval_map_.clear(); 
 22835 |          } 
 22836 |  
 22837 |          bool in_interval(const interval_point_t point, interval_t& interval) const 
 22838 |          { 
 22839 |             interval_map_citr_t itr = RangePolicy::end_inclusive() ? 
 22840 |                                       interval_map_.lower_bound(point): 
 22841 |                                       interval_map_.upper_bound(point); 
 22842 |  
 22843 |             for (; itr != interval_map_.end(); ++itr) 
 22844 |             { 
 22845 |                const interval_point_t& begin = itr->second.first; 
 22846 |                const interval_point_t& end   = itr->second.second; 
 22847 |  
 22848 |                if (RangePolicy::is_within(point, begin, end)) 
 22849 |                { 
 22850 |                   interval = interval_t(begin,end); 
 22851 |                   return true; 
 22852 |                } 
 22853 |                else if (RangePolicy::is_greater(point, end)) 
 22854 |                { 
 22855 |                   break; 
 22856 |                } 
 22857 |             } 
 22858 |  
 22859 |             return false; 
 22860 |          } 
 22861 |  
 22862 |          bool in_interval(const interval_point_t point) const 
 22863 |          { 
 22864 |             interval_t interval; 
 22865 |             return in_interval(point,interval); 
 22866 |          } 
 22867 |  
 22868 |          bool add_interval(const interval_point_t begin, const interval_point_t end) 
 22869 |          { 
 22870 |             if ((end <= begin) || in_interval(begin) || in_interval(end)) 
 22871 |             { 
 22872 |                return false; 
 22873 |             } 
 22874 |  
 22875 |             interval_map_[end] = std::make_pair(begin, end); 
 22876 |  
 22877 |             return true; 
 22878 |          } 
 22879 |  
 22880 |          bool add_interval(const interval_t interval) 
 22881 |          { 
 22882 |             return add_interval(interval.first, interval.second); 
 22883 |          } 
 22884 |  
 22885 |       private: 
 22886 |  
 22887 |          interval_map_t interval_map_; 
 22888 |       }; 
 22889 |  
 22890 |       class stack_limit_handler 
 22891 |       { 
 22892 |       public: 
 22893 |  
 22894 |          typedef parser<T> parser_t; 
 22895 |  
 22896 |          explicit stack_limit_handler(parser<T>& p) 
 22897 |          : parser_(p) 
 22898 |          , limit_exceeded_(false) 
 22899 |          { 
 22900 |             if (++parser_.state_.stack_depth > parser_.settings_.max_stack_depth_) 
 22901 |             { 
 22902 |                limit_exceeded_ = true; 
 22903 |                parser_.set_error(make_error( 
 22904 |                   parser_error::e_parser, 
 22905 |                   "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) + 
 22906 |                   " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_), 
 22907 |                   exprtk_error_location)); 
 22908 |             } 
 22909 |          } 
 22910 |  
 22911 |         ~stack_limit_handler() 
 22912 |          { 
 22913 |             assert(parser_.state_.stack_depth > 0); 
 22914 |             parser_.state_.stack_depth--; 
 22915 |          } 
 22916 |  
 22917 |          bool operator!() 
 22918 |          { 
 22919 |             return limit_exceeded_; 
 22920 |          } 
 22921 |  
 22922 |       private: 
 22923 |  
 22924 |          stack_limit_handler(const stack_limit_handler&) exprtk_delete; 
 22925 |          stack_limit_handler& operator=(const stack_limit_handler&) exprtk_delete; 
 22926 |  
 22927 |          parser_t& parser_; 
 22928 |          bool limit_exceeded_; 
 22929 |       }; 
 22930 |  
 22931 |       struct symtab_store 
 22932 |       { 
 22933 |          symbol_table_list_t symtab_list_; 
 22934 |  
 22935 |          typedef typename symbol_table_t::local_data_t local_data_t; 
 22936 |          typedef typename symbol_table_t::variable_ptr variable_ptr; 
 22937 |          typedef typename symbol_table_t::function_ptr function_ptr; 
 22938 |          #ifndef exprtk_disable_string_capabilities 
 22939 |          typedef typename symbol_table_t::stringvar_ptr stringvar_ptr; 
 22940 |          #endif 
 22941 |          typedef typename symbol_table_t::vector_holder_ptr    vector_holder_ptr; 
 22942 |          typedef typename symbol_table_t::vararg_function_ptr  vararg_function_ptr; 
 22943 |          typedef typename symbol_table_t::generic_function_ptr generic_function_ptr; 
 22944 |  
 22945 |          struct variable_context 
 22946 |          { 
 22947 |             variable_context() 
 22948 |             : symbol_table(0) 
 22949 |             , variable(0) 
 22950 |             {} 
 22951 |  
 22952 |             const symbol_table_t* symbol_table; 
 22953 |             variable_ptr variable; 
 22954 |          }; 
 22955 |  
 22956 |          struct vector_context 
 22957 |          { 
 22958 |             vector_context() 
 22959 |             : symbol_table(0) 
 22960 |             , vector_holder(0) 
 22961 |             {} 
 22962 |  
 22963 |             const symbol_table_t* symbol_table; 
 22964 |             vector_holder_ptr vector_holder; 
 22965 |          }; 
 22966 |  
 22967 |          #ifndef exprtk_disable_string_capabilities 
 22968 |          struct string_context 
 22969 |          { 
 22970 |             string_context() 
 22971 |             : symbol_table(0) 
 22972 |             , str_var(0) 
 22973 |             {} 
 22974 |  
 22975 |             const symbol_table_t* symbol_table; 
 22976 |             stringvar_ptr str_var; 
 22977 |          }; 
 22978 |          #endif 
 22979 |  
 22980 |          inline bool empty() const 
 22981 |          { 
 22982 |             return symtab_list_.empty(); 
 22983 |          } 
 22984 |  
 22985 |          inline void clear() 
 22986 |          { 
 22987 |             symtab_list_.clear(); 
 22988 |          } 
 22989 |  
 22990 |          inline bool valid() const 
 22991 |          { 
 22992 |             if (!empty()) 
 22993 |             { 
 22994 |                for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 22995 |                { 
 22996 |                   if (symtab_list_[i].valid()) 
 22997 |                      return true; 
 22998 |                } 
 22999 |             } 
 23000 |  
 23001 |             return false; 
 23002 |          } 
 23003 |  
 23004 |          inline bool valid_symbol(const std::string& symbol) const 
 23005 |          { 
 23006 |             if (!symtab_list_.empty()) 
 23007 |                return symtab_list_[0].valid_symbol(symbol); 
 23008 |             else 
 23009 |                return false; 
 23010 |          } 
 23011 |  
 23012 |          inline bool valid_function_name(const std::string& symbol) const 
 23013 |          { 
 23014 |             if (!symtab_list_.empty()) 
 23015 |                return symtab_list_[0].valid_function(symbol); 
 23016 |             else 
 23017 |                return false; 
 23018 |          } 
 23019 |  
 23020 |          inline variable_context get_variable_context(const std::string& variable_name) const 
 23021 |          { 
 23022 |             variable_context result; 
 23023 |  
 23024 |             if (valid_symbol(variable_name)) 
 23025 |             { 
 23026 |                for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23027 |                { 
 23028 |                   if (!symtab_list_[i].valid()) 
 23029 |                   { 
 23030 |                      continue; 
 23031 |                   } 
 23032 |  
 23033 |                   result.variable = local_data(i) 
 23034 |                                        .variable_store.get(variable_name); 
 23035 |                   if (result.variable) 
 23036 |                   { 
 23037 |                      result.symbol_table = &symtab_list_[i]; 
 23038 |                      break; 
 23039 |                   } 
 23040 |                } 
 23041 |             } 
 23042 |  
 23043 |             return result; 
 23044 |          } 
 23045 |  
 23046 |          inline variable_ptr get_variable(const std::string& variable_name) const 
 23047 |          { 
 23048 |             if (!valid_symbol(variable_name)) 
 23049 |                return reinterpret_cast<variable_ptr>(0); 
 23050 |  
 23051 |             variable_ptr result = reinterpret_cast<variable_ptr>(0); 
 23052 |  
 23053 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23054 |             { 
 23055 |                if (!symtab_list_[i].valid()) 
 23056 |                   continue; 
 23057 |                else 
 23058 |                   result = local_data(i) 
 23059 |                               .variable_store.get(variable_name); 
 23060 |  
 23061 |                if (result) break; 
 23062 |             } 
 23063 |  
 23064 |             return result; 
 23065 |          } 
 23066 |  
 23067 |          inline variable_ptr get_variable(const T& var_ref) const 
 23068 |          { 
 23069 |             variable_ptr result = reinterpret_cast<variable_ptr>(0); 
 23070 |  
 23071 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23072 |             { 
 23073 |                if (!symtab_list_[i].valid()) 
 23074 |                   continue; 
 23075 |                else 
 23076 |                   result = local_data(i).variable_store 
 23077 |                               .get_from_varptr(reinterpret_cast<const void*>(&var_ref)); 
 23078 |  
 23079 |                if (result) break; 
 23080 |             } 
 23081 |  
 23082 |             return result; 
 23083 |          } 
 23084 |  
 23085 |          #ifndef exprtk_disable_string_capabilities 
 23086 |          inline string_context get_string_context(const std::string& string_name) const 
 23087 |          { 
 23088 |             string_context result; 
 23089 |  
 23090 |             if (!valid_symbol(string_name)) 
 23091 |                return result; 
 23092 |  
 23093 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23094 |             { 
 23095 |                if (!symtab_list_[i].valid()) 
 23096 |                { 
 23097 |                   continue; 
 23098 |                } 
 23099 |  
 23100 |                result.str_var = local_data(i).stringvar_store.get(string_name); 
 23101 |  
 23102 |                if (result.str_var) 
 23103 |                { 
 23104 |                   result.symbol_table = &symtab_list_[i]; 
 23105 |                   break; 
 23106 |                } 
 23107 |             } 
 23108 |  
 23109 |             return result; 
 23110 |          } 
 23111 |  
 23112 |          inline stringvar_ptr get_stringvar(const std::string& string_name) const 
 23113 |          { 
 23114 |             if (!valid_symbol(string_name)) 
 23115 |                return reinterpret_cast<stringvar_ptr>(0); 
 23116 |  
 23117 |             stringvar_ptr result = reinterpret_cast<stringvar_ptr>(0); 
 23118 |  
 23119 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23120 |             { 
 23121 |                if (!symtab_list_[i].valid()) 
 23122 |                   continue; 
 23123 |                else 
 23124 |                   result = local_data(i) 
 23125 |                               .stringvar_store.get(string_name); 
 23126 |  
 23127 |                if (result) break; 
 23128 |             } 
 23129 |  
 23130 |             return result; 
 23131 |          } 
 23132 |          #endif 
 23133 |  
 23134 |          inline function_ptr get_function(const std::string& function_name) const 
 23135 |          { 
 23136 |             if (!valid_function_name(function_name)) 
 23137 |                return reinterpret_cast<function_ptr>(0); 
 23138 |  
 23139 |             function_ptr result = reinterpret_cast<function_ptr>(0); 
 23140 |  
 23141 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23142 |             { 
 23143 |                if (!symtab_list_[i].valid()) 
 23144 |                   continue; 
 23145 |                else 
 23146 |                   result = local_data(i) 
 23147 |                               .function_store.get(function_name); 
 23148 |  
 23149 |                if (result) break; 
 23150 |             } 
 23151 |  
 23152 |             return result; 
 23153 |          } 
 23154 |  
 23155 |          inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const 
 23156 |          { 
 23157 |             if (!valid_function_name(vararg_function_name)) 
 23158 |                return reinterpret_cast<vararg_function_ptr>(0); 
 23159 |  
 23160 |             vararg_function_ptr result = reinterpret_cast<vararg_function_ptr>(0); 
 23161 |  
 23162 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23163 |             { 
 23164 |                if (!symtab_list_[i].valid()) 
 23165 |                   continue; 
 23166 |                else 
 23167 |                   result = local_data(i) 
 23168 |                               .vararg_function_store.get(vararg_function_name); 
 23169 |  
 23170 |                if (result) break; 
 23171 |             } 
 23172 |  
 23173 |             return result; 
 23174 |          } 
 23175 |  
 23176 |          inline generic_function_ptr get_generic_function(const std::string& function_name) const 
 23177 |          { 
 23178 |             if (!valid_function_name(function_name)) 
 23179 |                return reinterpret_cast<generic_function_ptr>(0); 
 23180 |  
 23181 |             generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0); 
 23182 |  
 23183 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23184 |             { 
 23185 |                if (!symtab_list_[i].valid()) 
 23186 |                   continue; 
 23187 |                else 
 23188 |                   result = local_data(i) 
 23189 |                               .generic_function_store.get(function_name); 
 23190 |  
 23191 |                if (result) break; 
 23192 |             } 
 23193 |  
 23194 |             return result; 
 23195 |          } 
 23196 |  
 23197 |          inline generic_function_ptr get_string_function(const std::string& function_name) const 
 23198 |          { 
 23199 |             if (!valid_function_name(function_name)) 
 23200 |                return reinterpret_cast<generic_function_ptr>(0); 
 23201 |  
 23202 |             generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0); 
 23203 |  
 23204 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23205 |             { 
 23206 |                if (!symtab_list_[i].valid()) 
 23207 |                   continue; 
 23208 |                else 
 23209 |                   result = 
 23210 |                      local_data(i).string_function_store.get(function_name); 
 23211 |  
 23212 |                if (result) break; 
 23213 |             } 
 23214 |  
 23215 |             return result; 
 23216 |          } 
 23217 |  
 23218 |          inline generic_function_ptr get_overload_function(const std::string& function_name) const 
 23219 |          { 
 23220 |             if (!valid_function_name(function_name)) 
 23221 |                return reinterpret_cast<generic_function_ptr>(0); 
 23222 |  
 23223 |             generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0); 
 23224 |  
 23225 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23226 |             { 
 23227 |                if (!symtab_list_[i].valid()) 
 23228 |                   continue; 
 23229 |                else 
 23230 |                   result = 
 23231 |                      local_data(i).overload_function_store.get(function_name); 
 23232 |  
 23233 |                if (result) break; 
 23234 |             } 
 23235 |  
 23236 |             return result; 
 23237 |          } 
 23238 |  
 23239 |          inline vector_context get_vector_context(const std::string& vector_name) const 
 23240 |          { 
 23241 |             vector_context result; 
 23242 |             if (!valid_symbol(vector_name)) 
 23243 |                return result; 
 23244 |  
 23245 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23246 |             { 
 23247 |                if (!symtab_list_[i].valid()) 
 23248 |                { 
 23249 |                   continue; 
 23250 |                } 
 23251 |  
 23252 |                result.vector_holder = local_data(i).vector_store.get(vector_name); 
 23253 |  
 23254 |                if (result.vector_holder) 
 23255 |                { 
 23256 |                   result.symbol_table = &symtab_list_[i]; 
 23257 |                   break; 
 23258 |                } 
 23259 |             } 
 23260 |  
 23261 |             return result; 
 23262 |          } 
 23263 |  
 23264 |          inline vector_holder_ptr get_vector(const std::string& vector_name) const 
 23265 |          { 
 23266 |             if (!valid_symbol(vector_name)) 
 23267 |                return reinterpret_cast<vector_holder_ptr>(0); 
 23268 |  
 23269 |             vector_holder_ptr result = reinterpret_cast<vector_holder_ptr>(0); 
 23270 |  
 23271 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23272 |             { 
 23273 |                if (!symtab_list_[i].valid()) 
 23274 |                { 
 23275 |                   continue; 
 23276 |                } 
 23277 |  
 23278 |                result = local_data(i).vector_store.get(vector_name); 
 23279 |  
 23280 |                if (result) 
 23281 |                { 
 23282 |                   break; 
 23283 |                } 
 23284 |             } 
 23285 |  
 23286 |             return result; 
 23287 |          } 
 23288 |  
 23289 |          inline bool is_constant_node(const std::string& symbol_name) const 
 23290 |          { 
 23291 |             if (!valid_symbol(symbol_name)) 
 23292 |                return false; 
 23293 |  
 23294 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23295 |             { 
 23296 |                if (!symtab_list_[i].valid()) 
 23297 |                { 
 23298 |                   continue; 
 23299 |                } 
 23300 |  
 23301 |                if (local_data(i).variable_store.is_constant(symbol_name)) 
 23302 |                { 
 23303 |                   return true; 
 23304 |                } 
 23305 |             } 
 23306 |  
 23307 |             return false; 
 23308 |          } 
 23309 |  
 23310 |          #ifndef exprtk_disable_string_capabilities 
 23311 |          inline bool is_constant_string(const std::string& symbol_name) const 
 23312 |          { 
 23313 |             if (!valid_symbol(symbol_name)) 
 23314 |                return false; 
 23315 |  
 23316 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23317 |             { 
 23318 |                if (!symtab_list_[i].valid()) 
 23319 |                   continue; 
 23320 |                else if (!local_data(i).stringvar_store.symbol_exists(symbol_name)) 
 23321 |                   continue; 
 23322 |                else if (local_data(i).stringvar_store.is_constant(symbol_name)) 
 23323 |                   return true; 
 23324 |             } 
 23325 |  
 23326 |             return false; 
 23327 |          } 
 23328 |          #endif 
 23329 |  
 23330 |          inline bool symbol_exists(const std::string& symbol) const 
 23331 |          { 
 23332 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23333 |             { 
 23334 |                if (!symtab_list_[i].valid()) 
 23335 |                { 
 23336 |                   continue; 
 23337 |                } 
 23338 |  
 23339 |                if (symtab_list_[i].symbol_exists(symbol)) 
 23340 |                { 
 23341 |                   return true; 
 23342 |                } 
 23343 |             } 
 23344 |  
 23345 |             return false; 
 23346 |          } 
 23347 |  
 23348 |          inline bool is_variable(const std::string& variable_name) const 
 23349 |          { 
 23350 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23351 |             { 
 23352 |                if (!symtab_list_[i].valid()) 
 23353 |                   continue; 
 23354 |                else if ( 
 23355 |                          symtab_list_[i].local_data().variable_store 
 23356 |                            .symbol_exists(variable_name) 
 23357 |                        ) 
 23358 |                   return true; 
 23359 |             } 
 23360 |  
 23361 |             return false; 
 23362 |          } 
 23363 |  
 23364 |          #ifndef exprtk_disable_string_capabilities 
 23365 |          inline bool is_stringvar(const std::string& stringvar_name) const 
 23366 |          { 
 23367 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23368 |             { 
 23369 |                if (!symtab_list_[i].valid()) 
 23370 |                   continue; 
 23371 |                else if ( 
 23372 |                          symtab_list_[i].local_data().stringvar_store 
 23373 |                            .symbol_exists(stringvar_name) 
 23374 |                        ) 
 23375 |                   return true; 
 23376 |             } 
 23377 |  
 23378 |             return false; 
 23379 |          } 
 23380 |  
 23381 |          inline bool is_conststr_stringvar(const std::string& symbol_name) const 
 23382 |          { 
 23383 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23384 |             { 
 23385 |                if (!symtab_list_[i].valid()) 
 23386 |                   continue; 
 23387 |                else if ( 
 23388 |                          symtab_list_[i].local_data().stringvar_store 
 23389 |                            .symbol_exists(symbol_name) 
 23390 |                        ) 
 23391 |                { 
 23392 |                   return ( 
 23393 |                            local_data(i).stringvar_store.symbol_exists(symbol_name) || 
 23394 |                            local_data(i).stringvar_store.is_constant  (symbol_name) 
 23395 |                          ); 
 23396 |  
 23397 |                } 
 23398 |             } 
 23399 |  
 23400 |             return false; 
 23401 |          } 
 23402 |          #endif 
 23403 |  
 23404 |          inline bool is_function(const std::string& function_name) const 
 23405 |          { 
 23406 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23407 |             { 
 23408 |                if (!symtab_list_[i].valid()) 
 23409 |                   continue; 
 23410 |                else if ( 
 23411 |                          local_data(i).vararg_function_store 
 23412 |                            .symbol_exists(function_name) 
 23413 |                        ) 
 23414 |                   return true; 
 23415 |             } 
 23416 |  
 23417 |             return false; 
 23418 |          } 
 23419 |  
 23420 |          inline bool is_vararg_function(const std::string& vararg_function_name) const 
 23421 |          { 
 23422 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23423 |             { 
 23424 |                if (!symtab_list_[i].valid()) 
 23425 |                   continue; 
 23426 |                else if ( 
 23427 |                          local_data(i).vararg_function_store 
 23428 |                            .symbol_exists(vararg_function_name) 
 23429 |                        ) 
 23430 |                   return true; 
 23431 |             } 
 23432 |  
 23433 |             return false; 
 23434 |          } 
 23435 |  
 23436 |          inline bool is_vector(const std::string& vector_name) const 
 23437 |          { 
 23438 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23439 |             { 
 23440 |                if (!symtab_list_[i].valid()) 
 23441 |                   continue; 
 23442 |                else if ( 
 23443 |                          local_data(i).vector_store 
 23444 |                            .symbol_exists(vector_name) 
 23445 |                        ) 
 23446 |                   return true; 
 23447 |             } 
 23448 |  
 23449 |             return false; 
 23450 |          } 
 23451 |  
 23452 |          inline std::string get_variable_name(const expression_node_ptr& ptr) const 
 23453 |          { 
 23454 |             return local_data().variable_store.entity_name(ptr); 
 23455 |          } 
 23456 |  
 23457 |          inline std::string get_vector_name(const vector_holder_ptr& ptr) const 
 23458 |          { 
 23459 |             return local_data().vector_store.entity_name(ptr); 
 23460 |          } 
 23461 |  
 23462 |          #ifndef exprtk_disable_string_capabilities 
 23463 |          inline std::string get_stringvar_name(const expression_node_ptr& ptr) const 
 23464 |          { 
 23465 |             return local_data().stringvar_store.entity_name(ptr); 
 23466 |          } 
 23467 |  
 23468 |          inline std::string get_conststr_stringvar_name(const expression_node_ptr& ptr) const 
 23469 |          { 
 23470 |             return local_data().stringvar_store.entity_name(ptr); 
 23471 |          } 
 23472 |          #endif 
 23473 |  
 23474 |          inline local_data_t& local_data(const std::size_t& index = 0) 
 23475 |          { 
 23476 |             return symtab_list_[index].local_data(); 
 23477 |          } 
 23478 |  
 23479 |          inline const local_data_t& local_data(const std::size_t& index = 0) const 
 23480 |          { 
 23481 |             return symtab_list_[index].local_data(); 
 23482 |          } 
 23483 |  
 23484 |          inline symbol_table_t& get_symbol_table(const std::size_t& index = 0) 
 23485 |          { 
 23486 |             return symtab_list_[index]; 
 23487 |          } 
 23488 |       }; 
 23489 |  
 23490 |       struct parser_state 
 23491 |       { 
 23492 |          parser_state() 
 23493 |          : type_check_enabled(true) 
 23494 |          { 
 23495 |             reset(); 
 23496 |          } 
 23497 |  
 23498 |          void reset() 
 23499 |          { 
 23500 |             parsing_return_stmt     = false; 
 23501 |             parsing_break_stmt      = false; 
 23502 |             parsing_assert_stmt     = false; 
 23503 |             return_stmt_present     = false; 
 23504 |             side_effect_present     = false; 
 23505 |             scope_depth             = 0; 
 23506 |             stack_depth             = 0; 
 23507 |             parsing_loop_stmt_count = 0; 
 23508 |          } 
 23509 |  
 23510 |          #ifndef exprtk_enable_debugging 
 23511 |          void activate_side_effect(const std::string&) 
 23512 |          #else 
 23513 |          void activate_side_effect(const std::string& source) 
 23514 |          #endif 
 23515 |          { 
 23516 |             if (!side_effect_present) 
 23517 |             { 
 23518 |                side_effect_present = true; 
 23519 |  
 23520 |                exprtk_debug(("activate_side_effect() - caller: %s\n", source.c_str())); 
 23521 |             } 
 23522 |          } 
 23523 |  
 23524 |          bool parsing_return_stmt; 
 23525 |          bool parsing_break_stmt; 
 23526 |          bool parsing_assert_stmt; 
 23527 |          bool return_stmt_present; 
 23528 |          bool side_effect_present; 
 23529 |          bool type_check_enabled; 
 23530 |          std::size_t scope_depth; 
 23531 |          std::size_t stack_depth; 
 23532 |          std::size_t parsing_loop_stmt_count; 
 23533 |       }; 
 23534 |  
 23535 |    public: 
 23536 |  
 23537 |       struct unknown_symbol_resolver 
 23538 |       { 
 23539 |  
 23540 |          enum usr_symbol_type 
 23541 |          { 
 23542 |             e_usr_unknown_type  = 0, 
 23543 |             e_usr_variable_type = 1, 
 23544 |             e_usr_constant_type = 2 
 23545 |          }; 
 23546 |  
 23547 |          enum usr_mode 
 23548 |          { 
 23549 |             e_usrmode_default  = 0, 
 23550 |             e_usrmode_extended = 1 
 23551 |          }; 
 23552 |  
 23553 |          usr_mode mode; 
 23554 |  
 23555 |          explicit unknown_symbol_resolver(const usr_mode m = e_usrmode_default) 
 23556 |          : mode(m) 
 23557 |          {} 
 23558 |  
 23559 |          virtual ~unknown_symbol_resolver() 
 23560 |          {} 
 23561 |  
 23562 |          virtual bool process(const std::string& /*unknown_symbol*/, 
 23563 |                               usr_symbol_type&   st, 
 23564 |                               T&                 default_value, 
 23565 |                               std::string&       error_message) 
 23566 |          { 
 23567 |             if (e_usrmode_default != mode) 
 23568 |                return false; 
 23569 |  
 23570 |             st = e_usr_variable_type; 
 23571 |             default_value = T(0); 
 23572 |             error_message.clear(); 
 23573 |  
 23574 |             return true; 
 23575 |          } 
 23576 |  
 23577 |          virtual bool process(const std::string& /* unknown_symbol */, 
 23578 |                               symbol_table_t&    /* symbol_table   */, 
 23579 |                               std::string&       /* error_message  */) 
 23580 |          { 
 23581 |             return false; 
 23582 |          } 
 23583 |       }; 
 23584 |  
 23585 |       enum collect_type 
 23586 |       { 
 23587 |          e_ct_none        = 0, 
 23588 |          e_ct_variables   = 1, 
 23589 |          e_ct_functions   = 2, 
 23590 |          e_ct_assignments = 4 
 23591 |       }; 
 23592 |  
 23593 |       enum symbol_type 
 23594 |       { 
 23595 |          e_st_unknown        = 0, 
 23596 |          e_st_variable       = 1, 
 23597 |          e_st_vector         = 2, 
 23598 |          e_st_vecelem        = 3, 
 23599 |          e_st_string         = 4, 
 23600 |          e_st_function       = 5, 
 23601 |          e_st_local_variable = 6, 
 23602 |          e_st_local_vector   = 7, 
 23603 |          e_st_local_string   = 8 
 23604 |       }; 
 23605 |  
 23606 |       class dependent_entity_collector 
 23607 |       { 
 23608 |       public: 
 23609 |  
 23610 |          typedef std::pair<std::string,symbol_type> symbol_t; 
 23611 |          typedef std::vector<symbol_t> symbol_list_t; 
 23612 |  
 23613 |          explicit dependent_entity_collector(const std::size_t options = e_ct_none) 
 23614 |          : options_(options) 
 23615 |          , collect_variables_  ((options_ & e_ct_variables  ) == e_ct_variables  ) 
 23616 |          , collect_functions_  ((options_ & e_ct_functions  ) == e_ct_functions  ) 
 23617 |          , collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments) 
 23618 |          , return_present_   (false) 
 23619 |          , final_stmt_return_(false) 
 23620 |          {} 
 23621 |  
 23622 |          template <typename Allocator, 
 23623 |                    template <typename, typename> class Sequence> 
 23624 |          inline std::size_t symbols(Sequence<symbol_t,Allocator>& symbols_list) 
 23625 |          { 
 23626 |             if (!collect_variables_ && !collect_functions_) 
 23627 |                return 0; 
 23628 |             else if (symbol_name_list_.empty()) 
 23629 |                return 0; 
 23630 |  
 23631 |             for (std::size_t i = 0; i < symbol_name_list_.size(); ++i) 
 23632 |             { 
 23633 |                details::case_normalise(symbol_name_list_[i].first); 
 23634 |             } 
 23635 |  
 23636 |             std::sort(symbol_name_list_.begin(), symbol_name_list_.end()); 
 23637 |  
 23638 |             std::unique_copy 
 23639 |             ( 
 23640 |                symbol_name_list_.begin(), 
 23641 |                symbol_name_list_.end  (), 
 23642 |                std::back_inserter(symbols_list) 
 23643 |             ); 
 23644 |  
 23645 |             return symbols_list.size(); 
 23646 |          } 
 23647 |  
 23648 |          template <typename Allocator, 
 23649 |                    template <typename, typename> class Sequence> 
 23650 |          inline std::size_t assignment_symbols(Sequence<symbol_t,Allocator>& assignment_list) 
 23651 |          { 
 23652 |             if (!collect_assignments_) 
 23653 |                return 0; 
 23654 |             else if (assignment_name_list_.empty()) 
 23655 |                return 0; 
 23656 |  
 23657 |             for (std::size_t i = 0; i < assignment_name_list_.size(); ++i) 
 23658 |             { 
 23659 |                details::case_normalise(assignment_name_list_[i].first); 
 23660 |             } 
 23661 |  
 23662 |             std::sort(assignment_name_list_.begin(),assignment_name_list_.end()); 
 23663 |  
 23664 |             std::unique_copy 
 23665 |             ( 
 23666 |                assignment_name_list_.begin(), 
 23667 |                assignment_name_list_.end  (), 
 23668 |                std::back_inserter(assignment_list) 
 23669 |             ); 
 23670 |  
 23671 |             return assignment_list.size(); 
 23672 |          } 
 23673 |  
 23674 |          void clear() 
 23675 |          { 
 23676 |             symbol_name_list_    .clear(); 
 23677 |             assignment_name_list_.clear(); 
 23678 |             retparam_list_       .clear(); 
 23679 |             return_present_    = false; 
 23680 |             final_stmt_return_ = false; 
 23681 |          } 
 23682 |  
 23683 |          bool& collect_variables() 
 23684 |          { 
 23685 |             return collect_variables_; 
 23686 |          } 
 23687 |  
 23688 |          bool& collect_functions() 
 23689 |          { 
 23690 |             return collect_functions_; 
 23691 |          } 
 23692 |  
 23693 |          bool& collect_assignments() 
 23694 |          { 
 23695 |             return collect_assignments_; 
 23696 |          } 
 23697 |  
 23698 |          bool return_present() const 
 23699 |          { 
 23700 |             return return_present_; 
 23701 |          } 
 23702 |  
 23703 |          bool final_stmt_return() const 
 23704 |          { 
 23705 |             return final_stmt_return_; 
 23706 |          } 
 23707 |  
 23708 |          typedef std::vector<std::string> retparam_list_t; 
 23709 |  
 23710 |          retparam_list_t return_param_type_list() const 
 23711 |          { 
 23712 |             return retparam_list_; 
 23713 |          } 
 23714 |  
 23715 |       private: 
 23716 |  
 23717 |          inline void add_symbol(const std::string& symbol, const symbol_type st) 
 23718 |          { 
 23719 |             switch (st) 
 23720 |             { 
 23721 |                case e_st_variable       : 
 23722 |                case e_st_vector         : 
 23723 |                case e_st_string         : 
 23724 |                case e_st_local_variable : 
 23725 |                case e_st_local_vector   : 
 23726 |                case e_st_local_string   : if (collect_variables_) 
 23727 |                                              symbol_name_list_ 
 23728 |                                                 .push_back(std::make_pair(symbol, st)); 
 23729 |                                           break; 
 23730 |  
 23731 |                case e_st_function       : if (collect_functions_) 
 23732 |                                              symbol_name_list_ 
 23733 |                                                 .push_back(std::make_pair(symbol, st)); 
 23734 |                                           break; 
 23735 |  
 23736 |                default                  : return; 
 23737 |             } 
 23738 |          } 
 23739 |  
 23740 |          inline void add_assignment(const std::string& symbol, const symbol_type st) 
 23741 |          { 
 23742 |             switch (st) 
 23743 |             { 
 23744 |                case e_st_variable       : 
 23745 |                case e_st_vector         : 
 23746 |                case e_st_string         : if (collect_assignments_) 
 23747 |                                              assignment_name_list_ 
 23748 |                                                 .push_back(std::make_pair(symbol, st)); 
 23749 |                                           break; 
 23750 |  
 23751 |                default                  : return; 
 23752 |             } 
 23753 |          } 
 23754 |  
 23755 |          std::size_t options_; 
 23756 |          bool collect_variables_; 
 23757 |          bool collect_functions_; 
 23758 |          bool collect_assignments_; 
 23759 |          bool return_present_; 
 23760 |          bool final_stmt_return_; 
 23761 |          symbol_list_t symbol_name_list_; 
 23762 |          symbol_list_t assignment_name_list_; 
 23763 |          retparam_list_t retparam_list_; 
 23764 |  
 23765 |          friend class parser<T>; 
 23766 |       }; 
 23767 |  
 23768 |       class settings_store 
 23769 |       { 
 23770 |       private: 
 23771 |  
 23772 |          typedef std::set<std::string,details::ilesscompare> disabled_entity_set_t; 
 23773 |          typedef disabled_entity_set_t::iterator des_itr_t; 
 23774 |  
 23775 |       public: 
 23776 |  
 23777 |          enum settings_compilation_options 
 23778 |          { 
 23779 |             e_unknown              =    0, 
 23780 |             e_replacer             =    1, 
 23781 |             e_joiner               =    2, 
 23782 |             e_numeric_check        =    4, 
 23783 |             e_bracket_check        =    8, 
 23784 |             e_sequence_check       =   16, 
 23785 |             e_commutative_check    =   32, 
 23786 |             e_strength_reduction   =   64, 
 23787 |             e_disable_vardef       =  128, 
 23788 |             e_collect_vars         =  256, 
 23789 |             e_collect_funcs        =  512, 
 23790 |             e_collect_assings      = 1024, 
 23791 |             e_disable_usr_on_rsrvd = 2048, 
 23792 |             e_disable_zero_return  = 4096 
 23793 |          }; 
 23794 |  
 23795 |          enum settings_base_funcs 
 23796 |          { 
 23797 |             e_bf_unknown = 0, 
 23798 |             e_bf_abs       , e_bf_acos     , e_bf_acosh    , e_bf_asin    , 
 23799 |             e_bf_asinh     , e_bf_atan     , e_bf_atan2    , e_bf_atanh   , 
 23800 |             e_bf_avg       , e_bf_ceil     , e_bf_clamp    , e_bf_cos     , 
 23801 |             e_bf_cosh      , e_bf_cot      , e_bf_csc      , e_bf_equal   , 
 23802 |             e_bf_erf       , e_bf_erfc     , e_bf_exp      , e_bf_expm1   , 
 23803 |             e_bf_floor     , e_bf_frac     , e_bf_hypot    , e_bf_iclamp  , 
 23804 |             e_bf_like      , e_bf_log      , e_bf_log10    , e_bf_log1p   , 
 23805 |             e_bf_log2      , e_bf_logn     , e_bf_mand     , e_bf_max     , 
 23806 |             e_bf_min       , e_bf_mod      , e_bf_mor      , e_bf_mul     , 
 23807 |             e_bf_ncdf      , e_bf_pow      , e_bf_root     , e_bf_round   , 
 23808 |             e_bf_roundn    , e_bf_sec      , e_bf_sgn      , e_bf_sin     , 
 23809 |             e_bf_sinc      , e_bf_sinh     , e_bf_sqrt     , e_bf_sum     , 
 23810 |             e_bf_swap      , e_bf_tan      , e_bf_tanh     , e_bf_trunc   , 
 23811 |             e_bf_not_equal , e_bf_inrange  , e_bf_deg2grad , e_bf_deg2rad , 
 23812 |             e_bf_rad2deg   , e_bf_grad2deg 
 23813 |          }; 
 23814 |  
 23815 |          enum settings_control_structs 
 23816 |          { 
 23817 |             e_ctrl_unknown = 0, 
 23818 |             e_ctrl_ifelse, 
 23819 |             e_ctrl_switch, 
 23820 |             e_ctrl_for_loop, 
 23821 |             e_ctrl_while_loop, 
 23822 |             e_ctrl_repeat_loop, 
 23823 |             e_ctrl_return 
 23824 |          }; 
 23825 |  
 23826 |          enum settings_logic_opr 
 23827 |          { 
 23828 |             e_logic_unknown = 0, 
 23829 |             e_logic_and, e_logic_nand , e_logic_nor , 
 23830 |             e_logic_not, e_logic_or   , e_logic_xnor, 
 23831 |             e_logic_xor, e_logic_scand, e_logic_scor 
 23832 |          }; 
 23833 |  
 23834 |          enum settings_arithmetic_opr 
 23835 |          { 
 23836 |             e_arith_unknown = 0, 
 23837 |             e_arith_add, e_arith_sub, e_arith_mul, 
 23838 |             e_arith_div, e_arith_mod, e_arith_pow 
 23839 |          }; 
 23840 |  
 23841 |          enum settings_assignment_opr 
 23842 |          { 
 23843 |             e_assign_unknown = 0, 
 23844 |             e_assign_assign, e_assign_addass, e_assign_subass, 
 23845 |             e_assign_mulass, e_assign_divass, e_assign_modass 
 23846 |          }; 
 23847 |  
 23848 |          enum settings_inequality_opr 
 23849 |          { 
 23850 |             e_ineq_unknown = 0, 
 23851 |             e_ineq_lt   , e_ineq_lte, e_ineq_eq    , 
 23852 |             e_ineq_equal, e_ineq_ne , e_ineq_nequal, 
 23853 |             e_ineq_gte  , e_ineq_gt 
 23854 |          }; 
 23855 |  
 23856 |          static const std::size_t default_compile_all_opts = 
 23857 |                                      e_replacer          + 
 23858 |                                      e_joiner            + 
 23859 |                                      e_numeric_check     + 
 23860 |                                      e_bracket_check     + 
 23861 |                                      e_sequence_check    + 
 23862 |                                      e_commutative_check + 
 23863 |                                      e_strength_reduction; 
 23864 |  
 23865 |          settings_store(const std::size_t compile_options = default_compile_all_opts) 
 23866 |          : max_stack_depth_(400) 
 23867 |          , max_node_depth_(10000) 
 23868 |          , max_total_local_symbol_size_bytes_(2000000000) 
 23869 |          , max_local_vector_size_(max_total_local_symbol_size_bytes_ / sizeof(T)) 
 23870 |          { 
 23871 |             load_compile_options(compile_options); 
 23872 |          } 
 23873 |  
 23874 |          settings_store& enable_all_base_functions() 
 23875 |          { 
 23876 |             disabled_func_set_.clear(); 
 23877 |             return (*this); 
 23878 |          } 
 23879 |  
 23880 |          settings_store& enable_all_control_structures() 
 23881 |          { 
 23882 |             disabled_ctrl_set_.clear(); 
 23883 |             return (*this); 
 23884 |          } 
 23885 |  
 23886 |          settings_store& enable_all_logic_ops() 
 23887 |          { 
 23888 |             disabled_logic_set_.clear(); 
 23889 |             return (*this); 
 23890 |          } 
 23891 |  
 23892 |          settings_store& enable_all_arithmetic_ops() 
 23893 |          { 
 23894 |             disabled_arithmetic_set_.clear(); 
 23895 |             return (*this); 
 23896 |          } 
 23897 |  
 23898 |          settings_store& enable_all_assignment_ops() 
 23899 |          { 
 23900 |             disabled_assignment_set_.clear(); 
 23901 |             return (*this); 
 23902 |          } 
 23903 |  
 23904 |          settings_store& enable_all_inequality_ops() 
 23905 |          { 
 23906 |             disabled_inequality_set_.clear(); 
 23907 |             return (*this); 
 23908 |          } 
 23909 |  
 23910 |          settings_store& enable_local_vardef() 
 23911 |          { 
 23912 |             disable_vardef_ = false; 
 23913 |             return (*this); 
 23914 |          } 
 23915 |  
 23916 |          settings_store& enable_commutative_check() 
 23917 |          { 
 23918 |             enable_commutative_check_ = true; 
 23919 |             return (*this); 
 23920 |          } 
 23921 |  
 23922 |          settings_store& enable_strength_reduction() 
 23923 |          { 
 23924 |             enable_strength_reduction_ = true; 
 23925 |             return (*this); 
 23926 |          } 
 23927 |  
 23928 |          settings_store& disable_all_base_functions() 
 23929 |          { 
 23930 |             std::copy(details::base_function_list, 
 23931 |                       details::base_function_list + details::base_function_list_size, 
 23932 |                       std::insert_iterator<disabled_entity_set_t> 
 23933 |                          (disabled_func_set_, disabled_func_set_.begin())); 
 23934 |             return (*this); 
 23935 |          } 
 23936 |  
 23937 |          settings_store& disable_all_control_structures() 
 23938 |          { 
 23939 |             std::copy(details::cntrl_struct_list, 
 23940 |                       details::cntrl_struct_list + details::cntrl_struct_list_size, 
 23941 |                       std::insert_iterator<disabled_entity_set_t> 
 23942 |                          (disabled_ctrl_set_, disabled_ctrl_set_.begin())); 
 23943 |             return (*this); 
 23944 |          } 
 23945 |  
 23946 |          settings_store& disable_all_logic_ops() 
 23947 |          { 
 23948 |             std::copy(details::logic_ops_list, 
 23949 |                       details::logic_ops_list + details::logic_ops_list_size, 
 23950 |                       std::insert_iterator<disabled_entity_set_t> 
 23951 |                         (disabled_logic_set_, disabled_logic_set_.begin())); 
 23952 |             return (*this); 
 23953 |          } 
 23954 |  
 23955 |          settings_store& disable_all_arithmetic_ops() 
 23956 |          { 
 23957 |             std::copy(details::arithmetic_ops_list, 
 23958 |                       details::arithmetic_ops_list + details::arithmetic_ops_list_size, 
 23959 |                       std::insert_iterator<disabled_entity_set_t> 
 23960 |                          (disabled_arithmetic_set_, disabled_arithmetic_set_.begin())); 
 23961 |             return (*this); 
 23962 |          } 
 23963 |  
 23964 |          settings_store& disable_all_assignment_ops() 
 23965 |          { 
 23966 |             std::copy(details::assignment_ops_list, 
 23967 |                       details::assignment_ops_list + details::assignment_ops_list_size, 
 23968 |                       std::insert_iterator<disabled_entity_set_t> 
 23969 |                          (disabled_assignment_set_, disabled_assignment_set_.begin())); 
 23970 |             return (*this); 
 23971 |          } 
 23972 |  
 23973 |          settings_store& disable_all_inequality_ops() 
 23974 |          { 
 23975 |             std::copy(details::inequality_ops_list, 
 23976 |                       details::inequality_ops_list + details::inequality_ops_list_size, 
 23977 |                       std::insert_iterator<disabled_entity_set_t> 
 23978 |                          (disabled_inequality_set_, disabled_inequality_set_.begin())); 
 23979 |             return (*this); 
 23980 |          } 
 23981 |  
 23982 |          settings_store& disable_local_vardef() 
 23983 |          { 
 23984 |             disable_vardef_ = true; 
 23985 |             return (*this); 
 23986 |          } 
 23987 |  
 23988 |          settings_store& disable_commutative_check() 
 23989 |          { 
 23990 |             enable_commutative_check_ = false; 
 23991 |             return (*this); 
 23992 |          } 
 23993 |  
 23994 |          settings_store& disable_strength_reduction() 
 23995 |          { 
 23996 |             enable_strength_reduction_ = false; 
 23997 |             return (*this); 
 23998 |          } 
 23999 |  
 24000 |          bool replacer_enabled           () const { return enable_replacer_;           } 
 24001 |          bool commutative_check_enabled  () const { return enable_commutative_check_;  } 
 24002 |          bool joiner_enabled             () const { return enable_joiner_;             } 
 24003 |          bool numeric_check_enabled      () const { return enable_numeric_check_;      } 
 24004 |          bool bracket_check_enabled      () const { return enable_bracket_check_;      } 
 24005 |          bool sequence_check_enabled     () const { return enable_sequence_check_;     } 
 24006 |          bool strength_reduction_enabled () const { return enable_strength_reduction_; } 
 24007 |          bool collect_variables_enabled  () const { return enable_collect_vars_;       } 
 24008 |          bool collect_functions_enabled  () const { return enable_collect_funcs_;      } 
 24009 |          bool collect_assignments_enabled() const { return enable_collect_assings_;    } 
 24010 |          bool vardef_disabled            () const { return disable_vardef_;            } 
 24011 |          bool rsrvd_sym_usr_disabled     () const { return disable_rsrvd_sym_usr_;     } 
 24012 |          bool zero_return_disabled       () const { return disable_zero_return_;       } 
 24013 |  
 24014 |          bool function_enabled(const std::string& function_name) const 
 24015 |          { 
 24016 |             if (disabled_func_set_.empty()) 
 24017 |                return true; 
 24018 |             else 
 24019 |                return (disabled_func_set_.end() == disabled_func_set_.find(function_name)); 
 24020 |          } 
 24021 |  
 24022 |          bool control_struct_enabled(const std::string& control_struct) const 
 24023 |          { 
 24024 |             if (disabled_ctrl_set_.empty()) 
 24025 |                return true; 
 24026 |             else 
 24027 |                return (disabled_ctrl_set_.end() == disabled_ctrl_set_.find(control_struct)); 
 24028 |          } 
 24029 |  
 24030 |          bool logic_enabled(const std::string& logic_operation) const 
 24031 |          { 
 24032 |             if (disabled_logic_set_.empty()) 
 24033 |                return true; 
 24034 |             else 
 24035 |                return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation)); 
 24036 |          } 
 24037 |  
 24038 |          bool arithmetic_enabled(const details::operator_type& arithmetic_operation) const 
 24039 |          { 
 24040 |             if (disabled_logic_set_.empty()) 
 24041 |                return true; 
 24042 |             else 
 24043 |                return disabled_arithmetic_set_.end() == disabled_arithmetic_set_ 
 24044 |                                                             .find(arith_opr_to_string(arithmetic_operation)); 
 24045 |          } 
 24046 |  
 24047 |          bool assignment_enabled(const details::operator_type& assignment) const 
 24048 |          { 
 24049 |             if (disabled_assignment_set_.empty()) 
 24050 |                return true; 
 24051 |             else 
 24052 |                return disabled_assignment_set_.end() == disabled_assignment_set_ 
 24053 |                                                            .find(assign_opr_to_string(assignment)); 
 24054 |          } 
 24055 |  
 24056 |          bool inequality_enabled(const details::operator_type& inequality) const 
 24057 |          { 
 24058 |             if (disabled_inequality_set_.empty()) 
 24059 |                return true; 
 24060 |             else 
 24061 |                return disabled_inequality_set_.end() == disabled_inequality_set_ 
 24062 |                                                            .find(inequality_opr_to_string(inequality)); 
 24063 |          } 
 24064 |  
 24065 |          bool function_disabled(const std::string& function_name) const 
 24066 |          { 
 24067 |             if (disabled_func_set_.empty()) 
 24068 |                return false; 
 24069 |             else 
 24070 |                return (disabled_func_set_.end() != disabled_func_set_.find(function_name)); 
 24071 |          } 
 24072 |  
 24073 |          bool control_struct_disabled(const std::string& control_struct) const 
 24074 |          { 
 24075 |             if (disabled_ctrl_set_.empty()) 
 24076 |                return false; 
 24077 |             else 
 24078 |                return (disabled_ctrl_set_.end() != disabled_ctrl_set_.find(control_struct)); 
 24079 |          } 
 24080 |  
 24081 |          bool logic_disabled(const std::string& logic_operation) const 
 24082 |          { 
 24083 |             if (disabled_logic_set_.empty()) 
 24084 |                return false; 
 24085 |             else 
 24086 |                return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation)); 
 24087 |          } 
 24088 |  
 24089 |          bool assignment_disabled(const details::operator_type assignment_operation) const 
 24090 |          { 
 24091 |             if (disabled_assignment_set_.empty()) 
 24092 |                return false; 
 24093 |             else 
 24094 |                return disabled_assignment_set_.end() != disabled_assignment_set_ 
 24095 |                                                            .find(assign_opr_to_string(assignment_operation)); 
 24096 |          } 
 24097 |  
 24098 |          bool logic_disabled(const details::operator_type logic_operation) const 
 24099 |          { 
 24100 |             if (disabled_logic_set_.empty()) 
 24101 |                return false; 
 24102 |             else 
 24103 |                return disabled_logic_set_.end() != disabled_logic_set_ 
 24104 |                                                            .find(logic_opr_to_string(logic_operation)); 
 24105 |          } 
 24106 |  
 24107 |          bool arithmetic_disabled(const details::operator_type arithmetic_operation) const 
 24108 |          { 
 24109 |             if (disabled_arithmetic_set_.empty()) 
 24110 |                return false; 
 24111 |             else 
 24112 |                return disabled_arithmetic_set_.end() != disabled_arithmetic_set_ 
 24113 |                                                            .find(arith_opr_to_string(arithmetic_operation)); 
 24114 |          } 
 24115 |  
 24116 |          bool inequality_disabled(const details::operator_type& inequality) const 
 24117 |          { 
 24118 |             if (disabled_inequality_set_.empty()) 
 24119 |                return false; 
 24120 |             else 
 24121 |                return disabled_inequality_set_.end() != disabled_inequality_set_ 
 24122 |                                                            .find(inequality_opr_to_string(inequality)); 
 24123 |          } 
 24124 |  
 24125 |          settings_store& disable_base_function(const settings_base_funcs bf) 
 24126 |          { 
 24127 |             if ( 
 24128 |                  (e_bf_unknown != bf) && 
 24129 |                  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1)) 
 24130 |                ) 
 24131 |             { 
 24132 |                disabled_func_set_.insert(details::base_function_list[bf - 1]); 
 24133 |             } 
 24134 |  
 24135 |             return (*this); 
 24136 |          } 
 24137 |  
 24138 |          settings_store& disable_control_structure(const settings_control_structs ctrl_struct) 
 24139 |          { 
 24140 |             if ( 
 24141 |                  (e_ctrl_unknown != ctrl_struct) && 
 24142 |                  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1)) 
 24143 |                ) 
 24144 |             { 
 24145 |                disabled_ctrl_set_.insert(details::cntrl_struct_list[ctrl_struct - 1]); 
 24146 |             } 
 24147 |  
 24148 |             return (*this); 
 24149 |          } 
 24150 |  
 24151 |          settings_store& disable_logic_operation(const settings_logic_opr logic) 
 24152 |          { 
 24153 |             if ( 
 24154 |                  (e_logic_unknown != logic) && 
 24155 |                  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1)) 
 24156 |                ) 
 24157 |             { 
 24158 |                disabled_logic_set_.insert(details::logic_ops_list[logic - 1]); 
 24159 |             } 
 24160 |  
 24161 |             return (*this); 
 24162 |          } 
 24163 |  
 24164 |          settings_store& disable_arithmetic_operation(const settings_arithmetic_opr arithmetic) 
 24165 |          { 
 24166 |             if ( 
 24167 |                  (e_arith_unknown != arithmetic) && 
 24168 |                  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1)) 
 24169 |                ) 
 24170 |             { 
 24171 |                disabled_arithmetic_set_.insert(details::arithmetic_ops_list[arithmetic - 1]); 
 24172 |             } 
 24173 |  
 24174 |             return (*this); 
 24175 |          } 
 24176 |  
 24177 |          settings_store& disable_assignment_operation(const settings_assignment_opr assignment) 
 24178 |          { 
 24179 |             if ( 
 24180 |                  (e_assign_unknown != assignment) && 
 24181 |                  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1)) 
 24182 |                ) 
 24183 |             { 
 24184 |                disabled_assignment_set_.insert(details::assignment_ops_list[assignment - 1]); 
 24185 |             } 
 24186 |  
 24187 |             return (*this); 
 24188 |          } 
 24189 |  
 24190 |          settings_store& disable_inequality_operation(const settings_inequality_opr inequality) 
 24191 |          { 
 24192 |             if ( 
 24193 |                  (e_ineq_unknown != inequality) && 
 24194 |                  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1)) 
 24195 |                ) 
 24196 |             { 
 24197 |                disabled_inequality_set_.insert(details::inequality_ops_list[inequality - 1]); 
 24198 |             } 
 24199 |  
 24200 |             return (*this); 
 24201 |          } 
 24202 |  
 24203 |          settings_store& enable_base_function(const settings_base_funcs bf) 
 24204 |          { 
 24205 |             if ( 
 24206 |                  (e_bf_unknown != bf) && 
 24207 |                  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1)) 
 24208 |                ) 
 24209 |             { 
 24210 |                const des_itr_t itr = disabled_func_set_.find(details::base_function_list[bf - 1]); 
 24211 |  
 24212 |                if (disabled_func_set_.end() != itr) 
 24213 |                { 
 24214 |                   disabled_func_set_.erase(itr); 
 24215 |                } 
 24216 |             } 
 24217 |  
 24218 |             return (*this); 
 24219 |          } 
 24220 |  
 24221 |          settings_store& enable_control_structure(const settings_control_structs ctrl_struct) 
 24222 |          { 
 24223 |             if ( 
 24224 |                  (e_ctrl_unknown != ctrl_struct) && 
 24225 |                  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1)) 
 24226 |                ) 
 24227 |             { 
 24228 |                const des_itr_t itr = disabled_ctrl_set_.find(details::cntrl_struct_list[ctrl_struct - 1]); 
 24229 |  
 24230 |                if (disabled_ctrl_set_.end() != itr) 
 24231 |                { 
 24232 |                   disabled_ctrl_set_.erase(itr); 
 24233 |                } 
 24234 |             } 
 24235 |  
 24236 |             return (*this); 
 24237 |          } 
 24238 |  
 24239 |          settings_store& enable_logic_operation(const settings_logic_opr logic) 
 24240 |          { 
 24241 |             if ( 
 24242 |                  (e_logic_unknown != logic) && 
 24243 |                  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1)) 
 24244 |                ) 
 24245 |             { 
 24246 |                const des_itr_t itr = disabled_logic_set_.find(details::logic_ops_list[logic - 1]); 
 24247 |  
 24248 |                if (disabled_logic_set_.end() != itr) 
 24249 |                { 
 24250 |                   disabled_logic_set_.erase(itr); 
 24251 |                } 
 24252 |             } 
 24253 |  
 24254 |             return (*this); 
 24255 |          } 
 24256 |  
 24257 |          settings_store& enable_arithmetic_operation(const settings_arithmetic_opr arithmetic) 
 24258 |          { 
 24259 |             if ( 
 24260 |                  (e_arith_unknown != arithmetic) && 
 24261 |                  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1)) 
 24262 |                ) 
 24263 |             { 
 24264 |                const des_itr_t itr = disabled_arithmetic_set_.find(details::arithmetic_ops_list[arithmetic - 1]); 
 24265 |  
 24266 |                if (disabled_arithmetic_set_.end() != itr) 
 24267 |                { 
 24268 |                   disabled_arithmetic_set_.erase(itr); 
 24269 |                } 
 24270 |             } 
 24271 |  
 24272 |             return (*this); 
 24273 |          } 
 24274 |  
 24275 |          settings_store& enable_assignment_operation(const settings_assignment_opr assignment) 
 24276 |          { 
 24277 |             if ( 
 24278 |                  (e_assign_unknown != assignment) && 
 24279 |                  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1)) 
 24280 |                ) 
 24281 |             { 
 24282 |                const des_itr_t itr = disabled_assignment_set_.find(details::assignment_ops_list[assignment - 1]); 
 24283 |  
 24284 |                if (disabled_assignment_set_.end() != itr) 
 24285 |                { 
 24286 |                   disabled_assignment_set_.erase(itr); 
 24287 |                } 
 24288 |             } 
 24289 |  
 24290 |             return (*this); 
 24291 |          } 
 24292 |  
 24293 |          settings_store& enable_inequality_operation(const settings_inequality_opr inequality) 
 24294 |          { 
 24295 |             if ( 
 24296 |                  (e_ineq_unknown != inequality) && 
 24297 |                  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1)) 
 24298 |                ) 
 24299 |             { 
 24300 |                const des_itr_t itr = disabled_inequality_set_.find(details::inequality_ops_list[inequality - 1]); 
 24301 |  
 24302 |                if (disabled_inequality_set_.end() != itr) 
 24303 |                { 
 24304 |                   disabled_inequality_set_.erase(itr); 
 24305 |                } 
 24306 |             } 
 24307 |  
 24308 |             return (*this); 
 24309 |          } 
 24310 |  
 24311 |          void set_max_stack_depth(const std::size_t max_stack_depth) 
 24312 |          { 
 24313 |             max_stack_depth_ = max_stack_depth; 
 24314 |          } 
 24315 |  
 24316 |          void set_max_node_depth(const std::size_t max_node_depth) 
 24317 |          { 
 24318 |             max_node_depth_ = max_node_depth; 
 24319 |          } 
 24320 |  
 24321 |          void set_max_local_vector_size(const std::size_t max_local_vector_size) 
 24322 |          { 
 24323 |             max_local_vector_size_ = max_local_vector_size; 
 24324 |          } 
 24325 |  
 24326 |          void set_max_total_local_symbol_size_bytes(const std::size_t max_total_lcl_symb_size) 
 24327 |          { 
 24328 |             max_total_local_symbol_size_bytes_ = max_total_lcl_symb_size; 
 24329 |          } 
 24330 |  
 24331 |          std::size_t max_stack_depth() const 
 24332 |          { 
 24333 |             return max_stack_depth_; 
 24334 |          } 
 24335 |  
 24336 |          std::size_t max_node_depth() const 
 24337 |          { 
 24338 |             return max_node_depth_; 
 24339 |          } 
 24340 |  
 24341 |          std::size_t max_local_vector_size() const 
 24342 |          { 
 24343 |             return max_local_vector_size_; 
 24344 |          } 
 24345 |  
 24346 |          std::size_t max_total_local_symbol_size_bytes() const 
 24347 |          { 
 24348 |             return max_total_local_symbol_size_bytes_; 
 24349 |          } 
 24350 |  
 24351 |       private: 
 24352 |  
 24353 |          void load_compile_options(const std::size_t compile_options) 
 24354 |          { 
 24355 |             enable_replacer_           = (compile_options & e_replacer            ) == e_replacer; 
 24356 |             enable_joiner_             = (compile_options & e_joiner              ) == e_joiner; 
 24357 |             enable_numeric_check_      = (compile_options & e_numeric_check       ) == e_numeric_check; 
 24358 |             enable_bracket_check_      = (compile_options & e_bracket_check       ) == e_bracket_check; 
 24359 |             enable_sequence_check_     = (compile_options & e_sequence_check      ) == e_sequence_check; 
 24360 |             enable_commutative_check_  = (compile_options & e_commutative_check   ) == e_commutative_check; 
 24361 |             enable_strength_reduction_ = (compile_options & e_strength_reduction  ) == e_strength_reduction; 
 24362 |             enable_collect_vars_       = (compile_options & e_collect_vars        ) == e_collect_vars; 
 24363 |             enable_collect_funcs_      = (compile_options & e_collect_funcs       ) == e_collect_funcs; 
 24364 |             enable_collect_assings_    = (compile_options & e_collect_assings     ) == e_collect_assings; 
 24365 |             disable_vardef_            = (compile_options & e_disable_vardef      ) == e_disable_vardef; 
 24366 |             disable_rsrvd_sym_usr_     = (compile_options & e_disable_usr_on_rsrvd) == e_disable_usr_on_rsrvd; 
 24367 |             disable_zero_return_       = (compile_options & e_disable_zero_return ) == e_disable_zero_return; 
 24368 |          } 
 24369 |  
 24370 |          std::string assign_opr_to_string(details::operator_type opr) const 
 24371 |          { 
 24372 |             switch (opr) 
 24373 |             { 
 24374 |                case details::e_assign : return ":=" 
 24375 |                case details::e_addass : return "+=" 
 24376 |                case details::e_subass : return "-=" 
 24377 |                case details::e_mulass : return "*=" 
 24378 |                case details::e_divass : return "/=" 
 24379 |                case details::e_modass : return "%=" 
 24380 |                default                : return ""  ; 
 24381 |             } 
 24382 |          } 
 24383 |  
 24384 |          std::string arith_opr_to_string(details::operator_type opr) const 
 24385 |          { 
 24386 |             switch (opr) 
 24387 |             { 
 24388 |                case details::e_add : return "+" 
 24389 |                case details::e_sub : return "-" 
 24390 |                case details::e_mul : return "*" 
 24391 |                case details::e_div : return "/" 
 24392 |                case details::e_mod : return "%" 
 24393 |                case details::e_pow : return "^" 
 24394 |                default             : return "" ; 
 24395 |             } 
 24396 |          } 
 24397 |  
 24398 |          std::string inequality_opr_to_string(details::operator_type opr) const 
 24399 |          { 
 24400 |             switch (opr) 
 24401 |             { 
 24402 |                case details::e_lt    : return "<" ; 
 24403 |                case details::e_lte   : return "<=" 
 24404 |                case details::e_eq    : return "==" 
 24405 |                case details::e_equal : return "=" ; 
 24406 |                case details::e_ne    : return "!=" 
 24407 |                case details::e_nequal: return "<>" 
 24408 |                case details::e_gte   : return ">=" 
 24409 |                case details::e_gt    : return ">" ; 
 24410 |                default               : return ""  ; 
 24411 |             } 
 24412 |          } 
 24413 |  
 24414 |          std::string logic_opr_to_string(details::operator_type opr) const 
 24415 |          { 
 24416 |             switch (opr) 
 24417 |             { 
 24418 |                case details::e_and  : return "and" ; 
 24419 |                case details::e_or   : return "or"  ; 
 24420 |                case details::e_xor  : return "xor" ; 
 24421 |                case details::e_nand : return "nand" 
 24422 |                case details::e_nor  : return "nor" ; 
 24423 |                case details::e_xnor : return "xnor" 
 24424 |                case details::e_notl : return "not" ; 
 24425 |                default              : return ""    ; 
 24426 |             } 
 24427 |          } 
 24428 |  
 24429 |          bool enable_replacer_; 
 24430 |          bool enable_joiner_; 
 24431 |          bool enable_numeric_check_; 
 24432 |          bool enable_bracket_check_; 
 24433 |          bool enable_sequence_check_; 
 24434 |          bool enable_commutative_check_; 
 24435 |          bool enable_strength_reduction_; 
 24436 |          bool enable_collect_vars_; 
 24437 |          bool enable_collect_funcs_; 
 24438 |          bool enable_collect_assings_; 
 24439 |          bool disable_vardef_; 
 24440 |          bool disable_rsrvd_sym_usr_; 
 24441 |          bool disable_zero_return_; 
 24442 |  
 24443 |          disabled_entity_set_t disabled_func_set_ ; 
 24444 |          disabled_entity_set_t disabled_ctrl_set_ ; 
 24445 |          disabled_entity_set_t disabled_logic_set_; 
 24446 |          disabled_entity_set_t disabled_arithmetic_set_; 
 24447 |          disabled_entity_set_t disabled_assignment_set_; 
 24448 |          disabled_entity_set_t disabled_inequality_set_; 
 24449 |  
 24450 |          std::size_t max_stack_depth_; 
 24451 |          std::size_t max_node_depth_; 
 24452 |          std::size_t max_total_local_symbol_size_bytes_; 
 24453 |          std::size_t max_local_vector_size_; 
 24454 |  
 24455 |          friend class parser<T>; 
 24456 |       }; 
 24457 |  
 24458 |       typedef settings_store settings_t; 
 24459 |  
 24460 |       explicit parser(const settings_t& settings = settings_t()) 
 24461 |       : settings_(settings) 
 24462 |       , resolve_unknown_symbol_(false) 
 24463 |       , results_context_(0) 
 24464 |       , unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver*>(0)) 
 24465 |         #ifdef _MSC_VER 
 24466 |         #pragma warning(push) 
 24467 |         #pragma warning (disable:4355) 
 24468 |         #endif 
 24469 |       , sem_(*this) 
 24470 |         #ifdef _MSC_VER 
 24471 |         #pragma warning(pop) 
 24472 |         #endif 
 24473 |       , operator_joiner_2_(2) 
 24474 |       , operator_joiner_3_(3) 
 24475 |       , loop_runtime_check_(0) 
 24476 |       , vector_access_runtime_check_(0) 
 24477 |       , compilation_check_ptr_(0) 
 24478 |       , assert_check_(0) 
 24479 |       { 
 24480 |          init_precompilation(); 
 24481 |  
 24482 |          load_operations_map           (base_ops_map_     ); 
 24483 |          load_unary_operations_map     (unary_op_map_     ); 
 24484 |          load_binary_operations_map    (binary_op_map_    ); 
 24485 |          load_inv_binary_operations_map(inv_binary_op_map_); 
 24486 |          load_sf3_map                  (sf3_map_          ); 
 24487 |          load_sf4_map                  (sf4_map_          ); 
 24488 |  
 24489 |          expression_generator_.init_synthesize_map(); 
 24490 |          expression_generator_.set_parser(*this); 
 24491 |          expression_generator_.set_uom (unary_op_map_     ); 
 24492 |          expression_generator_.set_bom (binary_op_map_    ); 
 24493 |          expression_generator_.set_ibom(inv_binary_op_map_); 
 24494 |          expression_generator_.set_sf3m(sf3_map_          ); 
 24495 |          expression_generator_.set_sf4m(sf4_map_          ); 
 24496 |          expression_generator_.set_strength_reduction_state(settings_.strength_reduction_enabled()); 
 24497 |       } 
 24498 |  
 24499 |      ~parser() 
 24500 |       {} 
 24501 |  
 24502 |       inline void init_precompilation() 
 24503 |       { 
 24504 |          dec_.collect_variables() = 
 24505 |             settings_.collect_variables_enabled(); 
 24506 |  
 24507 |          dec_.collect_functions() = 
 24508 |             settings_.collect_functions_enabled(); 
 24509 |  
 24510 |          dec_.collect_assignments() = 
 24511 |             settings_.collect_assignments_enabled(); 
 24512 |  
 24513 |          if (settings_.replacer_enabled()) 
 24514 |          { 
 24515 |             symbol_replacer_.clear(); 
 24516 |             symbol_replacer_.add_replace("true" , "1", lexer::token::e_number); 
 24517 |             symbol_replacer_.add_replace("false", "0", lexer::token::e_number); 
 24518 |             helper_assembly_.token_modifier_list.clear(); 
 24519 |             helper_assembly_.register_modifier(&symbol_replacer_); 
 24520 |          } 
 24521 |  
 24522 |          if (settings_.commutative_check_enabled()) 
 24523 |          { 
 24524 |             for (std::size_t i = 0; i < details::reserved_words_size; ++i) 
 24525 |             { 
 24526 |                commutative_inserter_.ignore_symbol(details::reserved_words[i]); 
 24527 |             } 
 24528 |  
 24529 |             helper_assembly_.token_inserter_list.clear(); 
 24530 |             helper_assembly_.register_inserter(&commutative_inserter_); 
 24531 |          } 
 24532 |  
 24533 |          if (settings_.joiner_enabled()) 
 24534 |          { 
 24535 |             helper_assembly_.token_joiner_list.clear(); 
 24536 |             helper_assembly_.register_joiner(&operator_joiner_2_); 
 24537 |             helper_assembly_.register_joiner(&operator_joiner_3_); 
 24538 |          } 
 24539 |  
 24540 |          if ( 
 24541 |               settings_.numeric_check_enabled () || 
 24542 |               settings_.bracket_check_enabled () || 
 24543 |               settings_.sequence_check_enabled() 
 24544 |             ) 
 24545 |          { 
 24546 |             helper_assembly_.token_scanner_list.clear(); 
 24547 |  
 24548 |             if (settings_.numeric_check_enabled()) 
 24549 |             { 
 24550 |                helper_assembly_.register_scanner(&numeric_checker_); 
 24551 |             } 
 24552 |  
 24553 |             if (settings_.bracket_check_enabled()) 
 24554 |             { 
 24555 |                helper_assembly_.register_scanner(&bracket_checker_); 
 24556 |             } 
 24557 |  
 24558 |             if (settings_.sequence_check_enabled()) 
 24559 |             { 
 24560 |                helper_assembly_.register_scanner(&sequence_validator_      ); 
 24561 |                helper_assembly_.register_scanner(&sequence_validator_3tkns_); 
 24562 |             } 
 24563 |          } 
 24564 |       } 
 24565 |  
 24566 |       inline bool compile(const std::string& expression_string, expression<T>& expr) 
 24567 |       { 
 24568 |          state_               .reset(); 
 24569 |          error_list_          .clear(); 
 24570 |          brkcnt_list_         .clear(); 
 24571 |          synthesis_error_     .clear(); 
 24572 |          immutable_memory_map_.reset(); 
 24573 |          immutable_symtok_map_.clear(); 
 24574 |          current_state_stack_ .clear(); 
 24575 |          assert_ids_          .clear(); 
 24576 |          sem_                 .cleanup(); 
 24577 |  
 24578 |          return_cleanup(); 
 24579 |  
 24580 |          if (!valid_settings()) 
 24581 |          { 
 24582 |             return false; 
 24583 |          } 
 24584 |  
 24585 |          expression_generator_.set_allocator(node_allocator_); 
 24586 |  
 24587 |          if (expression_string.empty()) 
 24588 |          { 
 24589 |             set_error(make_error( 
 24590 |                parser_error::e_syntax, 
 24591 |                "ERR001 - Empty expression!", 
 24592 |                exprtk_error_location)); 
 24593 |  
 24594 |             return false; 
 24595 |          } 
 24596 |  
 24597 |          if (!init(expression_string)) 
 24598 |          { 
 24599 |             process_lexer_errors(); 
 24600 |             return false; 
 24601 |          } 
 24602 |  
 24603 |          if (lexer().empty()) 
 24604 |          { 
 24605 |             set_error(make_error( 
 24606 |                parser_error::e_syntax, 
 24607 |                "ERR002 - Empty expression!", 
 24608 |                exprtk_error_location)); 
 24609 |  
 24610 |             return false; 
 24611 |          } 
 24612 |  
 24613 |          if (halt_compilation_check()) 
 24614 |          { 
 24615 |             exprtk_debug(("halt_compilation_check() - compile checkpoint 0\n")); 
 24616 |             sem_.cleanup(); 
 24617 |             return false; 
 24618 |          } 
 24619 |  
 24620 |          if (!run_assemblies()) 
 24621 |          { 
 24622 |             sem_.cleanup(); 
 24623 |             return false; 
 24624 |          } 
 24625 |  
 24626 |          if (halt_compilation_check()) 
 24627 |          { 
 24628 |             exprtk_debug(("halt_compilation_check() - compile checkpoint 1\n")); 
 24629 |             sem_.cleanup(); 
 24630 |             return false; 
 24631 |          } 
 24632 |  
 24633 |          symtab_store_.symtab_list_ = expr.get_symbol_table_list(); 
 24634 |          dec_.clear(); 
 24635 |  
 24636 |          lexer().begin(); 
 24637 |  
 24638 |          next_token(); 
 24639 |  
 24640 |          expression_node_ptr e = parse_corpus(); 
 24641 |  
 24642 |          if ((0 != e) && (token_t::e_eof == current_token().type)) 
 24643 |          { 
 24644 |             bool* retinvk_ptr = 0; 
 24645 |  
 24646 |             if (state_.return_stmt_present) 
 24647 |             { 
 24648 |                dec_.return_present_ = true; 
 24649 |  
 24650 |                e = expression_generator_ 
 24651 |                      .return_envelope(e, results_context_, retinvk_ptr); 
 24652 |             } 
 24653 |  
 24654 |             expr.set_expression(e); 
 24655 |             expr.set_retinvk(retinvk_ptr); 
 24656 |  
 24657 |             register_local_vars(expr); 
 24658 |             register_return_results(expr); 
 24659 |  
 24660 |             return !(!expr); 
 24661 |          } 
 24662 |          else 
 24663 |          { 
 24664 |             if (error_list_.empty()) 
 24665 |             { 
 24666 |                set_error(make_error( 
 24667 |                   parser_error::e_syntax, 
 24668 |                   current_token(), 
 24669 |                   "ERR003 - Invalid expression encountered", 
 24670 |                   exprtk_error_location)); 
 24671 |             } 
 24672 |  
 24673 |             if ((0 != e) && branch_deletable(e)) 
 24674 |             { 
 24675 |                destroy_node(e); 
 24676 |             } 
 24677 |  
 24678 |             dec_.clear    (); 
 24679 |             sem_.cleanup  (); 
 24680 |             return_cleanup(); 
 24681 |  
 24682 |             return false; 
 24683 |          } 
 24684 |       } 
 24685 |  
 24686 |       inline expression_t compile(const std::string& expression_string, symbol_table_t& symtab) 
 24687 |       { 
 24688 |          expression_t expression; 
 24689 |          expression.register_symbol_table(symtab); 
 24690 |          compile(expression_string,expression); 
 24691 |          return expression; 
 24692 |       } 
 24693 |  
 24694 |       void process_lexer_errors() 
 24695 |       { 
 24696 |          for (std::size_t i = 0; i < lexer().size(); ++i) 
 24697 |          { 
 24698 |             if (lexer()[i].is_error()) 
 24699 |             { 
 24700 |                std::string diagnostic = "ERR004 - " 
 24701 |  
 24702 |                switch (lexer()[i].type) 
 24703 |                { 
 24704 |                   case lexer::token::e_error      : diagnostic += "General token error" 
 24705 |                                                     break; 
 24706 |  
 24707 |                   case lexer::token::e_err_symbol : diagnostic += "Symbol error" 
 24708 |                                                     break; 
 24709 |  
 24710 |                   case lexer::token::e_err_number : diagnostic += "Invalid numeric token" 
 24711 |                                                     break; 
 24712 |  
 24713 |                   case lexer::token::e_err_string : diagnostic += "Invalid string token" 
 24714 |                                                     break; 
 24715 |  
 24716 |                   case lexer::token::e_err_sfunc  : diagnostic += "Invalid special function token" 
 24717 |                                                     break; 
 24718 |  
 24719 |                   default                         : diagnostic += "Unknown compiler error" 
 24720 |                } 
 24721 |  
 24722 |                set_error(make_error( 
 24723 |                   parser_error::e_lexer, 
 24724 |                   lexer()[i], 
 24725 |                   diagnostic + ": " + lexer()[i].value, 
 24726 |                   exprtk_error_location)); 
 24727 |             } 
 24728 |          } 
 24729 |       } 
 24730 |  
 24731 |       inline bool run_assemblies() 
 24732 |       { 
 24733 |          if (settings_.commutative_check_enabled()) 
 24734 |          { 
 24735 |             helper_assembly_.run_inserters(lexer()); 
 24736 |          } 
 24737 |  
 24738 |          if (settings_.joiner_enabled()) 
 24739 |          { 
 24740 |             helper_assembly_.run_joiners(lexer()); 
 24741 |          } 
 24742 |  
 24743 |          if (settings_.replacer_enabled()) 
 24744 |          { 
 24745 |             helper_assembly_.run_modifiers(lexer()); 
 24746 |          } 
 24747 |  
 24748 |          if ( 
 24749 |               settings_.numeric_check_enabled () || 
 24750 |               settings_.bracket_check_enabled () || 
 24751 |               settings_.sequence_check_enabled() 
 24752 |             ) 
 24753 |          { 
 24754 |             if (!helper_assembly_.run_scanners(lexer())) 
 24755 |             { 
 24756 |                if (helper_assembly_.error_token_scanner) 
 24757 |                { 
 24758 |                   lexer::helper::bracket_checker*            bracket_checker_ptr     = 0; 
 24759 |                   lexer::helper::numeric_checker<T>*         numeric_checker_ptr     = 0; 
 24760 |                   lexer::helper::sequence_validator*         sequence_validator_ptr  = 0; 
 24761 |                   lexer::helper::sequence_validator_3tokens* sequence_validator3_ptr = 0; 
 24762 |  
 24763 |                   if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner))) 
 24764 |                   { 
 24765 |                      set_error(make_error( 
 24766 |                         parser_error::e_token, 
 24767 |                         bracket_checker_ptr->error_token(), 
 24768 |                         "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'", 
 24769 |                         exprtk_error_location)); 
 24770 |                   } 
 24771 |                   else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker<T>*>(helper_assembly_.error_token_scanner))) 
 24772 |                   { 
 24773 |                      for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i) 
 24774 |                      { 
 24775 |                         lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)]; 
 24776 |  
 24777 |                         set_error(make_error( 
 24778 |                            parser_error::e_token, 
 24779 |                            error_token, 
 24780 |                            "ERR006 - Invalid numeric token: '" + error_token.value + "'", 
 24781 |                            exprtk_error_location)); 
 24782 |                      } 
 24783 |  
 24784 |                      if (numeric_checker_ptr->error_count()) 
 24785 |                      { 
 24786 |                         numeric_checker_ptr->clear_errors(); 
 24787 |                      } 
 24788 |                   } 
 24789 |                   else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner))) 
 24790 |                   { 
 24791 |                      for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i) 
 24792 |                      { 
 24793 |                         std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i); 
 24794 |  
 24795 |                         set_error(make_error( 
 24796 |                            parser_error::e_token, 
 24797 |                            error_token.first, 
 24798 |                            "ERR007 - Invalid token sequence: '" + 
 24799 |                            error_token.first.value  + "' and '" + 
 24800 |                            error_token.second.value + "'", 
 24801 |                            exprtk_error_location)); 
 24802 |                      } 
 24803 |  
 24804 |                      if (sequence_validator_ptr->error_count()) 
 24805 |                      { 
 24806 |                         sequence_validator_ptr->clear_errors(); 
 24807 |                      } 
 24808 |                   } 
 24809 |                   else if (0 != (sequence_validator3_ptr = dynamic_cast<lexer::helper::sequence_validator_3tokens*>(helper_assembly_.error_token_scanner))) 
 24810 |                   { 
 24811 |                      for (std::size_t i = 0; i < sequence_validator3_ptr->error_count(); ++i) 
 24812 |                      { 
 24813 |                         std::pair<lexer::token,lexer::token> error_token = sequence_validator3_ptr->error(i); 
 24814 |  
 24815 |                         set_error(make_error( 
 24816 |                            parser_error::e_token, 
 24817 |                            error_token.first, 
 24818 |                            "ERR008 - Invalid token sequence: '" + 
 24819 |                            error_token.first.value  + "' and '" + 
 24820 |                            error_token.second.value + "'", 
 24821 |                            exprtk_error_location)); 
 24822 |                      } 
 24823 |  
 24824 |                      if (sequence_validator3_ptr->error_count()) 
 24825 |                      { 
 24826 |                         sequence_validator3_ptr->clear_errors(); 
 24827 |                      } 
 24828 |                   } 
 24829 |                } 
 24830 |  
 24831 |                return false; 
 24832 |             } 
 24833 |          } 
 24834 |  
 24835 |          return true; 
 24836 |       } 
 24837 |  
 24838 |       inline settings_store& settings() 
 24839 |       { 
 24840 |          return settings_; 
 24841 |       } 
 24842 |  
 24843 |       inline parser_error::type get_error(const std::size_t& index) const 
 24844 |       { 
 24845 |          if (index < error_list_.size()) 
 24846 |          { 
 24847 |             return error_list_[index]; 
 24848 |          } 
 24849 |  
 24850 |          throw std::invalid_argument("parser::get_error() - Invalid error index specified"); 
 24851 |       } 
 24852 |  
 24853 |       inline std::string error() const 
 24854 |       { 
 24855 |          if (!error_list_.empty()) 
 24856 |          { 
 24857 |             return error_list_[0].diagnostic; 
 24858 |          } 
 24859 |          else 
 24860 |             return std::string("No Error"); 
 24861 |       } 
 24862 |  
 24863 |       inline std::size_t error_count() const 
 24864 |       { 
 24865 |          return error_list_.size(); 
 24866 |       } 
 24867 |  
 24868 |       inline dependent_entity_collector& dec() 
 24869 |       { 
 24870 |          return dec_; 
 24871 |       } 
 24872 |  
 24873 |       inline std::size_t total_local_symbol_size_bytes() const 
 24874 |       { 
 24875 |          return sem_.total_local_symb_size_bytes(); 
 24876 |       } 
 24877 |  
 24878 |       inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol) 
 24879 |       { 
 24880 |          if (!settings_.replacer_enabled()) 
 24881 |             return false; 
 24882 |          else if (details::is_reserved_word(old_symbol)) 
 24883 |             return false; 
 24884 |          else 
 24885 |             return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol); 
 24886 |       } 
 24887 |  
 24888 |       inline bool remove_replace_symbol(const std::string& symbol) 
 24889 |       { 
 24890 |          if (!settings_.replacer_enabled()) 
 24891 |             return false; 
 24892 |          else if (details::is_reserved_word(symbol)) 
 24893 |             return false; 
 24894 |          else 
 24895 |             return symbol_replacer_.remove(symbol); 
 24896 |       } 
 24897 |  
 24898 |       inline void enable_unknown_symbol_resolver(unknown_symbol_resolver* usr = reinterpret_cast<unknown_symbol_resolver*>(0)) 
 24899 |       { 
 24900 |          resolve_unknown_symbol_ = true; 
 24901 |  
 24902 |          if (usr) 
 24903 |             unknown_symbol_resolver_ = usr; 
 24904 |          else 
 24905 |             unknown_symbol_resolver_ = &default_usr_; 
 24906 |       } 
 24907 |  
 24908 |       inline void enable_unknown_symbol_resolver(unknown_symbol_resolver& usr) 
 24909 |       { 
 24910 |          enable_unknown_symbol_resolver(&usr); 
 24911 |       } 
 24912 |  
 24913 |       inline void disable_unknown_symbol_resolver() 
 24914 |       { 
 24915 |          resolve_unknown_symbol_  = false; 
 24916 |          unknown_symbol_resolver_ = &default_usr_; 
 24917 |       } 
 24918 |  
 24919 |       inline void register_loop_runtime_check(loop_runtime_check& lrtchk) 
 24920 |       { 
 24921 |          loop_runtime_check_ = &lrtchk; 
 24922 |       } 
 24923 |  
 24924 |       inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk) 
 24925 |       { 
 24926 |          vector_access_runtime_check_ = &vartchk; 
 24927 |       } 
 24928 |  
 24929 |       inline void register_compilation_timeout_check(compilation_check& compchk) 
 24930 |       { 
 24931 |          compilation_check_ptr_ = &compchk; 
 24932 |       } 
 24933 |  
 24934 |       inline void register_assert_check(assert_check& assrt_chck) 
 24935 |       { 
 24936 |          assert_check_ = &assrt_chck; 
 24937 |       } 
 24938 |  
 24939 |       inline void clear_loop_runtime_check() 
 24940 |       { 
 24941 |          loop_runtime_check_ = loop_runtime_check_ptr(0); 
 24942 |       } 
 24943 |  
 24944 |       inline void clear_vector_access_runtime_check() 
 24945 |       { 
 24946 |          vector_access_runtime_check_ = vector_access_runtime_check_ptr(0); 
 24947 |       } 
 24948 |  
 24949 |       inline void clear_compilation_timeout_check() 
 24950 |       { 
 24951 |          compilation_check_ptr_ = compilation_check_ptr(0); 
 24952 |       } 
 24953 |  
 24954 |       inline void clear_assert_check() 
 24955 |       { 
 24956 |          assert_check_ = assert_check_ptr(0); 
 24957 |       } 
 24958 |  
 24959 |    private: 
 24960 |  
 24961 |       inline bool valid_base_operation(const std::string& symbol) const 
 24962 |       { 
 24963 |          const std::size_t length = symbol.size(); 
 24964 |  
 24965 |          if ( 
 24966 |               (length < 3) || // Shortest base op symbol length 
 24967 |               (length > 9)    // Longest base op symbol length 
 24968 |             ) 
 24969 |             return false; 
 24970 |          else 
 24971 |             return settings_.function_enabled(symbol) && 
 24972 |                    (base_ops_map_.end() != base_ops_map_.find(symbol)); 
 24973 |       } 
 24974 |  
 24975 |       inline bool valid_vararg_operation(const std::string& symbol) const 
 24976 |       { 
 24977 |          static const std::string s_sum     = "sum" ; 
 24978 |          static const std::string s_mul     = "mul" ; 
 24979 |          static const std::string s_avg     = "avg" ; 
 24980 |          static const std::string s_min     = "min" ; 
 24981 |          static const std::string s_max     = "max" ; 
 24982 |          static const std::string s_mand    = "mand" 
 24983 |          static const std::string s_mor     = "mor" ; 
 24984 |          static const std::string s_multi   = "~"   ; 
 24985 |          static const std::string s_mswitch = "[*]" ; 
 24986 |  
 24987 |          return 
 24988 |                ( 
 24989 |                   details::imatch(symbol,s_sum    ) || 
 24990 |                   details::imatch(symbol,s_mul    ) || 
 24991 |                   details::imatch(symbol,s_avg    ) || 
 24992 |                   details::imatch(symbol,s_min    ) || 
 24993 |                   details::imatch(symbol,s_max    ) || 
 24994 |                   details::imatch(symbol,s_mand   ) || 
 24995 |                   details::imatch(symbol,s_mor    ) || 
 24996 |                   details::imatch(symbol,s_multi  ) || 
 24997 |                   details::imatch(symbol,s_mswitch) 
 24998 |                ) && 
 24999 |                settings_.function_enabled(symbol); 
 25000 |       } 
 25001 |  
 25002 |       bool is_invalid_logic_operation(const details::operator_type operation) const 
 25003 |       { 
 25004 |          return settings_.logic_disabled(operation); 
 25005 |       } 
 25006 |  
 25007 |       bool is_invalid_arithmetic_operation(const details::operator_type operation) const 
 25008 |       { 
 25009 |          return settings_.arithmetic_disabled(operation); 
 25010 |       } 
 25011 |  
 25012 |       bool is_invalid_assignment_operation(const details::operator_type operation) const 
 25013 |       { 
 25014 |          return settings_.assignment_disabled(operation); 
 25015 |       } 
 25016 |  
 25017 |       bool is_invalid_inequality_operation(const details::operator_type operation) const 
 25018 |       { 
 25019 |          return settings_.inequality_disabled(operation); 
 25020 |       } 
 25021 |  
 25022 |       #ifdef exprtk_enable_debugging 
 25023 |       inline void next_token() 
 25024 |       { 
 25025 |          const std::string ct_str = current_token().value; 
 25026 |          const std::size_t ct_pos = current_token().position; 
 25027 |          parser_helper::next_token(); 
 25028 |          const std::string depth(2 * state_.scope_depth,' '); 
 25029 |          exprtk_debug(("%s" 
 25030 |                        "prev[%s | %04d] --> curr[%s | %04d]  stack_level: %3d\n", 
 25031 |                        depth.c_str(), 
 25032 |                        ct_str.c_str(), 
 25033 |                        static_cast<unsigned int>(ct_pos), 
 25034 |                        current_token().value.c_str(), 
 25035 |                        static_cast<unsigned int>(current_token().position), 
 25036 |                        static_cast<unsigned int>(state_.stack_depth))); 
 25037 |       } 
 25038 |       #endif 
 25039 |  
 25040 |       inline expression_node_ptr parse_corpus() 
 25041 |       { 
 25042 |          std::vector<expression_node_ptr> arg_list; 
 25043 |          std::vector<bool> side_effect_list; 
 25044 |  
 25045 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 25046 |  
 25047 |          lexer::token begin_token; 
 25048 |          lexer::token end_token; 
 25049 |  
 25050 |          for ( ; ; ) 
 25051 |          { 
 25052 |             state_.side_effect_present = false; 
 25053 |  
 25054 |             begin_token = current_token(); 
 25055 |  
 25056 |             expression_node_ptr arg = parse_expression(); 
 25057 |  
 25058 |             if (0 == arg) 
 25059 |             { 
 25060 |                if (error_list_.empty()) 
 25061 |                { 
 25062 |                   set_error(make_error( 
 25063 |                      parser_error::e_syntax, 
 25064 |                      current_token(), 
 25065 |                      "ERR009 - Invalid expression encountered", 
 25066 |                      exprtk_error_location)); 
 25067 |                } 
 25068 |  
 25069 |                return error_node(); 
 25070 |             } 
 25071 |             else 
 25072 |             { 
 25073 |                arg_list.push_back(arg); 
 25074 |  
 25075 |                side_effect_list.push_back(state_.side_effect_present); 
 25076 |  
 25077 |                end_token = current_token(); 
 25078 |  
 25079 |                const std::string sub_expr = construct_subexpr(begin_token, end_token); 
 25080 |  
 25081 |                exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n", 
 25082 |                              static_cast<int>(arg_list.size() - 1), 
 25083 |                              sub_expr.c_str())); 
 25084 |  
 25085 |                exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n", 
 25086 |                              static_cast<int>(arg_list.size() - 1), 
 25087 |                              state_.side_effect_present ? "true" : "false")); 
 25088 |  
 25089 |                exprtk_debug(("-------------------------------------------------\n")); 
 25090 |             } 
 25091 |  
 25092 |             if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 25093 |             { 
 25094 |                if (lexer().finished()) 
 25095 |                   break; 
 25096 |                else 
 25097 |                   next_token(); 
 25098 |             } 
 25099 |             else if ( 
 25100 |                       !settings_.commutative_check_enabled() && 
 25101 |                       ( 
 25102 |                         current_token().type == token_t::e_symbol || 
 25103 |                         current_token().type == token_t::e_number || 
 25104 |                         current_token().type == token_t::e_string || 
 25105 |                         token_is_bracket(prsrhlpr_t::e_hold) 
 25106 |                       ) 
 25107 |                     ) 
 25108 |             { 
 25109 |                set_error(make_error( 
 25110 |                   parser_error::e_syntax, 
 25111 |                   current_token(), 
 25112 |                   "ERR010 - Invalid syntax '" + current_token().value  + "' possible missing operator or context", 
 25113 |                   exprtk_error_location)); 
 25114 |  
 25115 |                return error_node(); 
 25116 |             } 
 25117 |          } 
 25118 |  
 25119 |          if ( 
 25120 |               !arg_list.empty() && 
 25121 |               is_return_node(arg_list.back()) 
 25122 |             ) 
 25123 |          { 
 25124 |             dec_.final_stmt_return_ = true; 
 25125 |          } 
 25126 |  
 25127 |          const expression_node_ptr result = simplify(arg_list,side_effect_list); 
 25128 |  
 25129 |          sdd.delete_ptr = (0 == result); 
 25130 |  
 25131 |          return result; 
 25132 |       } 
 25133 |  
 25134 |       std::string construct_subexpr(lexer::token& begin_token, 
 25135 |                                     lexer::token& end_token, 
 25136 |                                     const bool cleanup_whitespace = true) 
 25137 |       { 
 25138 |          std::string result = lexer().substr(begin_token.position,end_token.position); 
 25139 |          if (cleanup_whitespace) 
 25140 |          { 
 25141 |             for (std::size_t i = 0; i < result.size(); ++i) 
 25142 |             { 
 25143 |                if (details::is_whitespace(result[i])) result[i] = ' '; 
 25144 |             } 
 25145 |          } 
 25146 |  
 25147 |          return result; 
 25148 |       } 
 25149 |  
 25150 |       static const precedence_level default_precedence = e_level00; 
 25151 |  
 25152 |       struct state_t 
 25153 |       { 
 25154 |          inline void set(const precedence_level& l, 
 25155 |                          const precedence_level& r, 
 25156 |                          const details::operator_type& o, 
 25157 |                          const token_t tkn = token_t()) 
 25158 |          { 
 25159 |             left      = l; 
 25160 |             right     = r; 
 25161 |             operation = o; 
 25162 |             token     = tkn; 
 25163 |          } 
 25164 |  
 25165 |          inline void reset() 
 25166 |          { 
 25167 |             left      = e_level00; 
 25168 |             right     = e_level00; 
 25169 |             operation = details::e_default; 
 25170 |          } 
 25171 |  
 25172 |          precedence_level left; 
 25173 |          precedence_level right; 
 25174 |          details::operator_type operation; 
 25175 |          token_t token; 
 25176 |       }; 
 25177 |  
 25178 |       inline void push_current_state(const state_t current_state) 
 25179 |       { 
 25180 |          current_state_stack_.push_back(current_state); 
 25181 |       } 
 25182 |  
 25183 |       inline void pop_current_state() 
 25184 |       { 
 25185 |          if (!current_state_stack_.empty()) 
 25186 |          { 
 25187 |             current_state_stack_.pop_back(); 
 25188 |          } 
 25189 |       } 
 25190 |  
 25191 |       inline state_t current_state() const 
 25192 |       { 
 25193 |          return (!current_state_stack_.empty()) ? 
 25194 |                 current_state_stack_.back()     : 
 25195 |                 state_t(); 
 25196 |       } 
 25197 |  
 25198 |       inline bool halt_compilation_check() 
 25199 |       { 
 25200 |          compilation_check::compilation_context context; 
 25201 |  
 25202 |          if (compilation_check_ptr_ && !compilation_check_ptr_->continue_compilation(context)) 
 25203 |          { 
 25204 |             const std::string error_message = 
 25205 |                !context.error_message.empty() ? " Details: " + context.error_message : "" 
 25206 |  
 25207 |             set_error(make_error( 
 25208 |                parser_error::e_parser, 
 25209 |                token_t(), 
 25210 |                "ERR011 - Internal compilation check failed." + error_message, 
 25211 |                exprtk_error_location)); 
 25212 |  
 25213 |             return true; 
 25214 |          } 
 25215 |  
 25216 |          return false; 
 25217 |       } 
 25218 |  
 25219 |       inline expression_node_ptr parse_expression(precedence_level precedence = e_level00) 
 25220 |       { 
 25221 |          if (halt_compilation_check()) 
 25222 |          { 
 25223 |             exprtk_debug(("halt_compilation_check() - parse_expression checkpoint 2\n")); 
 25224 |             return error_node(); 
 25225 |          } 
 25226 |  
 25227 |          stack_limit_handler slh(*this); 
 25228 |  
 25229 |          if (!slh) 
 25230 |          { 
 25231 |             return error_node(); 
 25232 |          } 
 25233 |  
 25234 |          expression_node_ptr expression = parse_branch(precedence); 
 25235 |  
 25236 |          if (0 == expression) 
 25237 |          { 
 25238 |             return error_node(); 
 25239 |          } 
 25240 |  
 25241 |          if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 25242 |          { 
 25243 |             return expression; 
 25244 |          } 
 25245 |  
 25246 |          bool break_loop = false; 
 25247 |  
 25248 |          state_t current_state; 
 25249 |  
 25250 |          for ( ; ; ) 
 25251 |          { 
 25252 |             current_state.reset(); 
 25253 |  
 25254 |             switch (current_token().type) 
 25255 |             { 
 25256 |                case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign, current_token()); break; 
 25257 |                case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass, current_token()); break; 
 25258 |                case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass, current_token()); break; 
 25259 |                case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass, current_token()); break; 
 25260 |                case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass, current_token()); break; 
 25261 |                case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass, current_token()); break; 
 25262 |                case token_t::e_swap   : current_state.set(e_level00, e_level00, details::e_swap  , current_token()); break; 
 25263 |                case token_t::e_lt     : current_state.set(e_level05, e_level06, details::e_lt    , current_token()); break; 
 25264 |                case token_t::e_lte    : current_state.set(e_level05, e_level06, details::e_lte   , current_token()); break; 
 25265 |                case token_t::e_eq     : current_state.set(e_level05, e_level06, details::e_eq    , current_token()); break; 
 25266 |                case token_t::e_ne     : current_state.set(e_level05, e_level06, details::e_ne    , current_token()); break; 
 25267 |                case token_t::e_gte    : current_state.set(e_level05, e_level06, details::e_gte   , current_token()); break; 
 25268 |                case token_t::e_gt     : current_state.set(e_level05, e_level06, details::e_gt    , current_token()); break; 
 25269 |                case token_t::e_add    : current_state.set(e_level07, e_level08, details::e_add   , current_token()); break; 
 25270 |                case token_t::e_sub    : current_state.set(e_level07, e_level08, details::e_sub   , current_token()); break; 
 25271 |                case token_t::e_div    : current_state.set(e_level10, e_level11, details::e_div   , current_token()); break; 
 25272 |                case token_t::e_mul    : current_state.set(e_level10, e_level11, details::e_mul   , current_token()); break; 
 25273 |                case token_t::e_mod    : current_state.set(e_level10, e_level11, details::e_mod   , current_token()); break; 
 25274 |                case token_t::e_pow    : current_state.set(e_level12, e_level12, details::e_pow   , current_token()); break; 
 25275 |                default                : 
 25276 |                   if (token_t::e_symbol == current_token().type) 
 25277 |                   { 
 25278 |                      static const std::string s_and   = "and"  ; 
 25279 |                      static const std::string s_nand  = "nand" ; 
 25280 |                      static const std::string s_or    = "or"   ; 
 25281 |                      static const std::string s_nor   = "nor"  ; 
 25282 |                      static const std::string s_xor   = "xor"  ; 
 25283 |                      static const std::string s_xnor  = "xnor" ; 
 25284 |                      static const std::string s_in    = "in"   ; 
 25285 |                      static const std::string s_like  = "like" ; 
 25286 |                      static const std::string s_ilike = "ilike" 
 25287 |                      static const std::string s_and1  = "&"    ; 
 25288 |                      static const std::string s_or1   = "|"    ; 
 25289 |                      static const std::string s_not   = "not"  ; 
 25290 |  
 25291 |                      if (details::imatch(current_token().value,s_and)) 
 25292 |                      { 
 25293 |                         current_state.set(e_level03, e_level04, details::e_and, current_token()); 
 25294 |                         break; 
 25295 |                      } 
 25296 |                      else if (details::imatch(current_token().value,s_and1)) 
 25297 |                      { 
 25298 |                         #ifndef exprtk_disable_sc_andor 
 25299 |                         current_state.set(e_level03, e_level04, details::e_scand, current_token()); 
 25300 |                         #else 
 25301 |                         current_state.set(e_level03, e_level04, details::e_and, current_token()); 
 25302 |                         #endif 
 25303 |                         break; 
 25304 |                      } 
 25305 |                      else if (details::imatch(current_token().value,s_nand)) 
 25306 |                      { 
 25307 |                         current_state.set(e_level03, e_level04, details::e_nand, current_token()); 
 25308 |                         break; 
 25309 |                      } 
 25310 |                      else if (details::imatch(current_token().value,s_or)) 
 25311 |                      { 
 25312 |                         current_state.set(e_level01, e_level02, details::e_or, current_token()); 
 25313 |                         break; 
 25314 |                      } 
 25315 |                      else if (details::imatch(current_token().value,s_or1)) 
 25316 |                      { 
 25317 |                         #ifndef exprtk_disable_sc_andor 
 25318 |                         current_state.set(e_level01, e_level02, details::e_scor, current_token()); 
 25319 |                         #else 
 25320 |                         current_state.set(e_level01, e_level02, details::e_or, current_token()); 
 25321 |                         #endif 
 25322 |                         break; 
 25323 |                      } 
 25324 |                      else if (details::imatch(current_token().value,s_nor)) 
 25325 |                      { 
 25326 |                         current_state.set(e_level01, e_level02, details::e_nor, current_token()); 
 25327 |                         break; 
 25328 |                      } 
 25329 |                      else if (details::imatch(current_token().value,s_xor)) 
 25330 |                      { 
 25331 |                         current_state.set(e_level01, e_level02, details::e_xor, current_token()); 
 25332 |                         break; 
 25333 |                      } 
 25334 |                      else if (details::imatch(current_token().value,s_xnor)) 
 25335 |                      { 
 25336 |                         current_state.set(e_level01, e_level02, details::e_xnor, current_token()); 
 25337 |                         break; 
 25338 |                      } 
 25339 |                      else if (details::imatch(current_token().value,s_in)) 
 25340 |                      { 
 25341 |                         current_state.set(e_level04, e_level04, details::e_in, current_token()); 
 25342 |                         break; 
 25343 |                      } 
 25344 |                      else if (details::imatch(current_token().value,s_like)) 
 25345 |                      { 
 25346 |                         current_state.set(e_level04, e_level04, details::e_like, current_token()); 
 25347 |                         break; 
 25348 |                      } 
 25349 |                      else if (details::imatch(current_token().value,s_ilike)) 
 25350 |                      { 
 25351 |                         current_state.set(e_level04, e_level04, details::e_ilike, current_token()); 
 25352 |                         break; 
 25353 |                      } 
 25354 |                      else if (details::imatch(current_token().value,s_not)) 
 25355 |                      { 
 25356 |                         break; 
 25357 |                      } 
 25358 |                   } 
 25359 |  
 25360 |                   break_loop = true; 
 25361 |             } 
 25362 |  
 25363 |             if (break_loop) 
 25364 |             { 
 25365 |                parse_pending_string_rangesize(expression); 
 25366 |                break; 
 25367 |             } 
 25368 |             else if (current_state.left < precedence) 
 25369 |                break; 
 25370 |  
 25371 |             const lexer::token prev_token = current_token(); 
 25372 |  
 25373 |             next_token(); 
 25374 |  
 25375 |             expression_node_ptr right_branch   = error_node(); 
 25376 |             expression_node_ptr new_expression = error_node(); 
 25377 |  
 25378 |             if (is_invalid_logic_operation(current_state.operation)) 
 25379 |             { 
 25380 |                free_node(node_allocator_, expression); 
 25381 |  
 25382 |                set_error(make_error( 
 25383 |                   parser_error::e_syntax, 
 25384 |                   prev_token, 
 25385 |                   "ERR012 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'", 
 25386 |                   exprtk_error_location)); 
 25387 |  
 25388 |                return error_node(); 
 25389 |             } 
 25390 |             else if (is_invalid_arithmetic_operation(current_state.operation)) 
 25391 |             { 
 25392 |                free_node(node_allocator_, expression); 
 25393 |  
 25394 |                set_error(make_error( 
 25395 |                   parser_error::e_syntax, 
 25396 |                   prev_token, 
 25397 |                   "ERR013 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'", 
 25398 |                   exprtk_error_location)); 
 25399 |  
 25400 |                return error_node(); 
 25401 |             } 
 25402 |             else if (is_invalid_inequality_operation(current_state.operation)) 
 25403 |             { 
 25404 |                free_node(node_allocator_, expression); 
 25405 |  
 25406 |                set_error(make_error( 
 25407 |                   parser_error::e_syntax, 
 25408 |                   prev_token, 
 25409 |                   "ERR014 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'", 
 25410 |                   exprtk_error_location)); 
 25411 |  
 25412 |                return error_node(); 
 25413 |             } 
 25414 |             else if (is_invalid_assignment_operation(current_state.operation)) 
 25415 |             { 
 25416 |                free_node(node_allocator_, expression); 
 25417 |  
 25418 |                set_error(make_error( 
 25419 |                   parser_error::e_syntax, 
 25420 |                   prev_token, 
 25421 |                   "ERR015 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'", 
 25422 |                   exprtk_error_location)); 
 25423 |  
 25424 |                return error_node(); 
 25425 |             } 
 25426 |  
 25427 |             if (0 != (right_branch = parse_expression(current_state.right))) 
 25428 |             { 
 25429 |                if ( 
 25430 |                     details::is_return_node(expression  ) || 
 25431 |                     details::is_return_node(right_branch) 
 25432 |                   ) 
 25433 |                { 
 25434 |                   free_node(node_allocator_, expression  ); 
 25435 |                   free_node(node_allocator_, right_branch); 
 25436 |  
 25437 |                   set_error(make_error( 
 25438 |                      parser_error::e_syntax, 
 25439 |                      prev_token, 
 25440 |                      "ERR016 - Return statements cannot be part of sub-expressions", 
 25441 |                      exprtk_error_location)); 
 25442 |  
 25443 |                   return error_node(); 
 25444 |                } 
 25445 |  
 25446 |                push_current_state(current_state); 
 25447 |  
 25448 |                new_expression = expression_generator_ 
 25449 |                                   ( 
 25450 |                                     current_state.operation, 
 25451 |                                     expression, 
 25452 |                                     right_branch 
 25453 |                                   ); 
 25454 |  
 25455 |                pop_current_state(); 
 25456 |             } 
 25457 |  
 25458 |             if (0 == new_expression) 
 25459 |             { 
 25460 |                if (error_list_.empty()) 
 25461 |                { 
 25462 |                   set_error(make_error( 
 25463 |                      parser_error::e_syntax, 
 25464 |                      prev_token, 
 25465 |                      !synthesis_error_.empty() ? 
 25466 |                      synthesis_error_ : 
 25467 |                      "ERR017 - General parsing error at token: '" + prev_token.value + "'", 
 25468 |                      exprtk_error_location)); 
 25469 |                } 
 25470 |  
 25471 |                free_node(node_allocator_, expression  ); 
 25472 |                free_node(node_allocator_, right_branch); 
 25473 |  
 25474 |                return error_node(); 
 25475 |             } 
 25476 |             else 
 25477 |             { 
 25478 |                if ( 
 25479 |                     token_is(token_t::e_ternary,prsrhlpr_t::e_hold) && 
 25480 |                     (e_level00 == precedence) 
 25481 |                   ) 
 25482 |                { 
 25483 |                   expression = parse_ternary_conditional_statement(new_expression); 
 25484 |                } 
 25485 |                else 
 25486 |                   expression = new_expression; 
 25487 |  
 25488 |                parse_pending_string_rangesize(expression); 
 25489 |             } 
 25490 |          } 
 25491 |  
 25492 |          if ((0 != expression) && (expression->node_depth() > settings_.max_node_depth_)) 
 25493 |          { 
 25494 |             set_error(make_error( 
 25495 |                parser_error::e_syntax, 
 25496 |                current_token(), 
 25497 |                "ERR018 - Expression depth of " + details::to_str(static_cast<int>(expression->node_depth())) + 
 25498 |                " exceeds maximum allowed expression depth of " + details::to_str(static_cast<int>(settings_.max_node_depth_)), 
 25499 |                exprtk_error_location)); 
 25500 |  
 25501 |             free_node(node_allocator_, expression); 
 25502 |  
 25503 |             return error_node(); 
 25504 |          } 
 25505 |          else if ( 
 25506 |                    !settings_.commutative_check_enabled()          && 
 25507 |                    !details::is_logic_opr(current_token().value)   && 
 25508 |                    (current_state.operation == details::e_default) && 
 25509 |                    ( 
 25510 |                      current_token().type == token_t::e_symbol || 
 25511 |                      current_token().type == token_t::e_number || 
 25512 |                      current_token().type == token_t::e_string 
 25513 |                    ) 
 25514 |                  ) 
 25515 |          { 
 25516 |             set_error(make_error( 
 25517 |                parser_error::e_syntax, 
 25518 |                current_token(), 
 25519 |                "ERR019 - Invalid syntax '" + current_token().value  + "' possible missing operator or context", 
 25520 |                exprtk_error_location)); 
 25521 |  
 25522 |             free_node(node_allocator_, expression); 
 25523 |  
 25524 |             return error_node(); 
 25525 |          } 
 25526 |  
 25527 |          return expression; 
 25528 |       } 
 25529 |  
 25530 |       bool simplify_unary_negation_branch(expression_node_ptr& node) 
 25531 |       { 
 25532 |          { 
 25533 |             typedef details::unary_branch_node<T,details::neg_op<T> > ubn_t; 
 25534 |             ubn_t* n = dynamic_cast<ubn_t*>(node); 
 25535 |  
 25536 |             if (n) 
 25537 |             { 
 25538 |                expression_node_ptr un_r = n->branch(0); 
 25539 |                n->release(); 
 25540 |                free_node(node_allocator_, node); 
 25541 |                node = un_r; 
 25542 |  
 25543 |                return true; 
 25544 |             } 
 25545 |          } 
 25546 |  
 25547 |          { 
 25548 |             typedef details::unary_variable_node<T,details::neg_op<T> > uvn_t; 
 25549 |  
 25550 |             uvn_t* n = dynamic_cast<uvn_t*>(node); 
 25551 |  
 25552 |             if (n) 
 25553 |             { 
 25554 |                const T& v = n->v(); 
 25555 |                expression_node_ptr return_node = error_node(); 
 25556 |  
 25557 |                if ( 
 25558 |                     (0 != (return_node = symtab_store_.get_variable(v))) || 
 25559 |                     (0 != (return_node = sem_         .get_variable(v))) 
 25560 |                   ) 
 25561 |                { 
 25562 |                   free_node(node_allocator_, node); 
 25563 |                   node = return_node; 
 25564 |  
 25565 |                   return true; 
 25566 |                } 
 25567 |                else 
 25568 |                { 
 25569 |                   set_error(make_error( 
 25570 |                      parser_error::e_syntax, 
 25571 |                      current_token(), 
 25572 |                      "ERR020 - Failed to find variable node in symbol table", 
 25573 |                      exprtk_error_location)); 
 25574 |  
 25575 |                   free_node(node_allocator_, node); 
 25576 |  
 25577 |                   return false; 
 25578 |                } 
 25579 |             } 
 25580 |          } 
 25581 |  
 25582 |          return false; 
 25583 |       } 
 25584 |  
 25585 |       static inline expression_node_ptr error_node() 
 25586 |       { 
 25587 |          return reinterpret_cast<expression_node_ptr>(0); 
 25588 |       } 
 25589 |  
 25590 |       struct scoped_expression_delete 
 25591 |       { 
 25592 |          scoped_expression_delete(parser<T>& pr, expression_node_ptr& expression) 
 25593 |          : delete_ptr(true) 
 25594 |          , parser_(pr) 
 25595 |          , expression_(expression) 
 25596 |          {} 
 25597 |  
 25598 |         ~scoped_expression_delete() 
 25599 |          { 
 25600 |             if (delete_ptr) 
 25601 |             { 
 25602 |                free_node(parser_.node_allocator_, expression_); 
 25603 |             } 
 25604 |          } 
 25605 |  
 25606 |          bool delete_ptr; 
 25607 |          parser<T>& parser_; 
 25608 |          expression_node_ptr& expression_; 
 25609 |  
 25610 |       private: 
 25611 |  
 25612 |          scoped_expression_delete(const scoped_expression_delete&) exprtk_delete; 
 25613 |          scoped_expression_delete& operator=(const scoped_expression_delete&) exprtk_delete; 
 25614 |       }; 
 25615 |  
 25616 |       template <typename Type, std::size_t N> 
 25617 |       struct scoped_delete 
 25618 |       { 
 25619 |          typedef Type* ptr_t; 
 25620 |  
 25621 |          scoped_delete(parser<T>& pr, ptr_t& p) 
 25622 |          : delete_ptr(true) 
 25623 |          , parser_(pr) 
 25624 |          , p_(&p) 
 25625 |          {} 
 25626 |  
 25627 |          scoped_delete(parser<T>& pr, ptr_t (&p)[N]) 
 25628 |          : delete_ptr(true) 
 25629 |          , parser_(pr) 
 25630 |          , p_(&p[0]) 
 25631 |          {} 
 25632 |  
 25633 |         ~scoped_delete() 
 25634 |          { 
 25635 |             if (delete_ptr) 
 25636 |             { 
 25637 |                for (std::size_t i = 0; i < N; ++i) 
 25638 |                { 
 25639 |                   free_node(parser_.node_allocator_, p_[i]); 
 25640 |                } 
 25641 |             } 
 25642 |          } 
 25643 |  
 25644 |          bool delete_ptr; 
 25645 |          parser<T>& parser_; 
 25646 |          ptr_t* p_; 
 25647 |  
 25648 |       private: 
 25649 |  
 25650 |          scoped_delete(const scoped_delete<Type,N>&) exprtk_delete; 
 25651 |          scoped_delete<Type,N>& operator=(const scoped_delete<Type,N>&) exprtk_delete; 
 25652 |       }; 
 25653 |  
 25654 |       template <typename Type> 
 25655 |       struct scoped_deq_delete 
 25656 |       { 
 25657 |          typedef Type* ptr_t; 
 25658 |  
 25659 |          scoped_deq_delete(parser<T>& pr, std::deque<ptr_t>& deq) 
 25660 |          : delete_ptr(true) 
 25661 |          , parser_(pr) 
 25662 |          , deq_(deq) 
 25663 |          {} 
 25664 |  
 25665 |         ~scoped_deq_delete() 
 25666 |          { 
 25667 |             if (delete_ptr && !deq_.empty()) 
 25668 |             { 
 25669 |                for (std::size_t i = 0; i < deq_.size(); ++i) 
 25670 |                { 
 25671 |                   exprtk_debug(("~scoped_deq_delete() - deleting node: %p\n", reinterpret_cast<void*>(deq_[i]))); 
 25672 |                   free_node(parser_.node_allocator_,deq_[i]); 
 25673 |                } 
 25674 |  
 25675 |                deq_.clear(); 
 25676 |             } 
 25677 |          } 
 25678 |  
 25679 |          bool delete_ptr; 
 25680 |          parser<T>& parser_; 
 25681 |          std::deque<ptr_t>& deq_; 
 25682 |  
 25683 |       private: 
 25684 |  
 25685 |          scoped_deq_delete(const scoped_deq_delete<Type>&) exprtk_delete; 
 25686 |          scoped_deq_delete<Type>& operator=(const scoped_deq_delete<Type>&) exprtk_delete; 
 25687 |       }; 
 25688 |  
 25689 |       template <typename Type> 
 25690 |       struct scoped_vec_delete 
 25691 |       { 
 25692 |          typedef Type* ptr_t; 
 25693 |  
 25694 |          scoped_vec_delete(parser<T>& pr, std::vector<ptr_t>& vec) 
 25695 |          : delete_ptr(true) 
 25696 |          , parser_(pr) 
 25697 |          , vec_(vec) 
 25698 |          {} 
 25699 |  
 25700 |         ~scoped_vec_delete() 
 25701 |          { 
 25702 |             if (delete_ptr && !vec_.empty()) 
 25703 |             { 
 25704 |                for (std::size_t i = 0; i < vec_.size(); ++i) 
 25705 |                { 
 25706 |                   exprtk_debug(("~scoped_vec_delete() - deleting node: %p\n", reinterpret_cast<void*>(vec_[i]))); 
 25707 |                   free_node(parser_.node_allocator_,vec_[i]); 
 25708 |                } 
 25709 |  
 25710 |                vec_.clear(); 
 25711 |             } 
 25712 |          } 
 25713 |  
 25714 |          ptr_t operator[](const std::size_t index) 
 25715 |          { 
 25716 |             return vec_[index]; 
 25717 |          } 
 25718 |  
 25719 |          bool delete_ptr; 
 25720 |          parser<T>& parser_; 
 25721 |          std::vector<ptr_t>& vec_; 
 25722 |  
 25723 |       private: 
 25724 |  
 25725 |          scoped_vec_delete(const scoped_vec_delete<Type>&) exprtk_delete; 
 25726 |          scoped_vec_delete<Type>& operator=(const scoped_vec_delete<Type>&) exprtk_delete; 
 25727 |       }; 
 25728 |  
 25729 |       struct scoped_bool_negator 
 25730 |       { 
 25731 |          explicit scoped_bool_negator(bool& bb) 
 25732 |          : b(bb) 
 25733 |          { b = !b; } 
 25734 |  
 25735 |         ~scoped_bool_negator() 
 25736 |          { b = !b; } 
 25737 |  
 25738 |          bool& b; 
 25739 |       }; 
 25740 |  
 25741 |       struct scoped_bool_or_restorer 
 25742 |       { 
 25743 |          explicit scoped_bool_or_restorer(bool& bb) 
 25744 |          : b(bb) 
 25745 |          , original_value_(bb) 
 25746 |          {} 
 25747 |  
 25748 |         ~scoped_bool_or_restorer() 
 25749 |          { 
 25750 |             b = b || original_value_; 
 25751 |          } 
 25752 |  
 25753 |          bool& b; 
 25754 |          bool original_value_; 
 25755 |       }; 
 25756 |  
 25757 |       struct scoped_inc_dec 
 25758 |       { 
 25759 |          explicit scoped_inc_dec(std::size_t& v) 
 25760 |          : v_(v) 
 25761 |          { ++v_; } 
 25762 |  
 25763 |         ~scoped_inc_dec() 
 25764 |          { 
 25765 |            assert(v_ > 0); 
 25766 |            --v_; 
 25767 |          } 
 25768 |  
 25769 |          std::size_t& v_; 
 25770 |       }; 
 25771 |  
 25772 |       inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name) 
 25773 |       { 
 25774 |          expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0); 
 25775 |  
 25776 |          switch (function->param_count) 
 25777 |          { 
 25778 |             case  0 : func_node = parse_function_call_0  (function,function_name); break; 
 25779 |             case  1 : func_node = parse_function_call< 1>(function,function_name); break; 
 25780 |             case  2 : func_node = parse_function_call< 2>(function,function_name); break; 
 25781 |             case  3 : func_node = parse_function_call< 3>(function,function_name); break; 
 25782 |             case  4 : func_node = parse_function_call< 4>(function,function_name); break; 
 25783 |             case  5 : func_node = parse_function_call< 5>(function,function_name); break; 
 25784 |             case  6 : func_node = parse_function_call< 6>(function,function_name); break; 
 25785 |             case  7 : func_node = parse_function_call< 7>(function,function_name); break; 
 25786 |             case  8 : func_node = parse_function_call< 8>(function,function_name); break; 
 25787 |             case  9 : func_node = parse_function_call< 9>(function,function_name); break; 
 25788 |             case 10 : func_node = parse_function_call<10>(function,function_name); break; 
 25789 |             case 11 : func_node = parse_function_call<11>(function,function_name); break; 
 25790 |             case 12 : func_node = parse_function_call<12>(function,function_name); break; 
 25791 |             case 13 : func_node = parse_function_call<13>(function,function_name); break; 
 25792 |             case 14 : func_node = parse_function_call<14>(function,function_name); break; 
 25793 |             case 15 : func_node = parse_function_call<15>(function,function_name); break; 
 25794 |             case 16 : func_node = parse_function_call<16>(function,function_name); break; 
 25795 |             case 17 : func_node = parse_function_call<17>(function,function_name); break; 
 25796 |             case 18 : func_node = parse_function_call<18>(function,function_name); break; 
 25797 |             case 19 : func_node = parse_function_call<19>(function,function_name); break; 
 25798 |             case 20 : func_node = parse_function_call<20>(function,function_name); break; 
 25799 |             default : { 
 25800 |                          set_error(make_error( 
 25801 |                            parser_error::e_syntax, 
 25802 |                            current_token(), 
 25803 |                            "ERR021 - Invalid number of parameters for function: '" + function_name + "'", 
 25804 |                            exprtk_error_location)); 
 25805 |  
 25806 |                          return error_node(); 
 25807 |                       } 
 25808 |          } 
 25809 |  
 25810 |          if (func_node) 
 25811 |             return func_node; 
 25812 |          else 
 25813 |          { 
 25814 |             set_error(make_error( 
 25815 |                parser_error::e_syntax, 
 25816 |                current_token(), 
 25817 |                "ERR022 - Failed to generate call to function: '" + function_name + "'", 
 25818 |                exprtk_error_location)); 
 25819 |  
 25820 |             return error_node(); 
 25821 |          } 
 25822 |       } 
 25823 |  
 25824 |       template <std::size_t NumberofParameters> 
 25825 |       inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name) 
 25826 |       { 
 25827 |          #ifdef _MSC_VER 
 25828 |             #pragma warning(push) 
 25829 |             #pragma warning(disable: 4127) 
 25830 |          #endif 
 25831 |          if (0 == NumberofParameters) 
 25832 |          { 
 25833 |             set_error(make_error( 
 25834 |                parser_error::e_syntax, 
 25835 |                current_token(), 
 25836 |                "ERR023 - Expecting ifunction '" + function_name + "' to have non-zero parameter count", 
 25837 |                exprtk_error_location)); 
 25838 |  
 25839 |             return error_node(); 
 25840 |          } 
 25841 |          #ifdef _MSC_VER 
 25842 |             #pragma warning(pop) 
 25843 |          #endif 
 25844 |  
 25845 |          expression_node_ptr branch[NumberofParameters]; 
 25846 |          expression_node_ptr result  = error_node(); 
 25847 |  
 25848 |          std::fill_n(branch, NumberofParameters, reinterpret_cast<expression_node_ptr>(0)); 
 25849 |  
 25850 |          scoped_delete<expression_node_t,NumberofParameters> sd((*this),branch); 
 25851 |  
 25852 |          next_token(); 
 25853 |  
 25854 |          if (!token_is(token_t::e_lbracket)) 
 25855 |          { 
 25856 |             set_error(make_error( 
 25857 |                parser_error::e_syntax, 
 25858 |                current_token(), 
 25859 |                "ERR024 - Expecting argument list for function: '" + function_name + "'", 
 25860 |                exprtk_error_location)); 
 25861 |  
 25862 |             return error_node(); 
 25863 |          } 
 25864 |  
 25865 |          for (int i = 0; i < static_cast<int>(NumberofParameters); ++i) 
 25866 |          { 
 25867 |             branch[i] = parse_expression(); 
 25868 |  
 25869 |             if (0 == branch[i]) 
 25870 |             { 
 25871 |                set_error(make_error( 
 25872 |                   parser_error::e_syntax, 
 25873 |                   current_token(), 
 25874 |                   "ERR025 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'", 
 25875 |                   exprtk_error_location)); 
 25876 |  
 25877 |                return error_node(); 
 25878 |             } 
 25879 |             else if (i < static_cast<int>(NumberofParameters - 1)) 
 25880 |             { 
 25881 |                if (!token_is(token_t::e_comma)) 
 25882 |                { 
 25883 |                   set_error(make_error( 
 25884 |                      parser_error::e_syntax, 
 25885 |                      current_token(), 
 25886 |                      "ERR026 - Invalid number of arguments for function: '" + function_name + "'", 
 25887 |                      exprtk_error_location)); 
 25888 |  
 25889 |                   return error_node(); 
 25890 |                } 
 25891 |             } 
 25892 |          } 
 25893 |  
 25894 |          if (!token_is(token_t::e_rbracket)) 
 25895 |          { 
 25896 |             set_error(make_error( 
 25897 |                parser_error::e_syntax, 
 25898 |                current_token(), 
 25899 |                "ERR027 - Invalid number of arguments for function: '" + function_name + "'", 
 25900 |                exprtk_error_location)); 
 25901 |  
 25902 |             return error_node(); 
 25903 |          } 
 25904 |          else 
 25905 |             result = expression_generator_.function(function,branch); 
 25906 |  
 25907 |          sd.delete_ptr = (0 == result); 
 25908 |  
 25909 |          return result; 
 25910 |       } 
 25911 |  
 25912 |       inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name) 
 25913 |       { 
 25914 |          expression_node_ptr result = expression_generator_.function(function); 
 25915 |  
 25916 |          state_.side_effect_present = function->has_side_effects(); 
 25917 |  
 25918 |          next_token(); 
 25919 |  
 25920 |          if ( 
 25921 |                token_is(token_t::e_lbracket) && 
 25922 |               !token_is(token_t::e_rbracket) 
 25923 |             ) 
 25924 |          { 
 25925 |             set_error(make_error( 
 25926 |                parser_error::e_syntax, 
 25927 |                current_token(), 
 25928 |                "ERR028 - Expecting '()' to proceed call to function: '" + function_name + "'", 
 25929 |                exprtk_error_location)); 
 25930 |  
 25931 |             free_node(node_allocator_, result); 
 25932 |  
 25933 |             return error_node(); 
 25934 |          } 
 25935 |          else 
 25936 |             return result; 
 25937 |       } 
 25938 |  
 25939 |       template <std::size_t MaxNumberofParameters> 
 25940 |       inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters], const std::string& function_name = "") 
 25941 |       { 
 25942 |          std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0)); 
 25943 |  
 25944 |          scoped_delete<expression_node_t,MaxNumberofParameters> sd((*this),param_list); 
 25945 |  
 25946 |          next_token(); 
 25947 |  
 25948 |          if (!token_is(token_t::e_lbracket)) 
 25949 |          { 
 25950 |             set_error(make_error( 
 25951 |                parser_error::e_syntax, 
 25952 |                current_token(), 
 25953 |                "ERR029 - Expected a '(' at start of function call to '" + function_name  + 
 25954 |                "', instead got: '" + current_token().value + "'", 
 25955 |                exprtk_error_location)); 
 25956 |  
 25957 |             return 0; 
 25958 |          } 
 25959 |  
 25960 |          if (token_is(token_t::e_rbracket, e_hold)) 
 25961 |          { 
 25962 |             set_error(make_error( 
 25963 |                parser_error::e_syntax, 
 25964 |                current_token(), 
 25965 |                "ERR030 - Expected at least one input parameter for function call '" + function_name + "'", 
 25966 |                exprtk_error_location)); 
 25967 |  
 25968 |             return 0; 
 25969 |          } 
 25970 |  
 25971 |          std::size_t param_index = 0; 
 25972 |  
 25973 |          for (; param_index < MaxNumberofParameters; ++param_index) 
 25974 |          { 
 25975 |             param_list[param_index] = parse_expression(); 
 25976 |  
 25977 |             if (0 == param_list[param_index]) 
 25978 |                return 0; 
 25979 |             else if (token_is(token_t::e_rbracket)) 
 25980 |             { 
 25981 |                sd.delete_ptr = false; 
 25982 |                break; 
 25983 |             } 
 25984 |             else if (token_is(token_t::e_comma)) 
 25985 |                continue; 
 25986 |             else 
 25987 |             { 
 25988 |                set_error(make_error( 
 25989 |                   parser_error::e_syntax, 
 25990 |                   current_token(), 
 25991 |                   "ERR031 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'", 
 25992 |                   exprtk_error_location)); 
 25993 |  
 25994 |                return 0; 
 25995 |             } 
 25996 |          } 
 25997 |  
 25998 |          if (sd.delete_ptr) 
 25999 |          { 
 26000 |             set_error(make_error( 
 26001 |                parser_error::e_syntax, 
 26002 |                current_token(), 
 26003 |                "ERR032 - Invalid number of input parameters passed to function '" + function_name  + "'", 
 26004 |                exprtk_error_location)); 
 26005 |  
 26006 |             return 0; 
 26007 |          } 
 26008 |  
 26009 |          return (param_index + 1); 
 26010 |       } 
 26011 |  
 26012 |       inline expression_node_ptr parse_base_operation() 
 26013 |       { 
 26014 |          typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t; 
 26015 |  
 26016 |          const std::string operation_name   = current_token().value; 
 26017 |          const token_t     diagnostic_token = current_token(); 
 26018 |  
 26019 |          map_range_t itr_range = base_ops_map_.equal_range(operation_name); 
 26020 |  
 26021 |          if (0 == std::distance(itr_range.first,itr_range.second)) 
 26022 |          { 
 26023 |             set_error(make_error( 
 26024 |                parser_error::e_syntax, 
 26025 |                diagnostic_token, 
 26026 |                "ERR033 - No entry found for base operation: " + operation_name, 
 26027 |                exprtk_error_location)); 
 26028 |  
 26029 |             return error_node(); 
 26030 |          } 
 26031 |  
 26032 |          static const std::size_t MaxNumberofParameters = 4; 
 26033 |          expression_node_ptr param_list[MaxNumberofParameters] = {0}; 
 26034 |  
 26035 |          const std::size_t parameter_count = parse_base_function_call(param_list, operation_name); 
 26036 |  
 26037 |          if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters)) 
 26038 |          { 
 26039 |             for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr) 
 26040 |             { 
 26041 |                const details::base_operation_t& operation = itr->second; 
 26042 |  
 26043 |                if (operation.num_params == parameter_count) 
 26044 |                { 
 26045 |                   switch (parameter_count) 
 26046 |                   { 
 26047 |                      #define base_opr_case(N)                                         \ 
 26048 |                      case N : {                                                       \ 
 26049 |                                  expression_node_ptr pl##N[N] = {0};                  \ 
 26050 |                                  std::copy(param_list, param_list + N, pl##N);        \ 
 26051 |                                  lodge_symbol(operation_name, e_st_function);         \ 
 26052 |                                  return expression_generator_(operation.type, pl##N); \ 
 26053 |                               }                                                       \ 
 26054 |  
 26055 |                      base_opr_case(1) 
 26056 |                      base_opr_case(2) 
 26057 |                      base_opr_case(3) 
 26058 |                      base_opr_case(4) 
 26059 |                      #undef base_opr_case 
 26060 |                   } 
 26061 |                } 
 26062 |             } 
 26063 |          } 
 26064 |  
 26065 |          for (std::size_t i = 0; i < MaxNumberofParameters; ++i) 
 26066 |          { 
 26067 |             free_node(node_allocator_, param_list[i]); 
 26068 |          } 
 26069 |  
 26070 |          set_error(make_error( 
 26071 |             parser_error::e_syntax, 
 26072 |             diagnostic_token, 
 26073 |             "ERR034 - Invalid number of input parameters for call to function: '" + operation_name + "'", 
 26074 |             exprtk_error_location)); 
 26075 |  
 26076 |          return error_node(); 
 26077 |       } 
 26078 |  
 26079 |       inline expression_node_ptr parse_conditional_statement_01(expression_node_ptr condition) 
 26080 |       { 
 26081 |          // Parse: [if][(][condition][,][consequent][,][alternative][)] 
 26082 |  
 26083 |          expression_node_ptr consequent  = error_node(); 
 26084 |          expression_node_ptr alternative = error_node(); 
 26085 |  
 26086 |          bool result = true; 
 26087 |  
 26088 |          if (!token_is(token_t::e_comma)) 
 26089 |          { 
 26090 |             set_error(make_error( 
 26091 |                parser_error::e_syntax, 
 26092 |                current_token(), 
 26093 |                "ERR035 - Expected ',' between if-statement condition and consequent", 
 26094 |                exprtk_error_location)); 
 26095 |  
 26096 |             result = false; 
 26097 |          } 
 26098 |          else if (0 == (consequent = parse_expression())) 
 26099 |          { 
 26100 |             set_error(make_error( 
 26101 |                parser_error::e_syntax, 
 26102 |                current_token(), 
 26103 |                "ERR036 - Failed to parse consequent for if-statement", 
 26104 |                exprtk_error_location)); 
 26105 |  
 26106 |             result = false; 
 26107 |          } 
 26108 |          else if (!token_is(token_t::e_comma)) 
 26109 |          { 
 26110 |             set_error(make_error( 
 26111 |                parser_error::e_syntax, 
 26112 |                current_token(), 
 26113 |                "ERR037 - Expected ',' between if-statement consequent and alternative", 
 26114 |                exprtk_error_location)); 
 26115 |  
 26116 |             result = false; 
 26117 |          } 
 26118 |          else if (0 == (alternative = parse_expression())) 
 26119 |          { 
 26120 |             set_error(make_error( 
 26121 |                parser_error::e_syntax, 
 26122 |                current_token(), 
 26123 |                "ERR038 - Failed to parse alternative for if-statement", 
 26124 |                exprtk_error_location)); 
 26125 |  
 26126 |             result = false; 
 26127 |          } 
 26128 |          else if (!token_is(token_t::e_rbracket)) 
 26129 |          { 
 26130 |             set_error(make_error( 
 26131 |                parser_error::e_syntax, 
 26132 |                current_token(), 
 26133 |                "ERR039 - Expected ')' at the end of if-statement", 
 26134 |                exprtk_error_location)); 
 26135 |  
 26136 |             result = false; 
 26137 |          } 
 26138 |  
 26139 |          #ifndef exprtk_disable_string_capabilities 
 26140 |          if (result) 
 26141 |          { 
 26142 |             const bool consq_is_str = is_generally_string_node(consequent ); 
 26143 |             const bool alter_is_str = is_generally_string_node(alternative); 
 26144 |  
 26145 |             if (consq_is_str || alter_is_str) 
 26146 |             { 
 26147 |                if (consq_is_str && alter_is_str) 
 26148 |                { 
 26149 |                   expression_node_ptr result_node = 
 26150 |                      expression_generator_ 
 26151 |                         .conditional_string(condition, consequent, alternative); 
 26152 |  
 26153 |                   if (result_node && result_node->valid()) 
 26154 |                   { 
 26155 |                      return result_node; 
 26156 |                   } 
 26157 |  
 26158 |                   set_error(make_error( 
 26159 |                      parser_error::e_synthesis, 
 26160 |                      current_token(), 
 26161 |                      "ERR040 - Failed to synthesize node: conditional_string", 
 26162 |                      exprtk_error_location)); 
 26163 |  
 26164 |                   free_node(node_allocator_, result_node); 
 26165 |                   return error_node(); 
 26166 |                } 
 26167 |  
 26168 |                set_error(make_error( 
 26169 |                   parser_error::e_syntax, 
 26170 |                   current_token(), 
 26171 |                   "ERR041 - Return types of if-statement differ: string/non-string", 
 26172 |                   exprtk_error_location)); 
 26173 |  
 26174 |                result = false; 
 26175 |             } 
 26176 |          } 
 26177 |          #endif 
 26178 |  
 26179 |          if (result) 
 26180 |          { 
 26181 |             const bool consq_is_vec = is_ivector_node(consequent ); 
 26182 |             const bool alter_is_vec = is_ivector_node(alternative); 
 26183 |  
 26184 |             if (consq_is_vec || alter_is_vec) 
 26185 |             { 
 26186 |                if (consq_is_vec && alter_is_vec) 
 26187 |                { 
 26188 |                   return expression_generator_ 
 26189 |                            .conditional_vector(condition, consequent, alternative); 
 26190 |                } 
 26191 |  
 26192 |                set_error(make_error( 
 26193 |                   parser_error::e_syntax, 
 26194 |                   current_token(), 
 26195 |                   "ERR042 - Return types of if-statement differ: vector/non-vector", 
 26196 |                   exprtk_error_location)); 
 26197 |  
 26198 |                result = false; 
 26199 |             } 
 26200 |          } 
 26201 |  
 26202 |          if (!result) 
 26203 |          { 
 26204 |             free_node(node_allocator_, condition  ); 
 26205 |             free_node(node_allocator_, consequent ); 
 26206 |             free_node(node_allocator_, alternative); 
 26207 |  
 26208 |             return error_node(); 
 26209 |          } 
 26210 |          else 
 26211 |             return expression_generator_ 
 26212 |                       .conditional(condition, consequent, alternative); 
 26213 |       } 
 26214 |  
 26215 |       inline expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition) 
 26216 |       { 
 26217 |          expression_node_ptr consequent  = error_node(); 
 26218 |          expression_node_ptr alternative = error_node(); 
 26219 |  
 26220 |          bool result = true; 
 26221 |  
 26222 |          if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) 
 26223 |          { 
 26224 |             if (0 == (consequent = parse_multi_sequence("if-statement-01"))) 
 26225 |             { 
 26226 |                set_error(make_error( 
 26227 |                   parser_error::e_syntax, 
 26228 |                   current_token(), 
 26229 |                   "ERR043 - Failed to parse body of consequent for if-statement", 
 26230 |                   exprtk_error_location)); 
 26231 |  
 26232 |                result = false; 
 26233 |             } 
 26234 |             else if 
 26235 |             ( 
 26236 |               !settings_.commutative_check_enabled()           && 
 26237 |               !token_is("else",prsrhlpr_t::e_hold)             && 
 26238 |               !token_is_loop(prsrhlpr_t::e_hold)               && 
 26239 |               !token_is_arithmetic_opr(prsrhlpr_t::e_hold)     && 
 26240 |               !token_is_right_bracket (prsrhlpr_t::e_hold)     && 
 26241 |               !token_is_ineq_opr      (prsrhlpr_t::e_hold)     && 
 26242 |               !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) && 
 26243 |               !token_is(token_t::e_eof    ,prsrhlpr_t::e_hold) 
 26244 |             ) 
 26245 |             { 
 26246 |                set_error(make_error( 
 26247 |                   parser_error::e_syntax, 
 26248 |                   current_token(), 
 26249 |                   "ERR044 - Expected ';' at the end of the consequent for if-statement (1)", 
 26250 |                   exprtk_error_location)); 
 26251 |  
 26252 |                result = false; 
 26253 |             } 
 26254 |          } 
 26255 |          else 
 26256 |          { 
 26257 |             if ( 
 26258 |                  settings_.commutative_check_enabled() && 
 26259 |                  token_is(token_t::e_mul,prsrhlpr_t::e_hold) 
 26260 |                ) 
 26261 |             { 
 26262 |                next_token(); 
 26263 |             } 
 26264 |  
 26265 |             if (0 != (consequent = parse_expression())) 
 26266 |             { 
 26267 |                if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold)) 
 26268 |                { 
 26269 |                   set_error(make_error( 
 26270 |                      parser_error::e_syntax, 
 26271 |                      current_token(), 
 26272 |                      "ERR045 - Expected ';' at the end of the consequent for if-statement (2)", 
 26273 |                      exprtk_error_location)); 
 26274 |  
 26275 |                   result = false; 
 26276 |                } 
 26277 |             } 
 26278 |             else 
 26279 |             { 
 26280 |                set_error(make_error( 
 26281 |                   parser_error::e_syntax, 
 26282 |                   current_token(), 
 26283 |                   "ERR046 - Failed to parse body of consequent for if-statement", 
 26284 |                   exprtk_error_location)); 
 26285 |  
 26286 |                result = false; 
 26287 |             } 
 26288 |          } 
 26289 |  
 26290 |          if (result) 
 26291 |          { 
 26292 |             if ( 
 26293 |                  details::imatch(current_token().value,"else") || 
 26294 |                  (token_is(token_t::e_eof, prsrhlpr_t::e_hold) && peek_token_is("else")) 
 26295 |                ) 
 26296 |             { 
 26297 |                next_token(); 
 26298 |  
 26299 |                if (details::imatch(current_token().value,"else")) 
 26300 |                { 
 26301 |                   next_token(); 
 26302 |                } 
 26303 |  
 26304 |                if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) 
 26305 |                { 
 26306 |                   if (0 == (alternative = parse_multi_sequence("else-statement-01"))) 
 26307 |                   { 
 26308 |                      set_error(make_error( 
 26309 |                         parser_error::e_syntax, 
 26310 |                         current_token(), 
 26311 |                         "ERR047 - Failed to parse body of the 'else' for if-statement", 
 26312 |                         exprtk_error_location)); 
 26313 |  
 26314 |                      result = false; 
 26315 |                   } 
 26316 |                } 
 26317 |                else if (details::imatch(current_token().value,"if")) 
 26318 |                { 
 26319 |                   if (0 == (alternative = parse_conditional_statement())) 
 26320 |                   { 
 26321 |                      set_error(make_error( 
 26322 |                         parser_error::e_syntax, 
 26323 |                         current_token(), 
 26324 |                         "ERR048 - Failed to parse body of if-else statement", 
 26325 |                         exprtk_error_location)); 
 26326 |  
 26327 |                      result = false; 
 26328 |                   } 
 26329 |                } 
 26330 |                else if (0 != (alternative = parse_expression())) 
 26331 |                { 
 26332 |                   if ( 
 26333 |                        !token_is(token_t::e_ternary    , prsrhlpr_t::e_hold) && 
 26334 |                        !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && 
 26335 |                        !token_is(token_t::e_eof) 
 26336 |                      ) 
 26337 |                   { 
 26338 |                      set_error(make_error( 
 26339 |                         parser_error::e_syntax, 
 26340 |                         current_token(), 
 26341 |                         "ERR049 - Expected ';' at the end of the 'else-if' for the if-statement", 
 26342 |                         exprtk_error_location)); 
 26343 |  
 26344 |                      result = false; 
 26345 |                   } 
 26346 |                } 
 26347 |                else 
 26348 |                { 
 26349 |                   set_error(make_error( 
 26350 |                      parser_error::e_syntax, 
 26351 |                      current_token(), 
 26352 |                      "ERR050 - Failed to parse body of the 'else' for if-statement", 
 26353 |                      exprtk_error_location)); 
 26354 |  
 26355 |                   result = false; 
 26356 |                } 
 26357 |             } 
 26358 |          } 
 26359 |  
 26360 |          #ifndef exprtk_disable_string_capabilities 
 26361 |          if (result) 
 26362 |          { 
 26363 |             const bool consq_is_str = is_generally_string_node(consequent ); 
 26364 |             const bool alter_is_str = is_generally_string_node(alternative); 
 26365 |  
 26366 |             if (consq_is_str || alter_is_str) 
 26367 |             { 
 26368 |                if (consq_is_str && alter_is_str) 
 26369 |                { 
 26370 |                   return expression_generator_ 
 26371 |                            .conditional_string(condition, consequent, alternative); 
 26372 |                } 
 26373 |  
 26374 |                set_error(make_error( 
 26375 |                   parser_error::e_syntax, 
 26376 |                   current_token(), 
 26377 |                   "ERR051 - Return types of if-statement differ: string/non-string", 
 26378 |                   exprtk_error_location)); 
 26379 |  
 26380 |                result = false; 
 26381 |             } 
 26382 |          } 
 26383 |          #endif 
 26384 |  
 26385 |          if (result) 
 26386 |          { 
 26387 |             const bool consq_is_vec = is_ivector_node(consequent ); 
 26388 |             const bool alter_is_vec = is_ivector_node(alternative); 
 26389 |  
 26390 |             if (consq_is_vec || alter_is_vec) 
 26391 |             { 
 26392 |                if (consq_is_vec && alter_is_vec) 
 26393 |                { 
 26394 |                   return expression_generator_ 
 26395 |                            .conditional_vector(condition, consequent, alternative); 
 26396 |                } 
 26397 |  
 26398 |                set_error(make_error( 
 26399 |                   parser_error::e_syntax, 
 26400 |                   current_token(), 
 26401 |                   "ERR052 - Return types of if-statement differ: vector/non-vector", 
 26402 |                   exprtk_error_location)); 
 26403 |  
 26404 |                result = false; 
 26405 |             } 
 26406 |          } 
 26407 |  
 26408 |          if (!result) 
 26409 |          { 
 26410 |             free_node(node_allocator_, condition  ); 
 26411 |             free_node(node_allocator_, consequent ); 
 26412 |             free_node(node_allocator_, alternative); 
 26413 |  
 26414 |             return error_node(); 
 26415 |          } 
 26416 |          else 
 26417 |             return expression_generator_ 
 26418 |                       .conditional(condition, consequent, alternative); 
 26419 |       } 
 26420 |  
 26421 |       inline expression_node_ptr parse_conditional_statement() 
 26422 |       { 
 26423 |          expression_node_ptr condition = error_node(); 
 26424 |  
 26425 |          next_token(); 
 26426 |  
 26427 |          if (!token_is(token_t::e_lbracket)) 
 26428 |          { 
 26429 |             set_error(make_error( 
 26430 |                parser_error::e_syntax, 
 26431 |                current_token(), 
 26432 |                "ERR053 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'", 
 26433 |                exprtk_error_location)); 
 26434 |  
 26435 |             return error_node(); 
 26436 |          } 
 26437 |          else if (0 == (condition = parse_expression())) 
 26438 |          { 
 26439 |             set_error(make_error( 
 26440 |                parser_error::e_syntax, 
 26441 |                current_token(), 
 26442 |                "ERR054 - Failed to parse condition for if-statement", 
 26443 |                exprtk_error_location)); 
 26444 |  
 26445 |             return error_node(); 
 26446 |          } 
 26447 |          else if (token_is(token_t::e_comma,prsrhlpr_t::e_hold)) 
 26448 |          { 
 26449 |             // if (x,y,z) 
 26450 |             return parse_conditional_statement_01(condition); 
 26451 |          } 
 26452 |          else if (token_is(token_t::e_rbracket)) 
 26453 |          { 
 26454 |             /* 
 26455 |                00. if (x) y; 
 26456 |                01. if (x) y; else z; 
 26457 |                02. if (x) y; else {z0; ... zn;} 
 26458 |                03. if (x) y; else if (z) w; 
 26459 |                04. if (x) y; else if (z) w; else u; 
 26460 |                05. if (x) y; else if (z) w; else {u0; ... un;} 
 26461 |                06. if (x) y; else if (z) {w0; ... wn;} 
 26462 |                07. if (x) {y0; ... yn;} 
 26463 |                08. if (x) {y0; ... yn;} else z; 
 26464 |                09. if (x) {y0; ... yn;} else {z0; ... zn;}; 
 26465 |                10. if (x) {y0; ... yn;} else if (z) w; 
 26466 |                11. if (x) {y0; ... yn;} else if (z) w; else u; 
 26467 |                12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;} 
 26468 |                13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;} 
 26469 |             */ 
 26470 |             return parse_conditional_statement_02(condition); 
 26471 |          } 
 26472 |  
 26473 |          set_error(make_error( 
 26474 |             parser_error::e_syntax, 
 26475 |             current_token(), 
 26476 |             "ERR055 - Invalid if-statement", 
 26477 |             exprtk_error_location)); 
 26478 |  
 26479 |          free_node(node_allocator_, condition); 
 26480 |  
 26481 |          return error_node(); 
 26482 |       } 
 26483 |  
 26484 |       inline expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition) 
 26485 |       { 
 26486 |          // Parse: [condition][?][consequent][:][alternative] 
 26487 |          expression_node_ptr consequent  = error_node(); 
 26488 |          expression_node_ptr alternative = error_node(); 
 26489 |  
 26490 |          bool result = true; 
 26491 |  
 26492 |          if (0 == condition) 
 26493 |          { 
 26494 |             set_error(make_error( 
 26495 |                parser_error::e_syntax, 
 26496 |                current_token(), 
 26497 |                "ERR056 - Encountered invalid condition branch for ternary if-statement", 
 26498 |                exprtk_error_location)); 
 26499 |  
 26500 |             return error_node(); 
 26501 |          } 
 26502 |          else if (!token_is(token_t::e_ternary)) 
 26503 |          { 
 26504 |             set_error(make_error( 
 26505 |                parser_error::e_syntax, 
 26506 |                current_token(), 
 26507 |                "ERR057 - Expected '?' after condition of ternary if-statement", 
 26508 |                exprtk_error_location)); 
 26509 |  
 26510 |             result = false; 
 26511 |          } 
 26512 |          else if (0 == (consequent = parse_expression())) 
 26513 |          { 
 26514 |             set_error(make_error( 
 26515 |                parser_error::e_syntax, 
 26516 |                current_token(), 
 26517 |                "ERR058 - Failed to parse consequent for ternary if-statement", 
 26518 |                exprtk_error_location)); 
 26519 |  
 26520 |             result = false; 
 26521 |          } 
 26522 |          else if (!token_is(token_t::e_colon)) 
 26523 |          { 
 26524 |             set_error(make_error( 
 26525 |                parser_error::e_syntax, 
 26526 |                current_token(), 
 26527 |                "ERR059 - Expected ':' between ternary if-statement consequent and alternative", 
 26528 |                exprtk_error_location)); 
 26529 |  
 26530 |             result = false; 
 26531 |          } 
 26532 |          else if (0 == (alternative = parse_expression())) 
 26533 |          { 
 26534 |             set_error(make_error( 
 26535 |                parser_error::e_syntax, 
 26536 |                current_token(), 
 26537 |                "ERR060 - Failed to parse alternative for ternary if-statement", 
 26538 |                exprtk_error_location)); 
 26539 |  
 26540 |             result = false; 
 26541 |          } 
 26542 |  
 26543 |          #ifndef exprtk_disable_string_capabilities 
 26544 |          if (result) 
 26545 |          { 
 26546 |             const bool consq_is_str = is_generally_string_node(consequent ); 
 26547 |             const bool alter_is_str = is_generally_string_node(alternative); 
 26548 |  
 26549 |             if (consq_is_str || alter_is_str) 
 26550 |             { 
 26551 |                if (consq_is_str && alter_is_str) 
 26552 |                { 
 26553 |                   return expression_generator_ 
 26554 |                            .conditional_string(condition, consequent, alternative); 
 26555 |                } 
 26556 |  
 26557 |                set_error(make_error( 
 26558 |                   parser_error::e_syntax, 
 26559 |                   current_token(), 
 26560 |                   "ERR061 - Return types of ternary differ: string/non-string", 
 26561 |                   exprtk_error_location)); 
 26562 |  
 26563 |                result = false; 
 26564 |             } 
 26565 |          } 
 26566 |          #endif 
 26567 |  
 26568 |          if (result) 
 26569 |          { 
 26570 |             const bool consq_is_vec = is_ivector_node(consequent ); 
 26571 |             const bool alter_is_vec = is_ivector_node(alternative); 
 26572 |  
 26573 |             if (consq_is_vec || alter_is_vec) 
 26574 |             { 
 26575 |                if (consq_is_vec && alter_is_vec) 
 26576 |                { 
 26577 |                   return expression_generator_ 
 26578 |                            .conditional_vector(condition, consequent, alternative); 
 26579 |                } 
 26580 |  
 26581 |                set_error(make_error( 
 26582 |                   parser_error::e_syntax, 
 26583 |                   current_token(), 
 26584 |                   "ERR062 - Return types of ternary differ: vector/non-vector", 
 26585 |                   exprtk_error_location)); 
 26586 |  
 26587 |                result = false; 
 26588 |             } 
 26589 |          } 
 26590 |  
 26591 |          if (!result) 
 26592 |          { 
 26593 |             free_node(node_allocator_, condition  ); 
 26594 |             free_node(node_allocator_, consequent ); 
 26595 |             free_node(node_allocator_, alternative); 
 26596 |  
 26597 |             return error_node(); 
 26598 |          } 
 26599 |          else 
 26600 |             return expression_generator_ 
 26601 |                       .conditional(condition, consequent, alternative); 
 26602 |       } 
 26603 |  
 26604 |       inline expression_node_ptr parse_not_statement() 
 26605 |       { 
 26606 |          if (settings_.logic_disabled("not")) 
 26607 |          { 
 26608 |             set_error(make_error( 
 26609 |                parser_error::e_syntax, 
 26610 |                current_token(), 
 26611 |                "ERR063 - Invalid or disabled logic operation 'not'", 
 26612 |                exprtk_error_location)); 
 26613 |  
 26614 |             return error_node(); 
 26615 |          } 
 26616 |  
 26617 |          return parse_base_operation(); 
 26618 |       } 
 26619 |  
 26620 |       void handle_brkcnt_scope_exit() 
 26621 |       { 
 26622 |          assert(!brkcnt_list_.empty()); 
 26623 |          brkcnt_list_.pop_front(); 
 26624 |       } 
 26625 |  
 26626 |       inline expression_node_ptr parse_while_loop() 
 26627 |       { 
 26628 |          // Parse: [while][(][test expr][)][{][expression][}] 
 26629 |          expression_node_ptr condition   = error_node(); 
 26630 |          expression_node_ptr branch      = error_node(); 
 26631 |          expression_node_ptr result_node = error_node(); 
 26632 |  
 26633 |          bool result = true; 
 26634 |  
 26635 |          next_token(); 
 26636 |  
 26637 |          if (!token_is(token_t::e_lbracket)) 
 26638 |          { 
 26639 |             set_error(make_error( 
 26640 |                parser_error::e_syntax, 
 26641 |                current_token(), 
 26642 |                "ERR064 - Expected '(' at start of while-loop condition statement", 
 26643 |                exprtk_error_location)); 
 26644 |  
 26645 |             return error_node(); 
 26646 |          } 
 26647 |          else if (0 == (condition = parse_expression())) 
 26648 |          { 
 26649 |             set_error(make_error( 
 26650 |                parser_error::e_syntax, 
 26651 |                current_token(), 
 26652 |                "ERR065 - Failed to parse condition for while-loop", 
 26653 |                exprtk_error_location)); 
 26654 |  
 26655 |             return error_node(); 
 26656 |          } 
 26657 |          else if (!token_is(token_t::e_rbracket)) 
 26658 |          { 
 26659 |             set_error(make_error( 
 26660 |                parser_error::e_syntax, 
 26661 |                current_token(), 
 26662 |                "ERR066 - Expected ')' at end of while-loop condition statement", 
 26663 |                exprtk_error_location)); 
 26664 |  
 26665 |             result = false; 
 26666 |          } 
 26667 |  
 26668 |          brkcnt_list_.push_front(false); 
 26669 |  
 26670 |          if (result) 
 26671 |          { 
 26672 |             scoped_inc_dec sid(state_.parsing_loop_stmt_count); 
 26673 |  
 26674 |             if (0 == (branch = parse_multi_sequence("while-loop", true))) 
 26675 |             { 
 26676 |                set_error(make_error( 
 26677 |                   parser_error::e_syntax, 
 26678 |                   current_token(), 
 26679 |                   "ERR067 - Failed to parse body of while-loop")); 
 26680 |                result = false; 
 26681 |             } 
 26682 |             else if (0 == (result_node = expression_generator_.while_loop(condition, 
 26683 |                                                                           branch, 
 26684 |                                                                           brkcnt_list_.front()))) 
 26685 |             { 
 26686 |                set_error(make_error( 
 26687 |                   parser_error::e_syntax, 
 26688 |                   current_token(), 
 26689 |                   "ERR068 - Failed to synthesize while-loop", 
 26690 |                   exprtk_error_location)); 
 26691 |  
 26692 |                result = false; 
 26693 |             } 
 26694 |          } 
 26695 |  
 26696 |          handle_brkcnt_scope_exit(); 
 26697 |  
 26698 |          if (!result) 
 26699 |          { 
 26700 |             free_node(node_allocator_, branch     ); 
 26701 |             free_node(node_allocator_, condition  ); 
 26702 |             free_node(node_allocator_, result_node); 
 26703 |  
 26704 |             return error_node(); 
 26705 |          } 
 26706 |  
 26707 |          if (result_node && result_node->valid()) 
 26708 |          { 
 26709 |             return result_node; 
 26710 |          } 
 26711 |  
 26712 |          set_error(make_error( 
 26713 |             parser_error::e_synthesis, 
 26714 |             current_token(), 
 26715 |             "ERR069 - Failed to synthesize 'valid' while-loop", 
 26716 |             exprtk_error_location)); 
 26717 |  
 26718 |          free_node(node_allocator_, result_node); 
 26719 |  
 26720 |          return error_node(); 
 26721 |       } 
 26722 |  
 26723 |       inline expression_node_ptr parse_repeat_until_loop() 
 26724 |       { 
 26725 |          // Parse: [repeat][{][expression][}][until][(][test expr][)] 
 26726 |          expression_node_ptr condition = error_node(); 
 26727 |          expression_node_ptr branch    = error_node(); 
 26728 |          next_token(); 
 26729 |  
 26730 |          std::vector<expression_node_ptr> arg_list; 
 26731 |          std::vector<bool> side_effect_list; 
 26732 |  
 26733 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 26734 |  
 26735 |          brkcnt_list_.push_front(false); 
 26736 |  
 26737 |          if (details::imatch(current_token().value,"until")) 
 26738 |          { 
 26739 |             next_token(); 
 26740 |             branch = node_allocator_.allocate<details::null_node<T> >(); 
 26741 |          } 
 26742 |          else 
 26743 |          { 
 26744 |             const token_t::token_type separator = token_t::e_eof; 
 26745 |  
 26746 |             scope_handler sh(*this); 
 26747 |  
 26748 |             scoped_bool_or_restorer sbr(state_.side_effect_present); 
 26749 |  
 26750 |             scoped_inc_dec sid(state_.parsing_loop_stmt_count); 
 26751 |  
 26752 |             for ( ; ; ) 
 26753 |             { 
 26754 |                state_.side_effect_present = false; 
 26755 |  
 26756 |                expression_node_ptr arg = parse_expression(); 
 26757 |  
 26758 |                if (0 == arg) 
 26759 |                   return error_node(); 
 26760 |                else 
 26761 |                { 
 26762 |                   arg_list.push_back(arg); 
 26763 |                   side_effect_list.push_back(state_.side_effect_present); 
 26764 |                } 
 26765 |  
 26766 |                if (details::imatch(current_token().value,"until")) 
 26767 |                { 
 26768 |                   next_token(); 
 26769 |                   break; 
 26770 |                } 
 26771 |  
 26772 |                const bool is_next_until = peek_token_is(token_t::e_symbol) && 
 26773 |                                           peek_token_is("until"); 
 26774 |  
 26775 |                if (!token_is(separator) && is_next_until) 
 26776 |                { 
 26777 |                   set_error(make_error( 
 26778 |                      parser_error::e_syntax, 
 26779 |                      current_token(), 
 26780 |                      "ERR070 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop", 
 26781 |                      exprtk_error_location)); 
 26782 |  
 26783 |                   return error_node(); 
 26784 |                } 
 26785 |  
 26786 |                if (details::imatch(current_token().value,"until")) 
 26787 |                { 
 26788 |                   next_token(); 
 26789 |                   break; 
 26790 |                } 
 26791 |             } 
 26792 |  
 26793 |             branch = simplify(arg_list,side_effect_list); 
 26794 |  
 26795 |             sdd.delete_ptr = (0 == branch); 
 26796 |  
 26797 |             if (sdd.delete_ptr) 
 26798 |             { 
 26799 |                set_error(make_error( 
 26800 |                   parser_error::e_syntax, 
 26801 |                   current_token(), 
 26802 |                   "ERR071 - Failed to parse body of repeat until loop", 
 26803 |                   exprtk_error_location)); 
 26804 |  
 26805 |                return error_node(); 
 26806 |             } 
 26807 |          } 
 26808 |  
 26809 |          if (!token_is(token_t::e_lbracket)) 
 26810 |          { 
 26811 |             set_error(make_error( 
 26812 |                parser_error::e_syntax, 
 26813 |                current_token(), 
 26814 |                "ERR072 - Expected '(' before condition statement of repeat until loop", 
 26815 |                exprtk_error_location)); 
 26816 |  
 26817 |             free_node(node_allocator_, branch); 
 26818 |             return error_node(); 
 26819 |          } 
 26820 |          else if (0 == (condition = parse_expression())) 
 26821 |          { 
 26822 |             set_error(make_error( 
 26823 |                parser_error::e_syntax, 
 26824 |                current_token(), 
 26825 |                "ERR073 - Failed to parse condition for repeat until loop", 
 26826 |                exprtk_error_location)); 
 26827 |  
 26828 |             free_node(node_allocator_, branch); 
 26829 |             return error_node(); 
 26830 |          } 
 26831 |          else if (!token_is(token_t::e_rbracket)) 
 26832 |          { 
 26833 |             set_error(make_error( 
 26834 |                parser_error::e_syntax, 
 26835 |                current_token(), 
 26836 |                "ERR074 - Expected ')' after condition of repeat until loop", 
 26837 |                exprtk_error_location)); 
 26838 |  
 26839 |             free_node(node_allocator_, branch   ); 
 26840 |             free_node(node_allocator_, condition); 
 26841 |  
 26842 |             return error_node(); 
 26843 |          } 
 26844 |  
 26845 |          expression_node_ptr result_node = 
 26846 |             expression_generator_ 
 26847 |                .repeat_until_loop( 
 26848 |                   condition, 
 26849 |                   branch, 
 26850 |                   brkcnt_list_.front()); 
 26851 |  
 26852 |          if (0 == result_node) 
 26853 |          { 
 26854 |             set_error(make_error( 
 26855 |                parser_error::e_syntax, 
 26856 |                current_token(), 
 26857 |                "ERR075 - Failed to synthesize repeat until loop", 
 26858 |                exprtk_error_location)); 
 26859 |  
 26860 |             free_node(node_allocator_, condition); 
 26861 |  
 26862 |             return error_node(); 
 26863 |          } 
 26864 |  
 26865 |          handle_brkcnt_scope_exit(); 
 26866 |  
 26867 |          if (result_node && result_node->valid()) 
 26868 |          { 
 26869 |             return result_node; 
 26870 |          } 
 26871 |  
 26872 |          set_error(make_error( 
 26873 |             parser_error::e_synthesis, 
 26874 |             current_token(), 
 26875 |             "ERR076 - Failed to synthesize 'valid' repeat until loop", 
 26876 |             exprtk_error_location)); 
 26877 |  
 26878 |          free_node(node_allocator_, result_node); 
 26879 |  
 26880 |          return error_node(); 
 26881 |       } 
 26882 |  
 26883 |       inline expression_node_ptr parse_for_loop() 
 26884 |       { 
 26885 |          expression_node_ptr initialiser = error_node(); 
 26886 |          expression_node_ptr condition   = error_node(); 
 26887 |          expression_node_ptr incrementor = error_node(); 
 26888 |          expression_node_ptr loop_body   = error_node(); 
 26889 |  
 26890 |          scope_element* se = 0; 
 26891 |          bool result       = true; 
 26892 |  
 26893 |          next_token(); 
 26894 |  
 26895 |          scope_handler sh(*this); 
 26896 |  
 26897 |          if (!token_is(token_t::e_lbracket)) 
 26898 |          { 
 26899 |             set_error(make_error( 
 26900 |                parser_error::e_syntax, 
 26901 |                current_token(), 
 26902 |                "ERR077 - Expected '(' at start of for-loop", 
 26903 |                exprtk_error_location)); 
 26904 |  
 26905 |             return error_node(); 
 26906 |          } 
 26907 |  
 26908 |          if (!token_is(token_t::e_eof)) 
 26909 |          { 
 26910 |             if ( 
 26911 |                  !token_is(token_t::e_symbol,prsrhlpr_t::e_hold) && 
 26912 |                  details::imatch(current_token().value,"var") 
 26913 |                ) 
 26914 |             { 
 26915 |                next_token(); 
 26916 |  
 26917 |                if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) 
 26918 |                { 
 26919 |                   set_error(make_error( 
 26920 |                      parser_error::e_syntax, 
 26921 |                      current_token(), 
 26922 |                      "ERR078 - Expected a variable at the start of initialiser section of for-loop", 
 26923 |                      exprtk_error_location)); 
 26924 |  
 26925 |                   return error_node(); 
 26926 |                } 
 26927 |                else if (!peek_token_is(token_t::e_assign)) 
 26928 |                { 
 26929 |                   set_error(make_error( 
 26930 |                      parser_error::e_syntax, 
 26931 |                      current_token(), 
 26932 |                      "ERR079 - Expected variable assignment of initialiser section of for-loop", 
 26933 |                      exprtk_error_location)); 
 26934 |  
 26935 |                   return error_node(); 
 26936 |                } 
 26937 |  
 26938 |                const std::string loop_counter_symbol = current_token().value; 
 26939 |  
 26940 |                se = &sem_.get_element(loop_counter_symbol); 
 26941 |  
 26942 |                if ((se->name == loop_counter_symbol) && se->active) 
 26943 |                { 
 26944 |                   set_error(make_error( 
 26945 |                      parser_error::e_syntax, 
 26946 |                      current_token(), 
 26947 |                      "ERR080 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration", 
 26948 |                      exprtk_error_location)); 
 26949 |  
 26950 |                   return error_node(); 
 26951 |                } 
 26952 |                else if (!symtab_store_.is_variable(loop_counter_symbol)) 
 26953 |                { 
 26954 |                   if ( 
 26955 |                        !se->active && 
 26956 |                        (se->name == loop_counter_symbol) && 
 26957 |                        (se->type == scope_element::e_variable) 
 26958 |                      ) 
 26959 |                   { 
 26960 |                      se->active = true; 
 26961 |                      se->ref_count++; 
 26962 |                   } 
 26963 |                   else 
 26964 |                   { 
 26965 |                      scope_element nse; 
 26966 |                      nse.name      = loop_counter_symbol; 
 26967 |                      nse.active    = true; 
 26968 |                      nse.ref_count = 1; 
 26969 |                      nse.type      = scope_element::e_variable; 
 26970 |                      nse.depth     = state_.scope_depth; 
 26971 |                      nse.data      = new T(T(0)); 
 26972 |                      nse.var_node  = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data)); 
 26973 |  
 26974 |                      if (!sem_.add_element(nse)) 
 26975 |                      { 
 26976 |                         set_error(make_error( 
 26977 |                            parser_error::e_syntax, 
 26978 |                            current_token(), 
 26979 |                            "ERR081 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM", 
 26980 |                            exprtk_error_location)); 
 26981 |  
 26982 |                         sem_.free_element(nse); 
 26983 |  
 26984 |                         result = false; 
 26985 |                      } 
 26986 |                      else 
 26987 |                      { 
 26988 |                         exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n", nse.name.c_str())); 
 26989 |  
 26990 |                         state_.activate_side_effect("parse_for_loop()"); 
 26991 |                      } 
 26992 |                   } 
 26993 |                } 
 26994 |             } 
 26995 |  
 26996 |             if (0 == (initialiser = parse_expression())) 
 26997 |             { 
 26998 |                set_error(make_error( 
 26999 |                   parser_error::e_syntax, 
 27000 |                   current_token(), 
 27001 |                   "ERR082 - Failed to parse initialiser of for-loop", 
 27002 |                   exprtk_error_location)); 
 27003 |  
 27004 |                result = false; 
 27005 |             } 
 27006 |             else if (!token_is(token_t::e_eof)) 
 27007 |             { 
 27008 |                set_error(make_error( 
 27009 |                   parser_error::e_syntax, 
 27010 |                   current_token(), 
 27011 |                   "ERR083 - Expected ';' after initialiser of for-loop", 
 27012 |                   exprtk_error_location)); 
 27013 |  
 27014 |                result = false; 
 27015 |             } 
 27016 |          } 
 27017 |  
 27018 |          if (!token_is(token_t::e_eof)) 
 27019 |          { 
 27020 |             if (0 == (condition = parse_expression())) 
 27021 |             { 
 27022 |                set_error(make_error( 
 27023 |                   parser_error::e_syntax, 
 27024 |                   current_token(), 
 27025 |                   "ERR084 - Failed to parse condition of for-loop", 
 27026 |                   exprtk_error_location)); 
 27027 |  
 27028 |                result = false; 
 27029 |             } 
 27030 |             else if (!token_is(token_t::e_eof)) 
 27031 |             { 
 27032 |                set_error(make_error( 
 27033 |                   parser_error::e_syntax, 
 27034 |                   current_token(), 
 27035 |                   "ERR085 - Expected ';' after condition section of for-loop", 
 27036 |                   exprtk_error_location)); 
 27037 |  
 27038 |                result = false; 
 27039 |             } 
 27040 |          } 
 27041 |  
 27042 |          if (!token_is(token_t::e_rbracket)) 
 27043 |          { 
 27044 |             if (0 == (incrementor = parse_expression())) 
 27045 |             { 
 27046 |                set_error(make_error( 
 27047 |                   parser_error::e_syntax, 
 27048 |                   current_token(), 
 27049 |                   "ERR086 - Failed to parse incrementor of for-loop", 
 27050 |                   exprtk_error_location)); 
 27051 |  
 27052 |                result = false; 
 27053 |             } 
 27054 |             else if (!token_is(token_t::e_rbracket)) 
 27055 |             { 
 27056 |                set_error(make_error( 
 27057 |                   parser_error::e_syntax, 
 27058 |                   current_token(), 
 27059 |                   "ERR087 - Expected ')' after incrementor section of for-loop", 
 27060 |                   exprtk_error_location)); 
 27061 |  
 27062 |                result = false; 
 27063 |             } 
 27064 |          } 
 27065 |  
 27066 |          if (result) 
 27067 |          { 
 27068 |             brkcnt_list_.push_front(false); 
 27069 |  
 27070 |             scoped_inc_dec sid(state_.parsing_loop_stmt_count); 
 27071 |  
 27072 |             if (0 == (loop_body = parse_multi_sequence("for-loop", true))) 
 27073 |             { 
 27074 |                set_error(make_error( 
 27075 |                   parser_error::e_syntax, 
 27076 |                   current_token(), 
 27077 |                   "ERR088 - Failed to parse body of for-loop", 
 27078 |                   exprtk_error_location)); 
 27079 |  
 27080 |                result = false; 
 27081 |             } 
 27082 |          } 
 27083 |  
 27084 |          if (!result) 
 27085 |          { 
 27086 |             if (se) 
 27087 |             { 
 27088 |                se->ref_count--; 
 27089 |             } 
 27090 |  
 27091 |             free_node(node_allocator_, initialiser); 
 27092 |             free_node(node_allocator_, condition  ); 
 27093 |             free_node(node_allocator_, incrementor); 
 27094 |             free_node(node_allocator_, loop_body  ); 
 27095 |             return error_node(); 
 27096 |          } 
 27097 |  
 27098 |          expression_node_ptr result_node = 
 27099 |             expression_generator_.for_loop(initialiser, 
 27100 |                                            condition, 
 27101 |                                            incrementor, 
 27102 |                                            loop_body, 
 27103 |                                            brkcnt_list_.front()); 
 27104 |          handle_brkcnt_scope_exit(); 
 27105 |  
 27106 |          if (result_node && result_node->valid()) 
 27107 |          { 
 27108 |             return result_node; 
 27109 |          } 
 27110 |  
 27111 |          set_error(make_error( 
 27112 |             parser_error::e_synthesis, 
 27113 |             current_token(), 
 27114 |             "ERR089 - Failed to synthesize 'valid' for-loop", 
 27115 |             exprtk_error_location)); 
 27116 |  
 27117 |          free_node(node_allocator_, result_node); 
 27118 |  
 27119 |          return error_node(); 
 27120 |       } 
 27121 |  
 27122 |       inline expression_node_ptr parse_switch_statement() 
 27123 |       { 
 27124 |          std::vector<expression_node_ptr> arg_list; 
 27125 |  
 27126 |          if (!details::imatch(current_token().value,"switch")) 
 27127 |          { 
 27128 |             set_error(make_error( 
 27129 |                parser_error::e_syntax, 
 27130 |                current_token(), 
 27131 |                "ERR090 - Expected keyword 'switch'", 
 27132 |                exprtk_error_location)); 
 27133 |  
 27134 |             return error_node(); 
 27135 |          } 
 27136 |  
 27137 |          scoped_vec_delete<expression_node_t> svd((*this),arg_list); 
 27138 |  
 27139 |          next_token(); 
 27140 |  
 27141 |          if (!token_is(token_t::e_lcrlbracket)) 
 27142 |          { 
 27143 |             set_error(make_error( 
 27144 |                parser_error::e_syntax, 
 27145 |                current_token(), 
 27146 |                "ERR091 - Expected '{' for call to switch statement", 
 27147 |                exprtk_error_location)); 
 27148 |  
 27149 |             return error_node(); 
 27150 |          } 
 27151 |  
 27152 |          expression_node_ptr default_statement = error_node(); 
 27153 |  
 27154 |          scoped_expression_delete defstmt_delete((*this), default_statement); 
 27155 |  
 27156 |          for ( ; ; ) 
 27157 |          { 
 27158 |             if (details::imatch("case",current_token().value)) 
 27159 |             { 
 27160 |                next_token(); 
 27161 |  
 27162 |                expression_node_ptr condition = parse_expression(); 
 27163 |  
 27164 |                if (0 == condition) 
 27165 |                   return error_node(); 
 27166 |                else if (!token_is(token_t::e_colon)) 
 27167 |                { 
 27168 |                   set_error(make_error( 
 27169 |                      parser_error::e_syntax, 
 27170 |                      current_token(), 
 27171 |                      "ERR092 - Expected ':' for case of switch statement", 
 27172 |                      exprtk_error_location)); 
 27173 |  
 27174 |                   free_node(node_allocator_, condition); 
 27175 |  
 27176 |                   return error_node(); 
 27177 |                } 
 27178 |  
 27179 |                expression_node_ptr consequent = 
 27180 |                   (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? 
 27181 |                   parse_multi_sequence("switch-consequent") : 
 27182 |                   parse_expression(); 
 27183 |  
 27184 |                if (0 == consequent) 
 27185 |                { 
 27186 |                   free_node(node_allocator_, condition); 
 27187 |  
 27188 |                   return error_node(); 
 27189 |                } 
 27190 |                else if (!token_is(token_t::e_eof)) 
 27191 |                { 
 27192 |                   set_error(make_error( 
 27193 |                      parser_error::e_syntax, 
 27194 |                      current_token(), 
 27195 |                      "ERR093 - Expected ';' at end of case for switch statement", 
 27196 |                      exprtk_error_location)); 
 27197 |  
 27198 |                   free_node(node_allocator_, condition ); 
 27199 |                   free_node(node_allocator_, consequent); 
 27200 |  
 27201 |                   return error_node(); 
 27202 |                } 
 27203 |  
 27204 |                // Can we optimise away the case statement? 
 27205 |                if (is_constant_node(condition) && is_false(condition)) 
 27206 |                { 
 27207 |                   free_node(node_allocator_, condition ); 
 27208 |                   free_node(node_allocator_, consequent); 
 27209 |                } 
 27210 |                else 
 27211 |                { 
 27212 |                   arg_list.push_back(condition ); 
 27213 |                   arg_list.push_back(consequent); 
 27214 |                } 
 27215 |  
 27216 |             } 
 27217 |             else if (details::imatch("default",current_token().value)) 
 27218 |             { 
 27219 |                if (0 != default_statement) 
 27220 |                { 
 27221 |                   set_error(make_error( 
 27222 |                      parser_error::e_syntax, 
 27223 |                      current_token(), 
 27224 |                      "ERR094 - Multiple default cases for switch statement", 
 27225 |                      exprtk_error_location)); 
 27226 |  
 27227 |                   return error_node(); 
 27228 |                } 
 27229 |  
 27230 |                next_token(); 
 27231 |  
 27232 |                if (!token_is(token_t::e_colon)) 
 27233 |                { 
 27234 |                   set_error(make_error( 
 27235 |                      parser_error::e_syntax, 
 27236 |                      current_token(), 
 27237 |                      "ERR095 - Expected ':' for default of switch statement", 
 27238 |                      exprtk_error_location)); 
 27239 |  
 27240 |                   return error_node(); 
 27241 |                } 
 27242 |  
 27243 |                default_statement = 
 27244 |                   (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? 
 27245 |                   parse_multi_sequence("switch-default"): 
 27246 |                   parse_expression(); 
 27247 |  
 27248 |                if (0 == default_statement) 
 27249 |                   return error_node(); 
 27250 |                else if (!token_is(token_t::e_eof)) 
 27251 |                { 
 27252 |                   set_error(make_error( 
 27253 |                      parser_error::e_syntax, 
 27254 |                      current_token(), 
 27255 |                      "ERR096 - Expected ';' at end of default for switch statement", 
 27256 |                      exprtk_error_location)); 
 27257 |  
 27258 |                   return error_node(); 
 27259 |                } 
 27260 |             } 
 27261 |             else if (token_is(token_t::e_rcrlbracket)) 
 27262 |                break; 
 27263 |             else 
 27264 |             { 
 27265 |                set_error(make_error( 
 27266 |                   parser_error::e_syntax, 
 27267 |                   current_token(), 
 27268 |                   "ERR097 - Expected '}' at end of switch statement", 
 27269 |                   exprtk_error_location)); 
 27270 |  
 27271 |                return error_node(); 
 27272 |             } 
 27273 |          } 
 27274 |  
 27275 |          const bool default_statement_present = (0 != default_statement); 
 27276 |  
 27277 |          if (default_statement_present) 
 27278 |          { 
 27279 |             arg_list.push_back(default_statement); 
 27280 |          } 
 27281 |          else 
 27282 |          { 
 27283 |             arg_list.push_back(node_allocator_.allocate_c<literal_node_t>(std::numeric_limits<T>::quiet_NaN())); 
 27284 |          } 
 27285 |  
 27286 |          expression_node_ptr result = expression_generator_.switch_statement(arg_list, (0 != default_statement)); 
 27287 |  
 27288 |          svd.delete_ptr = (0 == result); 
 27289 |          defstmt_delete.delete_ptr = (0 == result); 
 27290 |  
 27291 |          return result; 
 27292 |       } 
 27293 |  
 27294 |       inline expression_node_ptr parse_multi_switch_statement() 
 27295 |       { 
 27296 |          std::vector<expression_node_ptr> arg_list; 
 27297 |  
 27298 |          if (!details::imatch(current_token().value,"[*]")) 
 27299 |          { 
 27300 |             set_error(make_error( 
 27301 |                parser_error::e_syntax, 
 27302 |                current_token(), 
 27303 |                "ERR098 - Expected token '[*]'", 
 27304 |                exprtk_error_location)); 
 27305 |  
 27306 |             return error_node(); 
 27307 |          } 
 27308 |  
 27309 |          scoped_vec_delete<expression_node_t> svd((*this),arg_list); 
 27310 |  
 27311 |          next_token(); 
 27312 |  
 27313 |          if (!token_is(token_t::e_lcrlbracket)) 
 27314 |          { 
 27315 |             set_error(make_error( 
 27316 |                parser_error::e_syntax, 
 27317 |                current_token(), 
 27318 |                "ERR099 - Expected '{' for call to [*] statement", 
 27319 |                exprtk_error_location)); 
 27320 |  
 27321 |             return error_node(); 
 27322 |          } 
 27323 |  
 27324 |          for ( ; ; ) 
 27325 |          { 
 27326 |             if (!details::imatch("case",current_token().value)) 
 27327 |             { 
 27328 |                set_error(make_error( 
 27329 |                   parser_error::e_syntax, 
 27330 |                   current_token(), 
 27331 |                   "ERR100 - Expected a 'case' statement for multi-switch", 
 27332 |                   exprtk_error_location)); 
 27333 |  
 27334 |                return error_node(); 
 27335 |             } 
 27336 |  
 27337 |             next_token(); 
 27338 |  
 27339 |             expression_node_ptr condition = parse_expression(); 
 27340 |  
 27341 |             if (0 == condition) 
 27342 |                return error_node(); 
 27343 |  
 27344 |             if (!token_is(token_t::e_colon)) 
 27345 |             { 
 27346 |                set_error(make_error( 
 27347 |                   parser_error::e_syntax, 
 27348 |                   current_token(), 
 27349 |                   "ERR101 - Expected ':' for case of [*] statement", 
 27350 |                   exprtk_error_location)); 
 27351 |  
 27352 |                return error_node(); 
 27353 |             } 
 27354 |  
 27355 |             expression_node_ptr consequent = 
 27356 |                (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? 
 27357 |                parse_multi_sequence("multi-switch-consequent") : 
 27358 |                parse_expression(); 
 27359 |  
 27360 |             if (0 == consequent) 
 27361 |                return error_node(); 
 27362 |  
 27363 |             if (!token_is(token_t::e_eof)) 
 27364 |             { 
 27365 |                set_error(make_error( 
 27366 |                   parser_error::e_syntax, 
 27367 |                   current_token(), 
 27368 |                   "ERR102 - Expected ';' at end of case for [*] statement", 
 27369 |                   exprtk_error_location)); 
 27370 |  
 27371 |                return error_node(); 
 27372 |             } 
 27373 |  
 27374 |             // Can we optimise away the case statement? 
 27375 |             if (is_constant_node(condition) && is_false(condition)) 
 27376 |             { 
 27377 |                free_node(node_allocator_, condition ); 
 27378 |                free_node(node_allocator_, consequent); 
 27379 |             } 
 27380 |             else 
 27381 |             { 
 27382 |                arg_list.push_back(condition ); 
 27383 |                arg_list.push_back(consequent); 
 27384 |             } 
 27385 |  
 27386 |             if (token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold)) 
 27387 |             { 
 27388 |                break; 
 27389 |             } 
 27390 |          } 
 27391 |  
 27392 |          if (!token_is(token_t::e_rcrlbracket)) 
 27393 |          { 
 27394 |             set_error(make_error( 
 27395 |                parser_error::e_syntax, 
 27396 |                current_token(), 
 27397 |                "ERR103 - Expected '}' at end of [*] statement", 
 27398 |                exprtk_error_location)); 
 27399 |  
 27400 |             return error_node(); 
 27401 |          } 
 27402 |  
 27403 |          const expression_node_ptr result = expression_generator_.multi_switch_statement(arg_list); 
 27404 |  
 27405 |          svd.delete_ptr = (0 == result); 
 27406 |  
 27407 |          return result; 
 27408 |       } 
 27409 |  
 27410 |       inline expression_node_ptr parse_vararg_function() 
 27411 |       { 
 27412 |          std::vector<expression_node_ptr> arg_list; 
 27413 |  
 27414 |          details::operator_type opt_type = details::e_default; 
 27415 |          const std::string symbol = current_token().value; 
 27416 |  
 27417 |          if (details::imatch(symbol,"~")) 
 27418 |          { 
 27419 |             next_token(); 
 27420 |             return check_block_statement_closure(parse_multi_sequence()); 
 27421 |          } 
 27422 |          else if (details::imatch(symbol,"[*]")) 
 27423 |          { 
 27424 |             return check_block_statement_closure(parse_multi_switch_statement()); 
 27425 |          } 
 27426 |          else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ; 
 27427 |          else if (details::imatch(symbol, "mand")) opt_type = details::e_mand; 
 27428 |          else if (details::imatch(symbol, "max" )) opt_type = details::e_max ; 
 27429 |          else if (details::imatch(symbol, "min" )) opt_type = details::e_min ; 
 27430 |          else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ; 
 27431 |          else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod; 
 27432 |          else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ; 
 27433 |          else 
 27434 |          { 
 27435 |             set_error(make_error( 
 27436 |                parser_error::e_syntax, 
 27437 |                current_token(), 
 27438 |                "ERR104 - Unsupported built-in vararg function: " + symbol, 
 27439 |                exprtk_error_location)); 
 27440 |  
 27441 |             return error_node(); 
 27442 |          } 
 27443 |  
 27444 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 27445 |  
 27446 |          lodge_symbol(symbol, e_st_function); 
 27447 |  
 27448 |          next_token(); 
 27449 |  
 27450 |          if (!token_is(token_t::e_lbracket)) 
 27451 |          { 
 27452 |             set_error(make_error( 
 27453 |                parser_error::e_syntax, 
 27454 |                current_token(), 
 27455 |                "ERR105 - Expected '(' for call to vararg function: " + symbol, 
 27456 |                exprtk_error_location)); 
 27457 |  
 27458 |             return error_node(); 
 27459 |          } 
 27460 |  
 27461 |          if (token_is(token_t::e_rbracket)) 
 27462 |          { 
 27463 |             set_error(make_error( 
 27464 |                parser_error::e_syntax, 
 27465 |                current_token(), 
 27466 |                "ERR106 - vararg function: " + symbol + 
 27467 |                " requires at least one input parameter", 
 27468 |                exprtk_error_location)); 
 27469 |  
 27470 |             return error_node(); 
 27471 |          } 
 27472 |  
 27473 |          for ( ; ; ) 
 27474 |          { 
 27475 |             expression_node_ptr arg = parse_expression(); 
 27476 |  
 27477 |             if (0 == arg) 
 27478 |                return error_node(); 
 27479 |             else 
 27480 |                arg_list.push_back(arg); 
 27481 |  
 27482 |             if (token_is(token_t::e_rbracket)) 
 27483 |                break; 
 27484 |             else if (!token_is(token_t::e_comma)) 
 27485 |             { 
 27486 |                set_error(make_error( 
 27487 |                   parser_error::e_syntax, 
 27488 |                   current_token(), 
 27489 |                   "ERR107 - Expected ',' for call to vararg function: " + symbol, 
 27490 |                   exprtk_error_location)); 
 27491 |  
 27492 |                return error_node(); 
 27493 |             } 
 27494 |          } 
 27495 |  
 27496 |          const expression_node_ptr result = expression_generator_.vararg_function(opt_type,arg_list); 
 27497 |  
 27498 |          sdd.delete_ptr = (0 == result); 
 27499 |          return result; 
 27500 |       } 
 27501 |  
 27502 |       #ifndef exprtk_disable_string_capabilities 
 27503 |       inline expression_node_ptr parse_string_range_statement(expression_node_ptr& expression) 
 27504 |       { 
 27505 |          if (!token_is(token_t::e_lsqrbracket)) 
 27506 |          { 
 27507 |             set_error(make_error( 
 27508 |                parser_error::e_syntax, 
 27509 |                current_token(), 
 27510 |                "ERR108 - Expected '[' as start of string range definition", 
 27511 |                exprtk_error_location)); 
 27512 |  
 27513 |             free_node(node_allocator_, expression); 
 27514 |  
 27515 |             return error_node(); 
 27516 |          } 
 27517 |          else if (token_is(token_t::e_rsqrbracket)) 
 27518 |          { 
 27519 |             return node_allocator_.allocate<details::string_size_node<T> >(expression); 
 27520 |          } 
 27521 |  
 27522 |          range_t rp; 
 27523 |  
 27524 |          if (!parse_range(rp,true)) 
 27525 |          { 
 27526 |             free_node(node_allocator_, expression); 
 27527 |  
 27528 |             return error_node(); 
 27529 |          } 
 27530 |  
 27531 |          expression_node_ptr result = expression_generator_(expression,rp); 
 27532 |  
 27533 |          if (0 == result) 
 27534 |          { 
 27535 |             set_error(make_error( 
 27536 |                parser_error::e_syntax, 
 27537 |                current_token(), 
 27538 |                "ERR109 - Failed to generate string range node", 
 27539 |                exprtk_error_location)); 
 27540 |  
 27541 |             free_node(node_allocator_, expression); 
 27542 |             rp.free(); 
 27543 |          } 
 27544 |  
 27545 |          rp.clear(); 
 27546 |  
 27547 |          if (result && result->valid()) 
 27548 |          { 
 27549 |             return result; 
 27550 |          } 
 27551 |  
 27552 |          set_error(make_error( 
 27553 |             parser_error::e_synthesis, 
 27554 |             current_token(), 
 27555 |             "ERR110 - Failed to synthesize node: string_range_node", 
 27556 |             exprtk_error_location)); 
 27557 |  
 27558 |          free_node(node_allocator_, result); 
 27559 |          rp.free(); 
 27560 |          return error_node(); 
 27561 |       } 
 27562 |       #else 
 27563 |       inline expression_node_ptr parse_string_range_statement(expression_node_ptr&) 
 27564 |       { 
 27565 |          return error_node(); 
 27566 |       } 
 27567 |       #endif 
 27568 |  
 27569 |       inline bool parse_pending_string_rangesize(expression_node_ptr& expression) 
 27570 |       { 
 27571 |          // Allow no more than 100 range calls, eg: s[][][]...[][] 
 27572 |          const std::size_t max_rangesize_parses = 100; 
 27573 |  
 27574 |          std::size_t i = 0; 
 27575 |  
 27576 |          while 
 27577 |             ( 
 27578 |               (0 != expression)                     && 
 27579 |               (i++ < max_rangesize_parses)          && 
 27580 |               error_list_.empty()                   && 
 27581 |               is_generally_string_node(expression)  && 
 27582 |               token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold) 
 27583 |             ) 
 27584 |          { 
 27585 |             expression = parse_string_range_statement(expression); 
 27586 |          } 
 27587 |  
 27588 |          return (i > 1); 
 27589 |       } 
 27590 |  
 27591 |       inline void parse_pending_vector_index_operator(expression_node_ptr& expression) 
 27592 |       { 
 27593 |          if 
 27594 |             ( 
 27595 |               (0 != expression)           && 
 27596 |               error_list_.empty()         && 
 27597 |               is_ivector_node(expression) 
 27598 |             ) 
 27599 |          { 
 27600 |             if ( 
 27601 |                  settings_.commutative_check_enabled()       && 
 27602 |                  token_is(token_t::e_mul,prsrhlpr_t::e_hold) && 
 27603 |                  peek_token_is(token_t::e_lsqrbracket) 
 27604 |                ) 
 27605 |             { 
 27606 |                token_is(token_t::e_mul); 
 27607 |                token_is(token_t::e_lsqrbracket); 
 27608 |             } 
 27609 |             else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)) 
 27610 |             { 
 27611 |                token_is(token_t::e_lsqrbracket); 
 27612 |             } 
 27613 |             else if ( 
 27614 |                       token_is(token_t::e_rbracket,prsrhlpr_t::e_hold) && 
 27615 |                       peek_token_is(token_t::e_lsqrbracket) 
 27616 |                     ) 
 27617 |             { 
 27618 |                token_is(token_t::e_rbracket   ); 
 27619 |                token_is(token_t::e_lsqrbracket); 
 27620 |             } 
 27621 |             else 
 27622 |                return; 
 27623 |  
 27624 |             details::vector_interface<T>* vi = dynamic_cast<details::vector_interface<T>*>(expression); 
 27625 |  
 27626 |             if (vi) 
 27627 |             { 
 27628 |                details::vector_holder<T>& vec = vi->vec()->vec_holder(); 
 27629 |                const std::string vector_name  = sem_.get_vector_name(vec.data()); 
 27630 |                expression_node_ptr index      = parse_vector_index(vector_name); 
 27631 |  
 27632 |                if (index) 
 27633 |                { 
 27634 |                   expression = synthesize_vector_element(vector_name, &vec, expression, index); 
 27635 |                   return; 
 27636 |                } 
 27637 |             } 
 27638 |  
 27639 |             free_node(node_allocator_, expression); 
 27640 |             expression = error_node(); 
 27641 |          } 
 27642 |       } 
 27643 |  
 27644 |       template <typename Allocator1, 
 27645 |                 typename Allocator2, 
 27646 |                 template <typename, typename> class Sequence> 
 27647 |       inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator1>& expression_list, 
 27648 |                                           Sequence<bool,Allocator2>& side_effect_list, 
 27649 |                                           const bool specialise_on_final_type = false) 
 27650 |       { 
 27651 |          if (expression_list.empty()) 
 27652 |             return error_node(); 
 27653 |          else if (1 == expression_list.size()) 
 27654 |             return expression_list[0]; 
 27655 |  
 27656 |          Sequence<expression_node_ptr,Allocator1> tmp_expression_list; 
 27657 |  
 27658 |          exprtk_debug(("simplify() - expression_list.size: %d  side_effect_list.size(): %d\n", 
 27659 |                        static_cast<int>(expression_list .size()), 
 27660 |                        static_cast<int>(side_effect_list.size()))); 
 27661 |  
 27662 |          bool return_node_present = false; 
 27663 |  
 27664 |          for (std::size_t i = 0; i < (expression_list.size() - 1); ++i) 
 27665 |          { 
 27666 |             if (is_variable_node(expression_list[i])) 
 27667 |                continue; 
 27668 |             else if ( 
 27669 |                       is_return_node  (expression_list[i]) || 
 27670 |                       is_break_node   (expression_list[i]) || 
 27671 |                       is_continue_node(expression_list[i]) 
 27672 |                     ) 
 27673 |             { 
 27674 |                tmp_expression_list.push_back(expression_list[i]); 
 27675 |  
 27676 |                // Remove all subexpressions after first short-circuit 
 27677 |                // node has been encountered. 
 27678 |  
 27679 |                for (std::size_t j = i + 1; j < expression_list.size(); ++j) 
 27680 |                { 
 27681 |                   free_node(node_allocator_, expression_list[j]); 
 27682 |                } 
 27683 |  
 27684 |                return_node_present = true; 
 27685 |  
 27686 |                break; 
 27687 |             } 
 27688 |             else if ( 
 27689 |                       is_constant_node(expression_list[i]) || 
 27690 |                       is_null_node    (expression_list[i]) || 
 27691 |                       !side_effect_list[i] 
 27692 |                     ) 
 27693 |             { 
 27694 |                free_node(node_allocator_, expression_list[i]); 
 27695 |                continue; 
 27696 |             } 
 27697 |             else 
 27698 |                tmp_expression_list.push_back(expression_list[i]); 
 27699 |          } 
 27700 |  
 27701 |          if (!return_node_present) 
 27702 |          { 
 27703 |             tmp_expression_list.push_back(expression_list.back()); 
 27704 |          } 
 27705 |  
 27706 |          expression_list.swap(tmp_expression_list); 
 27707 |  
 27708 |          if (tmp_expression_list.size() > expression_list.size()) 
 27709 |          { 
 27710 |             exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n", 
 27711 |                           static_cast<int>(tmp_expression_list.size()), 
 27712 |                           static_cast<int>(expression_list    .size()))); 
 27713 |          } 
 27714 |  
 27715 |          if ( 
 27716 |               return_node_present     || 
 27717 |               side_effect_list.back() || 
 27718 |               (expression_list.size() > 1) 
 27719 |             ) 
 27720 |             state_.activate_side_effect("simplify()"); 
 27721 |  
 27722 |          if (1 == expression_list.size()) 
 27723 |             return expression_list[0]; 
 27724 |          else if (specialise_on_final_type && is_generally_string_node(expression_list.back())) 
 27725 |             return expression_generator_.vararg_function(details::e_smulti,expression_list); 
 27726 |          else 
 27727 |             return expression_generator_.vararg_function(details::e_multi,expression_list); 
 27728 |       } 
 27729 |  
 27730 |       inline expression_node_ptr parse_multi_sequence(const std::string& source = "", 
 27731 |                                                       const bool enforce_crlbrackets = false) 
 27732 |       { 
 27733 |          token_t::token_type open_bracket  = token_t::e_lcrlbracket; 
 27734 |          token_t::token_type close_bracket = token_t::e_rcrlbracket; 
 27735 |          token_t::token_type separator     = token_t::e_eof; 
 27736 |  
 27737 |          if (!token_is(open_bracket)) 
 27738 |          { 
 27739 |             if (!enforce_crlbrackets && token_is(token_t::e_lbracket)) 
 27740 |             { 
 27741 |                open_bracket  = token_t::e_lbracket; 
 27742 |                close_bracket = token_t::e_rbracket; 
 27743 |                separator     = token_t::e_comma; 
 27744 |             } 
 27745 |             else 
 27746 |             { 
 27747 |                set_error(make_error( 
 27748 |                   parser_error::e_syntax, 
 27749 |                   current_token(), 
 27750 |                   "ERR111 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" + 
 27751 |                   ((!source.empty()) ? std::string(" section of " + source): ""), 
 27752 |                   exprtk_error_location)); 
 27753 |  
 27754 |                return error_node(); 
 27755 |             } 
 27756 |          } 
 27757 |          else if (token_is(close_bracket)) 
 27758 |          { 
 27759 |             return node_allocator_.allocate<details::null_node<T> >(); 
 27760 |          } 
 27761 |  
 27762 |          std::vector<expression_node_ptr> arg_list; 
 27763 |          std::vector<bool> side_effect_list; 
 27764 |  
 27765 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 27766 |  
 27767 |          scope_handler sh(*this); 
 27768 |  
 27769 |          scoped_bool_or_restorer sbr(state_.side_effect_present); 
 27770 |  
 27771 |          for ( ; ; ) 
 27772 |          { 
 27773 |             state_.side_effect_present = false; 
 27774 |  
 27775 |             expression_node_ptr arg = parse_expression(); 
 27776 |  
 27777 |             if (0 == arg) 
 27778 |                return error_node(); 
 27779 |             else 
 27780 |             { 
 27781 |                arg_list.push_back(arg); 
 27782 |                side_effect_list.push_back(state_.side_effect_present); 
 27783 |             } 
 27784 |  
 27785 |             if (token_is(close_bracket)) 
 27786 |                break; 
 27787 |  
 27788 |             const bool is_next_close = peek_token_is(close_bracket); 
 27789 |  
 27790 |             if (!token_is(separator) && is_next_close) 
 27791 |             { 
 27792 |                set_error(make_error( 
 27793 |                   parser_error::e_syntax, 
 27794 |                   current_token(), 
 27795 |                   "ERR112 - Expected '" + lexer::token::seperator_to_str(separator) + "' for call to multi-sequence section of " + source, 
 27796 |                   exprtk_error_location)); 
 27797 |  
 27798 |                return error_node(); 
 27799 |             } 
 27800 |  
 27801 |             if (token_is(close_bracket)) 
 27802 |                break; 
 27803 |          } 
 27804 |  
 27805 |          expression_node_ptr result = simplify(arg_list, side_effect_list, source.empty()); 
 27806 |  
 27807 |          sdd.delete_ptr = (0 == result); 
 27808 |          return result; 
 27809 |       } 
 27810 |  
 27811 |       inline bool parse_range(range_t& rp, const bool skip_lsqr = false) 
 27812 |       { 
 27813 |          // Examples of valid ranges: 
 27814 |          // 1. [1:5]     -> [1,5) 
 27815 |          // 2. [ :5]     -> [0,5) 
 27816 |          // 3. [1: ]     -> [1,end) 
 27817 |          // 4. [x:y]     -> [x,y) where x <= y 
 27818 |          // 5. [x+1:y/2] -> [x+1,y/2) where x+1 <= y/2 
 27819 |          // 6. [ :y]     -> [0,y) where 0 <= y 
 27820 |          // 7. [x: ]     -> [x,end) where x <= end 
 27821 |  
 27822 |          rp.clear(); 
 27823 |  
 27824 |          if (!skip_lsqr && !token_is(token_t::e_lsqrbracket)) 
 27825 |          { 
 27826 |             set_error(make_error( 
 27827 |                parser_error::e_syntax, 
 27828 |                current_token(), 
 27829 |                "ERR113 - Expected '[' for start of range", 
 27830 |                exprtk_error_location)); 
 27831 |  
 27832 |             return false; 
 27833 |          } 
 27834 |  
 27835 |          if (token_is(token_t::e_colon)) 
 27836 |          { 
 27837 |             rp.n0_c.first  = true; 
 27838 |             rp.n0_c.second = 0; 
 27839 |             rp.cache.first = 0; 
 27840 |          } 
 27841 |          else 
 27842 |          { 
 27843 |             expression_node_ptr r0 = parse_expression(); 
 27844 |  
 27845 |             if (0 == r0) 
 27846 |             { 
 27847 |                set_error(make_error( 
 27848 |                   parser_error::e_syntax, 
 27849 |                   current_token(), 
 27850 |                   "ERR114 - Failed parse begin section of range", 
 27851 |                   exprtk_error_location)); 
 27852 |  
 27853 |                return false; 
 27854 |             } 
 27855 |             else if (is_constant_node(r0)) 
 27856 |             { 
 27857 |                const T r0_value = r0->value(); 
 27858 |  
 27859 |                if (r0_value >= T(0)) 
 27860 |                { 
 27861 |                   rp.n0_c.first  = true; 
 27862 |                   rp.n0_c.second = static_cast<std::size_t>(details::numeric::to_int64(r0_value)); 
 27863 |                   rp.cache.first = rp.n0_c.second; 
 27864 |                } 
 27865 |  
 27866 |                free_node(node_allocator_, r0); 
 27867 |  
 27868 |                if (r0_value < T(0)) 
 27869 |                { 
 27870 |                   set_error(make_error( 
 27871 |                      parser_error::e_syntax, 
 27872 |                      current_token(), 
 27873 |                      "ERR115 - Range lower bound less than zero! Constraint: r0 >= 0", 
 27874 |                      exprtk_error_location)); 
 27875 |  
 27876 |                   return false; 
 27877 |                } 
 27878 |             } 
 27879 |             else 
 27880 |             { 
 27881 |                rp.n0_e.first  = true; 
 27882 |                rp.n0_e.second = r0; 
 27883 |             } 
 27884 |  
 27885 |             if (!token_is(token_t::e_colon)) 
 27886 |             { 
 27887 |                set_error(make_error( 
 27888 |                   parser_error::e_syntax, 
 27889 |                   current_token(), 
 27890 |                   "ERR116 - Expected ':' for break  in range", 
 27891 |                   exprtk_error_location)); 
 27892 |  
 27893 |                rp.free(); 
 27894 |  
 27895 |                return false; 
 27896 |             } 
 27897 |          } 
 27898 |  
 27899 |          if (token_is(token_t::e_rsqrbracket)) 
 27900 |          { 
 27901 |             rp.n1_c.first  = true; 
 27902 |             rp.n1_c.second = std::numeric_limits<std::size_t>::max(); 
 27903 |          } 
 27904 |          else 
 27905 |          { 
 27906 |             expression_node_ptr r1 = parse_expression(); 
 27907 |  
 27908 |             if (0 == r1) 
 27909 |             { 
 27910 |                set_error(make_error( 
 27911 |                   parser_error::e_syntax, 
 27912 |                   current_token(), 
 27913 |                   "ERR117 - Failed parse end section of range", 
 27914 |                   exprtk_error_location)); 
 27915 |  
 27916 |                rp.free(); 
 27917 |  
 27918 |                return false; 
 27919 |             } 
 27920 |             else if (is_constant_node(r1)) 
 27921 |             { 
 27922 |                const T r1_value = r1->value(); 
 27923 |  
 27924 |                if (r1_value >= T(0)) 
 27925 |                { 
 27926 |                   rp.n1_c.first   = true; 
 27927 |                   rp.n1_c.second  = static_cast<std::size_t>(details::numeric::to_int64(r1_value)); 
 27928 |                   rp.cache.second = rp.n1_c.second; 
 27929 |                } 
 27930 |  
 27931 |                free_node(node_allocator_, r1); 
 27932 |  
 27933 |                if (r1_value < T(0)) 
 27934 |                { 
 27935 |                   set_error(make_error( 
 27936 |                      parser_error::e_syntax, 
 27937 |                      current_token(), 
 27938 |                      "ERR118 - Range upper bound less than zero! Constraint: r1 >= 0", 
 27939 |                      exprtk_error_location)); 
 27940 |  
 27941 |                   rp.free(); 
 27942 |  
 27943 |                   return false; 
 27944 |                } 
 27945 |             } 
 27946 |             else 
 27947 |             { 
 27948 |                rp.n1_e.first  = true; 
 27949 |                rp.n1_e.second = r1; 
 27950 |             } 
 27951 |  
 27952 |             if (!token_is(token_t::e_rsqrbracket)) 
 27953 |             { 
 27954 |                set_error(make_error( 
 27955 |                   parser_error::e_syntax, 
 27956 |                   current_token(), 
 27957 |                   "ERR119 - Expected ']' for start of range", 
 27958 |                   exprtk_error_location)); 
 27959 |  
 27960 |                rp.free(); 
 27961 |  
 27962 |                return false; 
 27963 |             } 
 27964 |          } 
 27965 |  
 27966 |          if (rp.const_range()) 
 27967 |          { 
 27968 |             std::size_t r0 = 0; 
 27969 |             std::size_t r1 = 0; 
 27970 |  
 27971 |             bool rp_result = false; 
 27972 |  
 27973 |             try 
 27974 |             { 
 27975 |                rp_result = rp(r0, r1); 
 27976 |             } 
 27977 |             catch (std::runtime_error&) 
 27978 |             {} 
 27979 |  
 27980 |             if (!rp_result || (r0 > r1)) 
 27981 |             { 
 27982 |                set_error(make_error( 
 27983 |                   parser_error::e_syntax, 
 27984 |                   current_token(), 
 27985 |                   "ERR120 - Invalid range, Constraint: r0 <= r1", 
 27986 |                   exprtk_error_location)); 
 27987 |  
 27988 |                return false; 
 27989 |             } 
 27990 |          } 
 27991 |  
 27992 |          return true; 
 27993 |       } 
 27994 |  
 27995 |       inline void lodge_symbol(const std::string& symbol, 
 27996 |                                const symbol_type st) 
 27997 |       { 
 27998 |          dec_.add_symbol(symbol,st); 
 27999 |       } 
 28000 |  
 28001 |       #ifndef exprtk_disable_string_capabilities 
 28002 |       inline expression_node_ptr parse_string() 
 28003 |       { 
 28004 |          const std::string symbol = current_token().value; 
 28005 |  
 28006 |          typedef details::stringvar_node<T>* strvar_node_t; 
 28007 |  
 28008 |          expression_node_ptr result   = error_node(); 
 28009 |          strvar_node_t const_str_node = static_cast<strvar_node_t>(0); 
 28010 |  
 28011 |          scope_element& se = sem_.get_active_element(symbol); 
 28012 |  
 28013 |          if (scope_element::e_string == se.type) 
 28014 |          { 
 28015 |             se.active = true; 
 28016 |             result    = se.str_node; 
 28017 |             lodge_symbol(symbol, e_st_local_string); 
 28018 |          } 
 28019 |          else 
 28020 |          { 
 28021 |             typedef typename symtab_store::string_context str_ctxt_t; 
 28022 |             str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol); 
 28023 |  
 28024 |             if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol)) 
 28025 |             { 
 28026 |                set_error(make_error( 
 28027 |                   parser_error::e_syntax, 
 28028 |                   current_token(), 
 28029 |                   "ERR121 - Unknown string symbol", 
 28030 |                   exprtk_error_location)); 
 28031 |  
 28032 |                return error_node(); 
 28033 |             } 
 28034 |  
 28035 |             assert(str_ctx.str_var != 0); 
 28036 |             assert(str_ctx.symbol_table != 0); 
 28037 |  
 28038 |             result = str_ctx.str_var; 
 28039 |  
 28040 |             if (symtab_store_.is_constant_string(symbol)) 
 28041 |             { 
 28042 |                const_str_node = static_cast<strvar_node_t>(result); 
 28043 |                result = expression_generator_(const_str_node->str()); 
 28044 |             } 
 28045 |             else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability()) 
 28046 |             { 
 28047 |                lodge_immutable_symbol( 
 28048 |                   current_token(), 
 28049 |                   make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size())); 
 28050 |             } 
 28051 |  
 28052 |             lodge_symbol(symbol, e_st_string); 
 28053 |          } 
 28054 |  
 28055 |          if (peek_token_is(token_t::e_lsqrbracket)) 
 28056 |          { 
 28057 |             next_token(); 
 28058 |  
 28059 |             if (peek_token_is(token_t::e_rsqrbracket)) 
 28060 |             { 
 28061 |                next_token(); 
 28062 |                next_token(); 
 28063 |  
 28064 |                if (const_str_node) 
 28065 |                { 
 28066 |                   free_node(node_allocator_, result); 
 28067 |  
 28068 |                   return expression_generator_(T(const_str_node->size())); 
 28069 |                } 
 28070 |                else 
 28071 |                   return node_allocator_.allocate<details::stringvar_size_node<T> > 
 28072 |                             (static_cast<details::stringvar_node<T>*>(result)->ref()); 
 28073 |             } 
 28074 |  
 28075 |             range_t rp; 
 28076 |  
 28077 |             if (!parse_range(rp)) 
 28078 |             { 
 28079 |                free_node(node_allocator_, result); 
 28080 |  
 28081 |                return error_node(); 
 28082 |             } 
 28083 |             else if (const_str_node) 
 28084 |             { 
 28085 |                free_node(node_allocator_, result); 
 28086 |                result = expression_generator_(const_str_node->ref(),rp); 
 28087 |             } 
 28088 |             else 
 28089 |                result = expression_generator_(static_cast<details::stringvar_node<T>*> 
 28090 |                            (result)->ref(), rp); 
 28091 |  
 28092 |             if (result) 
 28093 |                rp.clear(); 
 28094 |          } 
 28095 |          else 
 28096 |             next_token(); 
 28097 |  
 28098 |          return result; 
 28099 |       } 
 28100 |       #else 
 28101 |       inline expression_node_ptr parse_string() 
 28102 |       { 
 28103 |          return error_node(); 
 28104 |       } 
 28105 |       #endif 
 28106 |  
 28107 |       #ifndef exprtk_disable_string_capabilities 
 28108 |       inline expression_node_ptr parse_const_string() 
 28109 |       { 
 28110 |          const std::string   const_str = current_token().value; 
 28111 |          expression_node_ptr result    = expression_generator_(const_str); 
 28112 |  
 28113 |          if (peek_token_is(token_t::e_lsqrbracket)) 
 28114 |          { 
 28115 |             next_token(); 
 28116 |  
 28117 |             if (peek_token_is(token_t::e_rsqrbracket)) 
 28118 |             { 
 28119 |                next_token(); 
 28120 |                next_token(); 
 28121 |  
 28122 |                free_node(node_allocator_, result); 
 28123 |  
 28124 |                return expression_generator_(T(const_str.size())); 
 28125 |             } 
 28126 |  
 28127 |             range_t rp; 
 28128 |  
 28129 |             if (!parse_range(rp)) 
 28130 |             { 
 28131 |                free_node(node_allocator_, result); 
 28132 |                rp.free(); 
 28133 |  
 28134 |                return error_node(); 
 28135 |             } 
 28136 |  
 28137 |             free_node(node_allocator_, result); 
 28138 |  
 28139 |             if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max())) 
 28140 |             { 
 28141 |                rp.n1_c.second  = const_str.size() - 1; 
 28142 |                rp.cache.second = rp.n1_c.second; 
 28143 |             } 
 28144 |  
 28145 |             if ( 
 28146 |                  (rp.n0_c.first && (rp.n0_c.second >= const_str.size())) || 
 28147 |                  (rp.n1_c.first && (rp.n1_c.second >= const_str.size())) 
 28148 |                ) 
 28149 |             { 
 28150 |                set_error(make_error( 
 28151 |                   parser_error::e_syntax, 
 28152 |                   current_token(), 
 28153 |                   "ERR122 - Overflow in range for string: '" + const_str + "'[" + 
 28154 |                   (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" + 
 28155 |                   (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]", 
 28156 |                   exprtk_error_location)); 
 28157 |  
 28158 |                rp.free(); 
 28159 |  
 28160 |                return error_node(); 
 28161 |             } 
 28162 |  
 28163 |             result = expression_generator_(const_str,rp); 
 28164 |  
 28165 |             if (result) 
 28166 |                rp.clear(); 
 28167 |          } 
 28168 |          else 
 28169 |             next_token(); 
 28170 |  
 28171 |          return result; 
 28172 |       } 
 28173 |       #else 
 28174 |       inline expression_node_ptr parse_const_string() 
 28175 |       { 
 28176 |          return error_node(); 
 28177 |       } 
 28178 |       #endif 
 28179 |  
 28180 |       inline expression_node_ptr parse_vector_index(const std::string& vector_name = "") 
 28181 |       { 
 28182 |          expression_node_ptr index_expr = error_node(); 
 28183 |  
 28184 |          if (0 == (index_expr = parse_expression())) 
 28185 |          { 
 28186 |             set_error(make_error( 
 28187 |                parser_error::e_syntax, 
 28188 |                current_token(), 
 28189 |                "ERR123 - Failed to parse index for vector: '" + vector_name + "'", 
 28190 |                exprtk_error_location)); 
 28191 |  
 28192 |             return error_node(); 
 28193 |          } 
 28194 |          else if (!token_is(token_t::e_rsqrbracket)) 
 28195 |          { 
 28196 |             set_error(make_error( 
 28197 |                parser_error::e_syntax, 
 28198 |                current_token(), 
 28199 |                "ERR124 - Expected ']' for index of vector: '" + vector_name + "'", 
 28200 |                exprtk_error_location)); 
 28201 |  
 28202 |             free_node(node_allocator_, index_expr); 
 28203 |  
 28204 |             return error_node(); 
 28205 |          } 
 28206 |  
 28207 |          return index_expr; 
 28208 |       } 
 28209 |  
 28210 |       inline expression_node_ptr parse_vector() 
 28211 |       { 
 28212 |          const std::string vector_name = current_token().value; 
 28213 |  
 28214 |          vector_holder_ptr vec = vector_holder_ptr(0); 
 28215 |  
 28216 |          const scope_element& se = sem_.get_active_element(vector_name); 
 28217 |  
 28218 |          if ( 
 28219 |               !details::imatch(se.name, vector_name) || 
 28220 |               (se.depth > state_.scope_depth)   || 
 28221 |               (scope_element::e_vector != se.type) 
 28222 |             ) 
 28223 |          { 
 28224 |             typedef typename symtab_store::vector_context vec_ctxt_t; 
 28225 |             vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(vector_name); 
 28226 |  
 28227 |             if (0 == vec_ctx.vector_holder) 
 28228 |             { 
 28229 |                set_error(make_error( 
 28230 |                   parser_error::e_syntax, 
 28231 |                   current_token(), 
 28232 |                   "ERR125 - Symbol '" + vector_name + " not a vector", 
 28233 |                   exprtk_error_location)); 
 28234 |  
 28235 |                return error_node(); 
 28236 |             } 
 28237 |  
 28238 |             assert(0 != vec_ctx.vector_holder); 
 28239 |             assert(0 != vec_ctx.symbol_table ); 
 28240 |  
 28241 |             vec = vec_ctx.vector_holder; 
 28242 |  
 28243 |             if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability()) 
 28244 |             { 
 28245 |                lodge_immutable_symbol( 
 28246 |                   current_token(), 
 28247 |                   make_memory_range(vec->data(), vec->size())); 
 28248 |             } 
 28249 |          } 
 28250 |          else 
 28251 |          { 
 28252 |             vec = se.vec_node; 
 28253 |          } 
 28254 |  
 28255 |          assert(0 != vec); 
 28256 |  
 28257 |          next_token(); 
 28258 |  
 28259 |          if (!token_is(token_t::e_lsqrbracket)) 
 28260 |          { 
 28261 |             return node_allocator_.allocate<vector_node_t>(vec); 
 28262 |          } 
 28263 |          else if (token_is(token_t::e_rsqrbracket)) 
 28264 |          { 
 28265 |             return (vec->rebaseable()) ? 
 28266 |                node_allocator_.allocate<vector_size_node_t>(vec) : 
 28267 |                expression_generator_(T(vec->size())); 
 28268 |          } 
 28269 |  
 28270 |          expression_node_ptr index_expr = parse_vector_index(vector_name); 
 28271 |  
 28272 |          if (index_expr) 
 28273 |          { 
 28274 |             expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec); 
 28275 |  
 28276 |             return synthesize_vector_element(vector_name, vec, vec_node, index_expr); 
 28277 |          } 
 28278 |  
 28279 |          return error_node(); 
 28280 |       } 
 28281 |  
 28282 |       inline expression_node_ptr synthesize_vector_element(const std::string& vector_name, 
 28283 |                                                            vector_holder_ptr vec, 
 28284 |                                                            expression_node_ptr vec_node, 
 28285 |                                                            expression_node_ptr index_expr) 
 28286 |       { 
 28287 |          // Perform compile-time range check 
 28288 |          if (details::is_constant_node(index_expr)) 
 28289 |          { 
 28290 |             const std::size_t index    = static_cast<std::size_t>(details::numeric::to_int32(index_expr->value())); 
 28291 |             const std::size_t vec_size = vec->size(); 
 28292 |  
 28293 |             if (index >= vec_size) 
 28294 |             { 
 28295 |                set_error(make_error( 
 28296 |                   parser_error::e_syntax, 
 28297 |                   current_token(), 
 28298 |                   "ERR126 - Index of " + details::to_str(index) + " out of range for " 
 28299 |                   "vector '" + vector_name + "' of size " + details::to_str(vec_size), 
 28300 |                   exprtk_error_location)); 
 28301 |  
 28302 |                free_node(node_allocator_, vec_node  ); 
 28303 |                free_node(node_allocator_, index_expr); 
 28304 |  
 28305 |                return error_node(); 
 28306 |             } 
 28307 |          } 
 28308 |  
 28309 |          return expression_generator_.vector_element(vector_name, vec, vec_node, index_expr); 
 28310 |       } 
 28311 |  
 28312 |       inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name) 
 28313 |       { 
 28314 |          std::vector<expression_node_ptr> arg_list; 
 28315 |  
 28316 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28317 |  
 28318 |          next_token(); 
 28319 |  
 28320 |          if (token_is(token_t::e_lbracket)) 
 28321 |          { 
 28322 |             if (token_is(token_t::e_rbracket)) 
 28323 |             { 
 28324 |                if (!vararg_function->allow_zero_parameters()) 
 28325 |                { 
 28326 |                   set_error(make_error( 
 28327 |                      parser_error::e_syntax, 
 28328 |                      current_token(), 
 28329 |                      "ERR127 - Zero parameter call to vararg function: " 
 28330 |                      + vararg_function_name + " not allowed", 
 28331 |                      exprtk_error_location)); 
 28332 |  
 28333 |                   return error_node(); 
 28334 |                } 
 28335 |             } 
 28336 |             else 
 28337 |             { 
 28338 |                for ( ; ; ) 
 28339 |                { 
 28340 |                   expression_node_ptr arg = parse_expression(); 
 28341 |  
 28342 |                   if (0 == arg) 
 28343 |                      return error_node(); 
 28344 |                   else 
 28345 |                      arg_list.push_back(arg); 
 28346 |  
 28347 |                   if (token_is(token_t::e_rbracket)) 
 28348 |                      break; 
 28349 |                   else if (!token_is(token_t::e_comma)) 
 28350 |                   { 
 28351 |                      set_error(make_error( 
 28352 |                         parser_error::e_syntax, 
 28353 |                         current_token(), 
 28354 |                         "ERR128 - Expected ',' for call to vararg function: " 
 28355 |                         + vararg_function_name, 
 28356 |                         exprtk_error_location)); 
 28357 |  
 28358 |                      return error_node(); 
 28359 |                   } 
 28360 |                } 
 28361 |             } 
 28362 |          } 
 28363 |          else if (!vararg_function->allow_zero_parameters()) 
 28364 |          { 
 28365 |             set_error(make_error( 
 28366 |                parser_error::e_syntax, 
 28367 |                current_token(), 
 28368 |                "ERR129 - Zero parameter call to vararg function: " 
 28369 |                + vararg_function_name + " not allowed", 
 28370 |                exprtk_error_location)); 
 28371 |  
 28372 |             return error_node(); 
 28373 |          } 
 28374 |  
 28375 |          if (arg_list.size() < vararg_function->min_num_args()) 
 28376 |          { 
 28377 |             set_error(make_error( 
 28378 |                parser_error::e_syntax, 
 28379 |                current_token(), 
 28380 |                "ERR130 - Invalid number of parameters to call to vararg function: " 
 28381 |                + vararg_function_name + ", require at least " 
 28382 |                + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters", 
 28383 |                exprtk_error_location)); 
 28384 |  
 28385 |             return error_node(); 
 28386 |          } 
 28387 |          else if (arg_list.size() > vararg_function->max_num_args()) 
 28388 |          { 
 28389 |             set_error(make_error( 
 28390 |                parser_error::e_syntax, 
 28391 |                current_token(), 
 28392 |                "ERR131 - Invalid number of parameters to call to vararg function: " 
 28393 |                + vararg_function_name + ", require no more than " 
 28394 |                + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters", 
 28395 |                exprtk_error_location)); 
 28396 |  
 28397 |             return error_node(); 
 28398 |          } 
 28399 |  
 28400 |          expression_node_ptr result = expression_generator_.vararg_function_call(vararg_function,arg_list); 
 28401 |  
 28402 |          sdd.delete_ptr = (0 == result); 
 28403 |  
 28404 |          return result; 
 28405 |       } 
 28406 |  
 28407 |       class type_checker 
 28408 |       { 
 28409 |       public: 
 28410 |  
 28411 |          enum return_type_t 
 28412 |          { 
 28413 |             e_overload = ' ', 
 28414 |             e_numeric  = 'T', 
 28415 |             e_string   = 'S' 
 28416 |          }; 
 28417 |  
 28418 |          struct function_prototype_t 
 28419 |          { 
 28420 |              return_type_t return_type; 
 28421 |              std::string   param_seq; 
 28422 |          }; 
 28423 |  
 28424 |          typedef parser<T> parser_t; 
 28425 |          typedef std::vector<function_prototype_t> function_definition_list_t; 
 28426 |  
 28427 |          type_checker(parser_t& p, 
 28428 |                       const std::string& func_name, 
 28429 |                       const std::string& func_prototypes, 
 28430 |                       const return_type_t default_return_type) 
 28431 |          : invalid_state_(true) 
 28432 |          , parser_(p) 
 28433 |          , function_name_(func_name) 
 28434 |          , default_return_type_(default_return_type) 
 28435 |          { 
 28436 |             parse_function_prototypes(func_prototypes); 
 28437 |          } 
 28438 |  
 28439 |          bool verify(const std::string& param_seq, std::size_t& pseq_index) 
 28440 |          { 
 28441 |             if (function_definition_list_.empty()) 
 28442 |                return true; 
 28443 |  
 28444 |             std::vector<std::pair<std::size_t,char> > error_list; 
 28445 |  
 28446 |             for (std::size_t i = 0; i < function_definition_list_.size(); ++i) 
 28447 |             { 
 28448 |                details::char_t diff_value = 0; 
 28449 |                std::size_t     diff_index = 0; 
 28450 |  
 28451 |                const bool result = details::sequence_match(function_definition_list_[i].param_seq, 
 28452 |                                                            param_seq, 
 28453 |                                                            diff_index, diff_value); 
 28454 |  
 28455 |               if (result) 
 28456 |               { 
 28457 |                  pseq_index = i; 
 28458 |                  return true; 
 28459 |               } 
 28460 |               else 
 28461 |                  error_list.push_back(std::make_pair(diff_index, diff_value)); 
 28462 |             } 
 28463 |  
 28464 |             if (1 == error_list.size()) 
 28465 |             { 
 28466 |                parser_.set_error(make_error( 
 28467 |                   parser_error::e_syntax, 
 28468 |                   parser_.current_token(), 
 28469 |                   "ERR132 - Failed parameter type check for function '" + function_name_ + "', " 
 28470 |                   "Expected '" + function_definition_list_[0].param_seq + 
 28471 |                   "' call set: '" + param_seq + "'", 
 28472 |                   exprtk_error_location)); 
 28473 |             } 
 28474 |             else 
 28475 |             { 
 28476 |                // find first with largest diff_index; 
 28477 |                std::size_t max_diff_index = 0; 
 28478 |  
 28479 |                for (std::size_t i = 1; i < error_list.size(); ++i) 
 28480 |                { 
 28481 |                   if (error_list[i].first > error_list[max_diff_index].first) 
 28482 |                   { 
 28483 |                      max_diff_index = i; 
 28484 |                   } 
 28485 |                } 
 28486 |  
 28487 |                parser_.set_error(make_error( 
 28488 |                   parser_error::e_syntax, 
 28489 |                   parser_.current_token(), 
 28490 |                   "ERR133 - Failed parameter type check for function '" + function_name_ + "', " 
 28491 |                   "Best match: '" + function_definition_list_[max_diff_index].param_seq + 
 28492 |                   "' call set: '" + param_seq + "'", 
 28493 |                   exprtk_error_location)); 
 28494 |             } 
 28495 |  
 28496 |             return false; 
 28497 |          } 
 28498 |  
 28499 |          std::size_t paramseq_count() const 
 28500 |          { 
 28501 |             return function_definition_list_.size(); 
 28502 |          } 
 28503 |  
 28504 |          std::string paramseq(const std::size_t& index) const 
 28505 |          { 
 28506 |             return function_definition_list_[index].param_seq; 
 28507 |          } 
 28508 |  
 28509 |          return_type_t return_type(const std::size_t& index) const 
 28510 |          { 
 28511 |             return function_definition_list_[index].return_type; 
 28512 |          } 
 28513 |  
 28514 |          bool invalid() const 
 28515 |          { 
 28516 |             return !invalid_state_; 
 28517 |          } 
 28518 |  
 28519 |          bool allow_zero_parameters() const 
 28520 |          { 
 28521 |  
 28522 |             for (std::size_t i = 0; i < function_definition_list_.size(); ++i) 
 28523 |             { 
 28524 |                if (std::string::npos != function_definition_list_[i].param_seq.find("Z")) 
 28525 |                { 
 28526 |                   return true; 
 28527 |                } 
 28528 |             } 
 28529 |  
 28530 |             return false; 
 28531 |          } 
 28532 |  
 28533 |       private: 
 28534 |  
 28535 |          std::vector<std::string> split_param_seq(const std::string& param_seq, const details::char_t delimiter = '|') const 
 28536 |          { 
 28537 |              std::string::const_iterator current_begin = param_seq.begin(); 
 28538 |              std::string::const_iterator iter          = param_seq.begin(); 
 28539 |  
 28540 |              std::vector<std::string> result; 
 28541 |  
 28542 |              while (iter != param_seq.end()) 
 28543 |              { 
 28544 |                  if (*iter == delimiter) 
 28545 |                  { 
 28546 |                      result.push_back(std::string(current_begin, iter)); 
 28547 |                      current_begin = ++iter; 
 28548 |                  } 
 28549 |                  else 
 28550 |                      ++iter; 
 28551 |              } 
 28552 |  
 28553 |              if (current_begin != iter) 
 28554 |              { 
 28555 |                  result.push_back(std::string(current_begin, iter)); 
 28556 |              } 
 28557 |  
 28558 |              return result; 
 28559 |          } 
 28560 |  
 28561 |          inline bool is_valid_token(std::string param_seq, 
 28562 |                                     function_prototype_t& funcproto) const 
 28563 |          { 
 28564 |             // Determine return type 
 28565 |             funcproto.return_type = default_return_type_; 
 28566 |  
 28567 |             if (param_seq.size() > 2) 
 28568 |             { 
 28569 |                if (':' == param_seq[1]) 
 28570 |                { 
 28571 |                   // Note: Only overloaded igeneric functions can have return 
 28572 |                   // type definitions. 
 28573 |                   if (type_checker::e_overload != default_return_type_) 
 28574 |                      return false; 
 28575 |  
 28576 |                   switch (param_seq[0]) 
 28577 |                   { 
 28578 |                      case 'T' : funcproto.return_type = type_checker::e_numeric; 
 28579 |                                 break; 
 28580 |  
 28581 |                      case 'S' : funcproto.return_type = type_checker::e_string; 
 28582 |                                 break; 
 28583 |  
 28584 |                      default  : return false; 
 28585 |                   } 
 28586 |  
 28587 |                   param_seq.erase(0,2); 
 28588 |                } 
 28589 |             } 
 28590 |  
 28591 |             if ( 
 28592 |                  (std::string::npos != param_seq.find("?*")) || 
 28593 |                  (std::string::npos != param_seq.find("**")) 
 28594 |                ) 
 28595 |             { 
 28596 |                return false; 
 28597 |             } 
 28598 |             else if ( 
 28599 |                       (std::string::npos == param_seq.find_first_not_of("STV*?|")) || 
 28600 |                       ("Z" == param_seq) 
 28601 |                     ) 
 28602 |             { 
 28603 |                funcproto.param_seq = param_seq; 
 28604 |                return true; 
 28605 |             } 
 28606 |  
 28607 |             return false; 
 28608 |          } 
 28609 |  
 28610 |          void parse_function_prototypes(const std::string& func_prototypes) 
 28611 |          { 
 28612 |             if (func_prototypes.empty()) 
 28613 |                return; 
 28614 |  
 28615 |             std::vector<std::string> param_seq_list = split_param_seq(func_prototypes); 
 28616 |  
 28617 |             typedef std::map<std::string,std::size_t> param_seq_map_t; 
 28618 |             param_seq_map_t param_seq_map; 
 28619 |  
 28620 |             for (std::size_t i = 0; i < param_seq_list.size(); ++i) 
 28621 |             { 
 28622 |                function_prototype_t func_proto; 
 28623 |  
 28624 |                if (!is_valid_token(param_seq_list[i], func_proto)) 
 28625 |                { 
 28626 |                   invalid_state_ = false; 
 28627 |  
 28628 |                   parser_.set_error(make_error( 
 28629 |                      parser_error::e_syntax, 
 28630 |                      parser_.current_token(), 
 28631 |                      "ERR134 - Invalid parameter sequence of '" + param_seq_list[i] + 
 28632 |                      "' for function: " + function_name_, 
 28633 |                      exprtk_error_location)); 
 28634 |                   return; 
 28635 |                } 
 28636 |  
 28637 |                param_seq_map_t::const_iterator seq_itr = param_seq_map.find(param_seq_list[i]); 
 28638 |  
 28639 |                if (param_seq_map.end() != seq_itr) 
 28640 |                { 
 28641 |                   invalid_state_ = false; 
 28642 |  
 28643 |                   parser_.set_error(make_error( 
 28644 |                      parser_error::e_syntax, 
 28645 |                      parser_.current_token(), 
 28646 |                      "ERR135 - Function '" + function_name_ + "' has a parameter sequence conflict between " + 
 28647 |                      "pseq_idx[" + details::to_str(seq_itr->second) + "] and" + 
 28648 |                      "pseq_idx[" + details::to_str(i) + "] " + 
 28649 |                      "param seq: " + param_seq_list[i], 
 28650 |                      exprtk_error_location)); 
 28651 |                   return; 
 28652 |                } 
 28653 |  
 28654 |                function_definition_list_.push_back(func_proto); 
 28655 |             } 
 28656 |          } 
 28657 |  
 28658 |          type_checker(const type_checker&) exprtk_delete; 
 28659 |          type_checker& operator=(const type_checker&) exprtk_delete; 
 28660 |  
 28661 |          bool invalid_state_; 
 28662 |          parser_t& parser_; 
 28663 |          std::string function_name_; 
 28664 |          const return_type_t default_return_type_; 
 28665 |          function_definition_list_t function_definition_list_; 
 28666 |       }; 
 28667 |  
 28668 |       inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name) 
 28669 |       { 
 28670 |          std::vector<expression_node_ptr> arg_list; 
 28671 |  
 28672 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28673 |  
 28674 |          next_token(); 
 28675 |  
 28676 |          std::string param_type_list; 
 28677 |  
 28678 |          type_checker tc( 
 28679 |             (*this), 
 28680 |             function_name, 
 28681 |             function->parameter_sequence, 
 28682 |             type_checker::e_string); 
 28683 |  
 28684 |          if (tc.invalid()) 
 28685 |          { 
 28686 |             set_error(make_error( 
 28687 |                parser_error::e_syntax, 
 28688 |                current_token(), 
 28689 |                "ERR136 - Type checker instantiation failure for generic function: " + function_name, 
 28690 |                exprtk_error_location)); 
 28691 |  
 28692 |             return error_node(); 
 28693 |          } 
 28694 |  
 28695 |          if (token_is(token_t::e_lbracket)) 
 28696 |          { 
 28697 |             if (token_is(token_t::e_rbracket)) 
 28698 |             { 
 28699 |                if ( 
 28700 |                     !function->allow_zero_parameters() && 
 28701 |                     !tc       .allow_zero_parameters() 
 28702 |                   ) 
 28703 |                { 
 28704 |                   set_error(make_error( 
 28705 |                      parser_error::e_syntax, 
 28706 |                      current_token(), 
 28707 |                      "ERR137 - Zero parameter call to generic function: " 
 28708 |                      + function_name + " not allowed", 
 28709 |                      exprtk_error_location)); 
 28710 |  
 28711 |                   return error_node(); 
 28712 |                } 
 28713 |             } 
 28714 |             else 
 28715 |             { 
 28716 |                for ( ; ; ) 
 28717 |                { 
 28718 |                   expression_node_ptr arg = parse_expression(); 
 28719 |  
 28720 |                   if (0 == arg) 
 28721 |                      return error_node(); 
 28722 |  
 28723 |                   if (is_ivector_node(arg)) 
 28724 |                      param_type_list += 'V'; 
 28725 |                   else if (is_generally_string_node(arg)) 
 28726 |                      param_type_list += 'S'; 
 28727 |                   else // Everything else is assumed to be a scalar returning expression 
 28728 |                      param_type_list += 'T'; 
 28729 |  
 28730 |                   arg_list.push_back(arg); 
 28731 |  
 28732 |                   if (token_is(token_t::e_rbracket)) 
 28733 |                      break; 
 28734 |                   else if (!token_is(token_t::e_comma)) 
 28735 |                   { 
 28736 |                      set_error(make_error( 
 28737 |                         parser_error::e_syntax, 
 28738 |                         current_token(), 
 28739 |                         "ERR138 - Expected ',' for call to generic function: " + function_name, 
 28740 |                         exprtk_error_location)); 
 28741 |  
 28742 |                      return error_node(); 
 28743 |                   } 
 28744 |                } 
 28745 |             } 
 28746 |          } 
 28747 |          else if ( 
 28748 |                    !function->parameter_sequence.empty() && 
 28749 |                    function->allow_zero_parameters    () && 
 28750 |                    !tc      .allow_zero_parameters    () 
 28751 |                  ) 
 28752 |          { 
 28753 |             set_error(make_error( 
 28754 |                parser_error::e_syntax, 
 28755 |                current_token(), 
 28756 |                "ERR139 - Zero parameter call to generic function: " 
 28757 |                + function_name + " not allowed", 
 28758 |                exprtk_error_location)); 
 28759 |  
 28760 |             return error_node(); 
 28761 |          } 
 28762 |  
 28763 |          std::size_t param_seq_index = 0; 
 28764 |  
 28765 |          if ( 
 28766 |               state_.type_check_enabled && 
 28767 |               !tc.verify(param_type_list, param_seq_index) 
 28768 |             ) 
 28769 |          { 
 28770 |             set_error(make_error( 
 28771 |                parser_error::e_syntax, 
 28772 |                current_token(), 
 28773 |                "ERR140 - Invalid input parameter sequence for call to generic function: " + function_name, 
 28774 |                exprtk_error_location)); 
 28775 |  
 28776 |             return error_node(); 
 28777 |          } 
 28778 |  
 28779 |          expression_node_ptr result = 
 28780 |             (tc.paramseq_count() <= 1) ? 
 28781 |                expression_generator_ 
 28782 |                   .generic_function_call(function, arg_list) : 
 28783 |                expression_generator_ 
 28784 |                   .generic_function_call(function, arg_list, param_seq_index); 
 28785 |  
 28786 |          sdd.delete_ptr = (0 == result); 
 28787 |  
 28788 |          return result; 
 28789 |       } 
 28790 |  
 28791 |       inline bool parse_igeneric_function_params(std::string& param_type_list, 
 28792 |                                                  std::vector<expression_node_ptr>& arg_list, 
 28793 |                                                  const std::string& function_name, 
 28794 |                                                  igeneric_function<T>* function, 
 28795 |                                                  const type_checker& tc) 
 28796 |       { 
 28797 |          if (token_is(token_t::e_lbracket)) 
 28798 |          { 
 28799 |             if (token_is(token_t::e_rbracket)) 
 28800 |             { 
 28801 |                if ( 
 28802 |                     !function->allow_zero_parameters() && 
 28803 |                     !tc       .allow_zero_parameters() 
 28804 |                   ) 
 28805 |                { 
 28806 |                   set_error(make_error( 
 28807 |                      parser_error::e_syntax, 
 28808 |                      current_token(), 
 28809 |                      "ERR141 - Zero parameter call to generic function: " 
 28810 |                      + function_name + " not allowed", 
 28811 |                      exprtk_error_location)); 
 28812 |  
 28813 |                   return false; 
 28814 |                } 
 28815 |             } 
 28816 |             else 
 28817 |             { 
 28818 |                for ( ; ; ) 
 28819 |                { 
 28820 |                   expression_node_ptr arg = parse_expression(); 
 28821 |  
 28822 |                   if (0 == arg) 
 28823 |                      return false; 
 28824 |  
 28825 |                   if (is_ivector_node(arg)) 
 28826 |                      param_type_list += 'V'; 
 28827 |                   else if (is_generally_string_node(arg)) 
 28828 |                      param_type_list += 'S'; 
 28829 |                   else // Everything else is a scalar returning expression 
 28830 |                      param_type_list += 'T'; 
 28831 |  
 28832 |                   arg_list.push_back(arg); 
 28833 |  
 28834 |                   if (token_is(token_t::e_rbracket)) 
 28835 |                      break; 
 28836 |                   else if (!token_is(token_t::e_comma)) 
 28837 |                   { 
 28838 |                      set_error(make_error( 
 28839 |                         parser_error::e_syntax, 
 28840 |                         current_token(), 
 28841 |                         "ERR142 - Expected ',' for call to string function: " + function_name, 
 28842 |                         exprtk_error_location)); 
 28843 |  
 28844 |                      return false; 
 28845 |                   } 
 28846 |                } 
 28847 |             } 
 28848 |  
 28849 |             return true; 
 28850 |          } 
 28851 |          else 
 28852 |             return false; 
 28853 |       } 
 28854 |  
 28855 |       #ifndef exprtk_disable_string_capabilities 
 28856 |       inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name) 
 28857 |       { 
 28858 |          // Move pass the function name 
 28859 |          next_token(); 
 28860 |  
 28861 |          std::string param_type_list; 
 28862 |  
 28863 |          type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string); 
 28864 |  
 28865 |          if ( 
 28866 |               (!function->parameter_sequence.empty()) && 
 28867 |               (0 == tc.paramseq_count()) 
 28868 |             ) 
 28869 |          { 
 28870 |             return error_node(); 
 28871 |          } 
 28872 |  
 28873 |          std::vector<expression_node_ptr> arg_list; 
 28874 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28875 |  
 28876 |          if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc)) 
 28877 |          { 
 28878 |             return error_node(); 
 28879 |          } 
 28880 |  
 28881 |          std::size_t param_seq_index = 0; 
 28882 |  
 28883 |          if (!tc.verify(param_type_list, param_seq_index)) 
 28884 |          { 
 28885 |             set_error(make_error( 
 28886 |                parser_error::e_syntax, 
 28887 |                current_token(), 
 28888 |                "ERR143 - Invalid input parameter sequence for call to string function: " + function_name, 
 28889 |                exprtk_error_location)); 
 28890 |  
 28891 |             return error_node(); 
 28892 |          } 
 28893 |  
 28894 |          expression_node_ptr result = 
 28895 |             (tc.paramseq_count() <= 1) ? 
 28896 |                expression_generator_ 
 28897 |                   .string_function_call(function, arg_list) : 
 28898 |                expression_generator_ 
 28899 |                   .string_function_call(function, arg_list, param_seq_index); 
 28900 |  
 28901 |          sdd.delete_ptr = (0 == result); 
 28902 |  
 28903 |          return result; 
 28904 |       } 
 28905 |  
 28906 |       inline expression_node_ptr parse_overload_function_call(igeneric_function<T>* function, const std::string& function_name) 
 28907 |       { 
 28908 |          // Move pass the function name 
 28909 |          next_token(); 
 28910 |  
 28911 |          std::string param_type_list; 
 28912 |  
 28913 |          type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_overload); 
 28914 |  
 28915 |          if ( 
 28916 |               (!function->parameter_sequence.empty()) && 
 28917 |               (0 == tc.paramseq_count()) 
 28918 |             ) 
 28919 |          { 
 28920 |             return error_node(); 
 28921 |          } 
 28922 |  
 28923 |          std::vector<expression_node_ptr> arg_list; 
 28924 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28925 |  
 28926 |          if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc)) 
 28927 |          { 
 28928 |             return error_node(); 
 28929 |          } 
 28930 |  
 28931 |          std::size_t param_seq_index = 0; 
 28932 |  
 28933 |          if (!tc.verify(param_type_list, param_seq_index)) 
 28934 |          { 
 28935 |             set_error(make_error( 
 28936 |                parser_error::e_syntax, 
 28937 |                current_token(), 
 28938 |                "ERR144 - Invalid input parameter sequence for call to overloaded function: " + function_name, 
 28939 |                exprtk_error_location)); 
 28940 |  
 28941 |             return error_node(); 
 28942 |          } 
 28943 |  
 28944 |          expression_node_ptr result = error_node(); 
 28945 |  
 28946 |          if (type_checker::e_numeric == tc.return_type(param_seq_index)) 
 28947 |          { 
 28948 |             if (tc.paramseq_count() <= 1) 
 28949 |                result = expression_generator_ 
 28950 |                           .generic_function_call(function, arg_list); 
 28951 |             else 
 28952 |                result = expression_generator_ 
 28953 |                           .generic_function_call(function, arg_list, param_seq_index); 
 28954 |          } 
 28955 |          else if (type_checker::e_string == tc.return_type(param_seq_index)) 
 28956 |          { 
 28957 |             if (tc.paramseq_count() <= 1) 
 28958 |                result = expression_generator_ 
 28959 |                           .string_function_call(function, arg_list); 
 28960 |             else 
 28961 |                result = expression_generator_ 
 28962 |                           .string_function_call(function, arg_list, param_seq_index); 
 28963 |          } 
 28964 |          else 
 28965 |          { 
 28966 |             set_error(make_error( 
 28967 |                parser_error::e_syntax, 
 28968 |                current_token(), 
 28969 |                "ERR145 - Invalid return type for call to overloaded function: " + function_name, 
 28970 |                exprtk_error_location)); 
 28971 |          } 
 28972 |  
 28973 |          sdd.delete_ptr = (0 == result); 
 28974 |          return result; 
 28975 |       } 
 28976 |       #endif 
 28977 |  
 28978 |       template <typename Type, std::size_t NumberOfParameters> 
 28979 |       struct parse_special_function_impl 
 28980 |       { 
 28981 |          static inline expression_node_ptr process(parser<Type>& p, const details::operator_type opt_type, const std::string& sf_name) 
 28982 |          { 
 28983 |             expression_node_ptr branch[NumberOfParameters]; 
 28984 |             expression_node_ptr result = error_node(); 
 28985 |  
 28986 |             std::fill_n(branch, NumberOfParameters, reinterpret_cast<expression_node_ptr>(0)); 
 28987 |  
 28988 |             scoped_delete<expression_node_t,NumberOfParameters> sd(p,branch); 
 28989 |  
 28990 |             p.next_token(); 
 28991 |  
 28992 |             if (!p.token_is(token_t::e_lbracket)) 
 28993 |             { 
 28994 |                p.set_error(make_error( 
 28995 |                   parser_error::e_syntax, 
 28996 |                   p.current_token(), 
 28997 |                   "ERR146 - Expected '(' for special function '" + sf_name + "'", 
 28998 |                   exprtk_error_location)); 
 28999 |  
 29000 |                return error_node(); 
 29001 |             } 
 29002 |  
 29003 |             for (std::size_t i = 0; i < NumberOfParameters; ++i) 
 29004 |             { 
 29005 |                branch[i] = p.parse_expression(); 
 29006 |  
 29007 |                if (0 == branch[i]) 
 29008 |                { 
 29009 |                   return p.error_node(); 
 29010 |                } 
 29011 |                else if (i < (NumberOfParameters - 1)) 
 29012 |                { 
 29013 |                   if (!p.token_is(token_t::e_comma)) 
 29014 |                   { 
 29015 |                      p.set_error(make_error( 
 29016 |                         parser_error::e_syntax, 
 29017 |                         p.current_token(), 
 29018 |                         "ERR147 - Expected ',' before next parameter of special function '" + sf_name + "'", 
 29019 |                         exprtk_error_location)); 
 29020 |  
 29021 |                      return p.error_node(); 
 29022 |                   } 
 29023 |                } 
 29024 |             } 
 29025 |  
 29026 |             if (!p.token_is(token_t::e_rbracket)) 
 29027 |             { 
 29028 |                p.set_error(make_error( 
 29029 |                   parser_error::e_syntax, 
 29030 |                   p.current_token(), 
 29031 |                   "ERR148 - Invalid number of parameters for special function '" + sf_name + "'", 
 29032 |                   exprtk_error_location)); 
 29033 |  
 29034 |                return p.error_node(); 
 29035 |             } 
 29036 |             else 
 29037 |                result = p.expression_generator_.special_function(opt_type,branch); 
 29038 |  
 29039 |             sd.delete_ptr = (0 == result); 
 29040 |  
 29041 |             return result; 
 29042 |          } 
 29043 |       }; 
 29044 |  
 29045 |       inline expression_node_ptr parse_special_function() 
 29046 |       { 
 29047 |          const std::string sf_name = current_token().value; 
 29048 |  
 29049 |          // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3) 
 29050 |          if ( 
 29051 |               !details::is_digit(sf_name[2]) || 
 29052 |               !details::is_digit(sf_name[3]) 
 29053 |             ) 
 29054 |          { 
 29055 |             set_error(make_error( 
 29056 |                parser_error::e_token, 
 29057 |                current_token(), 
 29058 |                "ERR149 - Invalid special function[1]: " + sf_name, 
 29059 |                exprtk_error_location)); 
 29060 |  
 29061 |             return error_node(); 
 29062 |          } 
 29063 |  
 29064 |          const int id = (sf_name[2] - '0') * 10 + 
 29065 |                         (sf_name[3] - '0'); 
 29066 |  
 29067 |          if (id >= details::e_sffinal) 
 29068 |          { 
 29069 |             set_error(make_error( 
 29070 |                parser_error::e_token, 
 29071 |                current_token(), 
 29072 |                "ERR150 - Invalid special function[2]: " + sf_name, 
 29073 |                exprtk_error_location)); 
 29074 |  
 29075 |             return error_node(); 
 29076 |          } 
 29077 |  
 29078 |          const int sf_3_to_4                   = details::e_sf48; 
 29079 |          const details::operator_type opt_type = details::operator_type(id + 1000); 
 29080 |          const std::size_t NumberOfParameters  = (id < (sf_3_to_4 - 1000)) ? 3U : 4U; 
 29081 |  
 29082 |          switch (NumberOfParameters) 
 29083 |          { 
 29084 |             case 3  : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name); 
 29085 |             case 4  : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name); 
 29086 |             default : return error_node(); 
 29087 |          } 
 29088 |       } 
 29089 |  
 29090 |       inline expression_node_ptr parse_null_statement() 
 29091 |       { 
 29092 |          next_token(); 
 29093 |          return node_allocator_.allocate<details::null_node<T> >(); 
 29094 |       } 
 29095 |  
 29096 |       #ifndef exprtk_disable_break_continue 
 29097 |       inline expression_node_ptr parse_break_statement() 
 29098 |       { 
 29099 |          if (state_.parsing_break_stmt) 
 29100 |          { 
 29101 |             set_error(make_error( 
 29102 |                parser_error::e_syntax, 
 29103 |                current_token(), 
 29104 |                "ERR151 - Invoking 'break' within a break call is not allowed", 
 29105 |                exprtk_error_location)); 
 29106 |  
 29107 |             return error_node(); 
 29108 |          } 
 29109 |          else if (0 == state_.parsing_loop_stmt_count) 
 29110 |          { 
 29111 |             set_error(make_error( 
 29112 |                parser_error::e_syntax, 
 29113 |                current_token(), 
 29114 |                "ERR152 - Invalid use of 'break', allowed only in the scope of a loop", 
 29115 |                exprtk_error_location)); 
 29116 |  
 29117 |             return error_node(); 
 29118 |          } 
 29119 |  
 29120 |          scoped_bool_negator sbn(state_.parsing_break_stmt); 
 29121 |  
 29122 |          if (!brkcnt_list_.empty()) 
 29123 |          { 
 29124 |             next_token(); 
 29125 |  
 29126 |             brkcnt_list_.front() = true; 
 29127 |  
 29128 |             expression_node_ptr return_expr = error_node(); 
 29129 |  
 29130 |             if (token_is(token_t::e_lsqrbracket)) 
 29131 |             { 
 29132 |                if (0 == (return_expr = parse_expression())) 
 29133 |                { 
 29134 |                   set_error(make_error( 
 29135 |                      parser_error::e_syntax, 
 29136 |                      current_token(), 
 29137 |                      "ERR153 - Failed to parse return expression for 'break' statement", 
 29138 |                      exprtk_error_location)); 
 29139 |  
 29140 |                   return error_node(); 
 29141 |                } 
 29142 |                else if (!token_is(token_t::e_rsqrbracket)) 
 29143 |                { 
 29144 |                   set_error(make_error( 
 29145 |                      parser_error::e_syntax, 
 29146 |                      current_token(), 
 29147 |                      "ERR154 - Expected ']' at the completion of break's return expression", 
 29148 |                      exprtk_error_location)); 
 29149 |  
 29150 |                   free_node(node_allocator_, return_expr); 
 29151 |  
 29152 |                   return error_node(); 
 29153 |                } 
 29154 |             } 
 29155 |  
 29156 |             state_.activate_side_effect("parse_break_statement()"); 
 29157 |  
 29158 |             return node_allocator_.allocate<details::break_node<T> >(return_expr); 
 29159 |          } 
 29160 |          else 
 29161 |          { 
 29162 |             set_error(make_error( 
 29163 |                parser_error::e_syntax, 
 29164 |                current_token(), 
 29165 |                "ERR155 - Invalid use of 'break', allowed only in the scope of a loop", 
 29166 |                exprtk_error_location)); 
 29167 |          } 
 29168 |  
 29169 |          return error_node(); 
 29170 |       } 
 29171 |  
 29172 |       inline expression_node_ptr parse_continue_statement() 
 29173 |       { 
 29174 |          if (0 == state_.parsing_loop_stmt_count) 
 29175 |          { 
 29176 |             set_error(make_error( 
 29177 |                parser_error::e_syntax, 
 29178 |                current_token(), 
 29179 |                "ERR156 - Invalid use of 'continue', allowed only in the scope of a loop", 
 29180 |                exprtk_error_location)); 
 29181 |  
 29182 |             return error_node(); 
 29183 |          } 
 29184 |          else 
 29185 |          { 
 29186 |             next_token(); 
 29187 |  
 29188 |             brkcnt_list_.front() = true; 
 29189 |             state_.activate_side_effect("parse_continue_statement()"); 
 29190 |  
 29191 |             return node_allocator_.allocate<details::continue_node<T> >(); 
 29192 |          } 
 29193 |       } 
 29194 |       #endif 
 29195 |  
 29196 |       inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name) 
 29197 |       { 
 29198 |          expression_node_ptr size_expression_node = error_node(); 
 29199 |  
 29200 |          if (!token_is(token_t::e_lsqrbracket)) 
 29201 |          { 
 29202 |             set_error(make_error( 
 29203 |                parser_error::e_syntax, 
 29204 |                current_token(), 
 29205 |                "ERR157 - Expected '[' as part of vector size definition", 
 29206 |                exprtk_error_location)); 
 29207 |  
 29208 |             return error_node(); 
 29209 |          } 
 29210 |          else if (0 == (size_expression_node = parse_expression())) 
 29211 |          { 
 29212 |             set_error(make_error( 
 29213 |                parser_error::e_syntax, 
 29214 |                current_token(), 
 29215 |                "ERR158 - Failed to determine size of vector '" + vec_name + "'", 
 29216 |                exprtk_error_location)); 
 29217 |  
 29218 |             return error_node(); 
 29219 |          } 
 29220 |          else if (!is_constant_node(size_expression_node)) 
 29221 |          { 
 29222 |             const bool is_rebaseble_vector = 
 29223 |                (size_expression_node->type() == details::expression_node<T>::e_vecsize) && 
 29224 |                static_cast<details::vector_size_node<T>*>(size_expression_node)->vec_holder()->rebaseable(); 
 29225 |  
 29226 |             free_node(node_allocator_, size_expression_node); 
 29227 |  
 29228 |             const std::string error_msg = (is_rebaseble_vector) ? 
 29229 |                                           std::string("Rebasable/Resizable vector cannot be used to define the size of vector") : 
 29230 |                                           std::string("Expected a constant literal number as size of vector"); 
 29231 |             set_error(make_error( 
 29232 |                parser_error::e_syntax, 
 29233 |                current_token(), 
 29234 |                "ERR159 - " + error_msg + " '" + vec_name + "'", 
 29235 |                exprtk_error_location)); 
 29236 |  
 29237 |             return error_node(); 
 29238 |          } 
 29239 |  
 29240 |          const T vector_size = size_expression_node->value(); 
 29241 |  
 29242 |          free_node(node_allocator_, size_expression_node); 
 29243 |  
 29244 |          const std::size_t max_vector_size = settings_.max_local_vector_size(); 
 29245 |  
 29246 |          if ( 
 29247 |               (vector_size <= T(0)) || 
 29248 |               std::not_equal_to<T>() 
 29249 |               (T(0),vector_size - details::numeric::trunc(vector_size)) || 
 29250 |               (static_cast<std::size_t>(vector_size) > max_vector_size) 
 29251 |             ) 
 29252 |          { 
 29253 |             set_error(make_error( 
 29254 |                parser_error::e_syntax, 
 29255 |                current_token(), 
 29256 |                "ERR160 - Invalid vector size. Must be an integer in the " 
 29257 |                "range [0," + details::to_str(static_cast<std::size_t>(max_vector_size)) + "], size: " + 
 29258 |                details::to_str(details::numeric::to_int32(vector_size)), 
 29259 |                exprtk_error_location)); 
 29260 |  
 29261 |             return error_node(); 
 29262 |          } 
 29263 |  
 29264 |          typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0); 
 29265 |  
 29266 |          const std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size)); 
 29267 |          const std::size_t predicted_total_lclsymb_size = sizeof(T) * vec_size + sem_.total_local_symb_size_bytes(); 
 29268 |  
 29269 |          if (predicted_total_lclsymb_size > settings().max_total_local_symbol_size_bytes()) 
 29270 |          { 
 29271 |             set_error(make_error( 
 29272 |                parser_error::e_syntax, 
 29273 |                current_token(), 
 29274 |                "ERR161 - Adding vector '" + vec_name + "' of size " + details::to_str(vec_size) + " bytes " 
 29275 |                "will exceed max total local symbol size of: " + details::to_str(settings().max_total_local_symbol_size_bytes())  + " bytes, " 
 29276 |                "current total size: " + details::to_str(sem_.total_local_symb_size_bytes()) + " bytes", 
 29277 |                exprtk_error_location)); 
 29278 |  
 29279 |             return error_node(); 
 29280 |          } 
 29281 |  
 29282 |          scope_element& se = sem_.get_element(vec_name); 
 29283 |  
 29284 |          if (se.name == vec_name) 
 29285 |          { 
 29286 |             if (se.active) 
 29287 |             { 
 29288 |                set_error(make_error( 
 29289 |                   parser_error::e_syntax, 
 29290 |                   current_token(), 
 29291 |                   "ERR162 - Illegal redefinition of local vector: '" + vec_name + "'", 
 29292 |                   exprtk_error_location)); 
 29293 |  
 29294 |                return error_node(); 
 29295 |             } 
 29296 |             else if ( 
 29297 |                       (se.size == vec_size) && 
 29298 |                       (scope_element::e_vector == se.type) 
 29299 |                     ) 
 29300 |             { 
 29301 |                vec_holder = se.vec_node; 
 29302 |                se.active  = true; 
 29303 |                se.depth   = state_.scope_depth; 
 29304 |                se.ref_count++; 
 29305 |             } 
 29306 |          } 
 29307 |  
 29308 |          if (0 == vec_holder) 
 29309 |          { 
 29310 |             scope_element nse; 
 29311 |             nse.name      = vec_name; 
 29312 |             nse.active    = true; 
 29313 |             nse.ref_count = 1; 
 29314 |             nse.type      = scope_element::e_vector; 
 29315 |             nse.depth     = state_.scope_depth; 
 29316 |             nse.size      = vec_size; 
 29317 |             nse.data      = new T[vec_size]; 
 29318 |             nse.vec_node  = new typename scope_element::vector_holder_t(reinterpret_cast<T*>(nse.data),nse.size); 
 29319 |  
 29320 |             details::set_zero_value(reinterpret_cast<T*>(nse.data),vec_size); 
 29321 |  
 29322 |             if (!sem_.add_element(nse)) 
 29323 |             { 
 29324 |                set_error(make_error( 
 29325 |                   parser_error::e_syntax, 
 29326 |                   current_token(), 
 29327 |                   "ERR163 - Failed to add new local vector '" + vec_name + "' to SEM", 
 29328 |                   exprtk_error_location)); 
 29329 |  
 29330 |                sem_.free_element(nse); 
 29331 |  
 29332 |                return error_node(); 
 29333 |             } 
 29334 |  
 29335 |             assert(sem_.total_local_symb_size_bytes() <= settings().max_total_local_symbol_size_bytes()); 
 29336 |  
 29337 |             vec_holder = nse.vec_node; 
 29338 |  
 29339 |             exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n", 
 29340 |                           nse.name.c_str(), 
 29341 |                           static_cast<int>(nse.size))); 
 29342 |          } 
 29343 |  
 29344 |          state_.activate_side_effect("parse_define_vector_statement()"); 
 29345 |  
 29346 |          lodge_symbol(vec_name, e_st_local_vector); 
 29347 |  
 29348 |          std::vector<expression_node_ptr> vec_initilizer_list; 
 29349 |  
 29350 |          scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list); 
 29351 |  
 29352 |          bool single_value_initialiser = false; 
 29353 |          bool range_value_initialiser  = false; 
 29354 |          bool vec_to_vec_initialiser   = false; 
 29355 |          bool null_initialisation      = false; 
 29356 |  
 29357 |          if (!token_is(token_t::e_rsqrbracket)) 
 29358 |          { 
 29359 |             set_error(make_error( 
 29360 |                parser_error::e_syntax, 
 29361 |                current_token(), 
 29362 |                "ERR164 - Expected ']' as part of vector size definition", 
 29363 |                exprtk_error_location)); 
 29364 |  
 29365 |             return error_node(); 
 29366 |          } 
 29367 |          else if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold)) 
 29368 |          { 
 29369 |             if (!token_is(token_t::e_assign)) 
 29370 |             { 
 29371 |                set_error(make_error( 
 29372 |                   parser_error::e_syntax, 
 29373 |                   current_token(), 
 29374 |                   "ERR165 - Expected ':=' as part of vector definition", 
 29375 |                   exprtk_error_location)); 
 29376 |  
 29377 |                return error_node(); 
 29378 |             } 
 29379 |             else if (token_is(token_t::e_lsqrbracket)) 
 29380 |             { 
 29381 |                expression_node_ptr initialiser_component = parse_expression(); 
 29382 |  
 29383 |                if (0 == initialiser_component) 
 29384 |                { 
 29385 |                   set_error(make_error( 
 29386 |                      parser_error::e_syntax, 
 29387 |                      current_token(), 
 29388 |                      "ERR166 - Failed to parse first component of vector initialiser for vector: " + vec_name, 
 29389 |                      exprtk_error_location)); 
 29390 |  
 29391 |                   return error_node(); 
 29392 |                } 
 29393 |  
 29394 |                vec_initilizer_list.push_back(initialiser_component); 
 29395 |  
 29396 |                if (token_is(token_t::e_colon)) 
 29397 |                { 
 29398 |                   initialiser_component = parse_expression(); 
 29399 |  
 29400 |                   if (0 == initialiser_component) 
 29401 |                   { 
 29402 |                      set_error(make_error( 
 29403 |                         parser_error::e_syntax, 
 29404 |                         current_token(), 
 29405 |                         "ERR167 - Failed to parse second component of vector initialiser for vector: " + vec_name, 
 29406 |                         exprtk_error_location)); 
 29407 |  
 29408 |                      return error_node(); 
 29409 |                   } 
 29410 |  
 29411 |                   vec_initilizer_list.push_back(initialiser_component); 
 29412 |                } 
 29413 |  
 29414 |                if (!token_is(token_t::e_rsqrbracket)) 
 29415 |                { 
 29416 |                   set_error(make_error( 
 29417 |                      parser_error::e_syntax, 
 29418 |                      current_token(), 
 29419 |                      "ERR168 - Expected ']' to close single value vector initialiser", 
 29420 |                      exprtk_error_location)); 
 29421 |  
 29422 |                   return error_node(); 
 29423 |                } 
 29424 |  
 29425 |                switch (vec_initilizer_list.size()) 
 29426 |                { 
 29427 |                   case 1 : single_value_initialiser = true; break; 
 29428 |                   case 2 : range_value_initialiser  = true; break; 
 29429 |                } 
 29430 |             } 
 29431 |             else if (!token_is(token_t::e_lcrlbracket)) 
 29432 |             { 
 29433 |                expression_node_ptr initialiser = error_node(); 
 29434 |  
 29435 |                // Is this a vector to vector assignment and initialisation? 
 29436 |                if (token_t::e_symbol == current_token().type) 
 29437 |                { 
 29438 |                   // Is it a locally defined vector? 
 29439 |                   const scope_element& lcl_se = sem_.get_active_element(current_token().value); 
 29440 |  
 29441 |                   if (scope_element::e_vector == lcl_se.type) 
 29442 |                   { 
 29443 |                      if (0 != (initialiser = parse_expression())) 
 29444 |                         vec_initilizer_list.push_back(initialiser); 
 29445 |                      else 
 29446 |                         return error_node(); 
 29447 |                   } 
 29448 |                   // Are we dealing with a user defined vector? 
 29449 |                   else if (symtab_store_.is_vector(current_token().value)) 
 29450 |                   { 
 29451 |                      lodge_symbol(current_token().value, e_st_vector); 
 29452 |  
 29453 |                      if (0 != (initialiser = parse_expression())) 
 29454 |                         vec_initilizer_list.push_back(initialiser); 
 29455 |                      else 
 29456 |                         return error_node(); 
 29457 |                   } 
 29458 |                   // Are we dealing with a null initialisation vector definition? 
 29459 |                   else if (token_is(token_t::e_symbol,"null")) 
 29460 |                      null_initialisation = true; 
 29461 |                } 
 29462 |  
 29463 |                if (!null_initialisation) 
 29464 |                { 
 29465 |                   if (0 == initialiser) 
 29466 |                   { 
 29467 |                      set_error(make_error( 
 29468 |                         parser_error::e_syntax, 
 29469 |                         current_token(), 
 29470 |                         "ERR169 - Expected '{' as part of vector initialiser list", 
 29471 |                         exprtk_error_location)); 
 29472 |  
 29473 |                      return error_node(); 
 29474 |                   } 
 29475 |                   else 
 29476 |                      vec_to_vec_initialiser = true; 
 29477 |                } 
 29478 |             } 
 29479 |             else if (!token_is(token_t::e_rcrlbracket)) 
 29480 |             { 
 29481 |                for ( ; ; ) 
 29482 |                { 
 29483 |                   expression_node_ptr initialiser = parse_expression(); 
 29484 |  
 29485 |                   if (0 == initialiser) 
 29486 |                   { 
 29487 |                      set_error(make_error( 
 29488 |                         parser_error::e_syntax, 
 29489 |                         current_token(), 
 29490 |                         "ERR170 - Expected '{' as part of vector initialiser list", 
 29491 |                         exprtk_error_location)); 
 29492 |  
 29493 |                      return error_node(); 
 29494 |                   } 
 29495 |                   else 
 29496 |                      vec_initilizer_list.push_back(initialiser); 
 29497 |  
 29498 |                   if (token_is(token_t::e_rcrlbracket)) 
 29499 |                      break; 
 29500 |  
 29501 |                   const bool is_next_close = peek_token_is(token_t::e_rcrlbracket); 
 29502 |  
 29503 |                   if (!token_is(token_t::e_comma) && is_next_close) 
 29504 |                   { 
 29505 |                      set_error(make_error( 
 29506 |                         parser_error::e_syntax, 
 29507 |                         current_token(), 
 29508 |                         "ERR171 - Expected ',' between vector initialisers", 
 29509 |                         exprtk_error_location)); 
 29510 |  
 29511 |                      return error_node(); 
 29512 |                   } 
 29513 |  
 29514 |                   if (token_is(token_t::e_rcrlbracket)) 
 29515 |                      break; 
 29516 |                } 
 29517 |             } 
 29518 |  
 29519 |             if ( 
 29520 |                  !token_is(token_t::e_rbracket   , prsrhlpr_t::e_hold) && 
 29521 |                  !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && 
 29522 |                  !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold) 
 29523 |                ) 
 29524 |             { 
 29525 |                if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 29526 |                { 
 29527 |                   set_error(make_error( 
 29528 |                      parser_error::e_syntax, 
 29529 |                      current_token(), 
 29530 |                      "ERR172 - Expected ';' at end of vector definition", 
 29531 |                      exprtk_error_location)); 
 29532 |  
 29533 |                   return error_node(); 
 29534 |                } 
 29535 |             } 
 29536 |  
 29537 |             if ( 
 29538 |                  !single_value_initialiser && 
 29539 |                  !range_value_initialiser  && 
 29540 |                  (T(vec_initilizer_list.size()) > vector_size) 
 29541 |                ) 
 29542 |             { 
 29543 |                set_error(make_error( 
 29544 |                   parser_error::e_syntax, 
 29545 |                   current_token(), 
 29546 |                   "ERR173 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", 
 29547 |                   exprtk_error_location)); 
 29548 |  
 29549 |                return error_node(); 
 29550 |             } 
 29551 |          } 
 29552 |  
 29553 |          expression_node_ptr result = error_node(); 
 29554 |  
 29555 |          if ( 
 29556 |               (vec_initilizer_list.size() == 1) && 
 29557 |               single_value_initialiser 
 29558 |             ) 
 29559 |          { 
 29560 |             if (details::is_constant_node(vec_initilizer_list[0])) 
 29561 |             { 
 29562 |               // vector_init_zero_value_node   var v[10] := [0] 
 29563 |                if (T(0) == vec_initilizer_list[0]->value()) 
 29564 |                { 
 29565 |                   result = node_allocator_ 
 29566 |                               .allocate<details::vector_init_zero_value_node<T> >( 
 29567 |                                  (*vec_holder)[0], 
 29568 |                                  vec_size, 
 29569 |                                  vec_initilizer_list); 
 29570 |                } 
 29571 |                else 
 29572 |                { 
 29573 |                   // vector_init_single_constvalue_node   var v[10] := [123] 
 29574 |                   result = node_allocator_ 
 29575 |                               .allocate<details::vector_init_single_constvalue_node<T> >( 
 29576 |                                  (*vec_holder)[0], 
 29577 |                                  vec_size, 
 29578 |                                  vec_initilizer_list); 
 29579 |                } 
 29580 |             } 
 29581 |             else 
 29582 |             { 
 29583 |                // vector_init_single_value_node   var v[10] := [123 + (x / y)] 
 29584 |                result = node_allocator_ 
 29585 |                            .allocate<details::vector_init_single_value_node<T> >( 
 29586 |                               (*vec_holder)[0], 
 29587 |                               vec_size, 
 29588 |                               vec_initilizer_list); 
 29589 |             } 
 29590 |          } 
 29591 |          else if ( 
 29592 |                    (vec_initilizer_list.size() == 2) && 
 29593 |                    range_value_initialiser 
 29594 |                  ) 
 29595 |          { 
 29596 |             bool base_const = details::is_constant_node(vec_initilizer_list[0]); 
 29597 |             bool inc_const  = details::is_constant_node(vec_initilizer_list[1]); 
 29598 |  
 29599 |             if (base_const && inc_const) 
 29600 |             { 
 29601 |                // vector_init_single_value_node   var v[10] := [1 : 3.5] 
 29602 |                result = node_allocator_ 
 29603 |                            .allocate<details::vector_init_iota_constconst_node<T> >( 
 29604 |                               (*vec_holder)[0], 
 29605 |                               vec_size, 
 29606 |                               vec_initilizer_list); 
 29607 |             } 
 29608 |             else if (base_const && !inc_const) 
 29609 |             { 
 29610 |                // vector_init_single_value_node   var v[10] := [1 : x + y] 
 29611 |                result = node_allocator_ 
 29612 |                            .allocate<details::vector_init_iota_constnconst_node<T> >( 
 29613 |                               (*vec_holder)[0], 
 29614 |                               vec_size, 
 29615 |                               vec_initilizer_list); 
 29616 |             } 
 29617 |             else if (!base_const && inc_const) 
 29618 |             { 
 29619 |                // vector_init_single_value_node   var v[10] := [x + y : 3] 
 29620 |                result = node_allocator_ 
 29621 |                            .allocate<details::vector_init_iota_nconstconst_node<T> >( 
 29622 |                               (*vec_holder)[0], 
 29623 |                               vec_size, 
 29624 |                               vec_initilizer_list); 
 29625 |             } 
 29626 |             else if (!base_const && !inc_const) 
 29627 |             { 
 29628 |                // vector_init_single_value_node   var v[10] := [x + y :  z / w] 
 29629 |                result = node_allocator_ 
 29630 |                            .allocate<details::vector_init_iota_nconstnconst_node<T> >( 
 29631 |                               (*vec_holder)[0], 
 29632 |                               vec_size, 
 29633 |                               vec_initilizer_list); 
 29634 |             } 
 29635 |          } 
 29636 |          else if (null_initialisation) 
 29637 |             result = expression_generator_(T(0.0)); 
 29638 |          else if (vec_to_vec_initialiser) 
 29639 |          { 
 29640 |             expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec_holder); 
 29641 |  
 29642 |             result = expression_generator_( 
 29643 |                         details::e_assign, 
 29644 |                         vec_node, 
 29645 |                         vec_initilizer_list[0]); 
 29646 |          } 
 29647 |          else 
 29648 |          { 
 29649 |             result = node_allocator_ 
 29650 |                         .allocate<details::vector_initialisation_node<T> >( 
 29651 |                            (*vec_holder)[0], 
 29652 |                            vec_size, 
 29653 |                            vec_initilizer_list, 
 29654 |                            single_value_initialiser); 
 29655 |          } 
 29656 |  
 29657 |          svd.delete_ptr = false; 
 29658 |  
 29659 |          if (result && result->valid()) 
 29660 |          { 
 29661 |             return result; 
 29662 |          } 
 29663 |  
 29664 |          details::free_node(node_allocator_, result); 
 29665 |  
 29666 |          set_error(make_error( 
 29667 |             parser_error::e_synthesis, 
 29668 |             current_token(), 
 29669 |             "ERR174 - Failed to generate initialisation node for vector: " + vec_name, 
 29670 |             exprtk_error_location)); 
 29671 |  
 29672 |          return error_node(); 
 29673 |       } 
 29674 |  
 29675 |       #ifndef exprtk_disable_string_capabilities 
 29676 |       inline expression_node_ptr parse_define_string_statement(const std::string& str_name, expression_node_ptr initialisation_expression) 
 29677 |       { 
 29678 |          stringvar_node_t* str_node = reinterpret_cast<stringvar_node_t*>(0); 
 29679 |  
 29680 |          scope_element& se = sem_.get_element(str_name); 
 29681 |  
 29682 |          if (se.name == str_name) 
 29683 |          { 
 29684 |             if (se.active) 
 29685 |             { 
 29686 |                set_error(make_error( 
 29687 |                   parser_error::e_syntax, 
 29688 |                   current_token(), 
 29689 |                   "ERR175 - Illegal redefinition of local variable: '" + str_name + "'", 
 29690 |                   exprtk_error_location)); 
 29691 |  
 29692 |                free_node(node_allocator_, initialisation_expression); 
 29693 |  
 29694 |                return error_node(); 
 29695 |             } 
 29696 |             else if (scope_element::e_string == se.type) 
 29697 |             { 
 29698 |                str_node  = se.str_node; 
 29699 |                se.active = true; 
 29700 |                se.depth  = state_.scope_depth; 
 29701 |                se.ref_count++; 
 29702 |             } 
 29703 |          } 
 29704 |  
 29705 |          if (0 == str_node) 
 29706 |          { 
 29707 |             scope_element nse; 
 29708 |             nse.name      = str_name; 
 29709 |             nse.active    = true; 
 29710 |             nse.ref_count = 1; 
 29711 |             nse.type      = scope_element::e_string; 
 29712 |             nse.depth     = state_.scope_depth; 
 29713 |             nse.data      = new std::string; 
 29714 |             nse.str_node  = new stringvar_node_t(*reinterpret_cast<std::string*>(nse.data)); 
 29715 |  
 29716 |             if (!sem_.add_element(nse)) 
 29717 |             { 
 29718 |                set_error(make_error( 
 29719 |                   parser_error::e_syntax, 
 29720 |                   current_token(), 
 29721 |                   "ERR176 - Failed to add new local string variable '" + str_name + "' to SEM", 
 29722 |                   exprtk_error_location)); 
 29723 |  
 29724 |                free_node(node_allocator_, initialisation_expression); 
 29725 |  
 29726 |                sem_.free_element(nse); 
 29727 |  
 29728 |                return error_node(); 
 29729 |             } 
 29730 |  
 29731 |             assert(sem_.total_local_symb_size_bytes() <= settings().max_total_local_symbol_size_bytes()); 
 29732 |  
 29733 |             str_node = nse.str_node; 
 29734 |  
 29735 |             exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n", nse.name.c_str())); 
 29736 |          } 
 29737 |  
 29738 |          lodge_symbol(str_name, e_st_local_string); 
 29739 |  
 29740 |          state_.activate_side_effect("parse_define_string_statement()"); 
 29741 |  
 29742 |          expression_node_ptr branch[2] = {0}; 
 29743 |  
 29744 |          branch[0] = str_node; 
 29745 |          branch[1] = initialisation_expression; 
 29746 |  
 29747 |          return expression_generator_(details::e_assign,branch); 
 29748 |       } 
 29749 |       #else 
 29750 |       inline expression_node_ptr parse_define_string_statement(const std::string&, expression_node_ptr) 
 29751 |       { 
 29752 |          return error_node(); 
 29753 |       } 
 29754 |       #endif 
 29755 |  
 29756 |       inline bool local_variable_is_shadowed(const std::string& symbol) 
 29757 |       { 
 29758 |          const scope_element& se = sem_.get_element(symbol); 
 29759 |          return (se.name == symbol) && se.active; 
 29760 |       } 
 29761 |  
 29762 |       inline expression_node_ptr parse_define_var_statement() 
 29763 |       { 
 29764 |          if (settings_.vardef_disabled()) 
 29765 |          { 
 29766 |             set_error(make_error( 
 29767 |                parser_error::e_syntax, 
 29768 |                current_token(), 
 29769 |                "ERR177 - Illegal variable definition", 
 29770 |                exprtk_error_location)); 
 29771 |  
 29772 |             return error_node(); 
 29773 |          } 
 29774 |          else if (!details::imatch(current_token().value,"var")) 
 29775 |          { 
 29776 |             return error_node(); 
 29777 |          } 
 29778 |          else 
 29779 |             next_token(); 
 29780 |  
 29781 |          const std::string var_name = current_token().value; 
 29782 |  
 29783 |          expression_node_ptr initialisation_expression = error_node(); 
 29784 |  
 29785 |          if (!token_is(token_t::e_symbol)) 
 29786 |          { 
 29787 |             set_error(make_error( 
 29788 |                parser_error::e_syntax, 
 29789 |                current_token(), 
 29790 |                "ERR178 - Expected a symbol for variable definition", 
 29791 |                exprtk_error_location)); 
 29792 |  
 29793 |             return error_node(); 
 29794 |          } 
 29795 |          else if (details::is_reserved_symbol(var_name)) 
 29796 |          { 
 29797 |             set_error(make_error( 
 29798 |                parser_error::e_syntax, 
 29799 |                current_token(), 
 29800 |                "ERR179 - Illegal redefinition of reserved keyword: '" + var_name + "'", 
 29801 |                exprtk_error_location)); 
 29802 |  
 29803 |             return error_node(); 
 29804 |          } 
 29805 |          else if (symtab_store_.symbol_exists(var_name)) 
 29806 |          { 
 29807 |             set_error(make_error( 
 29808 |                parser_error::e_syntax, 
 29809 |                current_token(), 
 29810 |                "ERR180 - Illegal redefinition of variable '" + var_name + "'", 
 29811 |                exprtk_error_location)); 
 29812 |  
 29813 |             return error_node(); 
 29814 |          } 
 29815 |          else if (local_variable_is_shadowed(var_name)) 
 29816 |          { 
 29817 |             set_error(make_error( 
 29818 |                parser_error::e_syntax, 
 29819 |                current_token(), 
 29820 |                "ERR181 - Illegal redefinition of local variable: '" + var_name + "'", 
 29821 |                exprtk_error_location)); 
 29822 |  
 29823 |             return error_node(); 
 29824 |          } 
 29825 |          else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)) 
 29826 |          { 
 29827 |             return parse_define_vector_statement(var_name); 
 29828 |          } 
 29829 |          else if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) 
 29830 |          { 
 29831 |             return parse_uninitialised_var_statement(var_name); 
 29832 |          } 
 29833 |          else if (token_is(token_t::e_assign)) 
 29834 |          { 
 29835 |             if (0 == (initialisation_expression = parse_expression())) 
 29836 |             { 
 29837 |                set_error(make_error( 
 29838 |                   parser_error::e_syntax, 
 29839 |                   current_token(), 
 29840 |                   "ERR182 - Failed to parse initialisation expression for variable '" + var_name + "'", 
 29841 |                   exprtk_error_location)); 
 29842 |  
 29843 |                return error_node(); 
 29844 |             } 
 29845 |          } 
 29846 |  
 29847 |          if ( 
 29848 |               !token_is(token_t::e_rbracket   , prsrhlpr_t::e_hold) && 
 29849 |               !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && 
 29850 |               !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold) 
 29851 |             ) 
 29852 |          { 
 29853 |             if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 29854 |             { 
 29855 |                set_error(make_error( 
 29856 |                   parser_error::e_syntax, 
 29857 |                   current_token(), 
 29858 |                   "ERR183 - Expected ';' after variable '" + var_name + "' definition", 
 29859 |                   exprtk_error_location)); 
 29860 |  
 29861 |                free_node(node_allocator_, initialisation_expression); 
 29862 |  
 29863 |                return error_node(); 
 29864 |             } 
 29865 |          } 
 29866 |  
 29867 |          if ( 
 29868 |               (0 != initialisation_expression) && 
 29869 |               details::is_generally_string_node(initialisation_expression) 
 29870 |             ) 
 29871 |          { 
 29872 |             return parse_define_string_statement(var_name,initialisation_expression); 
 29873 |          } 
 29874 |  
 29875 |          expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0); 
 29876 |  
 29877 |          scope_element& se = sem_.get_element(var_name); 
 29878 |  
 29879 |          if (se.name == var_name) 
 29880 |          { 
 29881 |             if (se.active) 
 29882 |             { 
 29883 |                set_error(make_error( 
 29884 |                   parser_error::e_syntax, 
 29885 |                   current_token(), 
 29886 |                   "ERR184 - Illegal redefinition of local variable: '" + var_name + "'", 
 29887 |                   exprtk_error_location)); 
 29888 |  
 29889 |                free_node(node_allocator_, initialisation_expression); 
 29890 |  
 29891 |                return error_node(); 
 29892 |             } 
 29893 |             else if (scope_element::e_variable == se.type) 
 29894 |             { 
 29895 |                var_node  = se.var_node; 
 29896 |                se.active = true; 
 29897 |                se.depth  = state_.scope_depth; 
 29898 |                se.ref_count++; 
 29899 |             } 
 29900 |          } 
 29901 |  
 29902 |          if (0 == var_node) 
 29903 |          { 
 29904 |             const std::size_t predicted_total_lclsymb_size = sizeof(T) + sem_.total_local_symb_size_bytes(); 
 29905 |  
 29906 |             if (predicted_total_lclsymb_size > settings().max_total_local_symbol_size_bytes()) 
 29907 |             { 
 29908 |                set_error(make_error( 
 29909 |                   parser_error::e_syntax, 
 29910 |                   current_token(), 
 29911 |                   "ERR185 - Adding variable '" + var_name + "' " 
 29912 |                   "will exceed max total local symbol size of: " + details::to_str(settings().max_total_local_symbol_size_bytes()) + " bytes, " 
 29913 |                   "current total size: " + details::to_str(sem_.total_local_symb_size_bytes()) + " bytes", 
 29914 |                   exprtk_error_location)); 
 29915 |  
 29916 |                free_node(node_allocator_, initialisation_expression); 
 29917 |  
 29918 |                return error_node(); 
 29919 |             } 
 29920 |  
 29921 |             scope_element nse; 
 29922 |             nse.name      = var_name; 
 29923 |             nse.active    = true; 
 29924 |             nse.ref_count = 1; 
 29925 |             nse.type      = scope_element::e_variable; 
 29926 |             nse.depth     = state_.scope_depth; 
 29927 |             nse.data      = new T(T(0)); 
 29928 |             nse.var_node  = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data)); 
 29929 |  
 29930 |             if (!sem_.add_element(nse)) 
 29931 |             { 
 29932 |                set_error(make_error( 
 29933 |                   parser_error::e_syntax, 
 29934 |                   current_token(), 
 29935 |                   "ERR186 - Failed to add new local variable '" + var_name + "' to SEM", 
 29936 |                   exprtk_error_location)); 
 29937 |  
 29938 |                free_node(node_allocator_, initialisation_expression); 
 29939 |  
 29940 |                sem_.free_element(nse); 
 29941 |  
 29942 |                return error_node(); 
 29943 |             } 
 29944 |  
 29945 |             assert(sem_.total_local_symb_size_bytes() <= settings().max_total_local_symbol_size_bytes()); 
 29946 |  
 29947 |             var_node = nse.var_node; 
 29948 |  
 29949 |             exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n", nse.name.c_str())); 
 29950 |          } 
 29951 |  
 29952 |          state_.activate_side_effect("parse_define_var_statement()"); 
 29953 |  
 29954 |          lodge_symbol(var_name, e_st_local_variable); 
 29955 |  
 29956 |          expression_node_ptr branch[2] = {0}; 
 29957 |  
 29958 |          branch[0] = var_node; 
 29959 |          branch[1] = initialisation_expression ? initialisation_expression : expression_generator_(T(0)); 
 29960 |  
 29961 |          return expression_generator_(details::e_assign,branch); 
 29962 |       } 
 29963 |  
 29964 |       inline expression_node_ptr parse_define_constvar_statement() 
 29965 |       { 
 29966 |          if (settings_.vardef_disabled()) 
 29967 |          { 
 29968 |             set_error(make_error( 
 29969 |                parser_error::e_syntax, 
 29970 |                current_token(), 
 29971 |                "ERR187 - Illegal const variable definition", 
 29972 |                exprtk_error_location)); 
 29973 |  
 29974 |             return error_node(); 
 29975 |          } 
 29976 |          else if (!token_is("const")) 
 29977 |          { 
 29978 |             set_error(make_error( 
 29979 |                parser_error::e_syntax, 
 29980 |                current_token(), 
 29981 |                "ERR188 - Expected 'const' keyword for const-variable definition", 
 29982 |                exprtk_error_location)); 
 29983 |  
 29984 |             return error_node(); 
 29985 |          } 
 29986 |          else if (!token_is("var")) 
 29987 |          { 
 29988 |             set_error(make_error( 
 29989 |                parser_error::e_syntax, 
 29990 |                current_token(), 
 29991 |                "ERR189 - Expected 'var' keyword for const-variable definition", 
 29992 |                exprtk_error_location)); 
 29993 |  
 29994 |             return error_node(); 
 29995 |          } 
 29996 |  
 29997 |          const std::string var_name = current_token().value; 
 29998 |  
 29999 |          expression_node_ptr initialisation_expression = error_node(); 
 30000 |  
 30001 |          if (!token_is(token_t::e_symbol)) 
 30002 |          { 
 30003 |             set_error(make_error( 
 30004 |                parser_error::e_syntax, 
 30005 |                current_token(), 
 30006 |                "ERR190 - Expected a symbol for const-variable definition", 
 30007 |                exprtk_error_location)); 
 30008 |  
 30009 |             return error_node(); 
 30010 |          } 
 30011 |          else if (details::is_reserved_symbol(var_name)) 
 30012 |          { 
 30013 |             set_error(make_error( 
 30014 |                parser_error::e_syntax, 
 30015 |                current_token(), 
 30016 |                "ERR191 - Illegal redefinition of reserved keyword: '" + var_name + "'", 
 30017 |                exprtk_error_location)); 
 30018 |  
 30019 |             return error_node(); 
 30020 |          } 
 30021 |          else if (symtab_store_.symbol_exists(var_name)) 
 30022 |          { 
 30023 |             set_error(make_error( 
 30024 |                parser_error::e_syntax, 
 30025 |                current_token(), 
 30026 |                "ERR192 - Illegal redefinition of variable '" + var_name + "'", 
 30027 |                exprtk_error_location)); 
 30028 |  
 30029 |             return error_node(); 
 30030 |          } 
 30031 |          else if (local_variable_is_shadowed(var_name)) 
 30032 |          { 
 30033 |             set_error(make_error( 
 30034 |                parser_error::e_syntax, 
 30035 |                current_token(), 
 30036 |                "ERR193 - Illegal redefinition of local variable: '" + var_name + "'", 
 30037 |                exprtk_error_location)); 
 30038 |  
 30039 |             return error_node(); 
 30040 |          } 
 30041 |          else if (token_is(token_t::e_assign)) 
 30042 |          { 
 30043 |             if (0 == (initialisation_expression = parse_expression())) 
 30044 |             { 
 30045 |                set_error(make_error( 
 30046 |                   parser_error::e_syntax, 
 30047 |                   current_token(), 
 30048 |                   "ERR194 - Failed to parse initialisation expression for const-variable: '" + var_name + "'", 
 30049 |                   exprtk_error_location)); 
 30050 |  
 30051 |                return error_node(); 
 30052 |             } 
 30053 |             else if (!details::is_literal_node(initialisation_expression)) 
 30054 |             { 
 30055 |                set_error(make_error( 
 30056 |                   parser_error::e_syntax, 
 30057 |                   current_token(), 
 30058 |                   "ERR195 - initialisation expression for const-variable: '" + var_name + "' must be a constant/literal", 
 30059 |                   exprtk_error_location)); 
 30060 |  
 30061 |                free_node(node_allocator_, initialisation_expression); 
 30062 |  
 30063 |                return error_node(); 
 30064 |             } 
 30065 |          } 
 30066 |  
 30067 |          const T init_value = initialisation_expression->value(); 
 30068 |  
 30069 |          free_node(node_allocator_, initialisation_expression); 
 30070 |  
 30071 |          expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0); 
 30072 |  
 30073 |          scope_element& se = sem_.get_element(var_name); 
 30074 |  
 30075 |          if (se.name == var_name) 
 30076 |          { 
 30077 |             if (se.active) 
 30078 |             { 
 30079 |                set_error(make_error( 
 30080 |                   parser_error::e_syntax, 
 30081 |                   current_token(), 
 30082 |                   "ERR196 - Illegal redefinition of local variable: '" + var_name + "'", 
 30083 |                   exprtk_error_location)); 
 30084 |  
 30085 |                return error_node(); 
 30086 |             } 
 30087 |             else if (scope_element::e_literal == se.type) 
 30088 |             { 
 30089 |                var_node  = se.var_node; 
 30090 |                se.active = true; 
 30091 |                se.depth  = state_.scope_depth; 
 30092 |                se.ref_count++; 
 30093 |             } 
 30094 |          } 
 30095 |  
 30096 |          if (0 == var_node) 
 30097 |          { 
 30098 |             const std::size_t predicted_total_lclsymb_size = sizeof(T) + sem_.total_local_symb_size_bytes(); 
 30099 |  
 30100 |             if (predicted_total_lclsymb_size > settings().max_total_local_symbol_size_bytes()) 
 30101 |             { 
 30102 |                set_error(make_error( 
 30103 |                   parser_error::e_syntax, 
 30104 |                   current_token(), 
 30105 |                   "ERR197 - Adding variable '" + var_name + "' " 
 30106 |                   "will exceed max total local symbol size of: " + details::to_str(settings().max_total_local_symbol_size_bytes()) + " bytes, " 
 30107 |                   "current total size: " + details::to_str(sem_.total_local_symb_size_bytes()) + " bytes", 
 30108 |                   exprtk_error_location)); 
 30109 |  
 30110 |                return error_node(); 
 30111 |             } 
 30112 |  
 30113 |             scope_element nse; 
 30114 |             nse.name      = var_name; 
 30115 |             nse.active    = true; 
 30116 |             nse.ref_count = 1; 
 30117 |             nse.type      = scope_element::e_literal; 
 30118 |             nse.depth     = state_.scope_depth; 
 30119 |             nse.data      = 0; 
 30120 |             nse.var_node  = node_allocator_.allocate<literal_node_t>(init_value); 
 30121 |  
 30122 |             if (!sem_.add_element(nse)) 
 30123 |             { 
 30124 |                set_error(make_error( 
 30125 |                   parser_error::e_syntax, 
 30126 |                   current_token(), 
 30127 |                   "ERR198 - Failed to add new local const-variable '" + var_name + "' to SEM", 
 30128 |                   exprtk_error_location)); 
 30129 |  
 30130 |                sem_.free_element(nse); 
 30131 |  
 30132 |                return error_node(); 
 30133 |             } 
 30134 |  
 30135 |             assert(sem_.total_local_symb_size_bytes() <= settings().max_total_local_symbol_size_bytes()); 
 30136 |  
 30137 |             var_node = nse.var_node; 
 30138 |  
 30139 |             exprtk_debug(("parse_define_constvar_statement() - INFO - Added new local const-variable: %s\n", nse.name.c_str())); 
 30140 |          } 
 30141 |  
 30142 |          state_.activate_side_effect("parse_define_constvar_statement()"); 
 30143 |  
 30144 |          lodge_symbol(var_name, e_st_local_variable); 
 30145 |  
 30146 |          return expression_generator_(var_node->value()); 
 30147 |       } 
 30148 |  
 30149 |       inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name) 
 30150 |       { 
 30151 |          if ( 
 30152 |               !token_is(token_t::e_lcrlbracket) || 
 30153 |               !token_is(token_t::e_rcrlbracket) 
 30154 |             ) 
 30155 |          { 
 30156 |             set_error(make_error( 
 30157 |                parser_error::e_syntax, 
 30158 |                current_token(), 
 30159 |                "ERR199 - Expected a '{}' for uninitialised var definition", 
 30160 |                exprtk_error_location)); 
 30161 |  
 30162 |             return error_node(); 
 30163 |          } 
 30164 |          else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 30165 |          { 
 30166 |             set_error(make_error( 
 30167 |                parser_error::e_syntax, 
 30168 |                current_token(), 
 30169 |                "ERR200 - Expected ';' after uninitialised variable definition", 
 30170 |                exprtk_error_location)); 
 30171 |  
 30172 |             return error_node(); 
 30173 |          } 
 30174 |  
 30175 |          expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0); 
 30176 |  
 30177 |          scope_element& se = sem_.get_element(var_name); 
 30178 |  
 30179 |          if (se.name == var_name) 
 30180 |          { 
 30181 |             if (se.active) 
 30182 |             { 
 30183 |                set_error(make_error( 
 30184 |                   parser_error::e_syntax, 
 30185 |                   current_token(), 
 30186 |                   "ERR201 - Illegal redefinition of local variable: '" + var_name + "'", 
 30187 |                   exprtk_error_location)); 
 30188 |  
 30189 |                return error_node(); 
 30190 |             } 
 30191 |             else if (scope_element::e_variable == se.type) 
 30192 |             { 
 30193 |                var_node  = se.var_node; 
 30194 |                se.active = true; 
 30195 |                se.ref_count++; 
 30196 |             } 
 30197 |          } 
 30198 |  
 30199 |          if (0 == var_node) 
 30200 |          { 
 30201 |             const std::size_t predicted_total_lclsymb_size = sizeof(T) + sem_.total_local_symb_size_bytes(); 
 30202 |  
 30203 |             if (predicted_total_lclsymb_size > settings().max_total_local_symbol_size_bytes()) 
 30204 |             { 
 30205 |                set_error(make_error( 
 30206 |                   parser_error::e_syntax, 
 30207 |                   current_token(), 
 30208 |                   "ERR202 - Adding variable '" + var_name + "' " 
 30209 |                   "will exceed max total local symbol size of: " + details::to_str(settings().max_total_local_symbol_size_bytes()) + " bytes, " 
 30210 |                   "current total size: " + details::to_str(sem_.total_local_symb_size_bytes()) + " bytes", 
 30211 |                   exprtk_error_location)); 
 30212 |  
 30213 |                return error_node(); 
 30214 |             } 
 30215 |  
 30216 |             scope_element nse; 
 30217 |             nse.name      = var_name; 
 30218 |             nse.active    = true; 
 30219 |             nse.ref_count = 1; 
 30220 |             nse.type      = scope_element::e_variable; 
 30221 |             nse.depth     = state_.scope_depth; 
 30222 |             nse.ip_index  = sem_.next_ip_index(); 
 30223 |             nse.data      = new T(T(0)); 
 30224 |             nse.var_node  = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data)); 
 30225 |  
 30226 |             if (!sem_.add_element(nse)) 
 30227 |             { 
 30228 |                set_error(make_error( 
 30229 |                   parser_error::e_syntax, 
 30230 |                   current_token(), 
 30231 |                   "ERR203 - Failed to add new local variable '" + var_name + "' to SEM", 
 30232 |                   exprtk_error_location)); 
 30233 |  
 30234 |                sem_.free_element(nse); 
 30235 |  
 30236 |                return error_node(); 
 30237 |             } 
 30238 |  
 30239 |             assert(sem_.total_local_symb_size_bytes() <= settings().max_total_local_symbol_size_bytes()); 
 30240 |  
 30241 |             exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n", 
 30242 |                           nse.name.c_str())); 
 30243 |          } 
 30244 |  
 30245 |          lodge_symbol(var_name, e_st_local_variable); 
 30246 |  
 30247 |          state_.activate_side_effect("parse_uninitialised_var_statement()"); 
 30248 |  
 30249 |          return expression_generator_(T(0)); 
 30250 |       } 
 30251 |  
 30252 |       inline expression_node_ptr parse_swap_statement() 
 30253 |       { 
 30254 |          if (!details::imatch(current_token().value,"swap")) 
 30255 |          { 
 30256 |             return error_node(); 
 30257 |          } 
 30258 |          else 
 30259 |             next_token(); 
 30260 |  
 30261 |          if (!token_is(token_t::e_lbracket)) 
 30262 |          { 
 30263 |             set_error(make_error( 
 30264 |                parser_error::e_syntax, 
 30265 |                current_token(), 
 30266 |                "ERR204 - Expected '(' at start of swap statement", 
 30267 |                exprtk_error_location)); 
 30268 |  
 30269 |             return error_node(); 
 30270 |          } 
 30271 |  
 30272 |          expression_node_ptr variable0 = error_node(); 
 30273 |          expression_node_ptr variable1 = error_node(); 
 30274 |  
 30275 |          bool variable0_generated = false; 
 30276 |          bool variable1_generated = false; 
 30277 |  
 30278 |          const std::string var0_name = current_token().value; 
 30279 |  
 30280 |          if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) 
 30281 |          { 
 30282 |             set_error(make_error( 
 30283 |                parser_error::e_syntax, 
 30284 |                current_token(), 
 30285 |                "ERR205 - Expected a symbol for variable or vector element definition", 
 30286 |                exprtk_error_location)); 
 30287 |  
 30288 |             return error_node(); 
 30289 |          } 
 30290 |          else if (peek_token_is(token_t::e_lsqrbracket)) 
 30291 |          { 
 30292 |             if (0 == (variable0 = parse_vector())) 
 30293 |             { 
 30294 |                set_error(make_error( 
 30295 |                   parser_error::e_syntax, 
 30296 |                   current_token(), 
 30297 |                   "ERR206 - First parameter to swap is an invalid vector element: '" + var0_name + "'", 
 30298 |                   exprtk_error_location)); 
 30299 |  
 30300 |                return error_node(); 
 30301 |             } 
 30302 |  
 30303 |             variable0_generated = true; 
 30304 |          } 
 30305 |          else 
 30306 |          { 
 30307 |             if (symtab_store_.is_variable(var0_name)) 
 30308 |             { 
 30309 |                variable0 = symtab_store_.get_variable(var0_name); 
 30310 |             } 
 30311 |  
 30312 |             const scope_element& se = sem_.get_element(var0_name); 
 30313 |  
 30314 |             if ( 
 30315 |                  (se.active)            && 
 30316 |                  (se.name == var0_name) && 
 30317 |                  (scope_element::e_variable == se.type) 
 30318 |                ) 
 30319 |             { 
 30320 |                variable0 = se.var_node; 
 30321 |             } 
 30322 |  
 30323 |             lodge_symbol(var0_name, e_st_variable); 
 30324 |  
 30325 |             if (0 == variable0) 
 30326 |             { 
 30327 |                set_error(make_error( 
 30328 |                   parser_error::e_syntax, 
 30329 |                   current_token(), 
 30330 |                   "ERR207 - First parameter to swap is an invalid variable: '" + var0_name + "'", 
 30331 |                   exprtk_error_location)); 
 30332 |  
 30333 |                return error_node(); 
 30334 |             } 
 30335 |             else 
 30336 |                next_token(); 
 30337 |          } 
 30338 |  
 30339 |          if (!token_is(token_t::e_comma)) 
 30340 |          { 
 30341 |             set_error(make_error( 
 30342 |                parser_error::e_syntax, 
 30343 |                current_token(), 
 30344 |                "ERR208 - Expected ',' between parameters to swap", 
 30345 |                exprtk_error_location)); 
 30346 |  
 30347 |             if (variable0_generated) 
 30348 |             { 
 30349 |                free_node(node_allocator_, variable0); 
 30350 |             } 
 30351 |  
 30352 |             return error_node(); 
 30353 |          } 
 30354 |  
 30355 |          const std::string var1_name = current_token().value; 
 30356 |  
 30357 |          if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) 
 30358 |          { 
 30359 |             set_error(make_error( 
 30360 |                parser_error::e_syntax, 
 30361 |                current_token(), 
 30362 |                "ERR209 - Expected a symbol for variable or vector element definition", 
 30363 |                exprtk_error_location)); 
 30364 |  
 30365 |             if (variable0_generated) 
 30366 |             { 
 30367 |                free_node(node_allocator_, variable0); 
 30368 |             } 
 30369 |  
 30370 |             return error_node(); 
 30371 |          } 
 30372 |          else if (peek_token_is(token_t::e_lsqrbracket)) 
 30373 |          { 
 30374 |             if (0 == (variable1 = parse_vector())) 
 30375 |             { 
 30376 |                set_error(make_error( 
 30377 |                   parser_error::e_syntax, 
 30378 |                   current_token(), 
 30379 |                   "ERR210 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", 
 30380 |                   exprtk_error_location)); 
 30381 |  
 30382 |                if (variable0_generated) 
 30383 |                { 
 30384 |                   free_node(node_allocator_, variable0); 
 30385 |                } 
 30386 |  
 30387 |                return error_node(); 
 30388 |             } 
 30389 |  
 30390 |             variable1_generated = true; 
 30391 |          } 
 30392 |          else 
 30393 |          { 
 30394 |             if (symtab_store_.is_variable(var1_name)) 
 30395 |             { 
 30396 |                variable1 = symtab_store_.get_variable(var1_name); 
 30397 |             } 
 30398 |  
 30399 |             const scope_element& se = sem_.get_element(var1_name); 
 30400 |  
 30401 |             if ( 
 30402 |                  (se.active) && 
 30403 |                  (se.name == var1_name) && 
 30404 |                  (scope_element::e_variable == se.type) 
 30405 |                ) 
 30406 |             { 
 30407 |                variable1 = se.var_node; 
 30408 |             } 
 30409 |  
 30410 |             lodge_symbol(var1_name, e_st_variable); 
 30411 |  
 30412 |             if (0 == variable1) 
 30413 |             { 
 30414 |                set_error(make_error( 
 30415 |                   parser_error::e_syntax, 
 30416 |                   current_token(), 
 30417 |                   "ERR211 - Second parameter to swap is an invalid variable: '" + var1_name + "'", 
 30418 |                   exprtk_error_location)); 
 30419 |  
 30420 |                if (variable0_generated) 
 30421 |                { 
 30422 |                   free_node(node_allocator_, variable0); 
 30423 |                } 
 30424 |  
 30425 |                return error_node(); 
 30426 |             } 
 30427 |             else 
 30428 |                next_token(); 
 30429 |          } 
 30430 |  
 30431 |          if (!token_is(token_t::e_rbracket)) 
 30432 |          { 
 30433 |             set_error(make_error( 
 30434 |                parser_error::e_syntax, 
 30435 |                current_token(), 
 30436 |                "ERR212 - Expected ')' at end of swap statement", 
 30437 |                exprtk_error_location)); 
 30438 |  
 30439 |             if (variable0_generated) 
 30440 |             { 
 30441 |                free_node(node_allocator_, variable0); 
 30442 |             } 
 30443 |  
 30444 |             if (variable1_generated) 
 30445 |             { 
 30446 |                free_node(node_allocator_, variable1); 
 30447 |             } 
 30448 |  
 30449 |             return error_node(); 
 30450 |          } 
 30451 |  
 30452 |          typedef details::variable_node<T>* variable_node_ptr; 
 30453 |  
 30454 |          variable_node_ptr v0 = variable_node_ptr(0); 
 30455 |          variable_node_ptr v1 = variable_node_ptr(0); 
 30456 |  
 30457 |          expression_node_ptr result = error_node(); 
 30458 |  
 30459 |          if ( 
 30460 |               (0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) && 
 30461 |               (0 != (v1 = dynamic_cast<variable_node_ptr>(variable1))) 
 30462 |             ) 
 30463 |          { 
 30464 |             result = node_allocator_.allocate<details::swap_node<T> >(v0, v1); 
 30465 |  
 30466 |             if (variable0_generated) 
 30467 |             { 
 30468 |                free_node(node_allocator_, variable0); 
 30469 |             } 
 30470 |  
 30471 |             if (variable1_generated) 
 30472 |             { 
 30473 |                free_node(node_allocator_, variable1); 
 30474 |             } 
 30475 |          } 
 30476 |          else 
 30477 |             result = node_allocator_.allocate<details::swap_generic_node<T> > 
 30478 |                         (variable0, variable1); 
 30479 |  
 30480 |          state_.activate_side_effect("parse_swap_statement()"); 
 30481 |  
 30482 |          return result; 
 30483 |       } 
 30484 |  
 30485 |       #ifndef exprtk_disable_return_statement 
 30486 |       inline expression_node_ptr parse_return_statement() 
 30487 |       { 
 30488 |          if (state_.parsing_return_stmt) 
 30489 |          { 
 30490 |             set_error(make_error( 
 30491 |                parser_error::e_syntax, 
 30492 |                current_token(), 
 30493 |                "ERR213 - Return call within a return call is not allowed", 
 30494 |                exprtk_error_location)); 
 30495 |  
 30496 |             return error_node(); 
 30497 |          } 
 30498 |  
 30499 |          scoped_bool_negator sbn(state_.parsing_return_stmt); 
 30500 |  
 30501 |          std::vector<expression_node_ptr> arg_list; 
 30502 |  
 30503 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 30504 |  
 30505 |          if (!details::imatch(current_token().value,"return")) 
 30506 |          { 
 30507 |             return error_node(); 
 30508 |          } 
 30509 |          else 
 30510 |             next_token(); 
 30511 |  
 30512 |          if (!token_is(token_t::e_lsqrbracket)) 
 30513 |          { 
 30514 |             set_error(make_error( 
 30515 |                parser_error::e_syntax, 
 30516 |                current_token(), 
 30517 |                "ERR214 - Expected '[' at start of return statement", 
 30518 |                exprtk_error_location)); 
 30519 |  
 30520 |             return error_node(); 
 30521 |          } 
 30522 |          else if (!token_is(token_t::e_rsqrbracket)) 
 30523 |          { 
 30524 |             for ( ; ; ) 
 30525 |             { 
 30526 |                expression_node_ptr arg = parse_expression(); 
 30527 |  
 30528 |                if (0 == arg) 
 30529 |                   return error_node(); 
 30530 |  
 30531 |                arg_list.push_back(arg); 
 30532 |  
 30533 |                if (token_is(token_t::e_rsqrbracket)) 
 30534 |                   break; 
 30535 |                else if (!token_is(token_t::e_comma)) 
 30536 |                { 
 30537 |                   set_error(make_error( 
 30538 |                      parser_error::e_syntax, 
 30539 |                      current_token(), 
 30540 |                      "ERR215 - Expected ',' between values during call to return", 
 30541 |                      exprtk_error_location)); 
 30542 |  
 30543 |                   return error_node(); 
 30544 |                } 
 30545 |             } 
 30546 |          } 
 30547 |          else if (settings_.zero_return_disabled()) 
 30548 |          { 
 30549 |             set_error(make_error( 
 30550 |                parser_error::e_syntax, 
 30551 |                current_token(), 
 30552 |                "ERR216 - Zero parameter return statement not allowed", 
 30553 |                exprtk_error_location)); 
 30554 |  
 30555 |             return error_node(); 
 30556 |          } 
 30557 |  
 30558 |          const lexer::token prev_token = current_token(); 
 30559 |  
 30560 |          if (token_is(token_t::e_rsqrbracket)) 
 30561 |          { 
 30562 |             if (!arg_list.empty()) 
 30563 |             { 
 30564 |                set_error(make_error( 
 30565 |                   parser_error::e_syntax, 
 30566 |                   prev_token, 
 30567 |                   "ERR217 - Invalid ']' found during return call", 
 30568 |                   exprtk_error_location)); 
 30569 |  
 30570 |                return error_node(); 
 30571 |             } 
 30572 |          } 
 30573 |  
 30574 |          std::string ret_param_type_list; 
 30575 |  
 30576 |          for (std::size_t i = 0; i < arg_list.size(); ++i) 
 30577 |          { 
 30578 |             if (0 == arg_list[i]) 
 30579 |                return error_node(); 
 30580 |             else if (is_ivector_node(arg_list[i])) 
 30581 |                ret_param_type_list += 'V'; 
 30582 |             else if (is_generally_string_node(arg_list[i])) 
 30583 |                ret_param_type_list += 'S'; 
 30584 |             else 
 30585 |                ret_param_type_list += 'T'; 
 30586 |          } 
 30587 |  
 30588 |          dec_.retparam_list_.push_back(ret_param_type_list); 
 30589 |  
 30590 |          expression_node_ptr result = expression_generator_.return_call(arg_list); 
 30591 |  
 30592 |          sdd.delete_ptr = (0 == result); 
 30593 |  
 30594 |          state_.return_stmt_present = true; 
 30595 |  
 30596 |          state_.activate_side_effect("parse_return_statement()"); 
 30597 |  
 30598 |          return result; 
 30599 |       } 
 30600 |       #else 
 30601 |       inline expression_node_ptr parse_return_statement() 
 30602 |       { 
 30603 |          return error_node(); 
 30604 |       } 
 30605 |       #endif 
 30606 |  
 30607 |       inline expression_node_ptr parse_assert_statement() 
 30608 |       { 
 30609 |          assert(details::imatch(current_token().value, "assert")); 
 30610 |  
 30611 |          if (state_.parsing_assert_stmt) 
 30612 |          { 
 30613 |             set_error(make_error( 
 30614 |                parser_error::e_syntax, 
 30615 |                current_token(), 
 30616 |                "ERR218 - Assert statement within an assert statement is not allowed", 
 30617 |                exprtk_error_location)); 
 30618 |  
 30619 |             return error_node(); 
 30620 |          } 
 30621 |  
 30622 |          scoped_bool_negator sbn(state_.parsing_assert_stmt); 
 30623 |  
 30624 |          next_token(); 
 30625 |  
 30626 |          std::vector<expression_node_ptr> assert_arg_list(3, error_node()); 
 30627 |          scoped_vec_delete<expression_node_t> sdd((*this), assert_arg_list); 
 30628 |  
 30629 |          expression_node_ptr& assert_condition = assert_arg_list[0]; 
 30630 |          expression_node_ptr& assert_message   = assert_arg_list[1]; 
 30631 |          expression_node_ptr& assert_id        = assert_arg_list[2]; 
 30632 |  
 30633 |          if (!token_is(token_t::e_lbracket)) 
 30634 |          { 
 30635 |             set_error(make_error( 
 30636 |                parser_error::e_syntax, 
 30637 |                current_token(), 
 30638 |                "ERR219 - Expected '(' at start of assert statement", 
 30639 |                exprtk_error_location)); 
 30640 |  
 30641 |             return error_node(); 
 30642 |          } 
 30643 |  
 30644 |          const token_t start_token = current_token(); 
 30645 |  
 30646 |          // Parse the assert condition 
 30647 |          if (0 == (assert_condition = parse_expression())) 
 30648 |          { 
 30649 |             set_error(make_error( 
 30650 |                parser_error::e_syntax, 
 30651 |                current_token(), 
 30652 |                "ERR220 - Failed to parse condition for assert statement", 
 30653 |                exprtk_error_location)); 
 30654 |  
 30655 |             return error_node(); 
 30656 |          } 
 30657 |  
 30658 |          const token_t end_token = current_token(); 
 30659 |  
 30660 |          if (!token_is(token_t::e_rbracket)) 
 30661 |          { 
 30662 |             if (!token_is(token_t::e_comma)) 
 30663 |             { 
 30664 |                set_error(make_error( 
 30665 |                   parser_error::e_syntax, 
 30666 |                   current_token(), 
 30667 |                   "ERR221 - Expected ',' between condition and message for assert statement", 
 30668 |                   exprtk_error_location)); 
 30669 |  
 30670 |                return error_node(); 
 30671 |             } 
 30672 |             // Parse the assert message 
 30673 |             else if ( 
 30674 |                       (0 == (assert_message = parse_expression())) || 
 30675 |                       !details::is_generally_string_node(assert_message) 
 30676 |                     ) 
 30677 |             { 
 30678 |                set_error(make_error( 
 30679 |                   parser_error::e_syntax, 
 30680 |                   current_token(), 
 30681 |                   "ERR222 - " + 
 30682 |                   (assert_message ? 
 30683 |                   std::string("Expected string for assert message") : 
 30684 |                   std::string("Failed to parse message for assert statement")), 
 30685 |                   exprtk_error_location)); 
 30686 |  
 30687 |                return error_node(); 
 30688 |             } 
 30689 |             else if (!token_is(token_t::e_rbracket)) 
 30690 |             { 
 30691 |                if (!token_is(token_t::e_comma)) 
 30692 |                { 
 30693 |                   set_error(make_error( 
 30694 |                      parser_error::e_syntax, 
 30695 |                      current_token(), 
 30696 |                      "ERR223 - Expected ',' between message and ID for assert statement", 
 30697 |                      exprtk_error_location)); 
 30698 |  
 30699 |                   return error_node(); 
 30700 |                } 
 30701 |                // Parse assert ID 
 30702 |                else if ( 
 30703 |                          (0 == (assert_id = parse_expression())) || 
 30704 |                          !details::is_const_string_node(assert_id) 
 30705 |                        ) 
 30706 |                { 
 30707 |                   set_error(make_error( 
 30708 |                      parser_error::e_syntax, 
 30709 |                      current_token(), 
 30710 |                      "ERR224 - " + 
 30711 |                      (assert_id ? 
 30712 |                      std::string("Expected literal string for assert ID") : 
 30713 |                      std::string("Failed to parse string for assert ID")), 
 30714 |                      exprtk_error_location)); 
 30715 |  
 30716 |                   return error_node(); 
 30717 |                } 
 30718 |                else if (!token_is(token_t::e_rbracket)) 
 30719 |                { 
 30720 |                   set_error(make_error( 
 30721 |                      parser_error::e_syntax, 
 30722 |                      current_token(), 
 30723 |                      "ERR225 - Expected ')' at start of assert statement", 
 30724 |                      exprtk_error_location)); 
 30725 |  
 30726 |                   return error_node(); 
 30727 |                } 
 30728 |             } 
 30729 |          } 
 30730 |  
 30731 |          exprtk::assert_check::assert_context context; 
 30732 |          context.condition = lexer().substr(start_token.position, end_token.position); 
 30733 |          context.offet     = start_token.position; 
 30734 |  
 30735 |          if (0 == assert_check_) 
 30736 |          { 
 30737 |             exprtk_debug(("parse_assert_statement() - assert functionality is disabled. assert condition: %s\n", 
 30738 |                           context.condition.c_str())); 
 30739 |  
 30740 |             return new details::null_node<T>(); 
 30741 |          } 
 30742 |  
 30743 |          #ifndef exprtk_disable_string_capabilities 
 30744 |          if (assert_message && details::is_const_string_node(assert_message)) 
 30745 |          { 
 30746 |             context.message = dynamic_cast<details::string_base_node<T>*>(assert_message)->str(); 
 30747 |          } 
 30748 |  
 30749 |          if (assert_id && details::is_const_string_node(assert_id)) 
 30750 |          { 
 30751 |             context.id = dynamic_cast<details::string_base_node<T>*>(assert_id)->str(); 
 30752 |  
 30753 |             if (assert_ids_.end() != assert_ids_.find(context.id)) 
 30754 |             { 
 30755 |                set_error(make_error( 
 30756 |                   parser_error::e_syntax, 
 30757 |                   current_token(), 
 30758 |                   "ERR226 - Duplicate assert ID: " + context.id, 
 30759 |                   exprtk_error_location)); 
 30760 |  
 30761 |                return error_node(); 
 30762 |             } 
 30763 |  
 30764 |             assert_ids_.insert(context.id); 
 30765 |             free_node(node_allocator_, assert_id); 
 30766 |          } 
 30767 |          #endif 
 30768 |  
 30769 |          expression_node_ptr result_node = 
 30770 |             expression_generator_.assert_call( 
 30771 |                assert_condition, 
 30772 |                assert_message, 
 30773 |                context); 
 30774 |  
 30775 |          exprtk_debug(("parse_assert_statement() - assert condition: [%s]\n", context.condition.c_str()      )); 
 30776 |          exprtk_debug(("parse_assert_statement() - assert message:   [%s]\n", context.message  .c_str()      )); 
 30777 |          exprtk_debug(("parse_assert_statement() - assert id:        [%s]\n", context.id       .c_str()      )); 
 30778 |          exprtk_debug(("parse_assert_statement() - assert offset:    [%d]\n", static_cast<int>(context.offet))); 
 30779 |  
 30780 |          if (0 == result_node) 
 30781 |          { 
 30782 |             set_error(make_error( 
 30783 |                parser_error::e_syntax, 
 30784 |                current_token(), 
 30785 |                "ERR227 - Failed to synthesize assert", 
 30786 |                exprtk_error_location)); 
 30787 |  
 30788 |             return error_node(); 
 30789 |          } 
 30790 |  
 30791 |          sdd.delete_ptr = false; 
 30792 |          return result_node; 
 30793 |       } 
 30794 |  
 30795 |       inline bool post_variable_process(const std::string& symbol) 
 30796 |       { 
 30797 |          if ( 
 30798 |               peek_token_is(token_t::e_lbracket   ) || 
 30799 |               peek_token_is(token_t::e_lcrlbracket) || 
 30800 |               peek_token_is(token_t::e_lsqrbracket) 
 30801 |             ) 
 30802 |          { 
 30803 |             if (!settings_.commutative_check_enabled()) 
 30804 |             { 
 30805 |                set_error(make_error( 
 30806 |                   parser_error::e_syntax, 
 30807 |                   current_token(), 
 30808 |                   "ERR228 - Invalid sequence of variable '" + symbol + "' and bracket", 
 30809 |                   exprtk_error_location)); 
 30810 |  
 30811 |                return false; 
 30812 |             } 
 30813 |  
 30814 |             lexer().insert_front(token_t::e_mul); 
 30815 |          } 
 30816 |  
 30817 |          return true; 
 30818 |       } 
 30819 |  
 30820 |       inline bool post_bracket_process(const typename token_t::token_type& token, expression_node_ptr& branch) 
 30821 |       { 
 30822 |          bool implied_mul = false; 
 30823 |  
 30824 |          if (details::is_generally_string_node(branch)) 
 30825 |             return true; 
 30826 |  
 30827 |          if (details::is_ivector_node(branch)) 
 30828 |             return true; 
 30829 |  
 30830 |          const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold; 
 30831 |  
 30832 |          switch (token) 
 30833 |          { 
 30834 |             case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket   , hold) || 
 30835 |                                                         token_is(token_t::e_lcrlbracket, hold) || 
 30836 |                                                         token_is(token_t::e_lsqrbracket, hold) ; 
 30837 |                                           break; 
 30838 |  
 30839 |             case token_t::e_lbracket    : implied_mul = token_is(token_t::e_lbracket   , hold) || 
 30840 |                                                         token_is(token_t::e_lcrlbracket, hold) || 
 30841 |                                                         token_is(token_t::e_lsqrbracket, hold) ; 
 30842 |                                           break; 
 30843 |  
 30844 |             case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket   , hold) || 
 30845 |                                                         token_is(token_t::e_lcrlbracket, hold) || 
 30846 |                                                         token_is(token_t::e_lsqrbracket, hold) ; 
 30847 |                                           break; 
 30848 |  
 30849 |             default                     : return true; 
 30850 |          } 
 30851 |  
 30852 |          if (implied_mul) 
 30853 |          { 
 30854 |             if (!settings_.commutative_check_enabled()) 
 30855 |             { 
 30856 |                set_error(make_error( 
 30857 |                   parser_error::e_syntax, 
 30858 |                   current_token(), 
 30859 |                   "ERR229 - Invalid sequence of brackets", 
 30860 |                   exprtk_error_location)); 
 30861 |  
 30862 |                return false; 
 30863 |             } 
 30864 |             else if (token_t::e_eof != current_token().type) 
 30865 |             { 
 30866 |                lexer().insert_front(current_token().type); 
 30867 |                lexer().insert_front(token_t::e_mul); 
 30868 |                next_token(); 
 30869 |             } 
 30870 |          } 
 30871 |  
 30872 |          return true; 
 30873 |       } 
 30874 |  
 30875 |       typedef typename interval_container_t<const void*>::interval_t interval_t; 
 30876 |       typedef interval_container_t<const void*> immutable_memory_map_t; 
 30877 |       typedef std::map<interval_t,token_t> immutable_symtok_map_t; 
 30878 |  
 30879 |       inline interval_t make_memory_range(const T& t) 
 30880 |       { 
 30881 |          const T* begin = reinterpret_cast<const T*>(&t); 
 30882 |          const T* end   = begin + 1; 
 30883 |          return interval_t(begin, end); 
 30884 |       } 
 30885 |  
 30886 |       inline interval_t make_memory_range(const T* begin, const std::size_t size) 
 30887 |       { 
 30888 |          return interval_t(begin, begin + size); 
 30889 |       } 
 30890 |  
 30891 |       inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size) 
 30892 |       { 
 30893 |          return interval_t(begin, begin + size); 
 30894 |       } 
 30895 |  
 30896 |       void lodge_immutable_symbol(const lexer::token& token, const interval_t interval) 
 30897 |       { 
 30898 |          immutable_memory_map_.add_interval(interval); 
 30899 |          immutable_symtok_map_[interval] = token; 
 30900 |       } 
 30901 |  
 30902 |       inline expression_node_ptr parse_symtab_symbol() 
 30903 |       { 
 30904 |          const std::string symbol = current_token().value; 
 30905 |  
 30906 |          // Are we dealing with a variable or a special constant? 
 30907 |          typedef typename symtab_store::variable_context var_ctxt_t; 
 30908 |          var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol); 
 30909 |  
 30910 |          if (var_ctx.variable) 
 30911 |          { 
 30912 |             assert(var_ctx.symbol_table); 
 30913 |  
 30914 |             expression_node_ptr result_variable = var_ctx.variable; 
 30915 |  
 30916 |             if (symtab_store_.is_constant_node(symbol)) 
 30917 |             { 
 30918 |                result_variable = expression_generator_(var_ctx.variable->value()); 
 30919 |             } 
 30920 |             else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability()) 
 30921 |             { 
 30922 |                lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref())); 
 30923 |                result_variable = var_ctx.variable; 
 30924 |             } 
 30925 |  
 30926 |             if (!post_variable_process(symbol)) 
 30927 |                return error_node(); 
 30928 |  
 30929 |             lodge_symbol(symbol, e_st_variable); 
 30930 |  
 30931 |             next_token(); 
 30932 |  
 30933 |             return result_variable; 
 30934 |          } 
 30935 |  
 30936 |          // Are we dealing with a locally defined variable, vector or string? 
 30937 |          if (!sem_.empty()) 
 30938 |          { 
 30939 |             scope_element& se = sem_.get_active_element(symbol); 
 30940 |  
 30941 |             if (se.active && details::imatch(se.name, symbol)) 
 30942 |             { 
 30943 |                if ( 
 30944 |                     (scope_element::e_variable == se.type) || 
 30945 |                     (scope_element::e_literal  == se.type) 
 30946 |                   ) 
 30947 |                { 
 30948 |                   se.active = true; 
 30949 |                   lodge_symbol(symbol, e_st_local_variable); 
 30950 |  
 30951 |                   if (!post_variable_process(symbol)) 
 30952 |                      return error_node(); 
 30953 |  
 30954 |                   next_token(); 
 30955 |  
 30956 |                   return (scope_element::e_variable == se.type) ? 
 30957 |                            se.var_node : 
 30958 |                            expression_generator_(se.var_node->value()); 
 30959 |                } 
 30960 |                else if (scope_element::e_vector == se.type) 
 30961 |                { 
 30962 |                   return parse_vector(); 
 30963 |                } 
 30964 |                #ifndef exprtk_disable_string_capabilities 
 30965 |                else if (scope_element::e_string == se.type) 
 30966 |                { 
 30967 |                   return parse_string(); 
 30968 |                } 
 30969 |                #endif 
 30970 |             } 
 30971 |          } 
 30972 |  
 30973 |          #ifndef exprtk_disable_string_capabilities 
 30974 |          // Are we dealing with a string variable? 
 30975 |          if (symtab_store_.is_stringvar(symbol)) 
 30976 |          { 
 30977 |             return parse_string(); 
 30978 |          } 
 30979 |          #endif 
 30980 |  
 30981 |          { 
 30982 |             // Are we dealing with a function? 
 30983 |             ifunction<T>* function = symtab_store_.get_function(symbol); 
 30984 |  
 30985 |             if (function) 
 30986 |             { 
 30987 |                lodge_symbol(symbol, e_st_function); 
 30988 |  
 30989 |                expression_node_ptr func_node = 
 30990 |                                       parse_function_invocation(function,symbol); 
 30991 |  
 30992 |                if (func_node) 
 30993 |                   return func_node; 
 30994 |                else 
 30995 |                { 
 30996 |                   set_error(make_error( 
 30997 |                      parser_error::e_syntax, 
 30998 |                      current_token(), 
 30999 |                      "ERR230 - Failed to generate node for function: '" + symbol + "'", 
 31000 |                      exprtk_error_location)); 
 31001 |  
 31002 |                   return error_node(); 
 31003 |                } 
 31004 |             } 
 31005 |          } 
 31006 |  
 31007 |          { 
 31008 |             // Are we dealing with a vararg function? 
 31009 |             ivararg_function<T>* vararg_function = symtab_store_.get_vararg_function(symbol); 
 31010 |  
 31011 |             if (vararg_function) 
 31012 |             { 
 31013 |                lodge_symbol(symbol, e_st_function); 
 31014 |  
 31015 |                expression_node_ptr vararg_func_node = 
 31016 |                                       parse_vararg_function_call(vararg_function, symbol); 
 31017 |  
 31018 |                if (vararg_func_node) 
 31019 |                   return vararg_func_node; 
 31020 |                else 
 31021 |                { 
 31022 |                   set_error(make_error( 
 31023 |                      parser_error::e_syntax, 
 31024 |                      current_token(), 
 31025 |                      "ERR231 - Failed to generate node for vararg function: '" + symbol + "'", 
 31026 |                      exprtk_error_location)); 
 31027 |  
 31028 |                   return error_node(); 
 31029 |                } 
 31030 |             } 
 31031 |          } 
 31032 |  
 31033 |          { 
 31034 |             // Are we dealing with a vararg generic function? 
 31035 |             igeneric_function<T>* generic_function = symtab_store_.get_generic_function(symbol); 
 31036 |  
 31037 |             if (generic_function) 
 31038 |             { 
 31039 |                lodge_symbol(symbol, e_st_function); 
 31040 |  
 31041 |                expression_node_ptr genericfunc_node = 
 31042 |                                       parse_generic_function_call(generic_function, symbol); 
 31043 |  
 31044 |                if (genericfunc_node) 
 31045 |                   return genericfunc_node; 
 31046 |                else 
 31047 |                { 
 31048 |                   set_error(make_error( 
 31049 |                      parser_error::e_syntax, 
 31050 |                      current_token(), 
 31051 |                      "ERR232 - Failed to generate node for generic function: '" + symbol + "'", 
 31052 |                      exprtk_error_location)); 
 31053 |  
 31054 |                   return error_node(); 
 31055 |                } 
 31056 |             } 
 31057 |          } 
 31058 |  
 31059 |          #ifndef exprtk_disable_string_capabilities 
 31060 |          { 
 31061 |             // Are we dealing with a vararg string returning function? 
 31062 |             igeneric_function<T>* string_function = symtab_store_.get_string_function(symbol); 
 31063 |  
 31064 |             if (string_function) 
 31065 |             { 
 31066 |                lodge_symbol(symbol, e_st_function); 
 31067 |  
 31068 |                expression_node_ptr stringfunc_node = 
 31069 |                                       parse_string_function_call(string_function, symbol); 
 31070 |  
 31071 |                if (stringfunc_node) 
 31072 |                   return stringfunc_node; 
 31073 |                else 
 31074 |                { 
 31075 |                   set_error(make_error( 
 31076 |                      parser_error::e_syntax, 
 31077 |                      current_token(), 
 31078 |                      "ERR233 - Failed to generate node for string function: '" + symbol + "'", 
 31079 |                      exprtk_error_location)); 
 31080 |  
 31081 |                   return error_node(); 
 31082 |                } 
 31083 |             } 
 31084 |          } 
 31085 |  
 31086 |          { 
 31087 |             // Are we dealing with a vararg overloaded scalar/string returning function? 
 31088 |             igeneric_function<T>* overload_function = symtab_store_.get_overload_function(symbol); 
 31089 |  
 31090 |             if (overload_function) 
 31091 |             { 
 31092 |                lodge_symbol(symbol, e_st_function); 
 31093 |  
 31094 |                expression_node_ptr overloadfunc_node = 
 31095 |                                       parse_overload_function_call(overload_function, symbol); 
 31096 |  
 31097 |                if (overloadfunc_node) 
 31098 |                   return overloadfunc_node; 
 31099 |                else 
 31100 |                { 
 31101 |                   set_error(make_error( 
 31102 |                      parser_error::e_syntax, 
 31103 |                      current_token(), 
 31104 |                      "ERR234 - Failed to generate node for overload function: '" + symbol + "'", 
 31105 |                      exprtk_error_location)); 
 31106 |  
 31107 |                   return error_node(); 
 31108 |                } 
 31109 |             } 
 31110 |          } 
 31111 |          #endif 
 31112 |  
 31113 |          // Are we dealing with a vector? 
 31114 |          if (symtab_store_.is_vector(symbol)) 
 31115 |          { 
 31116 |             lodge_symbol(symbol, e_st_vector); 
 31117 |             return parse_vector(); 
 31118 |          } 
 31119 |  
 31120 |          if (details::is_reserved_symbol(symbol)) 
 31121 |          { 
 31122 |                if ( 
 31123 |                     settings_.function_enabled(symbol) || 
 31124 |                     !details::is_base_function(symbol) 
 31125 |                   ) 
 31126 |                { 
 31127 |                   set_error(make_error( 
 31128 |                      parser_error::e_syntax, 
 31129 |                      current_token(), 
 31130 |                      "ERR235 - Invalid use of reserved symbol '" + symbol + "'", 
 31131 |                      exprtk_error_location)); 
 31132 |  
 31133 |                   return error_node(); 
 31134 |                } 
 31135 |          } 
 31136 |  
 31137 |          // Should we handle unknown symbols? 
 31138 |          if (resolve_unknown_symbol_ && unknown_symbol_resolver_) 
 31139 |          { 
 31140 |             if (!(settings_.rsrvd_sym_usr_disabled() && details::is_reserved_symbol(symbol))) 
 31141 |             { 
 31142 |                symbol_table_t& symtab = symtab_store_.get_symbol_table(); 
 31143 |  
 31144 |                std::string error_message; 
 31145 |  
 31146 |                if (unknown_symbol_resolver::e_usrmode_default == unknown_symbol_resolver_->mode) 
 31147 |                { 
 31148 |                   T default_value = T(0); 
 31149 |  
 31150 |                   typename unknown_symbol_resolver::usr_symbol_type usr_symbol_type = unknown_symbol_resolver::e_usr_unknown_type; 
 31151 |  
 31152 |                   if (unknown_symbol_resolver_->process(symbol, usr_symbol_type, default_value, error_message)) 
 31153 |                   { 
 31154 |                      bool create_result = false; 
 31155 |  
 31156 |                      switch (usr_symbol_type) 
 31157 |                      { 
 31158 |                         case unknown_symbol_resolver::e_usr_variable_type : 
 31159 |                            create_result = symtab.create_variable(symbol, default_value); 
 31160 |                            break; 
 31161 |  
 31162 |                         case unknown_symbol_resolver::e_usr_constant_type : 
 31163 |                            create_result = symtab.add_constant(symbol, default_value); 
 31164 |                            break; 
 31165 |  
 31166 |                         default                                           : create_result = false; 
 31167 |                      } 
 31168 |  
 31169 |                      if (create_result) 
 31170 |                      { 
 31171 |                         expression_node_ptr var = symtab_store_.get_variable(symbol); 
 31172 |  
 31173 |                         if (var) 
 31174 |                         { 
 31175 |                            if (symtab_store_.is_constant_node(symbol)) 
 31176 |                            { 
 31177 |                               var = expression_generator_(var->value()); 
 31178 |                            } 
 31179 |  
 31180 |                            lodge_symbol(symbol, e_st_variable); 
 31181 |  
 31182 |                            if (!post_variable_process(symbol)) 
 31183 |                               return error_node(); 
 31184 |  
 31185 |                            next_token(); 
 31186 |  
 31187 |                            return var; 
 31188 |                         } 
 31189 |                      } 
 31190 |                   } 
 31191 |  
 31192 |                   set_error(make_error( 
 31193 |                      parser_error::e_symtab, 
 31194 |                      current_token(), 
 31195 |                      "ERR236 - Failed to create variable: '" + symbol + "'" + 
 31196 |                      (error_message.empty() ? "" : " - " + error_message), 
 31197 |                      exprtk_error_location)); 
 31198 |  
 31199 |                } 
 31200 |                else if (unknown_symbol_resolver::e_usrmode_extended == unknown_symbol_resolver_->mode) 
 31201 |                { 
 31202 |                   if (unknown_symbol_resolver_->process(symbol, symtab, error_message)) 
 31203 |                   { 
 31204 |                      expression_node_ptr result = parse_symtab_symbol(); 
 31205 |  
 31206 |                      if (result) 
 31207 |                      { 
 31208 |                         return result; 
 31209 |                      } 
 31210 |                   } 
 31211 |  
 31212 |                   set_error(make_error( 
 31213 |                      parser_error::e_symtab, 
 31214 |                      current_token(), 
 31215 |                      "ERR237 - Failed to resolve symbol: '" + symbol + "'" + 
 31216 |                      (error_message.empty() ? "" : " - " + error_message), 
 31217 |                      exprtk_error_location)); 
 31218 |                } 
 31219 |  
 31220 |                return error_node(); 
 31221 |             } 
 31222 |          } 
 31223 |  
 31224 |          set_error(make_error( 
 31225 |             parser_error::e_syntax, 
 31226 |             current_token(), 
 31227 |             "ERR238 - Undefined symbol: '" + symbol + "'", 
 31228 |             exprtk_error_location)); 
 31229 |  
 31230 |          return error_node(); 
 31231 |       } 
 31232 |  
 31233 |       inline expression_node_ptr check_block_statement_closure(expression_node_ptr expression) 
 31234 |       { 
 31235 |          if ( 
 31236 |               expression && 
 31237 |               ( 
 31238 |                 (current_token().type == token_t::e_symbol) || 
 31239 |                 (current_token().type == token_t::e_number) 
 31240 |               ) 
 31241 |             ) 
 31242 |          { 
 31243 |             free_node(node_allocator_, expression); 
 31244 |  
 31245 |             set_error(make_error( 
 31246 |                parser_error::e_syntax, 
 31247 |                current_token(), 
 31248 |                "ERR239 - Invalid syntax '" + current_token().value  + "' possible missing operator or context", 
 31249 |                exprtk_error_location)); 
 31250 |  
 31251 |                return error_node(); 
 31252 |          } 
 31253 |  
 31254 |          return expression; 
 31255 |       } 
 31256 |  
 31257 |       inline expression_node_ptr parse_symbol() 
 31258 |       { 
 31259 |          static const std::string symbol_if       = "if"      ; 
 31260 |          static const std::string symbol_while    = "while"   ; 
 31261 |          static const std::string symbol_repeat   = "repeat"  ; 
 31262 |          static const std::string symbol_for      = "for"     ; 
 31263 |          static const std::string symbol_switch   = "switch"  ; 
 31264 |          static const std::string symbol_null     = "null"    ; 
 31265 |          static const std::string symbol_break    = "break"   ; 
 31266 |          static const std::string symbol_continue = "continue" 
 31267 |          static const std::string symbol_var      = "var"     ; 
 31268 |          static const std::string symbol_const    = "const"   ; 
 31269 |          static const std::string symbol_swap     = "swap"    ; 
 31270 |          static const std::string symbol_return   = "return"  ; 
 31271 |          static const std::string symbol_not      = "not"     ; 
 31272 |          static const std::string symbol_assert   = "assert"  ; 
 31273 |  
 31274 |          const std::string symbol = current_token().value; 
 31275 |  
 31276 |          if (valid_vararg_operation(symbol)) 
 31277 |          { 
 31278 |             return parse_vararg_function(); 
 31279 |          } 
 31280 |          else if (details::imatch(symbol, symbol_not)) 
 31281 |          { 
 31282 |             return parse_not_statement(); 
 31283 |          } 
 31284 |          else if (valid_base_operation(symbol)) 
 31285 |          { 
 31286 |             return parse_base_operation(); 
 31287 |          } 
 31288 |          else if ( 
 31289 |                    details::imatch(symbol, symbol_if) && 
 31290 |                    settings_.control_struct_enabled(symbol) 
 31291 |                  ) 
 31292 |          { 
 31293 |             return parse_conditional_statement(); 
 31294 |          } 
 31295 |          else if ( 
 31296 |                    details::imatch(symbol, symbol_while) && 
 31297 |                    settings_.control_struct_enabled(symbol) 
 31298 |                  ) 
 31299 |          { 
 31300 |             return check_block_statement_closure(parse_while_loop()); 
 31301 |          } 
 31302 |          else if ( 
 31303 |                    details::imatch(symbol, symbol_repeat) && 
 31304 |                    settings_.control_struct_enabled(symbol) 
 31305 |                  ) 
 31306 |          { 
 31307 |             return check_block_statement_closure(parse_repeat_until_loop()); 
 31308 |          } 
 31309 |          else if ( 
 31310 |                    details::imatch(symbol, symbol_for) && 
 31311 |                    settings_.control_struct_enabled(symbol) 
 31312 |                  ) 
 31313 |          { 
 31314 |             return check_block_statement_closure(parse_for_loop()); 
 31315 |          } 
 31316 |          else if ( 
 31317 |                    details::imatch(symbol, symbol_switch) && 
 31318 |                    settings_.control_struct_enabled(symbol) 
 31319 |                  ) 
 31320 |          { 
 31321 |             return check_block_statement_closure(parse_switch_statement()); 
 31322 |          } 
 31323 |          else if (details::is_valid_sf_symbol(symbol)) 
 31324 |          { 
 31325 |             return parse_special_function(); 
 31326 |          } 
 31327 |          else if (details::imatch(symbol, symbol_null)) 
 31328 |          { 
 31329 |             return parse_null_statement(); 
 31330 |          } 
 31331 |          #ifndef exprtk_disable_break_continue 
 31332 |          else if (details::imatch(symbol, symbol_break)) 
 31333 |          { 
 31334 |             return parse_break_statement(); 
 31335 |          } 
 31336 |          else if (details::imatch(symbol, symbol_continue)) 
 31337 |          { 
 31338 |             return parse_continue_statement(); 
 31339 |          } 
 31340 |          #endif 
 31341 |          else if (details::imatch(symbol, symbol_var)) 
 31342 |          { 
 31343 |             return parse_define_var_statement(); 
 31344 |          } 
 31345 |          else if (details::imatch(symbol, symbol_const)) 
 31346 |          { 
 31347 |             return parse_define_constvar_statement(); 
 31348 |          } 
 31349 |          else if (details::imatch(symbol, symbol_swap)) 
 31350 |          { 
 31351 |             return parse_swap_statement(); 
 31352 |          } 
 31353 |          #ifndef exprtk_disable_return_statement 
 31354 |          else if ( 
 31355 |                    details::imatch(symbol, symbol_return) && 
 31356 |                    settings_.control_struct_enabled(symbol) 
 31357 |                  ) 
 31358 |          { 
 31359 |             return check_block_statement_closure(parse_return_statement()); 
 31360 |          } 
 31361 |          #endif 
 31362 |          else if (details::imatch(symbol, symbol_assert)) 
 31363 |          { 
 31364 |             return parse_assert_statement(); 
 31365 |          } 
 31366 |          else if (symtab_store_.valid() || !sem_.empty()) 
 31367 |          { 
 31368 |             return parse_symtab_symbol(); 
 31369 |          } 
 31370 |          else 
 31371 |          { 
 31372 |             set_error(make_error( 
 31373 |                parser_error::e_symtab, 
 31374 |                current_token(), 
 31375 |                "ERR240 - Unknown variable or function encountered. Symbol table(s) " 
 31376 |                "is either invalid or does not contain symbol: '" + symbol + "'", 
 31377 |                exprtk_error_location)); 
 31378 |  
 31379 |             return error_node(); 
 31380 |          } 
 31381 |       } 
 31382 |  
 31383 |       inline expression_node_ptr parse_branch(precedence_level precedence = e_level00) 
 31384 |       { 
 31385 |          stack_limit_handler slh(*this); 
 31386 |  
 31387 |          if (!slh) 
 31388 |          { 
 31389 |             return error_node(); 
 31390 |          } 
 31391 |  
 31392 |          expression_node_ptr branch = error_node(); 
 31393 |  
 31394 |          if (token_t::e_number == current_token().type) 
 31395 |          { 
 31396 |             T numeric_value = T(0); 
 31397 |  
 31398 |             if (details::string_to_real(current_token().value, numeric_value)) 
 31399 |             { 
 31400 |                expression_node_ptr literal_exp = expression_generator_(numeric_value); 
 31401 |  
 31402 |                if (0 == literal_exp) 
 31403 |                { 
 31404 |                   set_error(make_error( 
 31405 |                      parser_error::e_numeric, 
 31406 |                      current_token(), 
 31407 |                      "ERR241 - Failed generate node for scalar: '" + current_token().value + "'", 
 31408 |                      exprtk_error_location)); 
 31409 |  
 31410 |                   return error_node(); 
 31411 |                } 
 31412 |  
 31413 |                next_token(); 
 31414 |                branch = literal_exp; 
 31415 |             } 
 31416 |             else 
 31417 |             { 
 31418 |                set_error(make_error( 
 31419 |                   parser_error::e_numeric, 
 31420 |                   current_token(), 
 31421 |                   "ERR242 - Failed to convert '" + current_token().value + "' to a number", 
 31422 |                   exprtk_error_location)); 
 31423 |  
 31424 |                return error_node(); 
 31425 |             } 
 31426 |          } 
 31427 |          else if (token_t::e_symbol == current_token().type) 
 31428 |          { 
 31429 |             branch = parse_symbol(); 
 31430 |          } 
 31431 |          #ifndef exprtk_disable_string_capabilities 
 31432 |          else if (token_t::e_string == current_token().type) 
 31433 |          { 
 31434 |             branch = parse_const_string(); 
 31435 |          } 
 31436 |          #endif 
 31437 |          else if (token_t::e_lbracket == current_token().type) 
 31438 |          { 
 31439 |             next_token(); 
 31440 |  
 31441 |             if (0 == (branch = parse_expression())) 
 31442 |             { 
 31443 |                return error_node(); 
 31444 |             } 
 31445 |  
 31446 |             token_is(token_t::e_eof); 
 31447 |  
 31448 |             if (!token_is(token_t::e_rbracket)) 
 31449 |             { 
 31450 |                set_error(make_error( 
 31451 |                   parser_error::e_syntax, 
 31452 |                   current_token(), 
 31453 |                   "ERR243 - Expected ')' instead of: '" + current_token().value + "'", 
 31454 |                   exprtk_error_location)); 
 31455 |  
 31456 |                details::free_node(node_allocator_, branch); 
 31457 |  
 31458 |                return error_node(); 
 31459 |             } 
 31460 |             else if (!post_bracket_process(token_t::e_lbracket,branch)) 
 31461 |             { 
 31462 |                details::free_node(node_allocator_, branch); 
 31463 |  
 31464 |                return error_node(); 
 31465 |             } 
 31466 |  
 31467 |             parse_pending_vector_index_operator(branch); 
 31468 |          } 
 31469 |          else if (token_t::e_lsqrbracket == current_token().type) 
 31470 |          { 
 31471 |             next_token(); 
 31472 |  
 31473 |             if (0 == (branch = parse_expression())) 
 31474 |                return error_node(); 
 31475 |             else if (!token_is(token_t::e_rsqrbracket)) 
 31476 |             { 
 31477 |                set_error(make_error( 
 31478 |                   parser_error::e_syntax, 
 31479 |                   current_token(), 
 31480 |                   "ERR244 - Expected ']' instead of: '" + current_token().value + "'", 
 31481 |                   exprtk_error_location)); 
 31482 |  
 31483 |                details::free_node(node_allocator_, branch); 
 31484 |  
 31485 |                return error_node(); 
 31486 |             } 
 31487 |             else if (!post_bracket_process(token_t::e_lsqrbracket,branch)) 
 31488 |             { 
 31489 |                details::free_node(node_allocator_, branch); 
 31490 |  
 31491 |                return error_node(); 
 31492 |             } 
 31493 |          } 
 31494 |          else if (token_t::e_lcrlbracket == current_token().type) 
 31495 |          { 
 31496 |             next_token(); 
 31497 |  
 31498 |             if (0 == (branch = parse_expression())) 
 31499 |                return error_node(); 
 31500 |             else if (!token_is(token_t::e_rcrlbracket)) 
 31501 |             { 
 31502 |                set_error(make_error( 
 31503 |                   parser_error::e_syntax, 
 31504 |                   current_token(), 
 31505 |                   "ERR245 - Expected '}' instead of: '" + current_token().value + "'", 
 31506 |                   exprtk_error_location)); 
 31507 |  
 31508 |                details::free_node(node_allocator_, branch); 
 31509 |  
 31510 |                return error_node(); 
 31511 |             } 
 31512 |             else if (!post_bracket_process(token_t::e_lcrlbracket,branch)) 
 31513 |             { 
 31514 |                details::free_node(node_allocator_, branch); 
 31515 |  
 31516 |                return error_node(); 
 31517 |             } 
 31518 |          } 
 31519 |          else if (token_t::e_sub == current_token().type) 
 31520 |          { 
 31521 |             next_token(); 
 31522 |             branch = parse_expression(e_level11); 
 31523 |  
 31524 |             if ( 
 31525 |                  branch && 
 31526 |                  !( 
 31527 |                     details::is_neg_unary_node    (branch) && 
 31528 |                     simplify_unary_negation_branch(branch) 
 31529 |                   ) 
 31530 |                ) 
 31531 |             { 
 31532 |                expression_node_ptr result = expression_generator_(details::e_neg,branch); 
 31533 |  
 31534 |                if (0 == result) 
 31535 |                { 
 31536 |                   details::free_node(node_allocator_, branch); 
 31537 |  
 31538 |                   return error_node(); 
 31539 |                } 
 31540 |                else 
 31541 |                   branch = result; 
 31542 |             } 
 31543 |          } 
 31544 |          else if (token_t::e_add == current_token().type) 
 31545 |          { 
 31546 |             next_token(); 
 31547 |             branch = parse_expression(e_level13); 
 31548 |          } 
 31549 |          else if (token_t::e_eof == current_token().type) 
 31550 |          { 
 31551 |             set_error(make_error( 
 31552 |                parser_error::e_syntax, 
 31553 |                current_token(), 
 31554 |                "ERR246 - Premature end of expression[1]", 
 31555 |                exprtk_error_location)); 
 31556 |  
 31557 |             return error_node(); 
 31558 |          } 
 31559 |          else 
 31560 |          { 
 31561 |             set_error(make_error( 
 31562 |                parser_error::e_syntax, 
 31563 |                current_token(), 
 31564 |                "ERR247 - Premature end of expression[2]", 
 31565 |                exprtk_error_location)); 
 31566 |  
 31567 |             return error_node(); 
 31568 |          } 
 31569 |  
 31570 |          if ( 
 31571 |               branch                    && 
 31572 |               (e_level00 == precedence) && 
 31573 |               token_is(token_t::e_ternary,prsrhlpr_t::e_hold) 
 31574 |             ) 
 31575 |          { 
 31576 |             branch = parse_ternary_conditional_statement(branch); 
 31577 |          } 
 31578 |  
 31579 |          parse_pending_string_rangesize(branch); 
 31580 |  
 31581 |          return branch; 
 31582 |       } 
 31583 |  
 31584 |       template <typename Type> 
 31585 |       class expression_generator 
 31586 |       { 
 31587 |       public: 
 31588 |  
 31589 |          typedef details::expression_node<Type>* expression_node_ptr; 
 31590 |          typedef expression_node_ptr (*synthesize_functor_t)(expression_generator<T>&, const details::operator_type& operation, expression_node_ptr (&branch)[2]); 
 31591 |          typedef std::map<std::string,synthesize_functor_t> synthesize_map_t; 
 31592 |          typedef typename exprtk::parser<Type> parser_t; 
 31593 |          typedef const Type& vtype; 
 31594 |          typedef const Type  ctype; 
 31595 |  
 31596 |          inline void init_synthesize_map() 
 31597 |          { 
 31598 |             #ifndef exprtk_disable_enhanced_features 
 31599 |             synthesize_map_["(v)o(v)"] = synthesize_vov_expression::process; 
 31600 |             synthesize_map_["(c)o(v)"] = synthesize_cov_expression::process; 
 31601 |             synthesize_map_["(v)o(c)"] = synthesize_voc_expression::process; 
 31602 |  
 31603 |             #define register_synthezier(S)                      \ 
 31604 |             synthesize_map_[S ::node_type::id()] = S ::process; \ 
 31605 |  
 31606 |             register_synthezier(synthesize_vovov_expression0) 
 31607 |             register_synthezier(synthesize_vovov_expression1) 
 31608 |             register_synthezier(synthesize_vovoc_expression0) 
 31609 |             register_synthezier(synthesize_vovoc_expression1) 
 31610 |             register_synthezier(synthesize_vocov_expression0) 
 31611 |             register_synthezier(synthesize_vocov_expression1) 
 31612 |             register_synthezier(synthesize_covov_expression0) 
 31613 |             register_synthezier(synthesize_covov_expression1) 
 31614 |             register_synthezier(synthesize_covoc_expression0) 
 31615 |             register_synthezier(synthesize_covoc_expression1) 
 31616 |             register_synthezier(synthesize_cocov_expression1) 
 31617 |             register_synthezier(synthesize_vococ_expression0) 
 31618 |  
 31619 |             register_synthezier(synthesize_vovovov_expression0) 
 31620 |             register_synthezier(synthesize_vovovoc_expression0) 
 31621 |             register_synthezier(synthesize_vovocov_expression0) 
 31622 |             register_synthezier(synthesize_vocovov_expression0) 
 31623 |             register_synthezier(synthesize_covovov_expression0) 
 31624 |             register_synthezier(synthesize_covocov_expression0) 
 31625 |             register_synthezier(synthesize_vocovoc_expression0) 
 31626 |             register_synthezier(synthesize_covovoc_expression0) 
 31627 |             register_synthezier(synthesize_vococov_expression0) 
 31628 |  
 31629 |             register_synthezier(synthesize_vovovov_expression1) 
 31630 |             register_synthezier(synthesize_vovovoc_expression1) 
 31631 |             register_synthezier(synthesize_vovocov_expression1) 
 31632 |             register_synthezier(synthesize_vocovov_expression1) 
 31633 |             register_synthezier(synthesize_covovov_expression1) 
 31634 |             register_synthezier(synthesize_covocov_expression1) 
 31635 |             register_synthezier(synthesize_vocovoc_expression1) 
 31636 |             register_synthezier(synthesize_covovoc_expression1) 
 31637 |             register_synthezier(synthesize_vococov_expression1) 
 31638 |  
 31639 |             register_synthezier(synthesize_vovovov_expression2) 
 31640 |             register_synthezier(synthesize_vovovoc_expression2) 
 31641 |             register_synthezier(synthesize_vovocov_expression2) 
 31642 |             register_synthezier(synthesize_vocovov_expression2) 
 31643 |             register_synthezier(synthesize_covovov_expression2) 
 31644 |             register_synthezier(synthesize_covocov_expression2) 
 31645 |             register_synthezier(synthesize_vocovoc_expression2) 
 31646 |             register_synthezier(synthesize_covovoc_expression2) 
 31647 |  
 31648 |             register_synthezier(synthesize_vovovov_expression3) 
 31649 |             register_synthezier(synthesize_vovovoc_expression3) 
 31650 |             register_synthezier(synthesize_vovocov_expression3) 
 31651 |             register_synthezier(synthesize_vocovov_expression3) 
 31652 |             register_synthezier(synthesize_covovov_expression3) 
 31653 |             register_synthezier(synthesize_covocov_expression3) 
 31654 |             register_synthezier(synthesize_vocovoc_expression3) 
 31655 |             register_synthezier(synthesize_covovoc_expression3) 
 31656 |             register_synthezier(synthesize_vococov_expression3) 
 31657 |  
 31658 |             register_synthezier(synthesize_vovovov_expression4) 
 31659 |             register_synthezier(synthesize_vovovoc_expression4) 
 31660 |             register_synthezier(synthesize_vovocov_expression4) 
 31661 |             register_synthezier(synthesize_vocovov_expression4) 
 31662 |             register_synthezier(synthesize_covovov_expression4) 
 31663 |             register_synthezier(synthesize_covocov_expression4) 
 31664 |             register_synthezier(synthesize_vocovoc_expression4) 
 31665 |             register_synthezier(synthesize_covovoc_expression4) 
 31666 |  
 31667 |             #undef register_synthezier 
 31668 |             #endif 
 31669 |          } 
 31670 |  
 31671 |          inline void set_parser(parser_t& p) 
 31672 |          { 
 31673 |             parser_ = &p; 
 31674 |          } 
 31675 |  
 31676 |          inline void set_uom(unary_op_map_t& unary_op_map) 
 31677 |          { 
 31678 |             unary_op_map_ = &unary_op_map; 
 31679 |          } 
 31680 |  
 31681 |          inline void set_bom(binary_op_map_t& binary_op_map) 
 31682 |          { 
 31683 |             binary_op_map_ = &binary_op_map; 
 31684 |          } 
 31685 |  
 31686 |          inline void set_ibom(inv_binary_op_map_t& inv_binary_op_map) 
 31687 |          { 
 31688 |             inv_binary_op_map_ = &inv_binary_op_map; 
 31689 |          } 
 31690 |  
 31691 |          inline void set_sf3m(sf3_map_t& sf3_map) 
 31692 |          { 
 31693 |             sf3_map_ = &sf3_map; 
 31694 |          } 
 31695 |  
 31696 |          inline void set_sf4m(sf4_map_t& sf4_map) 
 31697 |          { 
 31698 |             sf4_map_ = &sf4_map; 
 31699 |          } 
 31700 |  
 31701 |          inline void set_allocator(details::node_allocator& na) 
 31702 |          { 
 31703 |             node_allocator_ = &na; 
 31704 |          } 
 31705 |  
 31706 |          inline void set_strength_reduction_state(const bool enabled) 
 31707 |          { 
 31708 |             strength_reduction_enabled_ = enabled; 
 31709 |          } 
 31710 |  
 31711 |          inline bool strength_reduction_enabled() const 
 31712 |          { 
 31713 |             return strength_reduction_enabled_; 
 31714 |          } 
 31715 |  
 31716 |          inline bool valid_operator(const details::operator_type& operation, binary_functor_t& bop) 
 31717 |          { 
 31718 |             typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation); 
 31719 |  
 31720 |             if (binary_op_map_->end() == bop_itr) 
 31721 |                return false; 
 31722 |  
 31723 |             bop = bop_itr->second; 
 31724 |  
 31725 |             return true; 
 31726 |          } 
 31727 |  
 31728 |          inline bool valid_operator(const details::operator_type& operation, unary_functor_t& uop) 
 31729 |          { 
 31730 |             typename unary_op_map_t::iterator uop_itr = unary_op_map_->find(operation); 
 31731 |  
 31732 |             if ((*unary_op_map_).end() == uop_itr) 
 31733 |                return false; 
 31734 |  
 31735 |             uop = uop_itr->second; 
 31736 |  
 31737 |             return true; 
 31738 |          } 
 31739 |  
 31740 |          inline details::operator_type get_operator(const binary_functor_t& bop) const 
 31741 |          { 
 31742 |             return (*inv_binary_op_map_).find(bop)->second; 
 31743 |          } 
 31744 |  
 31745 |          inline expression_node_ptr operator() (const Type& v) const 
 31746 |          { 
 31747 |             return node_allocator_->allocate<literal_node_t>(v); 
 31748 |          } 
 31749 |  
 31750 |          #ifndef exprtk_disable_string_capabilities 
 31751 |          inline expression_node_ptr operator() (const std::string& s) const 
 31752 |          { 
 31753 |             return node_allocator_->allocate<string_literal_node_t>(s); 
 31754 |          } 
 31755 |  
 31756 |          inline expression_node_ptr operator() (std::string& s, range_t& rp) const 
 31757 |          { 
 31758 |             return node_allocator_->allocate_rr<string_range_node_t>(s,rp); 
 31759 |          } 
 31760 |  
 31761 |          inline expression_node_ptr operator() (const std::string& s, range_t& rp) const 
 31762 |          { 
 31763 |             return node_allocator_->allocate_tt<const_string_range_node_t>(s,rp); 
 31764 |          } 
 31765 |  
 31766 |          inline expression_node_ptr operator() (expression_node_ptr branch, range_t& rp) const 
 31767 |          { 
 31768 |             if (is_generally_string_node(branch)) 
 31769 |                return node_allocator_->allocate_tt<generic_string_range_node_t>(branch,rp); 
 31770 |             else 
 31771 |                return error_node(); 
 31772 |          } 
 31773 |          #endif 
 31774 |  
 31775 |          inline bool unary_optimisable(const details::operator_type& operation) const 
 31776 |          { 
 31777 |             return (details::e_abs   == operation) || (details::e_acos  == operation) || 
 31778 |                    (details::e_acosh == operation) || (details::e_asin  == operation) || 
 31779 |                    (details::e_asinh == operation) || (details::e_atan  == operation) || 
 31780 |                    (details::e_atanh == operation) || (details::e_ceil  == operation) || 
 31781 |                    (details::e_cos   == operation) || (details::e_cosh  == operation) || 
 31782 |                    (details::e_exp   == operation) || (details::e_expm1 == operation) || 
 31783 |                    (details::e_floor == operation) || (details::e_log   == operation) || 
 31784 |                    (details::e_log10 == operation) || (details::e_log2  == operation) || 
 31785 |                    (details::e_log1p == operation) || (details::e_neg   == operation) || 
 31786 |                    (details::e_pos   == operation) || (details::e_round == operation) || 
 31787 |                    (details::e_sin   == operation) || (details::e_sinc  == operation) || 
 31788 |                    (details::e_sinh  == operation) || (details::e_sqrt  == operation) || 
 31789 |                    (details::e_tan   == operation) || (details::e_tanh  == operation) || 
 31790 |                    (details::e_cot   == operation) || (details::e_sec   == operation) || 
 31791 |                    (details::e_csc   == operation) || (details::e_r2d   == operation) || 
 31792 |                    (details::e_d2r   == operation) || (details::e_d2g   == operation) || 
 31793 |                    (details::e_g2d   == operation) || (details::e_notl  == operation) || 
 31794 |                    (details::e_sgn   == operation) || (details::e_erf   == operation) || 
 31795 |                    (details::e_erfc  == operation) || (details::e_ncdf  == operation) || 
 31796 |                    (details::e_frac  == operation) || (details::e_trunc == operation) ; 
 31797 |          } 
 31798 |  
 31799 |          inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc) const 
 31800 |          { 
 31801 |             typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id); 
 31802 |  
 31803 |             if (sf3_map_->end() == itr) 
 31804 |                return false; 
 31805 |             else 
 31806 |                tfunc = itr->second.first; 
 31807 |  
 31808 |             return true; 
 31809 |          } 
 31810 |  
 31811 |          inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc) const 
 31812 |          { 
 31813 |             typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id); 
 31814 |  
 31815 |             if (sf4_map_->end() == itr) 
 31816 |                return false; 
 31817 |             else 
 31818 |                qfunc = itr->second.first; 
 31819 |  
 31820 |             return true; 
 31821 |          } 
 31822 |  
 31823 |          inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation) const 
 31824 |          { 
 31825 |             typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id); 
 31826 |  
 31827 |             if (sf3_map_->end() == itr) 
 31828 |                return false; 
 31829 |             else 
 31830 |                operation = itr->second.second; 
 31831 |  
 31832 |             return true; 
 31833 |          } 
 31834 |  
 31835 |          inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation) const 
 31836 |          { 
 31837 |             typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id); 
 31838 |  
 31839 |             if (sf4_map_->end() == itr) 
 31840 |                return false; 
 31841 |             else 
 31842 |                operation = itr->second.second; 
 31843 |  
 31844 |             return true; 
 31845 |          } 
 31846 |  
 31847 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[1]) 
 31848 |          { 
 31849 |             if (0 == branch[0]) 
 31850 |             { 
 31851 |                return error_node(); 
 31852 |             } 
 31853 |             else if (details::is_null_node(branch[0])) 
 31854 |             { 
 31855 |                return branch[0]; 
 31856 |             } 
 31857 |             else if (details::is_break_node(branch[0])) 
 31858 |             { 
 31859 |                return error_node(); 
 31860 |             } 
 31861 |             else if (details::is_continue_node(branch[0])) 
 31862 |             { 
 31863 |                return error_node(); 
 31864 |             } 
 31865 |             else if (details::is_constant_node(branch[0])) 
 31866 |             { 
 31867 |                return synthesize_expression<unary_node_t,1>(operation,branch); 
 31868 |             } 
 31869 |             else if (unary_optimisable(operation) && details::is_variable_node(branch[0])) 
 31870 |             { 
 31871 |                return synthesize_uv_expression(operation,branch); 
 31872 |             } 
 31873 |             else if (unary_optimisable(operation) && details::is_ivector_node(branch[0])) 
 31874 |             { 
 31875 |                return synthesize_uvec_expression(operation,branch); 
 31876 |             } 
 31877 |             else 
 31878 |                return synthesize_unary_expression(operation,branch); 
 31879 |          } 
 31880 |  
 31881 |          inline bool is_assignment_operation(const details::operator_type& operation) const 
 31882 |          { 
 31883 |             return ( 
 31884 |                      (details::e_addass == operation) || 
 31885 |                      (details::e_subass == operation) || 
 31886 |                      (details::e_mulass == operation) || 
 31887 |                      (details::e_divass == operation) || 
 31888 |                      (details::e_modass == operation) 
 31889 |                    ) && 
 31890 |                    parser_->settings_.assignment_enabled(operation); 
 31891 |          } 
 31892 |  
 31893 |          #ifndef exprtk_disable_string_capabilities 
 31894 |          inline bool valid_string_operation(const details::operator_type& operation) const 
 31895 |          { 
 31896 |             return (details::e_add    == operation) || 
 31897 |                    (details::e_lt     == operation) || 
 31898 |                    (details::e_lte    == operation) || 
 31899 |                    (details::e_gt     == operation) || 
 31900 |                    (details::e_gte    == operation) || 
 31901 |                    (details::e_eq     == operation) || 
 31902 |                    (details::e_ne     == operation) || 
 31903 |                    (details::e_in     == operation) || 
 31904 |                    (details::e_like   == operation) || 
 31905 |                    (details::e_ilike  == operation) || 
 31906 |                    (details::e_assign == operation) || 
 31907 |                    (details::e_addass == operation) || 
 31908 |                    (details::e_swap   == operation) ; 
 31909 |          } 
 31910 |          #else 
 31911 |          inline bool valid_string_operation(const details::operator_type&) const 
 31912 |          { 
 31913 |             return false; 
 31914 |          } 
 31915 |          #endif 
 31916 |  
 31917 |          inline std::string to_str(const details::operator_type& operation) const 
 31918 |          { 
 31919 |             switch (operation) 
 31920 |             { 
 31921 |                case details::e_add  : return "+"      ; 
 31922 |                case details::e_sub  : return "-"      ; 
 31923 |                case details::e_mul  : return "*"      ; 
 31924 |                case details::e_div  : return "/"      ; 
 31925 |                case details::e_mod  : return "%"      ; 
 31926 |                case details::e_pow  : return "^"      ; 
 31927 |                case details::e_lt   : return "<"      ; 
 31928 |                case details::e_lte  : return "<="     ; 
 31929 |                case details::e_gt   : return ">"      ; 
 31930 |                case details::e_gte  : return ">="     ; 
 31931 |                case details::e_eq   : return "=="     ; 
 31932 |                case details::e_ne   : return "!="     ; 
 31933 |                case details::e_and  : return "and"    ; 
 31934 |                case details::e_nand : return "nand"   ; 
 31935 |                case details::e_or   : return "or"     ; 
 31936 |                case details::e_nor  : return "nor"    ; 
 31937 |                case details::e_xor  : return "xor"    ; 
 31938 |                case details::e_xnor : return "xnor"   ; 
 31939 |                default              : return "UNKNOWN" 
 31940 |             } 
 31941 |          } 
 31942 |  
 31943 |          inline bool operation_optimisable(const details::operator_type& operation) const 
 31944 |          { 
 31945 |             return (details::e_add  == operation) || 
 31946 |                    (details::e_sub  == operation) || 
 31947 |                    (details::e_mul  == operation) || 
 31948 |                    (details::e_div  == operation) || 
 31949 |                    (details::e_mod  == operation) || 
 31950 |                    (details::e_pow  == operation) || 
 31951 |                    (details::e_lt   == operation) || 
 31952 |                    (details::e_lte  == operation) || 
 31953 |                    (details::e_gt   == operation) || 
 31954 |                    (details::e_gte  == operation) || 
 31955 |                    (details::e_eq   == operation) || 
 31956 |                    (details::e_ne   == operation) || 
 31957 |                    (details::e_and  == operation) || 
 31958 |                    (details::e_nand == operation) || 
 31959 |                    (details::e_or   == operation) || 
 31960 |                    (details::e_nor  == operation) || 
 31961 |                    (details::e_xor  == operation) || 
 31962 |                    (details::e_xnor == operation) ; 
 31963 |          } 
 31964 |  
 31965 |          inline std::string branch_to_id(expression_node_ptr branch) const 
 31966 |          { 
 31967 |             static const std::string null_str   ("(null)" ); 
 31968 |             static const std::string const_str  ("(c)"    ); 
 31969 |             static const std::string var_str    ("(v)"    ); 
 31970 |             static const std::string vov_str    ("(vov)"  ); 
 31971 |             static const std::string cov_str    ("(cov)"  ); 
 31972 |             static const std::string voc_str    ("(voc)"  ); 
 31973 |             static const std::string str_str    ("(s)"    ); 
 31974 |             static const std::string strrng_str ("(rngs)" ); 
 31975 |             static const std::string cs_str     ("(cs)"   ); 
 31976 |             static const std::string cstrrng_str("(crngs)"); 
 31977 |  
 31978 |             if (details::is_null_node(branch)) 
 31979 |                return null_str; 
 31980 |             else if (details::is_constant_node(branch)) 
 31981 |                return const_str; 
 31982 |             else if (details::is_variable_node(branch)) 
 31983 |                return var_str; 
 31984 |             else if (details::is_vov_node(branch)) 
 31985 |                return vov_str; 
 31986 |             else if (details::is_cov_node(branch)) 
 31987 |                return cov_str; 
 31988 |             else if (details::is_voc_node(branch)) 
 31989 |                return voc_str; 
 31990 |             else if (details::is_string_node(branch)) 
 31991 |                return str_str; 
 31992 |             else if (details::is_const_string_node(branch)) 
 31993 |                return cs_str; 
 31994 |             else if (details::is_string_range_node(branch)) 
 31995 |                return strrng_str; 
 31996 |             else if (details::is_const_string_range_node(branch)) 
 31997 |                return cstrrng_str; 
 31998 |             else if (details::is_t0ot1ot2_node(branch)) 
 31999 |                return "(" + dynamic_cast<details::T0oT1oT2_base_node<T>*>(branch)->type_id() + ")" 
 32000 |             else if (details::is_t0ot1ot2ot3_node(branch)) 
 32001 |                return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node<T>*>(branch)->type_id() + ")" 
 32002 |             else 
 32003 |                return "ERROR" 
 32004 |          } 
 32005 |  
 32006 |          inline std::string branch_to_id(expression_node_ptr (&branch)[2]) const 
 32007 |          { 
 32008 |             return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]); 
 32009 |          } 
 32010 |  
 32011 |          inline bool cov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32012 |          { 
 32013 |             if (!operation_optimisable(operation)) 
 32014 |                return false; 
 32015 |             else 
 32016 |                return details::is_constant_node(branch[0]) && 
 32017 |                       details::is_variable_node(branch[1]) ; 
 32018 |          } 
 32019 |  
 32020 |          inline bool voc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32021 |          { 
 32022 |             if (!operation_optimisable(operation)) 
 32023 |                return false; 
 32024 |             else 
 32025 |                return details::is_variable_node(branch[0]) && 
 32026 |                       details::is_constant_node(branch[1]) ; 
 32027 |          } 
 32028 |  
 32029 |          inline bool vov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32030 |          { 
 32031 |             if (!operation_optimisable(operation)) 
 32032 |                return false; 
 32033 |             else 
 32034 |                return details::is_variable_node(branch[0]) && 
 32035 |                       details::is_variable_node(branch[1]) ; 
 32036 |          } 
 32037 |  
 32038 |          inline bool cob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32039 |          { 
 32040 |             if (!operation_optimisable(operation)) 
 32041 |                return false; 
 32042 |             else 
 32043 |                return details::is_constant_node(branch[0]) && 
 32044 |                      !details::is_constant_node(branch[1]) ; 
 32045 |          } 
 32046 |  
 32047 |          inline bool boc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32048 |          { 
 32049 |             if (!operation_optimisable(operation)) 
 32050 |                return false; 
 32051 |             else 
 32052 |                return !details::is_constant_node(branch[0]) && 
 32053 |                        details::is_constant_node(branch[1]) ; 
 32054 |          } 
 32055 |  
 32056 |          inline bool cocob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32057 |          { 
 32058 |             if ( 
 32059 |                  (details::e_add == operation) || 
 32060 |                  (details::e_sub == operation) || 
 32061 |                  (details::e_mul == operation) || 
 32062 |                  (details::e_div == operation) 
 32063 |                ) 
 32064 |             { 
 32065 |                return (details::is_constant_node(branch[0]) && details::is_cob_node(branch[1])) || 
 32066 |                       (details::is_constant_node(branch[1]) && details::is_cob_node(branch[0])) ; 
 32067 |             } 
 32068 |             else 
 32069 |                return false; 
 32070 |          } 
 32071 |  
 32072 |          inline bool coboc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32073 |          { 
 32074 |             if ( 
 32075 |                  (details::e_add == operation) || 
 32076 |                  (details::e_sub == operation) || 
 32077 |                  (details::e_mul == operation) || 
 32078 |                  (details::e_div == operation) 
 32079 |                ) 
 32080 |             { 
 32081 |                return (details::is_constant_node(branch[0]) && details::is_boc_node(branch[1])) || 
 32082 |                       (details::is_constant_node(branch[1]) && details::is_boc_node(branch[0])) ; 
 32083 |             } 
 32084 |             else 
 32085 |                return false; 
 32086 |          } 
 32087 |  
 32088 |          inline bool uvouv_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32089 |          { 
 32090 |             if (!operation_optimisable(operation)) 
 32091 |                return false; 
 32092 |             else 
 32093 |                return details::is_uv_node(branch[0]) && 
 32094 |                       details::is_uv_node(branch[1]) ; 
 32095 |          } 
 32096 |  
 32097 |          inline bool vob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32098 |          { 
 32099 |             if (!operation_optimisable(operation)) 
 32100 |                return false; 
 32101 |             else 
 32102 |                return details::is_variable_node(branch[0]) && 
 32103 |                      !details::is_variable_node(branch[1]) ; 
 32104 |          } 
 32105 |  
 32106 |          inline bool bov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32107 |          { 
 32108 |             if (!operation_optimisable(operation)) 
 32109 |                return false; 
 32110 |             else 
 32111 |                return !details::is_variable_node(branch[0]) && 
 32112 |                        details::is_variable_node(branch[1]) ; 
 32113 |          } 
 32114 |  
 32115 |          inline bool binext_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32116 |          { 
 32117 |             if (!operation_optimisable(operation)) 
 32118 |                return false; 
 32119 |             else 
 32120 |                return !details::is_constant_node(branch[0]) || 
 32121 |                       !details::is_constant_node(branch[1]) ; 
 32122 |          } 
 32123 |  
 32124 |          inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32125 |          { 
 32126 |             if (is_assignment_operation(operation)) 
 32127 |             { 
 32128 |                const bool b1_is_genstring = details::is_generally_string_node(branch[1]); 
 32129 |  
 32130 |                if (details::is_string_node(branch[0])) 
 32131 |                   return !b1_is_genstring; 
 32132 |                else if (details::is_literal_node(branch[0])) 
 32133 |                   return true; 
 32134 |                else 
 32135 |                   return ( 
 32136 |                            !details::is_variable_node              (branch[0]) && 
 32137 |                            !details::is_vector_elem_node           (branch[0]) && 
 32138 |                            !details::is_vector_celem_node          (branch[0]) && 
 32139 |                            !details::is_vector_elem_rtc_node       (branch[0]) && 
 32140 |                            !details::is_vector_celem_rtc_node      (branch[0]) && 
 32141 |                            !details::is_rebasevector_elem_node     (branch[0]) && 
 32142 |                            !details::is_rebasevector_celem_node    (branch[0]) && 
 32143 |                            !details::is_rebasevector_elem_rtc_node (branch[0]) && 
 32144 |                            !details::is_rebasevector_celem_rtc_node(branch[0]) && 
 32145 |                            !details::is_vector_node                (branch[0]) 
 32146 |                          ) 
 32147 |                          || b1_is_genstring; 
 32148 |             } 
 32149 |             else 
 32150 |                return false; 
 32151 |          } 
 32152 |  
 32153 |          inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2]) const 
 32154 |          { 
 32155 |             if ( 
 32156 |                  !details::is_constant_node(branch[1]) || 
 32157 |                   details::is_constant_node(branch[0]) || 
 32158 |                   details::is_variable_node(branch[0]) || 
 32159 |                   details::is_vector_node  (branch[0]) || 
 32160 |                   details::is_generally_string_node(branch[0]) 
 32161 |                ) 
 32162 |                return false; 
 32163 |  
 32164 |             const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 32165 |  
 32166 |             return cardinal_pow_optimisable(operation, c); 
 32167 |          } 
 32168 |  
 32169 |          inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2]) const 
 32170 |          { 
 32171 |             return ( 
 32172 |                      details::is_break_node   (branch[0]) || 
 32173 |                      details::is_break_node   (branch[1]) || 
 32174 |                      details::is_continue_node(branch[0]) || 
 32175 |                      details::is_continue_node(branch[1]) 
 32176 |                    ); 
 32177 |          } 
 32178 |  
 32179 |          inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32180 |          { 
 32181 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32182 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32183 |  
 32184 |             bool result = false; 
 32185 |  
 32186 |             if (b0_string != b1_string) 
 32187 |                result = true; 
 32188 |             else if (!valid_string_operation(operation) && b0_string && b1_string) 
 32189 |                result = true; 
 32190 |  
 32191 |             if (result) 
 32192 |             { 
 32193 |                parser_->set_synthesis_error("Invalid string operation"); 
 32194 |             } 
 32195 |  
 32196 |             return result; 
 32197 |          } 
 32198 |  
 32199 |          inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const 
 32200 |          { 
 32201 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32202 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32203 |             const bool b2_string = is_generally_string_node(branch[2]); 
 32204 |  
 32205 |             bool result = false; 
 32206 |  
 32207 |             if ((b0_string != b1_string) || (b1_string != b2_string)) 
 32208 |                result = true; 
 32209 |             else if ((details::e_inrange != operation) && b0_string && b1_string && b2_string) 
 32210 |                result = true; 
 32211 |  
 32212 |             if (result) 
 32213 |             { 
 32214 |                parser_->set_synthesis_error("Invalid string operation"); 
 32215 |             } 
 32216 |  
 32217 |             return result; 
 32218 |          } 
 32219 |  
 32220 |          inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32221 |          { 
 32222 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32223 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32224 |  
 32225 |             return (b0_string && b1_string && valid_string_operation(operation)); 
 32226 |          } 
 32227 |  
 32228 |          inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const 
 32229 |          { 
 32230 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32231 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32232 |             const bool b2_string = is_generally_string_node(branch[2]); 
 32233 |  
 32234 |             return (b0_string && b1_string && b2_string && (details::e_inrange == operation)); 
 32235 |          } 
 32236 |  
 32237 |          #ifndef exprtk_disable_sc_andor 
 32238 |          inline bool is_shortcircuit_expression(const details::operator_type& operation) const 
 32239 |          { 
 32240 |             return ( 
 32241 |                      (details::e_scand == operation) || 
 32242 |                      (details::e_scor  == operation) 
 32243 |                    ); 
 32244 |          } 
 32245 |          #else 
 32246 |          inline bool is_shortcircuit_expression(const details::operator_type&) const 
 32247 |          { 
 32248 |             return false; 
 32249 |          } 
 32250 |          #endif 
 32251 |  
 32252 |          inline bool is_null_present(expression_node_ptr (&branch)[2]) const 
 32253 |          { 
 32254 |             return ( 
 32255 |                      details::is_null_node(branch[0]) || 
 32256 |                      details::is_null_node(branch[1]) 
 32257 |                    ); 
 32258 |          } 
 32259 |  
 32260 |          inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32261 |          { 
 32262 |             if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1])) 
 32263 |                return false; 
 32264 |             else 
 32265 |                return ( 
 32266 |                         (details::e_lt    == operation) || 
 32267 |                         (details::e_lte   == operation) || 
 32268 |                         (details::e_gt    == operation) || 
 32269 |                         (details::e_gte   == operation) || 
 32270 |                         (details::e_eq    == operation) || 
 32271 |                         (details::e_ne    == operation) || 
 32272 |                         (details::e_equal == operation) || 
 32273 |                         (details::e_and   == operation) || 
 32274 |                         (details::e_nand  == operation) || 
 32275 |                         (details::e_or    == operation) || 
 32276 |                         (details::e_nor   == operation) || 
 32277 |                         (details::e_xor   == operation) || 
 32278 |                         (details::e_xnor  == operation) 
 32279 |                       ); 
 32280 |          } 
 32281 |  
 32282 |          inline bool is_vector_arithmetic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32283 |          { 
 32284 |             if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1])) 
 32285 |                return false; 
 32286 |             else 
 32287 |                return ( 
 32288 |                         (details::e_add == operation) || 
 32289 |                         (details::e_sub == operation) || 
 32290 |                         (details::e_mul == operation) || 
 32291 |                         (details::e_div == operation) || 
 32292 |                         (details::e_pow == operation) 
 32293 |                       ); 
 32294 |          } 
 32295 |  
 32296 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 32297 |          { 
 32298 |             if ((0 == branch[0]) || (0 == branch[1])) 
 32299 |             { 
 32300 |                parser_->set_error(parser_error::make_error( 
 32301 |                   parser_error::e_syntax, 
 32302 |                   parser_->current_state().token, 
 32303 |                   "ERR248 - Invalid branches received for operator '" + details::to_str(operation) + "'", 
 32304 |                   exprtk_error_location)); 
 32305 |  
 32306 |                return error_node(); 
 32307 |             } 
 32308 |             else if (is_invalid_string_op(operation,branch)) 
 32309 |             { 
 32310 |                parser_->set_error(parser_error::make_error( 
 32311 |                   parser_error::e_syntax, 
 32312 |                   parser_->current_state().token, 
 32313 |                   "ERR249 - Invalid branch pair for string operator '" + details::to_str(operation) + "'", 
 32314 |                   exprtk_error_location)); 
 32315 |  
 32316 |                return error_node(); 
 32317 |             } 
 32318 |             else if (is_invalid_assignment_op(operation,branch)) 
 32319 |             { 
 32320 |                parser_->set_error(parser_error::make_error( 
 32321 |                   parser_error::e_syntax, 
 32322 |                   parser_->current_state().token, 
 32323 |                   "ERR250 - Invalid branch pair for assignment operator '" + details::to_str(operation) + "'", 
 32324 |                   exprtk_error_location)); 
 32325 |  
 32326 |                return error_node(); 
 32327 |             } 
 32328 |             else if (is_invalid_break_continue_op(branch)) 
 32329 |             { 
 32330 |                parser_->set_error(parser_error::make_error( 
 32331 |                   parser_error::e_syntax, 
 32332 |                   parser_->current_state().token, 
 32333 |                   "ERR251 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'", 
 32334 |                   exprtk_error_location)); 
 32335 |  
 32336 |                return error_node(); 
 32337 |             } 
 32338 |             else if (details::e_assign == operation) 
 32339 |             { 
 32340 |                return synthesize_assignment_expression(operation, branch); 
 32341 |             } 
 32342 |             else if (details::e_swap == operation) 
 32343 |             { 
 32344 |                return synthesize_swap_expression(branch); 
 32345 |             } 
 32346 |             else if (is_assignment_operation(operation)) 
 32347 |             { 
 32348 |                return synthesize_assignment_operation_expression(operation, branch); 
 32349 |             } 
 32350 |             else if (is_vector_eqineq_logic_operation(operation, branch)) 
 32351 |             { 
 32352 |                return synthesize_veceqineqlogic_operation_expression(operation, branch); 
 32353 |             } 
 32354 |             else if (is_vector_arithmetic_operation(operation, branch)) 
 32355 |             { 
 32356 |                return synthesize_vecarithmetic_operation_expression(operation, branch); 
 32357 |             } 
 32358 |             else if (is_shortcircuit_expression(operation)) 
 32359 |             { 
 32360 |                return synthesize_shortcircuit_expression(operation, branch); 
 32361 |             } 
 32362 |             else if (is_string_operation(operation, branch)) 
 32363 |             { 
 32364 |                return synthesize_string_expression(operation, branch); 
 32365 |             } 
 32366 |             else if (is_null_present(branch)) 
 32367 |             { 
 32368 |                return synthesize_null_expression(operation, branch); 
 32369 |             } 
 32370 |             #ifndef exprtk_disable_cardinal_pow_optimisation 
 32371 |             else if (is_constpow_operation(operation, branch)) 
 32372 |             { 
 32373 |                return cardinal_pow_optimisation(branch); 
 32374 |             } 
 32375 |             #endif 
 32376 |  
 32377 |             expression_node_ptr result = error_node(); 
 32378 |  
 32379 |             #ifndef exprtk_disable_enhanced_features 
 32380 |             if (synthesize_expression(operation, branch, result)) 
 32381 |             { 
 32382 |                return result; 
 32383 |             } 
 32384 |             else 
 32385 |             #endif 
 32386 |  
 32387 |             { 
 32388 |                /* 
 32389 |                   Possible reductions: 
 32390 |                   1. c o cob -> cob 
 32391 |                   2. cob o c -> cob 
 32392 |                   3. c o boc -> boc 
 32393 |                   4. boc o c -> boc 
 32394 |                */ 
 32395 |                result = error_node(); 
 32396 |  
 32397 |                if (cocob_optimisable(operation, branch)) 
 32398 |                { 
 32399 |                   result = synthesize_cocob_expression::process((*this), operation, branch); 
 32400 |                } 
 32401 |                else if (coboc_optimisable(operation, branch) && (0 == result)) 
 32402 |                { 
 32403 |                   result = synthesize_coboc_expression::process((*this), operation, branch); 
 32404 |                } 
 32405 |  
 32406 |                if (result) 
 32407 |                   return result; 
 32408 |             } 
 32409 |  
 32410 |             if (uvouv_optimisable(operation, branch)) 
 32411 |             { 
 32412 |                return synthesize_uvouv_expression(operation, branch); 
 32413 |             } 
 32414 |             else if (vob_optimisable(operation, branch)) 
 32415 |             { 
 32416 |                return synthesize_vob_expression::process((*this), operation, branch); 
 32417 |             } 
 32418 |             else if (bov_optimisable(operation, branch)) 
 32419 |             { 
 32420 |                return synthesize_bov_expression::process((*this), operation, branch); 
 32421 |             } 
 32422 |             else if (cob_optimisable(operation, branch)) 
 32423 |             { 
 32424 |                return synthesize_cob_expression::process((*this), operation, branch); 
 32425 |             } 
 32426 |             else if (boc_optimisable(operation, branch)) 
 32427 |             { 
 32428 |                return synthesize_boc_expression::process((*this), operation, branch); 
 32429 |             } 
 32430 |             #ifndef exprtk_disable_enhanced_features 
 32431 |             else if (cov_optimisable(operation, branch)) 
 32432 |             { 
 32433 |                return synthesize_cov_expression::process((*this), operation, branch); 
 32434 |             } 
 32435 |             #endif 
 32436 |             else if (binext_optimisable(operation, branch)) 
 32437 |             { 
 32438 |                return synthesize_binary_ext_expression::process((*this), operation, branch); 
 32439 |             } 
 32440 |             else 
 32441 |                return synthesize_expression<binary_node_t,2>(operation, branch); 
 32442 |          } 
 32443 |  
 32444 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[3]) 
 32445 |          { 
 32446 |             if ( 
 32447 |                  (0 == branch[0]) || 
 32448 |                  (0 == branch[1]) || 
 32449 |                  (0 == branch[2]) 
 32450 |                ) 
 32451 |             { 
 32452 |                details::free_all_nodes(*node_allocator_,branch); 
 32453 |  
 32454 |                parser_->set_error(parser_error::make_error( 
 32455 |                   parser_error::e_syntax, 
 32456 |                   parser_->current_state().token, 
 32457 |                   "ERR252 - Invalid branches operator '" + details::to_str(operation) + "'", 
 32458 |                   exprtk_error_location)); 
 32459 |  
 32460 |                return error_node(); 
 32461 |             } 
 32462 |             else if (is_invalid_string_op(operation, branch)) 
 32463 |             { 
 32464 |                parser_->set_error(parser_error::make_error( 
 32465 |                   parser_error::e_syntax, 
 32466 |                   parser_->current_state().token, 
 32467 |                   "ERR253 - Invalid branches for string operator '" + details::to_str(operation) + "'", 
 32468 |                   exprtk_error_location)); 
 32469 |  
 32470 |                return error_node(); 
 32471 |             } 
 32472 |             else if (is_string_operation(operation, branch)) 
 32473 |             { 
 32474 |                return synthesize_string_expression(operation, branch); 
 32475 |             } 
 32476 |             else 
 32477 |                return synthesize_expression<trinary_node_t,3>(operation, branch); 
 32478 |          } 
 32479 |  
 32480 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 32481 |          { 
 32482 |             return synthesize_expression<quaternary_node_t,4>(operation,branch); 
 32483 |          } 
 32484 |  
 32485 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr b0) 
 32486 |          { 
 32487 |             expression_node_ptr branch[1] = { b0 }; 
 32488 |             return (*this)(operation,branch); 
 32489 |          } 
 32490 |  
 32491 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr& b0, expression_node_ptr& b1) 
 32492 |          { 
 32493 |             expression_node_ptr result = error_node(); 
 32494 |  
 32495 |             if ((0 != b0) && (0 != b1)) 
 32496 |             { 
 32497 |                expression_node_ptr branch[2] = { b0, b1 }; 
 32498 |                result = expression_generator<Type>::operator()(operation, branch); 
 32499 |                b0 = branch[0]; 
 32500 |                b1 = branch[1]; 
 32501 |             } 
 32502 |  
 32503 |             return result; 
 32504 |          } 
 32505 |  
 32506 |          inline expression_node_ptr conditional(expression_node_ptr condition, 
 32507 |                                                 expression_node_ptr consequent, 
 32508 |                                                 expression_node_ptr alternative) const 
 32509 |          { 
 32510 |             if ((0 == condition) || (0 == consequent)) 
 32511 |             { 
 32512 |                details::free_node(*node_allocator_, condition  ); 
 32513 |                details::free_node(*node_allocator_, consequent ); 
 32514 |                details::free_node(*node_allocator_, alternative); 
 32515 |  
 32516 |                const std::string invalid_branches = 
 32517 |                                  ((0 == condition ) ? std::string("condition ") : "") + 
 32518 |                                  ((0 == consequent) ? std::string("consequent") : "") ; 
 32519 |  
 32520 |                parser_->set_error(parser_error::make_error( 
 32521 |                   parser_error::e_parser, 
 32522 |                   parser_->current_state().token, 
 32523 |                   "ERR254 - Invalid " + invalid_branches + " for conditional statement", 
 32524 |                   exprtk_error_location)); 
 32525 |  
 32526 |                return error_node(); 
 32527 |             } 
 32528 |             // Can the condition be immediately evaluated? if so optimise. 
 32529 |             else if (details::is_constant_node(condition)) 
 32530 |             { 
 32531 |                // True branch 
 32532 |                if (details::is_true(condition)) 
 32533 |                { 
 32534 |                   details::free_node(*node_allocator_, condition  ); 
 32535 |                   details::free_node(*node_allocator_, alternative); 
 32536 |  
 32537 |                   return consequent; 
 32538 |                } 
 32539 |                // False branch 
 32540 |                else 
 32541 |                { 
 32542 |                   details::free_node(*node_allocator_, condition ); 
 32543 |                   details::free_node(*node_allocator_, consequent); 
 32544 |  
 32545 |                   if (alternative) 
 32546 |                      return alternative; 
 32547 |                   else 
 32548 |                      return node_allocator_->allocate<details::null_node<T> >(); 
 32549 |                } 
 32550 |             } 
 32551 |  
 32552 |             expression_node_ptr result = error_node(); 
 32553 |             std::string node_name      = "Unknown!" 
 32554 |  
 32555 |             if ((0 != consequent) && (0 != alternative)) 
 32556 |             { 
 32557 |                result = node_allocator_->allocate<conditional_node_t>(condition, consequent, alternative); 
 32558 |                node_name = "conditional_node_t" 
 32559 |             } 
 32560 |             else 
 32561 |             { 
 32562 |                result = node_allocator_->allocate<cons_conditional_node_t>(condition, consequent); 
 32563 |                node_name = "cons_conditional_node_t" 
 32564 |             } 
 32565 |  
 32566 |             if (result && result->valid()) 
 32567 |             { 
 32568 |                return result; 
 32569 |             } 
 32570 |  
 32571 |             parser_->set_error(parser_error::make_error( 
 32572 |                parser_error::e_parser, 
 32573 |                token_t(), 
 32574 |                "ERR255 - Failed to synthesize node: " + node_name, 
 32575 |                exprtk_error_location)); 
 32576 |  
 32577 |             details::free_node(*node_allocator_, result); 
 32578 |             return error_node(); 
 32579 |          } 
 32580 |  
 32581 |          #ifndef exprtk_disable_string_capabilities 
 32582 |          inline expression_node_ptr conditional_string(expression_node_ptr condition, 
 32583 |                                                        expression_node_ptr consequent, 
 32584 |                                                        expression_node_ptr alternative) const 
 32585 |          { 
 32586 |             if ((0 == condition) || (0 == consequent)) 
 32587 |             { 
 32588 |                details::free_node(*node_allocator_, condition  ); 
 32589 |                details::free_node(*node_allocator_, consequent ); 
 32590 |                details::free_node(*node_allocator_, alternative); 
 32591 |  
 32592 |                const std::string invalid_branches = 
 32593 |                                  ((0 == condition ) ? std::string("condition ") : "") + 
 32594 |                                  ((0 == consequent) ? std::string("consequent") : "") ; 
 32595 |  
 32596 |                parser_->set_error(parser_error::make_error( 
 32597 |                   parser_error::e_parser, 
 32598 |                   parser_->current_state().token, 
 32599 |                   "ERR256 - Invalid " + invalid_branches + " for string conditional statement", 
 32600 |                   exprtk_error_location)); 
 32601 |  
 32602 |                return error_node(); 
 32603 |             } 
 32604 |             // Can the condition be immediately evaluated? if so optimise. 
 32605 |             else if (details::is_constant_node(condition)) 
 32606 |             { 
 32607 |                // True branch 
 32608 |                if (details::is_true(condition)) 
 32609 |                { 
 32610 |                   details::free_node(*node_allocator_, condition  ); 
 32611 |                   details::free_node(*node_allocator_, alternative); 
 32612 |  
 32613 |                   return consequent; 
 32614 |                } 
 32615 |                // False branch 
 32616 |                else 
 32617 |                { 
 32618 |                   details::free_node(*node_allocator_, condition ); 
 32619 |                   details::free_node(*node_allocator_, consequent); 
 32620 |  
 32621 |                   if (alternative) 
 32622 |                      return alternative; 
 32623 |                   else 
 32624 |                      return node_allocator_-> 
 32625 |                               allocate_c<details::string_literal_node<Type> >(""); 
 32626 |                } 
 32627 |             } 
 32628 |             else if ((0 != consequent) && (0 != alternative)) 
 32629 |             { 
 32630 |                expression_node_ptr result = 
 32631 |                   node_allocator_->allocate<conditional_string_node_t>(condition, consequent, alternative); 
 32632 |  
 32633 |                if (result && result->valid()) 
 32634 |                { 
 32635 |                   return result; 
 32636 |                } 
 32637 |  
 32638 |                parser_->set_error(parser_error::make_error( 
 32639 |                   parser_error::e_parser, 
 32640 |                   token_t(), 
 32641 |                   "ERR257 - Failed to synthesize node: conditional_string_node_t", 
 32642 |                   exprtk_error_location)); 
 32643 |  
 32644 |                details::free_node(*node_allocator_, result); 
 32645 |             } 
 32646 |  
 32647 |             return error_node(); 
 32648 |          } 
 32649 |          #else 
 32650 |          inline expression_node_ptr conditional_string(expression_node_ptr, 
 32651 |                                                        expression_node_ptr, 
 32652 |                                                        expression_node_ptr) const 
 32653 |          { 
 32654 |             return error_node(); 
 32655 |          } 
 32656 |          #endif 
 32657 |  
 32658 |          inline expression_node_ptr conditional_vector(expression_node_ptr condition, 
 32659 |                                                        expression_node_ptr consequent, 
 32660 |                                                        expression_node_ptr alternative) const 
 32661 |          { 
 32662 |             if ((0 == condition) || (0 == consequent)) 
 32663 |             { 
 32664 |                details::free_node(*node_allocator_, condition  ); 
 32665 |                details::free_node(*node_allocator_, consequent ); 
 32666 |                details::free_node(*node_allocator_, alternative); 
 32667 |  
 32668 |                const std::string invalid_branches = 
 32669 |                                  ((0 == condition ) ? std::string("condition ") : "") + 
 32670 |                                  ((0 == consequent) ? std::string("consequent") : "") ; 
 32671 |  
 32672 |                parser_->set_error(parser_error::make_error( 
 32673 |                   parser_error::e_parser, 
 32674 |                   parser_->current_state().token, 
 32675 |                   "ERR258 - Invalid " + invalid_branches + " for vector conditional statement", 
 32676 |                   exprtk_error_location)); 
 32677 |  
 32678 |                return error_node(); 
 32679 |             } 
 32680 |             // Can the condition be immediately evaluated? if so optimise. 
 32681 |             else if (details::is_constant_node(condition)) 
 32682 |             { 
 32683 |                // True branch 
 32684 |                if (details::is_true(condition)) 
 32685 |                { 
 32686 |                   details::free_node(*node_allocator_, condition  ); 
 32687 |                   details::free_node(*node_allocator_, alternative); 
 32688 |  
 32689 |                   return consequent; 
 32690 |                } 
 32691 |                // False branch 
 32692 |                else 
 32693 |                { 
 32694 |                   details::free_node(*node_allocator_, condition ); 
 32695 |                   details::free_node(*node_allocator_, consequent); 
 32696 |  
 32697 |                   if (alternative) 
 32698 |                      return alternative; 
 32699 |                   else 
 32700 |                      return node_allocator_->allocate<details::null_node<T> >(); 
 32701 |  
 32702 |                } 
 32703 |             } 
 32704 |             else if ((0 != consequent) && (0 != alternative)) 
 32705 |             { 
 32706 |                return node_allocator_-> 
 32707 |                         allocate<conditional_vector_node_t>(condition, consequent, alternative); 
 32708 |             } 
 32709 |             else 
 32710 |                return error_node(); 
 32711 |          } 
 32712 |  
 32713 |          inline loop_runtime_check_ptr get_loop_runtime_check(const loop_runtime_check::loop_types loop_type) const 
 32714 |          { 
 32715 |             if ( 
 32716 |                  parser_->loop_runtime_check_ && 
 32717 |                  (loop_type == (parser_->loop_runtime_check_->loop_set & loop_type)) 
 32718 |                ) 
 32719 |             { 
 32720 |                return parser_->loop_runtime_check_; 
 32721 |             } 
 32722 |  
 32723 |             return loop_runtime_check_ptr(0); 
 32724 |          } 
 32725 |  
 32726 |          inline vector_access_runtime_check_ptr get_vector_access_runtime_check() const 
 32727 |          { 
 32728 |             return parser_->vector_access_runtime_check_; 
 32729 |          } 
 32730 |  
 32731 |          inline expression_node_ptr while_loop(expression_node_ptr& condition, 
 32732 |                                                expression_node_ptr& branch, 
 32733 |                                                const bool break_continue_present = false) const 
 32734 |          { 
 32735 |             if ( 
 32736 |                  !break_continue_present              && 
 32737 |                  !parser_->state_.return_stmt_present && 
 32738 |                  details::is_constant_node(condition) 
 32739 |                ) 
 32740 |             { 
 32741 |                expression_node_ptr result = error_node(); 
 32742 |                if (details::is_true(condition)) 
 32743 |                { 
 32744 |                   // Infinite loops are not allowed. 
 32745 |  
 32746 |                   parser_->set_error(parser_error::make_error( 
 32747 |                      parser_error::e_parser, 
 32748 |                      parser_->current_state().token, 
 32749 |                      "ERR259 - Infinite loop condition without 'break' or 'return' not allowed in while-loops", 
 32750 |                      exprtk_error_location)); 
 32751 |  
 32752 |                   result = error_node(); 
 32753 |                } 
 32754 |                else 
 32755 |                   result = node_allocator_->allocate<details::null_node<Type> >(); 
 32756 |  
 32757 |                details::free_node(*node_allocator_, condition); 
 32758 |                details::free_node(*node_allocator_, branch   ); 
 32759 |  
 32760 |                return result; 
 32761 |             } 
 32762 |             else if (details::is_null_node(condition)) 
 32763 |             { 
 32764 |                details::free_node(*node_allocator_,condition); 
 32765 |  
 32766 |                return branch; 
 32767 |             } 
 32768 |  
 32769 |             loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_while_loop); 
 32770 |  
 32771 |             if (!break_continue_present) 
 32772 |             { 
 32773 |                if (rtc) 
 32774 |                   return node_allocator_->allocate<while_loop_rtc_node_t> 
 32775 |                            (condition, branch,  rtc); 
 32776 |                else 
 32777 |                   return node_allocator_->allocate<while_loop_node_t> 
 32778 |                            (condition, branch); 
 32779 |             } 
 32780 |             #ifndef exprtk_disable_break_continue 
 32781 |             else 
 32782 |             { 
 32783 |                if (rtc) 
 32784 |                   return node_allocator_->allocate<while_loop_bc_rtc_node_t> 
 32785 |                            (condition, branch, rtc); 
 32786 |                else 
 32787 |                   return node_allocator_->allocate<while_loop_bc_node_t> 
 32788 |                            (condition, branch); 
 32789 |             } 
 32790 |             #else 
 32791 |                return error_node(); 
 32792 |             #endif 
 32793 |          } 
 32794 |  
 32795 |          inline expression_node_ptr repeat_until_loop(expression_node_ptr& condition, 
 32796 |                                                       expression_node_ptr& branch, 
 32797 |                                                       const bool break_continue_present = false) const 
 32798 |          { 
 32799 |             if (!break_continue_present && details::is_constant_node(condition)) 
 32800 |             { 
 32801 |                if ( 
 32802 |                     details::is_true(condition) && 
 32803 |                     details::is_constant_node(branch) 
 32804 |                   ) 
 32805 |                { 
 32806 |                   free_node(*node_allocator_,condition); 
 32807 |  
 32808 |                   return branch; 
 32809 |                } 
 32810 |  
 32811 |                details::free_node(*node_allocator_, condition); 
 32812 |                details::free_node(*node_allocator_, branch   ); 
 32813 |  
 32814 |                return error_node(); 
 32815 |             } 
 32816 |             else if (details::is_null_node(condition)) 
 32817 |             { 
 32818 |                details::free_node(*node_allocator_,condition); 
 32819 |  
 32820 |                return branch; 
 32821 |             } 
 32822 |  
 32823 |             loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_repeat_until_loop); 
 32824 |  
 32825 |             if (!break_continue_present) 
 32826 |             { 
 32827 |                if (rtc) 
 32828 |                   return node_allocator_->allocate<repeat_until_loop_rtc_node_t> 
 32829 |                            (condition, branch,  rtc); 
 32830 |                else 
 32831 |                   return node_allocator_->allocate<repeat_until_loop_node_t> 
 32832 |                            (condition, branch); 
 32833 |             } 
 32834 |             #ifndef exprtk_disable_break_continue 
 32835 |             else 
 32836 |             { 
 32837 |                if (rtc) 
 32838 |                   return node_allocator_->allocate<repeat_until_loop_bc_rtc_node_t> 
 32839 |                            (condition, branch, rtc); 
 32840 |                else 
 32841 |                   return node_allocator_->allocate<repeat_until_loop_bc_node_t> 
 32842 |                            (condition, branch); 
 32843 |             } 
 32844 |             #else 
 32845 |                return error_node(); 
 32846 |             #endif 
 32847 |          } 
 32848 |  
 32849 |          inline expression_node_ptr for_loop(expression_node_ptr& initialiser, 
 32850 |                                              expression_node_ptr& condition, 
 32851 |                                              expression_node_ptr& incrementor, 
 32852 |                                              expression_node_ptr& loop_body, 
 32853 |                                              bool break_continue_present = false) const 
 32854 |          { 
 32855 |             if ( 
 32856 |                  !break_continue_present              && 
 32857 |                  !parser_->state_.return_stmt_present && 
 32858 |                  details::is_constant_node(condition) 
 32859 |                ) 
 32860 |             { 
 32861 |                expression_node_ptr result = error_node(); 
 32862 |  
 32863 |                if (details::is_true(condition)) 
 32864 |                { 
 32865 |                   // Infinite loops are not allowed. 
 32866 |  
 32867 |                   parser_->set_error(parser_error::make_error( 
 32868 |                      parser_error::e_parser, 
 32869 |                      parser_->current_state().token, 
 32870 |                      "ERR260 - Infinite loop condition without 'break' or 'return' not allowed in for-loop", 
 32871 |                      exprtk_error_location)); 
 32872 |  
 32873 |                   result = error_node(); 
 32874 |                } 
 32875 |                else 
 32876 |                   result = node_allocator_->allocate<details::null_node<Type> >(); 
 32877 |  
 32878 |                details::free_node(*node_allocator_, initialiser); 
 32879 |                details::free_node(*node_allocator_, condition  ); 
 32880 |                details::free_node(*node_allocator_, incrementor); 
 32881 |                details::free_node(*node_allocator_, loop_body  ); 
 32882 |  
 32883 |                return result; 
 32884 |             } 
 32885 |             else if (details::is_null_node(condition) || (0 == condition)) 
 32886 |             { 
 32887 |                details::free_node(*node_allocator_, initialiser); 
 32888 |                details::free_node(*node_allocator_, condition  ); 
 32889 |                details::free_node(*node_allocator_, incrementor); 
 32890 |  
 32891 |                return loop_body; 
 32892 |             } 
 32893 |  
 32894 |             loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_for_loop); 
 32895 |  
 32896 |             if (!break_continue_present) 
 32897 |             { 
 32898 |                if (rtc) 
 32899 |                   return node_allocator_->allocate<for_loop_rtc_node_t> 
 32900 |                                           ( 
 32901 |                                              initialiser, 
 32902 |                                              condition, 
 32903 |                                              incrementor, 
 32904 |                                              loop_body, 
 32905 |                                              rtc 
 32906 |                                           ); 
 32907 |                else 
 32908 |                   return node_allocator_->allocate<for_loop_node_t> 
 32909 |                                           ( 
 32910 |                                              initialiser, 
 32911 |                                              condition, 
 32912 |                                              incrementor, 
 32913 |                                              loop_body 
 32914 |                                           ); 
 32915 |             } 
 32916 |             #ifndef exprtk_disable_break_continue 
 32917 |             else 
 32918 |             { 
 32919 |                if (rtc) 
 32920 |                   return node_allocator_->allocate<for_loop_bc_rtc_node_t> 
 32921 |                                           ( 
 32922 |                                              initialiser, 
 32923 |                                              condition, 
 32924 |                                              incrementor, 
 32925 |                                              loop_body, 
 32926 |                                              rtc 
 32927 |                                           ); 
 32928 |                else 
 32929 |                   return node_allocator_->allocate<for_loop_bc_node_t> 
 32930 |                                           ( 
 32931 |                                              initialiser, 
 32932 |                                              condition, 
 32933 |                                              incrementor, 
 32934 |                                              loop_body 
 32935 |                                           ); 
 32936 |             } 
 32937 |             #else 
 32938 |                return error_node(); 
 32939 |             #endif 
 32940 |          } 
 32941 |  
 32942 |          template <typename Allocator, 
 32943 |                    template <typename, typename> class Sequence> 
 32944 |          inline expression_node_ptr const_optimise_switch(Sequence<expression_node_ptr,Allocator>& arg_list) 
 32945 |          { 
 32946 |             expression_node_ptr result = error_node(); 
 32947 |  
 32948 |             for (std::size_t i = 0; i < (arg_list.size() / 2); ++i) 
 32949 |             { 
 32950 |                expression_node_ptr condition  = arg_list[(2 * i)    ]; 
 32951 |                expression_node_ptr consequent = arg_list[(2 * i) + 1]; 
 32952 |  
 32953 |                if ((0 == result) && details::is_true(condition)) 
 32954 |                { 
 32955 |                   result = consequent; 
 32956 |                   break; 
 32957 |                } 
 32958 |             } 
 32959 |  
 32960 |             if (0 == result) 
 32961 |             { 
 32962 |                result = arg_list.back(); 
 32963 |             } 
 32964 |  
 32965 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 32966 |             { 
 32967 |                expression_node_ptr current_expr = arg_list[i]; 
 32968 |  
 32969 |                if (current_expr && (current_expr != result)) 
 32970 |                { 
 32971 |                   free_node(*node_allocator_,current_expr); 
 32972 |                } 
 32973 |             } 
 32974 |  
 32975 |             return result; 
 32976 |          } 
 32977 |  
 32978 |          template <typename Allocator, 
 32979 |                    template <typename, typename> class Sequence> 
 32980 |          inline expression_node_ptr const_optimise_mswitch(Sequence<expression_node_ptr,Allocator>& arg_list) 
 32981 |          { 
 32982 |             expression_node_ptr result = error_node(); 
 32983 |  
 32984 |             for (std::size_t i = 0; i < (arg_list.size() / 2); ++i) 
 32985 |             { 
 32986 |                expression_node_ptr condition  = arg_list[(2 * i)    ]; 
 32987 |                expression_node_ptr consequent = arg_list[(2 * i) + 1]; 
 32988 |  
 32989 |                if (details::is_true(condition)) 
 32990 |                { 
 32991 |                   result = consequent; 
 32992 |                } 
 32993 |             } 
 32994 |  
 32995 |             if (0 == result) 
 32996 |             { 
 32997 |                const T zero = T(0); 
 32998 |                result       = node_allocator_->allocate<literal_node_t>(zero); 
 32999 |             } 
 33000 |  
 33001 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 33002 |             { 
 33003 |                expression_node_ptr& current_expr = arg_list[i]; 
 33004 |  
 33005 |                if (current_expr && (current_expr != result)) 
 33006 |                { 
 33007 |                   details::free_node(*node_allocator_,current_expr); 
 33008 |                } 
 33009 |             } 
 33010 |  
 33011 |             return result; 
 33012 |          } 
 33013 |  
 33014 |          struct switch_nodes 
 33015 |          { 
 33016 |             typedef std::vector<std::pair<expression_node_ptr,bool> > arg_list_t; 
 33017 |  
 33018 |             #define case_stmt(N)                                                         \ 
 33019 |             if (is_true(arg[(2 * N)].first)) { return arg[(2 * N) + 1].first->value(); } \ 
 33020 |  
 33021 |             struct switch_impl_1 
 33022 |             { 
 33023 |                static inline T process(const arg_list_t& arg) 
 33024 |                { 
 33025 |                   case_stmt(0) 
 33026 |  
 33027 |                   assert(arg.size() == ((2 * 1) + 1)); 
 33028 |  
 33029 |                   return arg.back().first->value(); 
 33030 |                } 
 33031 |             }; 
 33032 |  
 33033 |             struct switch_impl_2 
 33034 |             { 
 33035 |                static inline T process(const arg_list_t& arg) 
 33036 |                { 
 33037 |                   case_stmt(0) case_stmt(1) 
 33038 |  
 33039 |                   assert(arg.size() == ((2 * 2) + 1)); 
 33040 |  
 33041 |                   return arg.back().first->value(); 
 33042 |                } 
 33043 |             }; 
 33044 |  
 33045 |             struct switch_impl_3 
 33046 |             { 
 33047 |                static inline T process(const arg_list_t& arg) 
 33048 |                { 
 33049 |                   case_stmt(0) case_stmt(1) 
 33050 |                   case_stmt(2) 
 33051 |  
 33052 |                   assert(arg.size() == ((2 * 3) + 1)); 
 33053 |  
 33054 |                   return arg.back().first->value(); 
 33055 |                } 
 33056 |             }; 
 33057 |  
 33058 |             struct switch_impl_4 
 33059 |             { 
 33060 |                static inline T process(const arg_list_t& arg) 
 33061 |                { 
 33062 |                   case_stmt(0) case_stmt(1) 
 33063 |                   case_stmt(2) case_stmt(3) 
 33064 |  
 33065 |                   assert(arg.size() == ((2 * 4) + 1)); 
 33066 |  
 33067 |                   return arg.back().first->value(); 
 33068 |                } 
 33069 |             }; 
 33070 |  
 33071 |             struct switch_impl_5 
 33072 |             { 
 33073 |                static inline T process(const arg_list_t& arg) 
 33074 |                { 
 33075 |                   case_stmt(0) case_stmt(1) 
 33076 |                   case_stmt(2) case_stmt(3) 
 33077 |                   case_stmt(4) 
 33078 |  
 33079 |                   assert(arg.size() == ((2 * 5) + 1)); 
 33080 |  
 33081 |                   return arg.back().first->value(); 
 33082 |                } 
 33083 |             }; 
 33084 |  
 33085 |             struct switch_impl_6 
 33086 |             { 
 33087 |                static inline T process(const arg_list_t& arg) 
 33088 |                { 
 33089 |                   case_stmt(0) case_stmt(1) 
 33090 |                   case_stmt(2) case_stmt(3) 
 33091 |                   case_stmt(4) case_stmt(5) 
 33092 |  
 33093 |                   assert(arg.size() == ((2 * 6) + 1)); 
 33094 |  
 33095 |                   return arg.back().first->value(); 
 33096 |                } 
 33097 |             }; 
 33098 |  
 33099 |             struct switch_impl_7 
 33100 |             { 
 33101 |                static inline T process(const arg_list_t& arg) 
 33102 |                { 
 33103 |                   case_stmt(0) case_stmt(1) 
 33104 |                   case_stmt(2) case_stmt(3) 
 33105 |                   case_stmt(4) case_stmt(5) 
 33106 |                   case_stmt(6) 
 33107 |  
 33108 |                   assert(arg.size() == ((2 * 7) + 1)); 
 33109 |  
 33110 |                   return arg.back().first->value(); 
 33111 |                } 
 33112 |             }; 
 33113 |  
 33114 |             #undef case_stmt 
 33115 |          }; 
 33116 |  
 33117 |          template <typename Allocator, 
 33118 |                    template <typename, typename> class Sequence> 
 33119 |          inline expression_node_ptr switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list, const bool default_statement_present) 
 33120 |          { 
 33121 |             if (arg_list.empty()) 
 33122 |                return error_node(); 
 33123 |             else if ( 
 33124 |                       !all_nodes_valid(arg_list) || 
 33125 |                       (!default_statement_present && (arg_list.size() < 2)) 
 33126 |                     ) 
 33127 |             { 
 33128 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33129 |  
 33130 |                return error_node(); 
 33131 |             } 
 33132 |             else if (is_constant_foldable(arg_list)) 
 33133 |                return const_optimise_switch(arg_list); 
 33134 |  
 33135 |             switch ((arg_list.size() - 1) / 2) 
 33136 |             { 
 33137 |                #define case_stmt(N)                                                       \ 
 33138 |                case N :                                                                   \ 
 33139 |                   return node_allocator_->                                                \ 
 33140 |                             allocate<details::switch_n_node                               \ 
 33141 |                               <Type,typename switch_nodes::switch_impl_##N > >(arg_list); \ 
 33142 |  
 33143 |                case_stmt(1) 
 33144 |                case_stmt(2) 
 33145 |                case_stmt(3) 
 33146 |                case_stmt(4) 
 33147 |                case_stmt(5) 
 33148 |                case_stmt(6) 
 33149 |                case_stmt(7) 
 33150 |                #undef case_stmt 
 33151 |  
 33152 |                default : return node_allocator_->allocate<details::switch_node<Type> >(arg_list); 
 33153 |             } 
 33154 |          } 
 33155 |  
 33156 |          template <typename Allocator, 
 33157 |                    template <typename, typename> class Sequence> 
 33158 |          inline expression_node_ptr multi_switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list) 
 33159 |          { 
 33160 |             if (!all_nodes_valid(arg_list)) 
 33161 |             { 
 33162 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33163 |  
 33164 |                return error_node(); 
 33165 |             } 
 33166 |             else if (is_constant_foldable(arg_list)) 
 33167 |                return const_optimise_mswitch(arg_list); 
 33168 |             else 
 33169 |                return node_allocator_->allocate<details::multi_switch_node<Type> >(arg_list); 
 33170 |          } 
 33171 |  
 33172 |          inline expression_node_ptr assert_call(expression_node_ptr& assert_condition, 
 33173 |                                                 expression_node_ptr& assert_message, 
 33174 |                                                 const assert_check::assert_context& context) 
 33175 |          { 
 33176 |             typedef details::assert_node<Type> alloc_type; 
 33177 |  
 33178 |             expression_node_ptr result = node_allocator_->allocate_rrrr<alloc_type> 
 33179 |                (assert_condition, assert_message, parser_->assert_check_, context); 
 33180 |  
 33181 |             if (result && result->valid()) 
 33182 |             { 
 33183 |                parser_->state_.activate_side_effect("assert_call()"); 
 33184 |                return result; 
 33185 |             } 
 33186 |  
 33187 |             details::free_node(*node_allocator_, result          ); 
 33188 |             details::free_node(*node_allocator_, assert_condition); 
 33189 |             details::free_node(*node_allocator_, assert_message  ); 
 33190 |  
 33191 |             return error_node(); 
 33192 |          } 
 33193 |  
 33194 |          #define unary_opr_switch_statements             \ 
 33195 |          case_stmt(details::e_abs   , details::abs_op  ) \ 
 33196 |          case_stmt(details::e_acos  , details::acos_op ) \ 
 33197 |          case_stmt(details::e_acosh , details::acosh_op) \ 
 33198 |          case_stmt(details::e_asin  , details::asin_op ) \ 
 33199 |          case_stmt(details::e_asinh , details::asinh_op) \ 
 33200 |          case_stmt(details::e_atan  , details::atan_op ) \ 
 33201 |          case_stmt(details::e_atanh , details::atanh_op) \ 
 33202 |          case_stmt(details::e_ceil  , details::ceil_op ) \ 
 33203 |          case_stmt(details::e_cos   , details::cos_op  ) \ 
 33204 |          case_stmt(details::e_cosh  , details::cosh_op ) \ 
 33205 |          case_stmt(details::e_exp   , details::exp_op  ) \ 
 33206 |          case_stmt(details::e_expm1 , details::expm1_op) \ 
 33207 |          case_stmt(details::e_floor , details::floor_op) \ 
 33208 |          case_stmt(details::e_log   , details::log_op  ) \ 
 33209 |          case_stmt(details::e_log10 , details::log10_op) \ 
 33210 |          case_stmt(details::e_log2  , details::log2_op ) \ 
 33211 |          case_stmt(details::e_log1p , details::log1p_op) \ 
 33212 |          case_stmt(details::e_neg   , details::neg_op  ) \ 
 33213 |          case_stmt(details::e_pos   , details::pos_op  ) \ 
 33214 |          case_stmt(details::e_round , details::round_op) \ 
 33215 |          case_stmt(details::e_sin   , details::sin_op  ) \ 
 33216 |          case_stmt(details::e_sinc  , details::sinc_op ) \ 
 33217 |          case_stmt(details::e_sinh  , details::sinh_op ) \ 
 33218 |          case_stmt(details::e_sqrt  , details::sqrt_op ) \ 
 33219 |          case_stmt(details::e_tan   , details::tan_op  ) \ 
 33220 |          case_stmt(details::e_tanh  , details::tanh_op ) \ 
 33221 |          case_stmt(details::e_cot   , details::cot_op  ) \ 
 33222 |          case_stmt(details::e_sec   , details::sec_op  ) \ 
 33223 |          case_stmt(details::e_csc   , details::csc_op  ) \ 
 33224 |          case_stmt(details::e_r2d   , details::r2d_op  ) \ 
 33225 |          case_stmt(details::e_d2r   , details::d2r_op  ) \ 
 33226 |          case_stmt(details::e_d2g   , details::d2g_op  ) \ 
 33227 |          case_stmt(details::e_g2d   , details::g2d_op  ) \ 
 33228 |          case_stmt(details::e_notl  , details::notl_op ) \ 
 33229 |          case_stmt(details::e_sgn   , details::sgn_op  ) \ 
 33230 |          case_stmt(details::e_erf   , details::erf_op  ) \ 
 33231 |          case_stmt(details::e_erfc  , details::erfc_op ) \ 
 33232 |          case_stmt(details::e_ncdf  , details::ncdf_op ) \ 
 33233 |          case_stmt(details::e_frac  , details::frac_op ) \ 
 33234 |          case_stmt(details::e_trunc , details::trunc_op) \ 
 33235 |  
 33236 |          inline expression_node_ptr synthesize_uv_expression(const details::operator_type& operation, 
 33237 |                                                              expression_node_ptr (&branch)[1]) 
 33238 |          { 
 33239 |             T& v = static_cast<details::variable_node<T>*>(branch[0])->ref(); 
 33240 |  
 33241 |             switch (operation) 
 33242 |             { 
 33243 |                #define case_stmt(op0, op1)                                                         \ 
 33244 |                case op0 : return node_allocator_->                                                 \ 
 33245 |                              allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \ 
 33246 |  
 33247 |                unary_opr_switch_statements 
 33248 |                #undef case_stmt 
 33249 |                default : return error_node(); 
 33250 |             } 
 33251 |          } 
 33252 |  
 33253 |          inline expression_node_ptr synthesize_uvec_expression(const details::operator_type& operation, 
 33254 |                                                                expression_node_ptr (&branch)[1]) 
 33255 |          { 
 33256 |             switch (operation) 
 33257 |             { 
 33258 |                #define case_stmt(op0, op1)                                                   \ 
 33259 |                case op0 : return node_allocator_->                                           \ 
 33260 |                              allocate<typename details::unary_vector_node<Type,op1<Type> > > \ 
 33261 |                                 (operation, branch[0]);                                      \ 
 33262 |  
 33263 |                unary_opr_switch_statements 
 33264 |                #undef case_stmt 
 33265 |                default : return error_node(); 
 33266 |             } 
 33267 |          } 
 33268 |  
 33269 |          inline expression_node_ptr synthesize_unary_expression(const details::operator_type& operation, 
 33270 |                                                                 expression_node_ptr (&branch)[1]) 
 33271 |          { 
 33272 |             switch (operation) 
 33273 |             { 
 33274 |                #define case_stmt(op0, op1)                                                               \ 
 33275 |                case op0 : return node_allocator_->                                                       \ 
 33276 |                              allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \ 
 33277 |  
 33278 |                unary_opr_switch_statements 
 33279 |                #undef case_stmt 
 33280 |                default : return error_node(); 
 33281 |             } 
 33282 |          } 
 33283 |  
 33284 |          inline expression_node_ptr const_optimise_sf3(const details::operator_type& operation, 
 33285 |                                                        expression_node_ptr (&branch)[3]) 
 33286 |          { 
 33287 |             expression_node_ptr temp_node = error_node(); 
 33288 |  
 33289 |             switch (operation) 
 33290 |             { 
 33291 |                #define case_stmt(op)                                                        \ 
 33292 |                case details::e_sf##op : temp_node = node_allocator_->                       \ 
 33293 |                              allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \ 
 33294 |                                 (operation, branch);                                        \ 
 33295 |                              break;                                                         \ 
 33296 |  
 33297 |                case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 33298 |                case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 33299 |                case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 33300 |                case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 33301 |                case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 33302 |                case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 33303 |                case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 33304 |                case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31) 
 33305 |                case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35) 
 33306 |                case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39) 
 33307 |                case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43) 
 33308 |                case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47) 
 33309 |                #undef case_stmt 
 33310 |                default : return error_node(); 
 33311 |             } 
 33312 |  
 33313 |             assert(temp_node); 
 33314 |  
 33315 |             const T v = temp_node->value(); 
 33316 |  
 33317 |             details::free_node(*node_allocator_,temp_node); 
 33318 |  
 33319 |             return node_allocator_->allocate<literal_node_t>(v); 
 33320 |          } 
 33321 |  
 33322 |          inline expression_node_ptr varnode_optimise_sf3(const details::operator_type& operation, expression_node_ptr (&branch)[3]) 
 33323 |          { 
 33324 |             typedef details::variable_node<Type>* variable_ptr; 
 33325 |  
 33326 |             const Type& v0 = static_cast<variable_ptr>(branch[0])->ref(); 
 33327 |             const Type& v1 = static_cast<variable_ptr>(branch[1])->ref(); 
 33328 |             const Type& v2 = static_cast<variable_ptr>(branch[2])->ref(); 
 33329 |  
 33330 |             switch (operation) 
 33331 |             { 
 33332 |                #define case_stmt(op)                                                                \ 
 33333 |                case details::e_sf##op : return node_allocator_->                                    \ 
 33334 |                              allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \ 
 33335 |                                 (v0, v1, v2);                                                       \ 
 33336 |  
 33337 |                case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 33338 |                case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 33339 |                case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 33340 |                case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 33341 |                case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 33342 |                case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 33343 |                case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 33344 |                case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31) 
 33345 |                case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35) 
 33346 |                case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39) 
 33347 |                case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43) 
 33348 |                case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47) 
 33349 |                #undef case_stmt 
 33350 |                default : return error_node(); 
 33351 |             } 
 33352 |          } 
 33353 |  
 33354 |          inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[3]) 
 33355 |          { 
 33356 |             if (!all_nodes_valid(branch)) 
 33357 |                return error_node(); 
 33358 |             else if (is_constant_foldable(branch)) 
 33359 |                return const_optimise_sf3(operation,branch); 
 33360 |             else if (all_nodes_variables(branch)) 
 33361 |                return varnode_optimise_sf3(operation,branch); 
 33362 |             else 
 33363 |             { 
 33364 |                switch (operation) 
 33365 |                { 
 33366 |                   #define case_stmt(op)                                                        \ 
 33367 |                   case details::e_sf##op : return node_allocator_->                            \ 
 33368 |                                 allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \ 
 33369 |                                    (operation, branch);                                        \ 
 33370 |  
 33371 |                   case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 33372 |                   case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 33373 |                   case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 33374 |                   case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 33375 |                   case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 33376 |                   case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 33377 |                   case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 33378 |                   case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31) 
 33379 |                   case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35) 
 33380 |                   case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39) 
 33381 |                   case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43) 
 33382 |                   case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47) 
 33383 |                   #undef case_stmt 
 33384 |                   default : return error_node(); 
 33385 |                } 
 33386 |             } 
 33387 |          } 
 33388 |  
 33389 |          inline expression_node_ptr const_optimise_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 33390 |          { 
 33391 |             expression_node_ptr temp_node = error_node(); 
 33392 |  
 33393 |             switch (operation) 
 33394 |             { 
 33395 |                #define case_stmt(op)                                                                    \ 
 33396 |                case details::e_sf##op : temp_node = node_allocator_->                                   \ 
 33397 |                                          allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \ 
 33398 |                                             (operation, branch);                                        \ 
 33399 |                                         break;                                                          \ 
 33400 |  
 33401 |                case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51) 
 33402 |                case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55) 
 33403 |                case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59) 
 33404 |                case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63) 
 33405 |                case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67) 
 33406 |                case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71) 
 33407 |                case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75) 
 33408 |                case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79) 
 33409 |                case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83) 
 33410 |                case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87) 
 33411 |                case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91) 
 33412 |                case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95) 
 33413 |                case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99) 
 33414 |                #undef case_stmt 
 33415 |                default : return error_node(); 
 33416 |             } 
 33417 |  
 33418 |             assert(temp_node); 
 33419 |  
 33420 |             const T v = temp_node->value(); 
 33421 |  
 33422 |             details::free_node(*node_allocator_,temp_node); 
 33423 |  
 33424 |             return node_allocator_->allocate<literal_node_t>(v); 
 33425 |          } 
 33426 |  
 33427 |          inline expression_node_ptr varnode_optimise_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 33428 |          { 
 33429 |             typedef details::variable_node<Type>* variable_ptr; 
 33430 |  
 33431 |             const Type& v0 = static_cast<variable_ptr>(branch[0])->ref(); 
 33432 |             const Type& v1 = static_cast<variable_ptr>(branch[1])->ref(); 
 33433 |             const Type& v2 = static_cast<variable_ptr>(branch[2])->ref(); 
 33434 |             const Type& v3 = static_cast<variable_ptr>(branch[3])->ref(); 
 33435 |  
 33436 |             switch (operation) 
 33437 |             { 
 33438 |                #define case_stmt(op)                                                                 \ 
 33439 |                case details::e_sf##op : return node_allocator_->                                     \ 
 33440 |                              allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \ 
 33441 |                                 (v0, v1, v2, v3);                                                    \ 
 33442 |  
 33443 |                case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51) 
 33444 |                case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55) 
 33445 |                case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59) 
 33446 |                case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63) 
 33447 |                case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67) 
 33448 |                case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71) 
 33449 |                case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75) 
 33450 |                case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79) 
 33451 |                case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83) 
 33452 |                case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87) 
 33453 |                case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91) 
 33454 |                case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95) 
 33455 |                case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99) 
 33456 |                #undef case_stmt 
 33457 |                default : return error_node(); 
 33458 |             } 
 33459 |          } 
 33460 |  
 33461 |          inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 33462 |          { 
 33463 |             if (!all_nodes_valid(branch)) 
 33464 |                return error_node(); 
 33465 |             else if (is_constant_foldable(branch)) 
 33466 |                return const_optimise_sf4(operation,branch); 
 33467 |             else if (all_nodes_variables(branch)) 
 33468 |                return varnode_optimise_sf4(operation,branch); 
 33469 |             switch (operation) 
 33470 |             { 
 33471 |                #define case_stmt(op)                                                        \ 
 33472 |                case details::e_sf##op : return node_allocator_->                            \ 
 33473 |                              allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \ 
 33474 |                                 (operation, branch);                                        \ 
 33475 |  
 33476 |                case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51) 
 33477 |                case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55) 
 33478 |                case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59) 
 33479 |                case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63) 
 33480 |                case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67) 
 33481 |                case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71) 
 33482 |                case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75) 
 33483 |                case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79) 
 33484 |                case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83) 
 33485 |                case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87) 
 33486 |                case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91) 
 33487 |                case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95) 
 33488 |                case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99) 
 33489 |                #undef case_stmt 
 33490 |                default : return error_node(); 
 33491 |             } 
 33492 |          } 
 33493 |  
 33494 |          template <typename Allocator, 
 33495 |                    template <typename, typename> class Sequence> 
 33496 |          inline expression_node_ptr const_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list) 
 33497 |          { 
 33498 |             expression_node_ptr temp_node = error_node(); 
 33499 |  
 33500 |             switch (operation) 
 33501 |             { 
 33502 |                #define case_stmt(op0, op1)                                                \ 
 33503 |                case op0 : temp_node = node_allocator_->                                   \ 
 33504 |                                          allocate<details::vararg_node<Type,op1<Type> > > \ 
 33505 |                                             (arg_list);                                   \ 
 33506 |                           break;                                                          \ 
 33507 |  
 33508 |                case_stmt(details::e_sum   , details::vararg_add_op  ) 
 33509 |                case_stmt(details::e_prod  , details::vararg_mul_op  ) 
 33510 |                case_stmt(details::e_avg   , details::vararg_avg_op  ) 
 33511 |                case_stmt(details::e_min   , details::vararg_min_op  ) 
 33512 |                case_stmt(details::e_max   , details::vararg_max_op  ) 
 33513 |                case_stmt(details::e_mand  , details::vararg_mand_op ) 
 33514 |                case_stmt(details::e_mor   , details::vararg_mor_op  ) 
 33515 |                case_stmt(details::e_multi , details::vararg_multi_op) 
 33516 |                #undef case_stmt 
 33517 |                default : return error_node(); 
 33518 |             } 
 33519 |  
 33520 |             const T v = temp_node->value(); 
 33521 |  
 33522 |             details::free_node(*node_allocator_,temp_node); 
 33523 |  
 33524 |             return node_allocator_->allocate<literal_node_t>(v); 
 33525 |          } 
 33526 |  
 33527 |          inline bool special_one_parameter_vararg(const details::operator_type& operation) const 
 33528 |          { 
 33529 |             return ( 
 33530 |                      (details::e_sum  == operation) || 
 33531 |                      (details::e_prod == operation) || 
 33532 |                      (details::e_avg  == operation) || 
 33533 |                      (details::e_min  == operation) || 
 33534 |                      (details::e_max  == operation) 
 33535 |                    ); 
 33536 |          } 
 33537 |  
 33538 |          template <typename Allocator, 
 33539 |                    template <typename, typename> class Sequence> 
 33540 |          inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, 
 33541 |                                                                 Sequence<expression_node_ptr,Allocator>& arg_list) 
 33542 |          { 
 33543 |             switch (operation) 
 33544 |             { 
 33545 |                #define case_stmt(op0, op1)                                                  \ 
 33546 |                case op0 : return node_allocator_->                                          \ 
 33547 |                              allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \ 
 33548 |  
 33549 |                case_stmt(details::e_sum   , details::vararg_add_op  ) 
 33550 |                case_stmt(details::e_prod  , details::vararg_mul_op  ) 
 33551 |                case_stmt(details::e_avg   , details::vararg_avg_op  ) 
 33552 |                case_stmt(details::e_min   , details::vararg_min_op  ) 
 33553 |                case_stmt(details::e_max   , details::vararg_max_op  ) 
 33554 |                case_stmt(details::e_mand  , details::vararg_mand_op ) 
 33555 |                case_stmt(details::e_mor   , details::vararg_mor_op  ) 
 33556 |                case_stmt(details::e_multi , details::vararg_multi_op) 
 33557 |                #undef case_stmt 
 33558 |                default : return error_node(); 
 33559 |             } 
 33560 |          } 
 33561 |  
 33562 |          template <typename Allocator, 
 33563 |                    template <typename, typename> class Sequence> 
 33564 |          inline expression_node_ptr vectorize_func(const details::operator_type& operation, 
 33565 |                                                    Sequence<expression_node_ptr,Allocator>& arg_list) 
 33566 |          { 
 33567 |             if (1 == arg_list.size()) 
 33568 |             { 
 33569 |                switch (operation) 
 33570 |                { 
 33571 |                   #define case_stmt(op0, op1)                                                     \ 
 33572 |                   case op0 : return node_allocator_->                                             \ 
 33573 |                                 allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \ 
 33574 |  
 33575 |                   case_stmt(details::e_sum  , details::vec_add_op) 
 33576 |                   case_stmt(details::e_prod , details::vec_mul_op) 
 33577 |                   case_stmt(details::e_avg  , details::vec_avg_op) 
 33578 |                   case_stmt(details::e_min  , details::vec_min_op) 
 33579 |                   case_stmt(details::e_max  , details::vec_max_op) 
 33580 |                   #undef case_stmt 
 33581 |                   default : return error_node(); 
 33582 |                } 
 33583 |             } 
 33584 |             else 
 33585 |                return error_node(); 
 33586 |          } 
 33587 |  
 33588 |          template <typename Allocator, 
 33589 |                    template <typename, typename> class Sequence> 
 33590 |          inline expression_node_ptr vararg_function(const details::operator_type& operation, 
 33591 |                                                     Sequence<expression_node_ptr,Allocator>& arg_list) 
 33592 |          { 
 33593 |             if (!all_nodes_valid(arg_list)) 
 33594 |             { 
 33595 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33596 |  
 33597 |                return error_node(); 
 33598 |             } 
 33599 |             else if (is_constant_foldable(arg_list)) 
 33600 |                return const_optimise_varargfunc(operation,arg_list); 
 33601 |             else if ((1 == arg_list.size()) && details::is_ivector_node(arg_list[0])) 
 33602 |                return vectorize_func(operation,arg_list); 
 33603 |             else if ((1 == arg_list.size()) && special_one_parameter_vararg(operation)) 
 33604 |                return arg_list[0]; 
 33605 |             else if (all_nodes_variables(arg_list)) 
 33606 |                return varnode_optimise_varargfunc(operation,arg_list); 
 33607 |  
 33608 |             #ifndef exprtk_disable_string_capabilities 
 33609 |             if (details::e_smulti == operation) 
 33610 |             { 
 33611 |                expression_node_ptr result = node_allocator_-> 
 33612 |                  allocate<details::str_vararg_node<Type,details::vararg_multi_op<Type> > >(arg_list); 
 33613 |                if (result && result->valid()) 
 33614 |                { 
 33615 |                   return result; 
 33616 |                } 
 33617 |  
 33618 |                parser_->set_error(parser_error::make_error( 
 33619 |                   parser_error::e_synthesis, 
 33620 |                   token_t(), 
 33621 |                   "ERR261 - Failed to synthesize node: str_vararg_node<vararg_multi_op>", 
 33622 |                   exprtk_error_location)); 
 33623 |  
 33624 |                details::free_node(*node_allocator_, result); 
 33625 |             } 
 33626 |             else 
 33627 |             #endif 
 33628 |             { 
 33629 |                expression_node_ptr result = error_node(); 
 33630 |  
 33631 |                switch (operation) 
 33632 |                { 
 33633 |                   #define case_stmt(op0, op1)                                               \ 
 33634 |                   case op0 : result = node_allocator_->                                     \ 
 33635 |                                 allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \ 
 33636 |                              break;                                                         \ 
 33637 |  
 33638 |                   case_stmt(details::e_sum   , details::vararg_add_op  ) 
 33639 |                   case_stmt(details::e_prod  , details::vararg_mul_op  ) 
 33640 |                   case_stmt(details::e_avg   , details::vararg_avg_op  ) 
 33641 |                   case_stmt(details::e_min   , details::vararg_min_op  ) 
 33642 |                   case_stmt(details::e_max   , details::vararg_max_op  ) 
 33643 |                   case_stmt(details::e_mand  , details::vararg_mand_op ) 
 33644 |                   case_stmt(details::e_mor   , details::vararg_mor_op  ) 
 33645 |                   case_stmt(details::e_multi , details::vararg_multi_op) 
 33646 |                   #undef case_stmt 
 33647 |                   default : return error_node(); 
 33648 |                } 
 33649 |  
 33650 |                if (result && result->valid()) 
 33651 |                { 
 33652 |                   return result; 
 33653 |                } 
 33654 |  
 33655 |                parser_->set_error(parser_error::make_error( 
 33656 |                   parser_error::e_synthesis, 
 33657 |                   token_t(), 
 33658 |                   "ERR262 - Failed to synthesize node: vararg_node", 
 33659 |                   exprtk_error_location)); 
 33660 |  
 33661 |                details::free_node(*node_allocator_, result); 
 33662 |             } 
 33663 |  
 33664 |             return error_node(); 
 33665 |          } 
 33666 |  
 33667 |          template <std::size_t N> 
 33668 |          inline expression_node_ptr function(ifunction_t* f, expression_node_ptr (&b)[N]) 
 33669 |          { 
 33670 |             typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t; 
 33671 |             expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b); 
 33672 |  
 33673 |             if (0 == result) 
 33674 |                return error_node(); 
 33675 |             else 
 33676 |             { 
 33677 |                // Can the function call be completely optimised? 
 33678 |                if (details::is_constant_node(result)) 
 33679 |                   return result; 
 33680 |                else if (!all_nodes_valid(b)) 
 33681 |                { 
 33682 |                   details::free_node(*node_allocator_,result); 
 33683 |                   std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0)); 
 33684 |  
 33685 |                   return error_node(); 
 33686 |                } 
 33687 |                else if (N != f->param_count) 
 33688 |                { 
 33689 |                   details::free_node(*node_allocator_,result); 
 33690 |                   std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0)); 
 33691 |  
 33692 |                   return error_node(); 
 33693 |                } 
 33694 |  
 33695 |                function_N_node_t* func_node_ptr = reinterpret_cast<function_N_node_t*>(result); 
 33696 |  
 33697 |                if (!func_node_ptr->init_branches(b)) 
 33698 |                { 
 33699 |                   details::free_node(*node_allocator_,result); 
 33700 |                   std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0)); 
 33701 |  
 33702 |                   return error_node(); 
 33703 |                } 
 33704 |  
 33705 |                if (result && result->valid()) 
 33706 |                { 
 33707 |                   return result; 
 33708 |                } 
 33709 |  
 33710 |                parser_->set_error(parser_error::make_error( 
 33711 |                   parser_error::e_synthesis, 
 33712 |                   token_t(), 
 33713 |                   "ERR263 - Failed to synthesize node: function_N_node_t", 
 33714 |                   exprtk_error_location)); 
 33715 |  
 33716 |                details::free_node(*node_allocator_, result); 
 33717 |                return error_node(); 
 33718 |             } 
 33719 |          } 
 33720 |  
 33721 |          inline expression_node_ptr function(ifunction_t* f) 
 33722 |          { 
 33723 |             typedef typename details::function_N_node<Type,ifunction_t,0> function_N_node_t; 
 33724 |             return node_allocator_->allocate<function_N_node_t>(f); 
 33725 |          } 
 33726 |  
 33727 |          inline expression_node_ptr vararg_function_call(ivararg_function_t* vaf, 
 33728 |                                                          std::vector<expression_node_ptr>& arg_list) 
 33729 |          { 
 33730 |             if (!all_nodes_valid(arg_list)) 
 33731 |             { 
 33732 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33733 |  
 33734 |                return error_node(); 
 33735 |             } 
 33736 |  
 33737 |             typedef details::vararg_function_node<Type,ivararg_function_t> alloc_type; 
 33738 |  
 33739 |             expression_node_ptr result = node_allocator_->allocate<alloc_type>(vaf,arg_list); 
 33740 |  
 33741 |             if ( 
 33742 |                  !arg_list.empty()        && 
 33743 |                  !vaf->has_side_effects() && 
 33744 |                  is_constant_foldable(arg_list) 
 33745 |                ) 
 33746 |             { 
 33747 |                const Type v = result->value(); 
 33748 |                details::free_node(*node_allocator_,result); 
 33749 |                result = node_allocator_->allocate<literal_node_t>(v); 
 33750 |             } 
 33751 |  
 33752 |             parser_->state_.activate_side_effect("vararg_function_call()"); 
 33753 |  
 33754 |             if (result && result->valid()) 
 33755 |             { 
 33756 |                return result; 
 33757 |             } 
 33758 |  
 33759 |             parser_->set_error(parser_error::make_error( 
 33760 |                parser_error::e_synthesis, 
 33761 |                token_t(), 
 33762 |                "ERR264 - Failed to synthesize node: vararg_function_node<ivararg_function_t>", 
 33763 |                exprtk_error_location)); 
 33764 |  
 33765 |             details::free_node(*node_allocator_, result); 
 33766 |             return error_node(); 
 33767 |          } 
 33768 |  
 33769 |          inline expression_node_ptr generic_function_call(igeneric_function_t* gf, 
 33770 |                                                           std::vector<expression_node_ptr>& arg_list, 
 33771 |                                                           const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max()) 
 33772 |          { 
 33773 |             if (!all_nodes_valid(arg_list)) 
 33774 |             { 
 33775 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33776 |                return error_node(); 
 33777 |             } 
 33778 |  
 33779 |             typedef details::generic_function_node     <Type,igeneric_function_t> alloc_type1; 
 33780 |             typedef details::multimode_genfunction_node<Type,igeneric_function_t> alloc_type2; 
 33781 |  
 33782 |             const std::size_t no_psi = std::numeric_limits<std::size_t>::max(); 
 33783 |  
 33784 |             expression_node_ptr result = error_node(); 
 33785 |             std::string node_name = "Unknown" 
 33786 |  
 33787 |             if (no_psi == param_seq_index) 
 33788 |             { 
 33789 |                result = node_allocator_->allocate<alloc_type1>(arg_list,gf); 
 33790 |                node_name = "generic_function_node<igeneric_function_t>" 
 33791 |             } 
 33792 |             else 
 33793 |             { 
 33794 |                result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list); 
 33795 |                node_name = "multimode_genfunction_node<igeneric_function_t>" 
 33796 |             } 
 33797 |  
 33798 |             alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result); 
 33799 |  
 33800 |             assert(genfunc_node_ptr); 
 33801 |  
 33802 |             if ( 
 33803 |                  !arg_list.empty()                  && 
 33804 |                  !gf->has_side_effects()            && 
 33805 |                  parser_->state_.type_check_enabled && 
 33806 |                  is_constant_foldable(arg_list) 
 33807 |                ) 
 33808 |             { 
 33809 |                genfunc_node_ptr->init_branches(); 
 33810 |  
 33811 |                const Type v = result->value(); 
 33812 |  
 33813 |                details::free_node(*node_allocator_,result); 
 33814 |  
 33815 |                return node_allocator_->allocate<literal_node_t>(v); 
 33816 |             } 
 33817 |             else if (genfunc_node_ptr->init_branches()) 
 33818 |             { 
 33819 |                if (result && result->valid()) 
 33820 |                { 
 33821 |                   parser_->state_.activate_side_effect("generic_function_call()"); 
 33822 |                   return result; 
 33823 |                } 
 33824 |  
 33825 |                parser_->set_error(parser_error::make_error( 
 33826 |                   parser_error::e_synthesis, 
 33827 |                   token_t(), 
 33828 |                   "ERR265 - Failed to synthesize node: " + node_name, 
 33829 |                   exprtk_error_location)); 
 33830 |  
 33831 |                details::free_node(*node_allocator_, result); 
 33832 |                return error_node(); 
 33833 |             } 
 33834 |             else 
 33835 |             { 
 33836 |                details::free_node(*node_allocator_, result); 
 33837 |                details::free_all_nodes(*node_allocator_, arg_list); 
 33838 |  
 33839 |                return error_node(); 
 33840 |             } 
 33841 |          } 
 33842 |  
 33843 |          #ifndef exprtk_disable_string_capabilities 
 33844 |          inline expression_node_ptr string_function_call(igeneric_function_t* gf, 
 33845 |                                                          std::vector<expression_node_ptr>& arg_list, 
 33846 |                                                          const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max()) 
 33847 |          { 
 33848 |             if (!all_nodes_valid(arg_list)) 
 33849 |             { 
 33850 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33851 |                return error_node(); 
 33852 |             } 
 33853 |  
 33854 |             typedef details::string_function_node      <Type,igeneric_function_t> alloc_type1; 
 33855 |             typedef details::multimode_strfunction_node<Type,igeneric_function_t> alloc_type2; 
 33856 |  
 33857 |             const std::size_t no_psi = std::numeric_limits<std::size_t>::max(); 
 33858 |  
 33859 |             expression_node_ptr result = error_node(); 
 33860 |             std::string node_name = "Unknown" 
 33861 |  
 33862 |             if (no_psi == param_seq_index) 
 33863 |             { 
 33864 |                result = node_allocator_->allocate<alloc_type1>(gf,arg_list); 
 33865 |                node_name = "string_function_node<igeneric_function_t>" 
 33866 |             } 
 33867 |             else 
 33868 |             { 
 33869 |                result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list); 
 33870 |                node_name = "multimode_strfunction_node<igeneric_function_t>" 
 33871 |             } 
 33872 |  
 33873 |             alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result); 
 33874 |  
 33875 |             assert(strfunc_node_ptr); 
 33876 |  
 33877 |             if ( 
 33878 |                  !arg_list.empty()       && 
 33879 |                  !gf->has_side_effects() && 
 33880 |                  is_constant_foldable(arg_list) 
 33881 |                ) 
 33882 |             { 
 33883 |                strfunc_node_ptr->init_branches(); 
 33884 |  
 33885 |                const Type v = result->value(); 
 33886 |  
 33887 |                details::free_node(*node_allocator_,result); 
 33888 |  
 33889 |                return node_allocator_->allocate<literal_node_t>(v); 
 33890 |             } 
 33891 |             else if (strfunc_node_ptr->init_branches()) 
 33892 |             { 
 33893 |                if (result && result->valid()) 
 33894 |                { 
 33895 |                   parser_->state_.activate_side_effect("string_function_call()"); 
 33896 |                   return result; 
 33897 |                } 
 33898 |  
 33899 |                parser_->set_error(parser_error::make_error( 
 33900 |                   parser_error::e_synthesis, 
 33901 |                   token_t(), 
 33902 |                   "ERR266 - Failed to synthesize node: " + node_name, 
 33903 |                   exprtk_error_location)); 
 33904 |  
 33905 |                details::free_node(*node_allocator_, result); 
 33906 |                return error_node(); 
 33907 |             } 
 33908 |             else 
 33909 |             { 
 33910 |                details::free_node     (*node_allocator_,result  ); 
 33911 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33912 |  
 33913 |                return error_node(); 
 33914 |             } 
 33915 |          } 
 33916 |          #endif 
 33917 |  
 33918 |          #ifndef exprtk_disable_return_statement 
 33919 |          inline expression_node_ptr return_call(std::vector<expression_node_ptr>& arg_list) 
 33920 |          { 
 33921 |             if (!all_nodes_valid(arg_list)) 
 33922 |             { 
 33923 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33924 |                return error_node(); 
 33925 |             } 
 33926 |  
 33927 |             typedef details::return_node<Type> alloc_type; 
 33928 |  
 33929 |             expression_node_ptr result = node_allocator_-> 
 33930 |                                             allocate_rr<alloc_type>(arg_list,parser_->results_ctx()); 
 33931 |  
 33932 |             alloc_type* return_node_ptr = static_cast<alloc_type*>(result); 
 33933 |  
 33934 |             assert(return_node_ptr); 
 33935 |  
 33936 |             if (return_node_ptr->init_branches()) 
 33937 |             { 
 33938 |                if (result && result->valid()) 
 33939 |                { 
 33940 |                   parser_->state_.activate_side_effect("return_call()"); 
 33941 |                   return result; 
 33942 |                } 
 33943 |  
 33944 |                parser_->set_error(parser_error::make_error( 
 33945 |                   parser_error::e_synthesis, 
 33946 |                   token_t(), 
 33947 |                   "ERR267 - Failed to synthesize node: return_node", 
 33948 |                   exprtk_error_location)); 
 33949 |  
 33950 |                details::free_node(*node_allocator_, result); 
 33951 |                return error_node(); 
 33952 |             } 
 33953 |             else 
 33954 |             { 
 33955 |                details::free_node     (*node_allocator_, result  ); 
 33956 |                details::free_all_nodes(*node_allocator_, arg_list); 
 33957 |  
 33958 |                return error_node(); 
 33959 |             } 
 33960 |          } 
 33961 |  
 33962 |          inline expression_node_ptr return_envelope(expression_node_ptr body, 
 33963 |                                                     results_context_t* rc, 
 33964 |                                                     bool*& return_invoked) 
 33965 |          { 
 33966 |             typedef details::return_envelope_node<Type> alloc_type; 
 33967 |  
 33968 |             expression_node_ptr result = node_allocator_-> 
 33969 |                                             allocate_cr<alloc_type>(body,(*rc)); 
 33970 |  
 33971 |             return_invoked = static_cast<alloc_type*>(result)->retinvk_ptr(); 
 33972 |  
 33973 |             return result; 
 33974 |          } 
 33975 |          #else 
 33976 |          inline expression_node_ptr return_call(std::vector<expression_node_ptr>&) 
 33977 |          { 
 33978 |             return error_node(); 
 33979 |          } 
 33980 |  
 33981 |          inline expression_node_ptr return_envelope(expression_node_ptr, 
 33982 |                                                     results_context_t*, 
 33983 |                                                     bool*&) 
 33984 |          { 
 33985 |             return error_node(); 
 33986 |          } 
 33987 |          #endif 
 33988 |  
 33989 |          inline expression_node_ptr vector_element(const std::string&  symbol, 
 33990 |                                                    vector_holder_ptr   vector_base, 
 33991 |                                                    expression_node_ptr vec_node, 
 33992 |                                                    expression_node_ptr index) 
 33993 |          { 
 33994 |             expression_node_ptr result = error_node(); 
 33995 |             std::string node_name = "Unknown" 
 33996 |  
 33997 |             if (details::is_constant_node(index)) 
 33998 |             { 
 33999 |                const std::size_t vec_index = static_cast<std::size_t>(details::numeric::to_int64(index->value())); 
 34000 |  
 34001 |                details::free_node(*node_allocator_,index); 
 34002 |  
 34003 |                if (vec_index >= vector_base->size()) 
 34004 |                { 
 34005 |                   parser_->set_error(parser_error::make_error( 
 34006 |                      parser_error::e_parser, 
 34007 |                      token_t(), 
 34008 |                      "ERR268 - Index of " + details::to_str(vec_index) + " out of range for " 
 34009 |                      "vector '" + symbol + "' of size " + details::to_str(vector_base->size()), 
 34010 |                      exprtk_error_location)); 
 34011 |  
 34012 |                   details::free_node(*node_allocator_,vec_node); 
 34013 |  
 34014 |                   return error_node(); 
 34015 |                } 
 34016 |  
 34017 |                if (vector_base->rebaseable()) 
 34018 |                { 
 34019 |                   vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); 
 34020 |  
 34021 |                   result = (rtc) ? 
 34022 |                      node_allocator_->allocate<rebasevector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) : 
 34023 |                      node_allocator_->allocate<rebasevector_celem_node_t    >(vec_node, vec_index, vector_base     ) ; 
 34024 |  
 34025 |                   node_name = (rtc) ? 
 34026 |                      "rebasevector_elem_rtc_node_t" : 
 34027 |                      "rebasevector_elem_node_t"     ; 
 34028 |  
 34029 |                   if (result && result->valid()) 
 34030 |                   { 
 34031 |                      return result; 
 34032 |                   } 
 34033 |  
 34034 |                   parser_->set_error(parser_error::make_error( 
 34035 |                      parser_error::e_synthesis, 
 34036 |                      token_t(), 
 34037 |                      "ERR269 - Failed to synthesize node: " + node_name + " for vector: " + symbol, 
 34038 |                      exprtk_error_location)); 
 34039 |  
 34040 |                   details::free_node(*node_allocator_, result); 
 34041 |                   return error_node(); 
 34042 |                } 
 34043 |                else if (details::is_ivector_node(vec_node) && !details::is_vector_node(vec_node)) 
 34044 |                { 
 34045 |                   vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); 
 34046 |  
 34047 |                   result = (rtc) ? 
 34048 |                      node_allocator_->allocate<vector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) : 
 34049 |                      node_allocator_->allocate<vector_celem_node_t    >(vec_node, vec_index, vector_base     ) ; 
 34050 |  
 34051 |                   node_name = (rtc) ? 
 34052 |                      "vector_elem_rtc_node_t" : 
 34053 |                      "vector_elem_node_t"     ; 
 34054 |  
 34055 |                   if (result && result->valid()) 
 34056 |                   { 
 34057 |                      return result; 
 34058 |                   } 
 34059 |  
 34060 |                   parser_->set_error(parser_error::make_error( 
 34061 |                      parser_error::e_synthesis, 
 34062 |                      token_t(), 
 34063 |                      "ERR270 - Failed to synthesize node: " + node_name + " for vector: " + symbol, 
 34064 |                      exprtk_error_location)); 
 34065 |  
 34066 |                   details::free_node(*node_allocator_, result); 
 34067 |                   return error_node(); 
 34068 |                } 
 34069 |  
 34070 |                const scope_element& se = parser_->sem_.get_element(symbol,vec_index); 
 34071 |  
 34072 |                if (se.index == vec_index) 
 34073 |                { 
 34074 |                   result = se.var_node; 
 34075 |                   details::free_node(*node_allocator_,vec_node); 
 34076 |                } 
 34077 |                else 
 34078 |                { 
 34079 |                   scope_element nse; 
 34080 |                   nse.name      = symbol; 
 34081 |                   nse.active    = true; 
 34082 |                   nse.ref_count = 1; 
 34083 |                   nse.type      = scope_element::e_vecelem; 
 34084 |                   nse.index     = vec_index; 
 34085 |                   nse.depth     = parser_->state_.scope_depth; 
 34086 |                   nse.data      = 0; 
 34087 |                   nse.var_node  = node_allocator_->allocate<variable_node_t>((*(*vector_base)[vec_index])); 
 34088 |  
 34089 |                   if (!parser_->sem_.add_element(nse)) 
 34090 |                   { 
 34091 |                      parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]"); 
 34092 |  
 34093 |                      parser_->sem_.free_element(nse); 
 34094 |  
 34095 |                      result = error_node(); 
 34096 |                   } 
 34097 |  
 34098 |                   assert(parser_->sem_.total_local_symb_size_bytes() <= parser_->settings().max_total_local_symbol_size_bytes()); 
 34099 |  
 34100 |                   details::free_node(*node_allocator_,vec_node); 
 34101 |  
 34102 |                   exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n", nse.name.c_str())); 
 34103 |  
 34104 |                   parser_->state_.activate_side_effect("vector_element()"); 
 34105 |  
 34106 |                   result = nse.var_node; 
 34107 |                   node_name = "variable_node_t" 
 34108 |                } 
 34109 |             } 
 34110 |             else 
 34111 |             { 
 34112 |                vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); 
 34113 |  
 34114 |                if (vector_base->rebaseable()) 
 34115 |                { 
 34116 |                   result = (rtc) ? 
 34117 |                      node_allocator_->allocate<rebasevector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) : 
 34118 |                      node_allocator_->allocate<rebasevector_elem_node_t    >(vec_node, index, vector_base     ) ; 
 34119 |  
 34120 |                   node_name = (rtc) ? 
 34121 |                      "rebasevector_elem_rtc_node_t" : 
 34122 |                      "rebasevector_elem_node_t"     ; 
 34123 |                } 
 34124 |                else 
 34125 |                { 
 34126 |                   result = rtc ? 
 34127 |                      node_allocator_->allocate<vector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) : 
 34128 |                      node_allocator_->allocate<vector_elem_node_t    >(vec_node, index, vector_base     ) ; 
 34129 |  
 34130 |                   node_name = (rtc) ? 
 34131 |                      "vector_elem_rtc_node_t" : 
 34132 |                      "vector_elem_node_t"     ; 
 34133 |                } 
 34134 |             } 
 34135 |  
 34136 |             if (result && result->valid()) 
 34137 |             { 
 34138 |                return result; 
 34139 |             } 
 34140 |  
 34141 |             parser_->set_error(parser_error::make_error( 
 34142 |                parser_error::e_synthesis, 
 34143 |                token_t(), 
 34144 |                "ERR271 - Failed to synthesize node: " + node_name, 
 34145 |                exprtk_error_location)); 
 34146 |  
 34147 |             details::free_node(*node_allocator_, result); 
 34148 |             return error_node(); 
 34149 |          } 
 34150 |  
 34151 |       private: 
 34152 |  
 34153 |          template <std::size_t N, typename NodePtr> 
 34154 |          inline bool is_constant_foldable(NodePtr (&b)[N]) const 
 34155 |          { 
 34156 |             for (std::size_t i = 0; i < N; ++i) 
 34157 |             { 
 34158 |                if (0 == b[i]) 
 34159 |                   return false; 
 34160 |                else if (!details::is_constant_node(b[i])) 
 34161 |                   return false; 
 34162 |             } 
 34163 |  
 34164 |             return true; 
 34165 |          } 
 34166 |  
 34167 |          template <typename NodePtr, 
 34168 |                    typename Allocator, 
 34169 |                    template <typename, typename> class Sequence> 
 34170 |          inline bool is_constant_foldable(const Sequence<NodePtr,Allocator>& b) const 
 34171 |          { 
 34172 |             for (std::size_t i = 0; i < b.size(); ++i) 
 34173 |             { 
 34174 |                if (0 == b[i]) 
 34175 |                   return false; 
 34176 |                else if (!details::is_constant_node(b[i])) 
 34177 |                   return false; 
 34178 |             } 
 34179 |  
 34180 |             return true; 
 34181 |          } 
 34182 |  
 34183 |          void lodge_assignment(symbol_type cst, expression_node_ptr node) 
 34184 |          { 
 34185 |             parser_->state_.activate_side_effect("lodge_assignment()"); 
 34186 |  
 34187 |             if (!parser_->dec_.collect_assignments()) 
 34188 |                return; 
 34189 |  
 34190 |             std::string symbol_name; 
 34191 |  
 34192 |             switch (cst) 
 34193 |             { 
 34194 |                case e_st_variable : symbol_name = parser_->symtab_store_ 
 34195 |                                                      .get_variable_name(node); 
 34196 |                                     break; 
 34197 |  
 34198 |                #ifndef exprtk_disable_string_capabilities 
 34199 |                case e_st_string   : symbol_name = parser_->symtab_store_ 
 34200 |                                                      .get_stringvar_name(node); 
 34201 |                                     break; 
 34202 |                #endif 
 34203 |  
 34204 |                case e_st_vector   : { 
 34205 |                                        typedef details::vector_holder<T> vector_holder_t; 
 34206 |  
 34207 |                                        vector_holder_t& vh = static_cast<vector_node_t*>(node)->vec_holder(); 
 34208 |  
 34209 |                                        symbol_name = parser_->symtab_store_.get_vector_name(&vh); 
 34210 |                                     } 
 34211 |                                     break; 
 34212 |  
 34213 |                case e_st_vecelem  : { 
 34214 |                                        typedef details::vector_holder<T> vector_holder_t; 
 34215 |  
 34216 |                                        vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder(); 
 34217 |  
 34218 |                                        symbol_name = parser_->symtab_store_.get_vector_name(&vh); 
 34219 |  
 34220 |                                        cst = e_st_vector; 
 34221 |                                     } 
 34222 |                                     break; 
 34223 |  
 34224 |                default            : return; 
 34225 |             } 
 34226 |  
 34227 |             if (!symbol_name.empty()) 
 34228 |             { 
 34229 |                parser_->dec_.add_assignment(symbol_name,cst); 
 34230 |             } 
 34231 |          } 
 34232 |  
 34233 |          const void* base_ptr(expression_node_ptr node) 
 34234 |          { 
 34235 |             if (node) 
 34236 |             { 
 34237 |                switch (node->type()) 
 34238 |                { 
 34239 |                   case details::expression_node<T>::e_variable: 
 34240 |                      return reinterpret_cast<const void*>(&static_cast<variable_node_t*>(node)->ref()); 
 34241 |  
 34242 |                   case details::expression_node<T>::e_vecelem: 
 34243 |                      return reinterpret_cast<const void*>(&static_cast<vector_elem_node_t*>(node)->ref()); 
 34244 |  
 34245 |                   case details::expression_node<T>::e_veccelem: 
 34246 |                      return reinterpret_cast<const void*>(&static_cast<vector_celem_node_t*>(node)->ref()); 
 34247 |  
 34248 |                   case details::expression_node<T>::e_vecelemrtc: 
 34249 |                      return reinterpret_cast<const void*>(&static_cast<vector_elem_rtc_node_t*>(node)->ref()); 
 34250 |  
 34251 |                   case details::expression_node<T>::e_veccelemrtc: 
 34252 |                      return reinterpret_cast<const void*>(&static_cast<vector_celem_rtc_node_t*>(node)->ref()); 
 34253 |  
 34254 |                   case details::expression_node<T>::e_rbvecelem: 
 34255 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_node_t*>(node)->ref()); 
 34256 |  
 34257 |                   case details::expression_node<T>::e_rbvecelemrtc: 
 34258 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_rtc_node_t*>(node)->ref()); 
 34259 |  
 34260 |                   case details::expression_node<T>::e_rbveccelem: 
 34261 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_node_t*>(node)->ref()); 
 34262 |  
 34263 |                   case details::expression_node<T>::e_rbveccelemrtc: 
 34264 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_rtc_node_t*>(node)->ref()); 
 34265 |  
 34266 |                   case details::expression_node<T>::e_vector: 
 34267 |                      return reinterpret_cast<const void*>(static_cast<vector_node_t*>(node)->vec_holder().data()); 
 34268 |  
 34269 |                   #ifndef exprtk_disable_string_capabilities 
 34270 |                   case details::expression_node<T>::e_stringvar: 
 34271 |                      return reinterpret_cast<const void*>((static_cast<stringvar_node_t*>(node)->base())); 
 34272 |  
 34273 |                   case details::expression_node<T>::e_stringvarrng: 
 34274 |                      return reinterpret_cast<const void*>((static_cast<string_range_node_t*>(node)->base())); 
 34275 |                   #endif 
 34276 |                   default : return reinterpret_cast<const void*>(0); 
 34277 |                } 
 34278 |             } 
 34279 |  
 34280 |             return reinterpret_cast<const void*>(0); 
 34281 |          } 
 34282 |  
 34283 |          bool assign_immutable_symbol(expression_node_ptr node) 
 34284 |          { 
 34285 |             interval_t interval; 
 34286 |             const void* baseptr_addr = base_ptr(node); 
 34287 |  
 34288 |             exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr)); 
 34289 |  
 34290 |             if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval)) 
 34291 |             { 
 34292 |                typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval); 
 34293 |  
 34294 |                if (parser_->immutable_symtok_map_.end() != itr) 
 34295 |                { 
 34296 |                   token_t& token = itr->second; 
 34297 |                   parser_->set_error(parser_error::make_error( 
 34298 |                      parser_error::e_parser, 
 34299 |                      token, 
 34300 |                      "ERR272 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.", 
 34301 |                      exprtk_error_location)); 
 34302 |                } 
 34303 |                else 
 34304 |                   parser_->set_synthesis_error("Unable to assign symbol is immutable."); 
 34305 |  
 34306 |                return true; 
 34307 |             } 
 34308 |  
 34309 |             return false; 
 34310 |          } 
 34311 |  
 34312 |          inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 34313 |          { 
 34314 |             if (assign_immutable_symbol(branch[0])) 
 34315 |             { 
 34316 |                return error_node(); 
 34317 |             } 
 34318 |             else if (details::is_variable_node(branch[0])) 
 34319 |             { 
 34320 |                lodge_assignment(e_st_variable,branch[0]); 
 34321 |                return synthesize_expression<assignment_node_t,2>(operation,branch); 
 34322 |             } 
 34323 |             else if (details::is_vector_elem_node(branch[0]) || details::is_vector_celem_node(branch[0])) 
 34324 |             { 
 34325 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34326 |                return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch); 
 34327 |             } 
 34328 |             else if (details::is_vector_elem_rtc_node(branch[0]) || details::is_vector_celem_rtc_node(branch[0])) 
 34329 |             { 
 34330 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34331 |                return synthesize_expression<assignment_vec_elem_rtc_node_t, 2>(operation, branch); 
 34332 |             } 
 34333 |             else if (details::is_rebasevector_elem_node(branch[0])) 
 34334 |             { 
 34335 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34336 |                return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch); 
 34337 |             } 
 34338 |             else if (details::is_rebasevector_elem_rtc_node(branch[0])) 
 34339 |             { 
 34340 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34341 |                return synthesize_expression<assignment_rebasevec_elem_rtc_node_t, 2>(operation, branch); 
 34342 |             } 
 34343 |             else if (details::is_rebasevector_celem_node(branch[0])) 
 34344 |             { 
 34345 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34346 |                return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch); 
 34347 |             } 
 34348 |             #ifndef exprtk_disable_string_capabilities 
 34349 |             else if (details::is_string_node(branch[0])) 
 34350 |             { 
 34351 |                lodge_assignment(e_st_string,branch[0]); 
 34352 |                return synthesize_expression<assignment_string_node_t,2>(operation, branch); 
 34353 |             } 
 34354 |             else if (details::is_string_range_node(branch[0])) 
 34355 |             { 
 34356 |                lodge_assignment(e_st_string,branch[0]); 
 34357 |                return synthesize_expression<assignment_string_range_node_t,2>(operation, branch); 
 34358 |             } 
 34359 |             #endif 
 34360 |             else if (details::is_vector_node(branch[0])) 
 34361 |             { 
 34362 |                lodge_assignment(e_st_vector,branch[0]); 
 34363 |  
 34364 |                if (details::is_ivector_node(branch[1])) 
 34365 |                   return synthesize_expression<assignment_vecvec_node_t,2>(operation, branch); 
 34366 |                else 
 34367 |                   return synthesize_expression<assignment_vec_node_t,2>(operation, branch); 
 34368 |             } 
 34369 |             else if (details::is_literal_node(branch[0])) 
 34370 |             { 
 34371 |                parser_->set_error(parser_error::make_error( 
 34372 |                   parser_error::e_syntax, 
 34373 |                   parser_->current_state().token, 
 34374 |                   "ERR273 - Cannot assign value to const variable", 
 34375 |                   exprtk_error_location)); 
 34376 |  
 34377 |                return error_node(); 
 34378 |             } 
 34379 |             else 
 34380 |             { 
 34381 |                parser_->set_error(parser_error::make_error( 
 34382 |                   parser_error::e_syntax, 
 34383 |                   parser_->current_state().token, 
 34384 |                   "ERR274 - Invalid branches for assignment operator '" + details::to_str(operation) + "'", 
 34385 |                   exprtk_error_location)); 
 34386 |  
 34387 |                return error_node(); 
 34388 |             } 
 34389 |          } 
 34390 |  
 34391 |          inline expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type& operation, 
 34392 |                                                                                expression_node_ptr (&branch)[2]) 
 34393 |          { 
 34394 |             if (assign_immutable_symbol(branch[0])) 
 34395 |             { 
 34396 |                return error_node(); 
 34397 |             } 
 34398 |  
 34399 |             expression_node_ptr result = error_node(); 
 34400 |             std::string node_name = "Unknown" 
 34401 |  
 34402 |             if (details::is_variable_node(branch[0])) 
 34403 |             { 
 34404 |                lodge_assignment(e_st_variable,branch[0]); 
 34405 |  
 34406 |                switch (operation) 
 34407 |                { 
 34408 |                   #define case_stmt(op0, op1)                                                                 \ 
 34409 |                   case op0 : result = node_allocator_->                                                       \ 
 34410 |                                 template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \ 
 34411 |                                    (operation, branch[0], branch[1]);                                         \ 
 34412 |                              node_name = "assignment_op_node"                                                \ 
 34413 |                              break;                                                                           \ 
 34414 |  
 34415 |                   case_stmt(details::e_addass , details::add_op) 
 34416 |                   case_stmt(details::e_subass , details::sub_op) 
 34417 |                   case_stmt(details::e_mulass , details::mul_op) 
 34418 |                   case_stmt(details::e_divass , details::div_op) 
 34419 |                   case_stmt(details::e_modass , details::mod_op) 
 34420 |                   #undef case_stmt 
 34421 |                   default : return error_node(); 
 34422 |                } 
 34423 |             } 
 34424 |             else if (details::is_vector_elem_node(branch[0])) 
 34425 |             { 
 34426 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34427 |  
 34428 |                switch (operation) 
 34429 |                { 
 34430 |                   #define case_stmt(op0, op1)                                                                           \ 
 34431 |                   case op0 : result = node_allocator_->                                                                 \ 
 34432 |                                  template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \ 
 34433 |                                     (operation, branch[0], branch[1]);                                                  \ 
 34434 |                              node_name = "assignment_vec_elem_op_node"                                                 \ 
 34435 |                              break;                                                                                     \ 
 34436 |  
 34437 |                   case_stmt(details::e_addass , details::add_op) 
 34438 |                   case_stmt(details::e_subass , details::sub_op) 
 34439 |                   case_stmt(details::e_mulass , details::mul_op) 
 34440 |                   case_stmt(details::e_divass , details::div_op) 
 34441 |                   case_stmt(details::e_modass , details::mod_op) 
 34442 |                   #undef case_stmt 
 34443 |                   default : return error_node(); 
 34444 |                } 
 34445 |             } 
 34446 |             else if (details::is_vector_elem_rtc_node(branch[0])) 
 34447 |             { 
 34448 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34449 |  
 34450 |                switch (operation) 
 34451 |                { 
 34452 |                   #define case_stmt(op0, op1)                                                                               \ 
 34453 |                   case op0 : result = node_allocator_->                                                                     \ 
 34454 |                                  template allocate_rrr<typename details::assignment_vec_elem_op_rtc_node<Type,op1<Type> > > \ 
 34455 |                                     (operation, branch[0], branch[1]);                                                      \ 
 34456 |                              node_name = "assignment_vec_elem_op_rtc_node"                                                 \ 
 34457 |                              break;                                                                                         \ 
 34458 |  
 34459 |                   case_stmt(details::e_addass , details::add_op) 
 34460 |                   case_stmt(details::e_subass , details::sub_op) 
 34461 |                   case_stmt(details::e_mulass , details::mul_op) 
 34462 |                   case_stmt(details::e_divass , details::div_op) 
 34463 |                   case_stmt(details::e_modass , details::mod_op) 
 34464 |                   #undef case_stmt 
 34465 |                   default : return error_node(); 
 34466 |                } 
 34467 |             } 
 34468 |             else if (details::is_vector_celem_rtc_node(branch[0])) 
 34469 |             { 
 34470 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34471 |  
 34472 |                switch (operation) 
 34473 |                { 
 34474 |                   #define case_stmt(op0, op1)                                                                                \ 
 34475 |                   case op0 : result = node_allocator_->                                                                      \ 
 34476 |                                  template allocate_rrr<typename details::assignment_vec_celem_op_rtc_node<Type,op1<Type> > > \ 
 34477 |                                     (operation, branch[0], branch[1]);                                                       \ 
 34478 |                              node_name = "assignment_vec_celem_op_rtc_node"                                                 \ 
 34479 |                              break;                                                                                          \ 
 34480 |  
 34481 |                   case_stmt(details::e_addass , details::add_op) 
 34482 |                   case_stmt(details::e_subass , details::sub_op) 
 34483 |                   case_stmt(details::e_mulass , details::mul_op) 
 34484 |                   case_stmt(details::e_divass , details::div_op) 
 34485 |                   case_stmt(details::e_modass , details::mod_op) 
 34486 |                   #undef case_stmt 
 34487 |                   default : return error_node(); 
 34488 |                } 
 34489 |             } 
 34490 |             else if (details::is_rebasevector_elem_node(branch[0])) 
 34491 |             { 
 34492 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34493 |  
 34494 |                switch (operation) 
 34495 |                { 
 34496 |                   #define case_stmt(op0, op1)                                                                                 \ 
 34497 |                   case op0 : result = node_allocator_->                                                                       \ 
 34498 |                                  template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \ 
 34499 |                                     (operation, branch[0], branch[1]);                                                        \ 
 34500 |                              node_name = "assignment_rebasevec_elem_op_node"                                                 \ 
 34501 |                              break;                                                                                           \ 
 34502 |  
 34503 |                   case_stmt(details::e_addass , details::add_op) 
 34504 |                   case_stmt(details::e_subass , details::sub_op) 
 34505 |                   case_stmt(details::e_mulass , details::mul_op) 
 34506 |                   case_stmt(details::e_divass , details::div_op) 
 34507 |                   case_stmt(details::e_modass , details::mod_op) 
 34508 |                   #undef case_stmt 
 34509 |                   default : return error_node(); 
 34510 |                } 
 34511 |             } 
 34512 |             else if (details::is_rebasevector_celem_node(branch[0])) 
 34513 |             { 
 34514 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34515 |  
 34516 |                switch (operation) 
 34517 |                { 
 34518 |                   #define case_stmt(op0, op1)                                                                                  \ 
 34519 |                   case op0 : result = node_allocator_->                                                                        \ 
 34520 |                                  template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \ 
 34521 |                                     (operation, branch[0], branch[1]);                                                         \ 
 34522 |                              node_name = "assignment_rebasevec_celem_op_node"                                                 \ 
 34523 |                              break;                                                                                            \ 
 34524 |  
 34525 |                   case_stmt(details::e_addass , details::add_op) 
 34526 |                   case_stmt(details::e_subass , details::sub_op) 
 34527 |                   case_stmt(details::e_mulass , details::mul_op) 
 34528 |                   case_stmt(details::e_divass , details::div_op) 
 34529 |                   case_stmt(details::e_modass , details::mod_op) 
 34530 |                   #undef case_stmt 
 34531 |                   default : return error_node(); 
 34532 |                } 
 34533 |             } 
 34534 |             else if (details::is_rebasevector_elem_rtc_node(branch[0])) 
 34535 |             { 
 34536 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34537 |  
 34538 |                switch (operation) 
 34539 |                { 
 34540 |                   #define case_stmt(op0, op1)                                                                                     \ 
 34541 |                   case op0 : result = node_allocator_->                                                                           \ 
 34542 |                                  template allocate_rrr<typename details::assignment_rebasevec_elem_op_rtc_node<Type,op1<Type> > > \ 
 34543 |                                     (operation, branch[0], branch[1]);                                                            \ 
 34544 |                              node_name = "assignment_rebasevec_elem_op_rtc_node"                                                 \ 
 34545 |                              break;                                                                                               \ 
 34546 |  
 34547 |                   case_stmt(details::e_addass , details::add_op) 
 34548 |                   case_stmt(details::e_subass , details::sub_op) 
 34549 |                   case_stmt(details::e_mulass , details::mul_op) 
 34550 |                   case_stmt(details::e_divass , details::div_op) 
 34551 |                   case_stmt(details::e_modass , details::mod_op) 
 34552 |                   #undef case_stmt 
 34553 |                   default : return error_node(); 
 34554 |                } 
 34555 |             } 
 34556 |             else if (details::is_rebasevector_celem_rtc_node(branch[0])) 
 34557 |             { 
 34558 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34559 |  
 34560 |                switch (operation) 
 34561 |                { 
 34562 |                   #define case_stmt(op0, op1)                                                                                      \ 
 34563 |                   case op0 : result = node_allocator_->                                                                            \ 
 34564 |                                  template allocate_rrr<typename details::assignment_rebasevec_celem_op_rtc_node<Type,op1<Type> > > \ 
 34565 |                                     (operation, branch[0], branch[1]);                                                             \ 
 34566 |                              node_name = "assignment_rebasevec_celem_op_rtc_node"                                                 \ 
 34567 |                              break;                                                                                                \ 
 34568 |  
 34569 |                   case_stmt(details::e_addass , details::add_op) 
 34570 |                   case_stmt(details::e_subass , details::sub_op) 
 34571 |                   case_stmt(details::e_mulass , details::mul_op) 
 34572 |                   case_stmt(details::e_divass , details::div_op) 
 34573 |                   case_stmt(details::e_modass , details::mod_op) 
 34574 |                   #undef case_stmt 
 34575 |                   default : return error_node(); 
 34576 |                } 
 34577 |             } 
 34578 |             else if (details::is_vector_node(branch[0])) 
 34579 |             { 
 34580 |                lodge_assignment(e_st_vector,branch[0]); 
 34581 |  
 34582 |                if (details::is_ivector_node(branch[1])) 
 34583 |                { 
 34584 |                   switch (operation) 
 34585 |                   { 
 34586 |                      #define case_stmt(op0, op1)                                                                        \ 
 34587 |                      case op0 : result = node_allocator_->                                                              \ 
 34588 |                                    template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \ 
 34589 |                                       (operation, branch[0], branch[1]);                                                \ 
 34590 |                                 node_name = "assignment_rebasevec_celem_op_node"                                       \ 
 34591 |                                 break;                                                                                  \ 
 34592 |  
 34593 |                      case_stmt(details::e_addass , details::add_op) 
 34594 |                      case_stmt(details::e_subass , details::sub_op) 
 34595 |                      case_stmt(details::e_mulass , details::mul_op) 
 34596 |                      case_stmt(details::e_divass , details::div_op) 
 34597 |                      case_stmt(details::e_modass , details::mod_op) 
 34598 |                      #undef case_stmt 
 34599 |                      default : return error_node(); 
 34600 |                   } 
 34601 |                } 
 34602 |                else 
 34603 |                { 
 34604 |                   switch (operation) 
 34605 |                   { 
 34606 |                      #define case_stmt(op0, op1)                                                                     \ 
 34607 |                      case op0 : result = node_allocator_->                                                           \ 
 34608 |                                    template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \ 
 34609 |                                       (operation, branch[0], branch[1]);                                             \ 
 34610 |                                 node_name = "assignment_vec_op_node"                                                \ 
 34611 |                                 break;                                                                               \ 
 34612 |  
 34613 |                      case_stmt(details::e_addass , details::add_op) 
 34614 |                      case_stmt(details::e_subass , details::sub_op) 
 34615 |                      case_stmt(details::e_mulass , details::mul_op) 
 34616 |                      case_stmt(details::e_divass , details::div_op) 
 34617 |                      case_stmt(details::e_modass , details::mod_op) 
 34618 |                      #undef case_stmt 
 34619 |                      default : return error_node(); 
 34620 |                   } 
 34621 |                } 
 34622 |             } 
 34623 |             #ifndef exprtk_disable_string_capabilities 
 34624 |             else if ( 
 34625 |                       (details::e_addass == operation) && 
 34626 |                       details::is_string_node(branch[0]) 
 34627 |                     ) 
 34628 |             { 
 34629 |                typedef details::assignment_string_node<T,details::asn_addassignment> addass_t; 
 34630 |  
 34631 |                lodge_assignment(e_st_string,branch[0]); 
 34632 |  
 34633 |                result = synthesize_expression<addass_t,2>(operation,branch); 
 34634 |                node_name = "assignment_string_node<T,details::asn_addassignment>" 
 34635 |             } 
 34636 |             #endif 
 34637 |             else 
 34638 |             { 
 34639 |                parser_->set_error(parser_error::make_error( 
 34640 |                   parser_error::e_syntax, 
 34641 |                   parser_->current_state().token, 
 34642 |                   "ERR275 - Invalid branches for assignment operator '" + details::to_str(operation) + "'", 
 34643 |                   exprtk_error_location)); 
 34644 |  
 34645 |                return error_node(); 
 34646 |             } 
 34647 |  
 34648 |             if (result && result->valid()) 
 34649 |             { 
 34650 |                return result; 
 34651 |             } 
 34652 |  
 34653 |             parser_->set_error(parser_error::make_error( 
 34654 |                parser_error::e_synthesis, 
 34655 |                token_t(), 
 34656 |                "ERR276 - Failed to synthesize node: " + node_name, 
 34657 |                exprtk_error_location)); 
 34658 |  
 34659 |             details::free_node(*node_allocator_, result); 
 34660 |             return error_node(); 
 34661 |          } 
 34662 |  
 34663 |          inline expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type& operation, 
 34664 |                                                                                    expression_node_ptr (&branch)[2]) 
 34665 |          { 
 34666 |             const bool is_b0_ivec = details::is_ivector_node(branch[0]); 
 34667 |             const bool is_b1_ivec = details::is_ivector_node(branch[1]); 
 34668 |  
 34669 |             #define batch_eqineq_logic_case                 \ 
 34670 |             case_stmt(details::e_lt    , details::lt_op   ) \ 
 34671 |             case_stmt(details::e_lte   , details::lte_op  ) \ 
 34672 |             case_stmt(details::e_gt    , details::gt_op   ) \ 
 34673 |             case_stmt(details::e_gte   , details::gte_op  ) \ 
 34674 |             case_stmt(details::e_eq    , details::eq_op   ) \ 
 34675 |             case_stmt(details::e_ne    , details::ne_op   ) \ 
 34676 |             case_stmt(details::e_equal , details::equal_op) \ 
 34677 |             case_stmt(details::e_and   , details::and_op  ) \ 
 34678 |             case_stmt(details::e_nand  , details::nand_op ) \ 
 34679 |             case_stmt(details::e_or    , details::or_op   ) \ 
 34680 |             case_stmt(details::e_nor   , details::nor_op  ) \ 
 34681 |             case_stmt(details::e_xor   , details::xor_op  ) \ 
 34682 |             case_stmt(details::e_xnor  , details::xnor_op ) \ 
 34683 |  
 34684 |             expression_node_ptr result = error_node(); 
 34685 |             std::string node_name = "Unknown" 
 34686 |  
 34687 |             if (is_b0_ivec && is_b1_ivec) 
 34688 |             { 
 34689 |                switch (operation) 
 34690 |                { 
 34691 |                   #define case_stmt(op0, op1)                                                                    \ 
 34692 |                   case op0 : result = node_allocator_->                                                          \ 
 34693 |                                 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \ 
 34694 |                                    (operation, branch[0], branch[1]);                                            \ 
 34695 |                              node_name = "vec_binop_vecvec_node"                                                \ 
 34696 |                              break;                                                                              \ 
 34697 |  
 34698 |                   batch_eqineq_logic_case 
 34699 |                   #undef case_stmt 
 34700 |                   default : return error_node(); 
 34701 |                } 
 34702 |             } 
 34703 |             else if (is_b0_ivec && !is_b1_ivec) 
 34704 |             { 
 34705 |                switch (operation) 
 34706 |                { 
 34707 |                   #define case_stmt(op0, op1)                                                                    \ 
 34708 |                   case op0 : result = node_allocator_->                                                          \ 
 34709 |                                 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \ 
 34710 |                                    (operation, branch[0], branch[1]);                                            \ 
 34711 |                              node_name = "vec_binop_vecval_node"                                                \ 
 34712 |                              break;                                                                              \ 
 34713 |  
 34714 |                   batch_eqineq_logic_case 
 34715 |                   #undef case_stmt 
 34716 |                   default : return error_node(); 
 34717 |                } 
 34718 |             } 
 34719 |             else if (!is_b0_ivec && is_b1_ivec) 
 34720 |             { 
 34721 |                switch (operation) 
 34722 |                { 
 34723 |                   #define case_stmt(op0, op1)                                                                    \ 
 34724 |                   case op0 : result = node_allocator_->                                                          \ 
 34725 |                                 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \ 
 34726 |                                    (operation, branch[0], branch[1]);                                            \ 
 34727 |                              node_name = "vec_binop_valvec_node"                                                \ 
 34728 |                              break;                                                                              \ 
 34729 |  
 34730 |                   batch_eqineq_logic_case 
 34731 |                   #undef case_stmt 
 34732 |                   default : return error_node(); 
 34733 |                } 
 34734 |             } 
 34735 |             else 
 34736 |                return error_node(); 
 34737 |  
 34738 |             if (result && result->valid()) 
 34739 |             { 
 34740 |                return result; 
 34741 |             } 
 34742 |  
 34743 |             parser_->set_error(parser_error::make_error( 
 34744 |                parser_error::e_synthesis, 
 34745 |                token_t(), 
 34746 |                "ERR277 - Failed to synthesize node: " + node_name, 
 34747 |                exprtk_error_location)); 
 34748 |  
 34749 |             details::free_node(*node_allocator_, result); 
 34750 |             return error_node(); 
 34751 |  
 34752 |             #undef batch_eqineq_logic_case 
 34753 |          } 
 34754 |  
 34755 |          inline expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type& operation, 
 34756 |                                                                                   expression_node_ptr (&branch)[2]) 
 34757 |          { 
 34758 |             const bool is_b0_ivec = details::is_ivector_node(branch[0]); 
 34759 |             const bool is_b1_ivec = details::is_ivector_node(branch[1]); 
 34760 |  
 34761 |             #define vector_ops                          \ 
 34762 |             case_stmt(details::e_add , details::add_op) \ 
 34763 |             case_stmt(details::e_sub , details::sub_op) \ 
 34764 |             case_stmt(details::e_mul , details::mul_op) \ 
 34765 |             case_stmt(details::e_div , details::div_op) \ 
 34766 |             case_stmt(details::e_mod , details::mod_op) \ 
 34767 |  
 34768 |             expression_node_ptr result = error_node(); 
 34769 |             std::string node_name = "Unknown" 
 34770 |  
 34771 |             if (is_b0_ivec && is_b1_ivec) 
 34772 |             { 
 34773 |                switch (operation) 
 34774 |                { 
 34775 |                   #define case_stmt(op0, op1)                                                                    \ 
 34776 |                   case op0 : result = node_allocator_->                                                          \ 
 34777 |                                 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \ 
 34778 |                                    (operation, branch[0], branch[1]);                                            \ 
 34779 |                              node_name = "vec_binop_vecvec_node"                                                \ 
 34780 |                              break;                                                                              \ 
 34781 |  
 34782 |                   vector_ops 
 34783 |                   case_stmt(details::e_pow,details:: pow_op) 
 34784 |                   #undef case_stmt 
 34785 |                   default : return error_node(); 
 34786 |                } 
 34787 |             } 
 34788 |             else if (is_b0_ivec && !is_b1_ivec) 
 34789 |             { 
 34790 |                switch (operation) 
 34791 |                { 
 34792 |                   #define case_stmt(op0, op1)                                                                    \ 
 34793 |                   case op0 : result = node_allocator_->                                                          \ 
 34794 |                                 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \ 
 34795 |                                    (operation, branch[0], branch[1]);                                            \ 
 34796 |                              node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)"                                \ 
 34797 |                              break;                                                                              \ 
 34798 |  
 34799 |                   vector_ops 
 34800 |                   case_stmt(details::e_pow,details:: pow_op) 
 34801 |                   #undef case_stmt 
 34802 |                   default : return error_node(); 
 34803 |                } 
 34804 |             } 
 34805 |             else if (!is_b0_ivec && is_b1_ivec) 
 34806 |             { 
 34807 |                switch (operation) 
 34808 |                { 
 34809 |                   #define case_stmt(op0, op1)                                                                    \ 
 34810 |                   case op0 : result = node_allocator_->                                                          \ 
 34811 |                                 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \ 
 34812 |                                    (operation, branch[0], branch[1]);                                            \ 
 34813 |                              node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)"                                \ 
 34814 |                              break;                                                                              \ 
 34815 |  
 34816 |                   vector_ops 
 34817 |                   #undef case_stmt 
 34818 |                   default : return error_node(); 
 34819 |                } 
 34820 |             } 
 34821 |             else 
 34822 |                return error_node(); 
 34823 |  
 34824 |             if (result && result->valid()) 
 34825 |             { 
 34826 |                return result; 
 34827 |             } 
 34828 |  
 34829 |             parser_->set_error(parser_error::make_error( 
 34830 |                parser_error::e_synthesis, 
 34831 |                token_t(), 
 34832 |                "ERR278 - Failed to synthesize node: " + node_name, 
 34833 |                exprtk_error_location)); 
 34834 |  
 34835 |             details::free_node(*node_allocator_, result); 
 34836 |             return error_node(); 
 34837 |  
 34838 |             #undef vector_ops 
 34839 |          } 
 34840 |  
 34841 |          inline expression_node_ptr synthesize_swap_expression(expression_node_ptr (&branch)[2]) 
 34842 |          { 
 34843 |             const bool v0_is_ivar = details::is_ivariable_node(branch[0]); 
 34844 |             const bool v1_is_ivar = details::is_ivariable_node(branch[1]); 
 34845 |  
 34846 |             const bool v0_is_ivec = details::is_ivector_node  (branch[0]); 
 34847 |             const bool v1_is_ivec = details::is_ivector_node  (branch[1]); 
 34848 |  
 34849 |             #ifndef exprtk_disable_string_capabilities 
 34850 |             const bool v0_is_str = details::is_generally_string_node(branch[0]); 
 34851 |             const bool v1_is_str = details::is_generally_string_node(branch[1]); 
 34852 |             #endif 
 34853 |  
 34854 |             expression_node_ptr result = error_node(); 
 34855 |             std::string node_name      = "Unknown" 
 34856 |  
 34857 |             if (v0_is_ivar && v1_is_ivar) 
 34858 |             { 
 34859 |                typedef details::variable_node<T>* variable_node_ptr; 
 34860 |  
 34861 |                variable_node_ptr v0 = variable_node_ptr(0); 
 34862 |                variable_node_ptr v1 = variable_node_ptr(0); 
 34863 |  
 34864 |                if ( 
 34865 |                     (0 != (v0 = dynamic_cast<variable_node_ptr>(branch[0]))) && 
 34866 |                     (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1]))) 
 34867 |                   ) 
 34868 |                { 
 34869 |                   result    = node_allocator_->allocate<details::swap_node<T> >(v0,v1); 
 34870 |                   node_name = "swap_node" 
 34871 |                } 
 34872 |                else 
 34873 |                { 
 34874 |                   result    = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]); 
 34875 |                   node_name = "swap_generic_node" 
 34876 |                } 
 34877 |             } 
 34878 |             else if (v0_is_ivec && v1_is_ivec) 
 34879 |             { 
 34880 |                result    = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]); 
 34881 |                node_name = "swap_vecvec_node" 
 34882 |             } 
 34883 |             #ifndef exprtk_disable_string_capabilities 
 34884 |             else if (v0_is_str && v1_is_str) 
 34885 |             { 
 34886 |                if (is_string_node(branch[0]) && is_string_node(branch[1])) 
 34887 |                { 
 34888 |                   result = node_allocator_->allocate<details::swap_string_node<T> > 
 34889 |                                                (branch[0], branch[1]); 
 34890 |                   node_name = "swap_string_node" 
 34891 |                } 
 34892 |                else 
 34893 |                { 
 34894 |                   result = node_allocator_->allocate<details::swap_genstrings_node<T> > 
 34895 |                                                (branch[0], branch[1]); 
 34896 |                   node_name = "swap_genstrings_node" 
 34897 |                } 
 34898 |             } 
 34899 |             #endif 
 34900 |             else 
 34901 |             { 
 34902 |                parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped"); 
 34903 |                return error_node(); 
 34904 |             } 
 34905 |  
 34906 |             if (result && result->valid()) 
 34907 |             { 
 34908 |                parser_->state_.activate_side_effect("synthesize_swap_expression()"); 
 34909 |                return result; 
 34910 |             } 
 34911 |  
 34912 |             parser_->set_error(parser_error::make_error( 
 34913 |                parser_error::e_synthesis, 
 34914 |                token_t(), 
 34915 |                "ERR279 - Failed to synthesize node: " + node_name, 
 34916 |                exprtk_error_location)); 
 34917 |  
 34918 |             details::free_node(*node_allocator_, result); 
 34919 |             return error_node(); 
 34920 |          } 
 34921 |  
 34922 |          #ifndef exprtk_disable_sc_andor 
 34923 |          inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 34924 |          { 
 34925 |             expression_node_ptr result = error_node(); 
 34926 |  
 34927 |             if (details::is_constant_node(branch[0])) 
 34928 |             { 
 34929 |                if ( 
 34930 |                     (details::e_scand == operation) && 
 34931 |                     std::equal_to<T>()(T(0),branch[0]->value()) 
 34932 |                   ) 
 34933 |                   result = node_allocator_->allocate_c<literal_node_t>(T(0)); 
 34934 |                else if ( 
 34935 |                          (details::e_scor == operation) && 
 34936 |                          std::not_equal_to<T>()(T(0),branch[0]->value()) 
 34937 |                        ) 
 34938 |                   result = node_allocator_->allocate_c<literal_node_t>(T(1)); 
 34939 |             } 
 34940 |  
 34941 |             if (details::is_constant_node(branch[1]) && (0 == result)) 
 34942 |             { 
 34943 |                if ( 
 34944 |                     (details::e_scand == operation) && 
 34945 |                     std::equal_to<T>()(T(0),branch[1]->value()) 
 34946 |                   ) 
 34947 |                   result = node_allocator_->allocate_c<literal_node_t>(T(0)); 
 34948 |                else if ( 
 34949 |                          (details::e_scor == operation) && 
 34950 |                          std::not_equal_to<T>()(T(0),branch[1]->value()) 
 34951 |                        ) 
 34952 |                   result = node_allocator_->allocate_c<literal_node_t>(T(1)); 
 34953 |             } 
 34954 |  
 34955 |             if (result) 
 34956 |             { 
 34957 |                details::free_node(*node_allocator_, branch[0]); 
 34958 |                details::free_node(*node_allocator_, branch[1]); 
 34959 |  
 34960 |                return result; 
 34961 |             } 
 34962 |             else if (details::e_scand == operation) 
 34963 |             { 
 34964 |                return synthesize_expression<scand_node_t,2>(operation, branch); 
 34965 |             } 
 34966 |             else if (details::e_scor == operation) 
 34967 |             { 
 34968 |                return synthesize_expression<scor_node_t,2>(operation, branch); 
 34969 |             } 
 34970 |             else 
 34971 |                return error_node(); 
 34972 |          } 
 34973 |          #else 
 34974 |          inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type&, expression_node_ptr (&)[2]) 
 34975 |          { 
 34976 |             return error_node(); 
 34977 |          } 
 34978 |          #endif 
 34979 |  
 34980 |          #define basic_opr_switch_statements         \ 
 34981 |          case_stmt(details::e_add , details::add_op) \ 
 34982 |          case_stmt(details::e_sub , details::sub_op) \ 
 34983 |          case_stmt(details::e_mul , details::mul_op) \ 
 34984 |          case_stmt(details::e_div , details::div_op) \ 
 34985 |          case_stmt(details::e_mod , details::mod_op) \ 
 34986 |          case_stmt(details::e_pow , details::pow_op) \ 
 34987 |  
 34988 |          #define extended_opr_switch_statements        \ 
 34989 |          case_stmt(details::e_lt   , details::lt_op  ) \ 
 34990 |          case_stmt(details::e_lte  , details::lte_op ) \ 
 34991 |          case_stmt(details::e_gt   , details::gt_op  ) \ 
 34992 |          case_stmt(details::e_gte  , details::gte_op ) \ 
 34993 |          case_stmt(details::e_eq   , details::eq_op  ) \ 
 34994 |          case_stmt(details::e_ne   , details::ne_op  ) \ 
 34995 |          case_stmt(details::e_and  , details::and_op ) \ 
 34996 |          case_stmt(details::e_nand , details::nand_op) \ 
 34997 |          case_stmt(details::e_or   , details::or_op  ) \ 
 34998 |          case_stmt(details::e_nor  , details::nor_op ) \ 
 34999 |          case_stmt(details::e_xor  , details::xor_op ) \ 
 35000 |          case_stmt(details::e_xnor , details::xnor_op) \ 
 35001 |  
 35002 |          #ifndef exprtk_disable_cardinal_pow_optimisation 
 35003 |          template <typename TType, template <typename, typename> class IPowNode> 
 35004 |          inline expression_node_ptr cardinal_pow_optimisation_impl(const TType& v, const unsigned int& p) 
 35005 |          { 
 35006 |             switch (p) 
 35007 |             { 
 35008 |                #define case_stmt(cp)                                                     \ 
 35009 |                case cp : return node_allocator_->                                        \ 
 35010 |                             allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \ 
 35011 |  
 35012 |                case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4) 
 35013 |                case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8) 
 35014 |                case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12) 
 35015 |                case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16) 
 35016 |                case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20) 
 35017 |                case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24) 
 35018 |                case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28) 
 35019 |                case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32) 
 35020 |                case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36) 
 35021 |                case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40) 
 35022 |                case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44) 
 35023 |                case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48) 
 35024 |                case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52) 
 35025 |                case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56) 
 35026 |                case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60) 
 35027 |                #undef case_stmt 
 35028 |                default : return error_node(); 
 35029 |             } 
 35030 |          } 
 35031 |  
 35032 |          inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c) 
 35033 |          { 
 35034 |             const bool not_recipricol = (c >= T(0)); 
 35035 |             const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c))); 
 35036 |  
 35037 |             if (0 == p) 
 35038 |                return node_allocator_->allocate_c<literal_node_t>(T(1)); 
 35039 |             else if (std::equal_to<T>()(T(2),c)) 
 35040 |             { 
 35041 |                return node_allocator_-> 
 35042 |                   template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v); 
 35043 |             } 
 35044 |             else 
 35045 |             { 
 35046 |                if (not_recipricol) 
 35047 |                   return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p); 
 35048 |                else 
 35049 |                   return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p); 
 35050 |             } 
 35051 |          } 
 35052 |  
 35053 |          inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const 
 35054 |          { 
 35055 |             return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c); 
 35056 |          } 
 35057 |  
 35058 |          inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr (&branch)[2]) 
 35059 |          { 
 35060 |             const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35061 |             const bool not_recipricol = (c >= T(0)); 
 35062 |             const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c))); 
 35063 |  
 35064 |             node_allocator_->free(branch[1]); 
 35065 |  
 35066 |             if (0 == p) 
 35067 |             { 
 35068 |                details::free_all_nodes(*node_allocator_, branch); 
 35069 |  
 35070 |                return node_allocator_->allocate_c<literal_node_t>(T(1)); 
 35071 |             } 
 35072 |             else if (not_recipricol) 
 35073 |                return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p); 
 35074 |             else 
 35075 |                return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p); 
 35076 |          } 
 35077 |          #else 
 35078 |          inline expression_node_ptr cardinal_pow_optimisation(T&, const T&) 
 35079 |          { 
 35080 |             return error_node(); 
 35081 |          } 
 35082 |  
 35083 |          inline bool cardinal_pow_optimisable(const details::operator_type&, const T&) 
 35084 |          { 
 35085 |             return false; 
 35086 |          } 
 35087 |  
 35088 |          inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2]) 
 35089 |          { 
 35090 |             return error_node(); 
 35091 |          } 
 35092 |          #endif 
 35093 |  
 35094 |          struct synthesize_binary_ext_expression 
 35095 |          { 
 35096 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35097 |                                                       const details::operator_type& operation, 
 35098 |                                                       expression_node_ptr (&branch)[2]) 
 35099 |             { 
 35100 |                const bool left_neg  = is_neg_unary_node(branch[0]); 
 35101 |                const bool right_neg = is_neg_unary_node(branch[1]); 
 35102 |  
 35103 |                if (left_neg && right_neg) 
 35104 |                { 
 35105 |                   if ( 
 35106 |                        (details::e_add == operation) || 
 35107 |                        (details::e_sub == operation) || 
 35108 |                        (details::e_mul == operation) || 
 35109 |                        (details::e_div == operation) 
 35110 |                      ) 
 35111 |                   { 
 35112 |                      if ( 
 35113 |                           !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) || 
 35114 |                           !expr_gen.parser_->simplify_unary_negation_branch(branch[1]) 
 35115 |                         ) 
 35116 |                      { 
 35117 |                         details::free_all_nodes(*expr_gen.node_allocator_,branch); 
 35118 |  
 35119 |                         return error_node(); 
 35120 |                      } 
 35121 |                   } 
 35122 |  
 35123 |                   switch (operation) 
 35124 |                   { 
 35125 |                                            // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1)) 
 35126 |                      case details::e_add : return expr_gen(details::e_neg, 
 35127 |                                               expr_gen.node_allocator_-> 
 35128 |                                                  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > > 
 35129 |                                                     (branch[0],branch[1])); 
 35130 |  
 35131 |                                            // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1) 
 35132 |                      case details::e_sub : return expr_gen.node_allocator_-> 
 35133 |                                               template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > > 
 35134 |                                                  (branch[1],branch[0]); 
 35135 |  
 35136 |                      default             : break; 
 35137 |                   } 
 35138 |                } 
 35139 |                else if (left_neg && !right_neg) 
 35140 |                { 
 35141 |                   if ( 
 35142 |                        (details::e_add == operation) || 
 35143 |                        (details::e_sub == operation) || 
 35144 |                        (details::e_mul == operation) || 
 35145 |                        (details::e_div == operation) 
 35146 |                      ) 
 35147 |                   { 
 35148 |                      if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0])) 
 35149 |                      { 
 35150 |                         details::free_all_nodes(*expr_gen.node_allocator_,branch); 
 35151 |  
 35152 |                         return error_node(); 
 35153 |                      } 
 35154 |  
 35155 |                      switch (operation) 
 35156 |                      { 
 35157 |                                               // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1) 
 35158 |                         case details::e_add : return expr_gen.node_allocator_-> 
 35159 |                                                  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > > 
 35160 |                                                    (branch[1], branch[0]); 
 35161 |  
 35162 |                                               // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1)) 
 35163 |                         case details::e_sub : return expr_gen(details::e_neg, 
 35164 |                                                  expr_gen.node_allocator_-> 
 35165 |                                                     template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > > 
 35166 |                                                        (branch[0], branch[1])); 
 35167 |  
 35168 |                                               // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1)) 
 35169 |                         case details::e_mul : return expr_gen(details::e_neg, 
 35170 |                                                  expr_gen.node_allocator_-> 
 35171 |                                                     template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > > 
 35172 |                                                        (branch[0], branch[1])); 
 35173 |  
 35174 |                                               // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1)) 
 35175 |                         case details::e_div : return expr_gen(details::e_neg, 
 35176 |                                                  expr_gen.node_allocator_-> 
 35177 |                                                     template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > > 
 35178 |                                                        (branch[0], branch[1])); 
 35179 |  
 35180 |                         default             : return error_node(); 
 35181 |                      } 
 35182 |                   } 
 35183 |                } 
 35184 |                else if (!left_neg && right_neg) 
 35185 |                { 
 35186 |                   if ( 
 35187 |                        (details::e_add == operation) || 
 35188 |                        (details::e_sub == operation) || 
 35189 |                        (details::e_mul == operation) || 
 35190 |                        (details::e_div == operation) 
 35191 |                      ) 
 35192 |                   { 
 35193 |                      if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1])) 
 35194 |                      { 
 35195 |                         details::free_all_nodes(*expr_gen.node_allocator_,branch); 
 35196 |  
 35197 |                         return error_node(); 
 35198 |                      } 
 35199 |  
 35200 |                      switch (operation) 
 35201 |                      { 
 35202 |                                               // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1) 
 35203 |                         case details::e_add : return expr_gen.node_allocator_-> 
 35204 |                                                  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > > 
 35205 |                                                    (branch[0], branch[1]); 
 35206 |  
 35207 |                                               // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1) 
 35208 |                         case details::e_sub : return expr_gen.node_allocator_-> 
 35209 |                                                  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > > 
 35210 |                                                    (branch[0], branch[1]); 
 35211 |  
 35212 |                                               // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1)) 
 35213 |                         case details::e_mul : return expr_gen(details::e_neg, 
 35214 |                                                  expr_gen.node_allocator_-> 
 35215 |                                                     template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > > 
 35216 |                                                        (branch[0], branch[1])); 
 35217 |  
 35218 |                                               // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1)) 
 35219 |                         case details::e_div : return expr_gen(details::e_neg, 
 35220 |                                                  expr_gen.node_allocator_-> 
 35221 |                                                     template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > > 
 35222 |                                                        (branch[0], branch[1])); 
 35223 |  
 35224 |                         default             : return error_node(); 
 35225 |                      } 
 35226 |                   } 
 35227 |                } 
 35228 |  
 35229 |                switch (operation) 
 35230 |                { 
 35231 |                   #define case_stmt(op0, op1)                                                          \ 
 35232 |                   case op0 : return expr_gen.node_allocator_->                                         \ 
 35233 |                                 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \ 
 35234 |                                    (branch[0], branch[1]);                                             \ 
 35235 |  
 35236 |                   basic_opr_switch_statements 
 35237 |                   extended_opr_switch_statements 
 35238 |                   #undef case_stmt 
 35239 |                   default : return error_node(); 
 35240 |                } 
 35241 |             } 
 35242 |          }; 
 35243 |  
 35244 |          struct synthesize_vob_expression 
 35245 |          { 
 35246 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35247 |                                                       const details::operator_type& operation, 
 35248 |                                                       expression_node_ptr (&branch)[2]) 
 35249 |             { 
 35250 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 35251 |  
 35252 |                #ifndef exprtk_disable_enhanced_features 
 35253 |                if (details::is_sf3ext_node(branch[1])) 
 35254 |                { 
 35255 |                   expression_node_ptr result = error_node(); 
 35256 |  
 35257 |                   const bool synthesis_result = 
 35258 |                      synthesize_sf4ext_expression::template compile_right<vtype> 
 35259 |                         (expr_gen, v, operation, branch[1], result); 
 35260 |  
 35261 |                   if (synthesis_result) 
 35262 |                   { 
 35263 |                      details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35264 |                      return result; 
 35265 |                   } 
 35266 |                } 
 35267 |                #endif 
 35268 |  
 35269 |                if ( 
 35270 |                     (details::e_mul == operation) || 
 35271 |                     (details::e_div == operation) 
 35272 |                   ) 
 35273 |                { 
 35274 |                   if (details::is_uv_node(branch[1])) 
 35275 |                   { 
 35276 |                      typedef details::uv_base_node<Type>* uvbn_ptr_t; 
 35277 |  
 35278 |                      details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation(); 
 35279 |  
 35280 |                      if (details::e_neg == o) 
 35281 |                      { 
 35282 |                         const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v(); 
 35283 |  
 35284 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35285 |  
 35286 |                         switch (operation) 
 35287 |                         { 
 35288 |                            case details::e_mul : return expr_gen(details::e_neg, 
 35289 |                                                     expr_gen.node_allocator_-> 
 35290 |                                                        template allocate_rr<typename details:: 
 35291 |                                                           vov_node<Type,details::mul_op<Type> > >(v,v1)); 
 35292 |  
 35293 |                            case details::e_div : return expr_gen(details::e_neg, 
 35294 |                                                     expr_gen.node_allocator_-> 
 35295 |                                                        template allocate_rr<typename details:: 
 35296 |                                                           vov_node<Type,details::div_op<Type> > >(v,v1)); 
 35297 |  
 35298 |                            default             : break; 
 35299 |                         } 
 35300 |                      } 
 35301 |                   } 
 35302 |                } 
 35303 |  
 35304 |                switch (operation) 
 35305 |                { 
 35306 |                   #define case_stmt(op0, op1)                                                      \ 
 35307 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35308 |                                 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \ 
 35309 |                                    (v, branch[1]);                                                 \ 
 35310 |  
 35311 |                   basic_opr_switch_statements 
 35312 |                   extended_opr_switch_statements 
 35313 |                   #undef case_stmt 
 35314 |                   default : return error_node(); 
 35315 |                } 
 35316 |             } 
 35317 |          }; 
 35318 |  
 35319 |          struct synthesize_bov_expression 
 35320 |          { 
 35321 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35322 |                                                       const details::operator_type& operation, 
 35323 |                                                       expression_node_ptr (&branch)[2]) 
 35324 |             { 
 35325 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 35326 |  
 35327 |                #ifndef exprtk_disable_enhanced_features 
 35328 |                if (details::is_sf3ext_node(branch[0])) 
 35329 |                { 
 35330 |                   expression_node_ptr result = error_node(); 
 35331 |  
 35332 |                   const bool synthesis_result = 
 35333 |                      synthesize_sf4ext_expression::template compile_left<vtype> 
 35334 |                         (expr_gen, v, operation, branch[0], result); 
 35335 |  
 35336 |                   if (synthesis_result) 
 35337 |                   { 
 35338 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35339 |  
 35340 |                      return result; 
 35341 |                   } 
 35342 |                } 
 35343 |                #endif 
 35344 |  
 35345 |                if ( 
 35346 |                     (details::e_add == operation) || 
 35347 |                     (details::e_sub == operation) || 
 35348 |                     (details::e_mul == operation) || 
 35349 |                     (details::e_div == operation) 
 35350 |                   ) 
 35351 |                { 
 35352 |                   if (details::is_uv_node(branch[0])) 
 35353 |                   { 
 35354 |                      typedef details::uv_base_node<Type>* uvbn_ptr_t; 
 35355 |  
 35356 |                      details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation(); 
 35357 |  
 35358 |                      if (details::e_neg == o) 
 35359 |                      { 
 35360 |                         const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v(); 
 35361 |  
 35362 |                         details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35363 |  
 35364 |                         switch (operation) 
 35365 |                         { 
 35366 |                            case details::e_add : return expr_gen.node_allocator_-> 
 35367 |                                                     template allocate_rr<typename details:: 
 35368 |                                                        vov_node<Type,details::sub_op<Type> > >(v,v0); 
 35369 |  
 35370 |                            case details::e_sub : return expr_gen(details::e_neg, 
 35371 |                                                     expr_gen.node_allocator_-> 
 35372 |                                                        template allocate_rr<typename details:: 
 35373 |                                                           vov_node<Type,details::add_op<Type> > >(v0,v)); 
 35374 |  
 35375 |                            case details::e_mul : return expr_gen(details::e_neg, 
 35376 |                                                     expr_gen.node_allocator_-> 
 35377 |                                                        template allocate_rr<typename details:: 
 35378 |                                                           vov_node<Type,details::mul_op<Type> > >(v0,v)); 
 35379 |  
 35380 |                            case details::e_div : return expr_gen(details::e_neg, 
 35381 |                                                     expr_gen.node_allocator_-> 
 35382 |                                                        template allocate_rr<typename details:: 
 35383 |                                                           vov_node<Type,details::div_op<Type> > >(v0,v)); 
 35384 |                            default : break; 
 35385 |                         } 
 35386 |                      } 
 35387 |                   } 
 35388 |                } 
 35389 |  
 35390 |                switch (operation) 
 35391 |                { 
 35392 |                   #define case_stmt(op0, op1)                                                      \ 
 35393 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35394 |                                 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \ 
 35395 |                                    (branch[0], v);                                                 \ 
 35396 |  
 35397 |                   basic_opr_switch_statements 
 35398 |                   extended_opr_switch_statements 
 35399 |                   #undef case_stmt 
 35400 |                   default : return error_node(); 
 35401 |                } 
 35402 |             } 
 35403 |          }; 
 35404 |  
 35405 |          struct synthesize_cob_expression 
 35406 |          { 
 35407 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35408 |                                                       const details::operator_type& operation, 
 35409 |                                                       expression_node_ptr (&branch)[2]) 
 35410 |             { 
 35411 |                const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 35412 |  
 35413 |                details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35414 |  
 35415 |                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35416 |                { 
 35417 |                   details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35418 |  
 35419 |                   return expr_gen(T(0)); 
 35420 |                } 
 35421 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35422 |                { 
 35423 |                   details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35424 |  
 35425 |                   return expr_gen(T(0)); 
 35426 |                } 
 35427 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35428 |                   return branch[1]; 
 35429 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35430 |                   return branch[1]; 
 35431 |  
 35432 |                if (details::is_cob_node(branch[1])) 
 35433 |                { 
 35434 |                   // Simplify expressions of the form: 
 35435 |                   // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x) 
 35436 |                   // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x 
 35437 |                   if ( 
 35438 |                        (details::e_mul == operation) || 
 35439 |                        (details::e_add == operation) 
 35440 |                      ) 
 35441 |                   { 
 35442 |                      details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35443 |  
 35444 |                      if (operation == cobnode->operation()) 
 35445 |                      { 
 35446 |                         switch (operation) 
 35447 |                         { 
 35448 |                            case details::e_add : cobnode->set_c(c + cobnode->c()); break; 
 35449 |                            case details::e_mul : cobnode->set_c(c * cobnode->c()); break; 
 35450 |                            default             : return error_node(); 
 35451 |                         } 
 35452 |  
 35453 |                         return cobnode; 
 35454 |                      } 
 35455 |                   } 
 35456 |  
 35457 |                   if (operation == details::e_mul) 
 35458 |                   { 
 35459 |                      details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35460 |                      details::operator_type cob_opr = cobnode->operation(); 
 35461 |  
 35462 |                      if ( 
 35463 |                           (details::e_div == cob_opr) || 
 35464 |                           (details::e_mul == cob_opr) 
 35465 |                         ) 
 35466 |                      { 
 35467 |                         switch (cob_opr) 
 35468 |                         { 
 35469 |                            case details::e_div : cobnode->set_c(c * cobnode->c()); break; 
 35470 |                            case details::e_mul : cobnode->set_c(cobnode->c() / c); break; 
 35471 |                            default             : return error_node(); 
 35472 |                         } 
 35473 |  
 35474 |                         return cobnode; 
 35475 |                      } 
 35476 |                   } 
 35477 |                   else if (operation == details::e_div) 
 35478 |                   { 
 35479 |                      details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35480 |                      details::operator_type cob_opr = cobnode->operation(); 
 35481 |  
 35482 |                      if ( 
 35483 |                           (details::e_div == cob_opr) || 
 35484 |                           (details::e_mul == cob_opr) 
 35485 |                         ) 
 35486 |                      { 
 35487 |                         details::expression_node<Type>* new_cobnode = error_node(); 
 35488 |  
 35489 |                         switch (cob_opr) 
 35490 |                         { 
 35491 |                            case details::e_div : new_cobnode = expr_gen.node_allocator_-> 
 35492 |                                                     template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > > 
 35493 |                                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35494 |                                                  break; 
 35495 |  
 35496 |                            case details::e_mul : new_cobnode = expr_gen.node_allocator_-> 
 35497 |                                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35498 |                                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35499 |                                                  break; 
 35500 |  
 35501 |                            default             : return error_node(); 
 35502 |                         } 
 35503 |  
 35504 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35505 |  
 35506 |                         return new_cobnode; 
 35507 |                      } 
 35508 |                   } 
 35509 |                } 
 35510 |                #ifndef exprtk_disable_enhanced_features 
 35511 |                else if (details::is_sf3ext_node(branch[1])) 
 35512 |                { 
 35513 |                   expression_node_ptr result = error_node(); 
 35514 |  
 35515 |                   const bool synthesis_result = 
 35516 |                      synthesize_sf4ext_expression::template compile_right<ctype> 
 35517 |                         (expr_gen, c, operation, branch[1], result); 
 35518 |  
 35519 |                   if (synthesis_result) 
 35520 |                   { 
 35521 |                      details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35522 |  
 35523 |                      return result; 
 35524 |                   } 
 35525 |                } 
 35526 |                #endif 
 35527 |  
 35528 |                switch (operation) 
 35529 |                { 
 35530 |                   #define case_stmt(op0, op1)                                                      \ 
 35531 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35532 |                                 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \ 
 35533 |                                    (c,  branch[1]);                                                \ 
 35534 |  
 35535 |                   basic_opr_switch_statements 
 35536 |                   extended_opr_switch_statements 
 35537 |                   #undef case_stmt 
 35538 |                   default : return error_node(); 
 35539 |                } 
 35540 |             } 
 35541 |          }; 
 35542 |  
 35543 |          struct synthesize_boc_expression 
 35544 |          { 
 35545 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35546 |                                                       const details::operator_type& operation, 
 35547 |                                                       expression_node_ptr (&branch)[2]) 
 35548 |             { 
 35549 |                const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35550 |  
 35551 |                details::free_node(*(expr_gen.node_allocator_), branch[1]); 
 35552 |  
 35553 |                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35554 |                { 
 35555 |                   details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35556 |  
 35557 |                   return expr_gen(T(0)); 
 35558 |                } 
 35559 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35560 |                { 
 35561 |                   details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35562 |  
 35563 |                   return expr_gen(std::numeric_limits<T>::quiet_NaN()); 
 35564 |                } 
 35565 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35566 |                   return branch[0]; 
 35567 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35568 |                   return branch[0]; 
 35569 |  
 35570 |                if (details::is_boc_node(branch[0])) 
 35571 |                { 
 35572 |                   // Simplify expressions of the form: 
 35573 |                   // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320 
 35574 |                   // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45 
 35575 |                   if ( 
 35576 |                        (details::e_mul == operation) || 
 35577 |                        (details::e_add == operation) 
 35578 |                      ) 
 35579 |                   { 
 35580 |                      details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35581 |  
 35582 |                      if (operation == bocnode->operation()) 
 35583 |                      { 
 35584 |                         switch (operation) 
 35585 |                         { 
 35586 |                            case details::e_add : bocnode->set_c(c + bocnode->c()); break; 
 35587 |                            case details::e_mul : bocnode->set_c(c * bocnode->c()); break; 
 35588 |                            default             : return error_node(); 
 35589 |                         } 
 35590 |  
 35591 |                         return bocnode; 
 35592 |                      } 
 35593 |                   } 
 35594 |                   else if (operation == details::e_div) 
 35595 |                   { 
 35596 |                      details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35597 |                      details::operator_type        boc_opr = bocnode->operation(); 
 35598 |  
 35599 |                      if ( 
 35600 |                           (details::e_div == boc_opr) || 
 35601 |                           (details::e_mul == boc_opr) 
 35602 |                         ) 
 35603 |                      { 
 35604 |                         switch (boc_opr) 
 35605 |                         { 
 35606 |                            case details::e_div : bocnode->set_c(c * bocnode->c()); break; 
 35607 |                            case details::e_mul : bocnode->set_c(bocnode->c() / c); break; 
 35608 |                            default             : return error_node(); 
 35609 |                         } 
 35610 |  
 35611 |                         return bocnode; 
 35612 |                      } 
 35613 |                   } 
 35614 |                   else if (operation == details::e_pow) 
 35615 |                   { 
 35616 |                      // (v ^ c0) ^ c1 --> v ^(c0 * c1) 
 35617 |                      details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35618 |                      details::operator_type        boc_opr = bocnode->operation(); 
 35619 |  
 35620 |                      if (details::e_pow == boc_opr) 
 35621 |                      { 
 35622 |                         bocnode->set_c(bocnode->c() * c); 
 35623 |  
 35624 |                         return bocnode; 
 35625 |                      } 
 35626 |                   } 
 35627 |                } 
 35628 |  
 35629 |                #ifndef exprtk_disable_enhanced_features 
 35630 |                if (details::is_sf3ext_node(branch[0])) 
 35631 |                { 
 35632 |                   expression_node_ptr result = error_node(); 
 35633 |  
 35634 |                   const bool synthesis_result = 
 35635 |                      synthesize_sf4ext_expression::template compile_left<ctype> 
 35636 |                         (expr_gen, c, operation, branch[0], result); 
 35637 |  
 35638 |                   if (synthesis_result) 
 35639 |                   { 
 35640 |                      free_node(*expr_gen.node_allocator_, branch[0]); 
 35641 |  
 35642 |                      return result; 
 35643 |                   } 
 35644 |                } 
 35645 |                #endif 
 35646 |  
 35647 |                switch (operation) 
 35648 |                { 
 35649 |                   #define case_stmt(op0, op1)                                                      \ 
 35650 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35651 |                                 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \ 
 35652 |                                    (branch[0], c);                                                 \ 
 35653 |  
 35654 |                   basic_opr_switch_statements 
 35655 |                   extended_opr_switch_statements 
 35656 |                   #undef case_stmt 
 35657 |                   default : return error_node(); 
 35658 |                } 
 35659 |             } 
 35660 |          }; 
 35661 |  
 35662 |          struct synthesize_cocob_expression 
 35663 |          { 
 35664 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35665 |                                                       const details::operator_type& operation, 
 35666 |                                                       expression_node_ptr (&branch)[2]) 
 35667 |             { 
 35668 |                expression_node_ptr result = error_node(); 
 35669 |  
 35670 |                // (cob) o c --> cob 
 35671 |                if (details::is_cob_node(branch[0])) 
 35672 |                { 
 35673 |                   details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]); 
 35674 |  
 35675 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35676 |  
 35677 |                   if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35678 |                   { 
 35679 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35680 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35681 |  
 35682 |                      return expr_gen(T(0)); 
 35683 |                   } 
 35684 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35685 |                   { 
 35686 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35687 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35688 |  
 35689 |                      return expr_gen(T(std::numeric_limits<T>::quiet_NaN())); 
 35690 |                   } 
 35691 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35692 |                   { 
 35693 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35694 |  
 35695 |                      return branch[0]; 
 35696 |                   } 
 35697 |                   else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35698 |                   { 
 35699 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35700 |  
 35701 |                      return branch[0]; 
 35702 |                   } 
 35703 |                   else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation)) 
 35704 |                   { 
 35705 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35706 |  
 35707 |                      return branch[0]; 
 35708 |                   } 
 35709 |  
 35710 |                   const bool op_addsub = (details::e_add == cobnode->operation()) || 
 35711 |                                          (details::e_sub == cobnode->operation()) ; 
 35712 |  
 35713 |                   if (op_addsub) 
 35714 |                   { 
 35715 |                      switch (operation) 
 35716 |                      { 
 35717 |                         case details::e_add : cobnode->set_c(cobnode->c() + c); break; 
 35718 |                         case details::e_sub : cobnode->set_c(cobnode->c() - c); break; 
 35719 |                         default             : return error_node(); 
 35720 |                      } 
 35721 |  
 35722 |                      result = cobnode; 
 35723 |                   } 
 35724 |                   else if (details::e_mul == cobnode->operation()) 
 35725 |                   { 
 35726 |                      switch (operation) 
 35727 |                      { 
 35728 |                         case details::e_mul : cobnode->set_c(cobnode->c() * c); break; 
 35729 |                         case details::e_div : cobnode->set_c(cobnode->c() / c); break; 
 35730 |                         default             : return error_node(); 
 35731 |                      } 
 35732 |  
 35733 |                      result = cobnode; 
 35734 |                   } 
 35735 |                   else if (details::e_div == cobnode->operation()) 
 35736 |                   { 
 35737 |                      if (details::e_mul == operation) 
 35738 |                      { 
 35739 |                         cobnode->set_c(cobnode->c() * c); 
 35740 |                         result = cobnode; 
 35741 |                      } 
 35742 |                      else if (details::e_div == operation) 
 35743 |                      { 
 35744 |                         result = expr_gen.node_allocator_-> 
 35745 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35746 |                                        (cobnode->c() / c, cobnode->move_branch(0)); 
 35747 |  
 35748 |                         details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35749 |                      } 
 35750 |                   } 
 35751 |  
 35752 |                   if (result) 
 35753 |                   { 
 35754 |                      details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35755 |                   } 
 35756 |                } 
 35757 |  
 35758 |                // c o (cob) --> cob 
 35759 |                else if (details::is_cob_node(branch[1])) 
 35760 |                { 
 35761 |                   details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35762 |  
 35763 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 35764 |  
 35765 |                   if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35766 |                   { 
 35767 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35768 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35769 |  
 35770 |                      return expr_gen(T(0)); 
 35771 |                   } 
 35772 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35773 |                   { 
 35774 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35775 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35776 |  
 35777 |                      return expr_gen(T(0)); 
 35778 |                   } 
 35779 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35780 |                   { 
 35781 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35782 |  
 35783 |                      return branch[1]; 
 35784 |                   } 
 35785 |                   else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35786 |                   { 
 35787 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35788 |  
 35789 |                      return branch[1]; 
 35790 |                   } 
 35791 |  
 35792 |                   if (details::e_add == cobnode->operation()) 
 35793 |                   { 
 35794 |                      if (details::e_add == operation) 
 35795 |                      { 
 35796 |                         cobnode->set_c(c + cobnode->c()); 
 35797 |                         result = cobnode; 
 35798 |                      } 
 35799 |                      else if (details::e_sub == operation) 
 35800 |                      { 
 35801 |                         result = expr_gen.node_allocator_-> 
 35802 |                                     template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > > 
 35803 |                                        (c - cobnode->c(), cobnode->move_branch(0)); 
 35804 |  
 35805 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35806 |                      } 
 35807 |                   } 
 35808 |                   else if (details::e_sub == cobnode->operation()) 
 35809 |                   { 
 35810 |                      if (details::e_add == operation) 
 35811 |                      { 
 35812 |                         cobnode->set_c(c + cobnode->c()); 
 35813 |                         result = cobnode; 
 35814 |                      } 
 35815 |                      else if (details::e_sub == operation) 
 35816 |                      { 
 35817 |                         result = expr_gen.node_allocator_-> 
 35818 |                                     template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > > 
 35819 |                                        (c - cobnode->c(), cobnode->move_branch(0)); 
 35820 |  
 35821 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35822 |                      } 
 35823 |                   } 
 35824 |                   else if (details::e_mul == cobnode->operation()) 
 35825 |                   { 
 35826 |                      if (details::e_mul == operation) 
 35827 |                      { 
 35828 |                         cobnode->set_c(c * cobnode->c()); 
 35829 |                         result = cobnode; 
 35830 |                      } 
 35831 |                      else if (details::e_div == operation) 
 35832 |                      { 
 35833 |                         result = expr_gen.node_allocator_-> 
 35834 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35835 |                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35836 |  
 35837 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35838 |                      } 
 35839 |                   } 
 35840 |                   else if (details::e_div == cobnode->operation()) 
 35841 |                   { 
 35842 |                      if (details::e_mul == operation) 
 35843 |                      { 
 35844 |                         cobnode->set_c(c * cobnode->c()); 
 35845 |                         result = cobnode; 
 35846 |                      } 
 35847 |                      else if (details::e_div == operation) 
 35848 |                      { 
 35849 |                         result = expr_gen.node_allocator_-> 
 35850 |                                     template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > > 
 35851 |                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35852 |  
 35853 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35854 |                      } 
 35855 |                   } 
 35856 |  
 35857 |                   if (result) 
 35858 |                   { 
 35859 |                      details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35860 |                   } 
 35861 |                } 
 35862 |  
 35863 |                return result; 
 35864 |             } 
 35865 |          }; 
 35866 |  
 35867 |          struct synthesize_coboc_expression 
 35868 |          { 
 35869 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35870 |                                                       const details::operator_type& operation, 
 35871 |                                                       expression_node_ptr (&branch)[2]) 
 35872 |             { 
 35873 |                expression_node_ptr result = error_node(); 
 35874 |  
 35875 |                // (boc) o c --> boc 
 35876 |                if (details::is_boc_node(branch[0])) 
 35877 |                { 
 35878 |                   details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35879 |  
 35880 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35881 |  
 35882 |                   if (details::e_add == bocnode->operation()) 
 35883 |                   { 
 35884 |                      switch (operation) 
 35885 |                      { 
 35886 |                         case details::e_add : bocnode->set_c(bocnode->c() + c); break; 
 35887 |                         case details::e_sub : bocnode->set_c(bocnode->c() - c); break; 
 35888 |                         default             : return error_node(); 
 35889 |                      } 
 35890 |  
 35891 |                      result = bocnode; 
 35892 |                   } 
 35893 |                   else if (details::e_mul == bocnode->operation()) 
 35894 |                   { 
 35895 |                      switch (operation) 
 35896 |                      { 
 35897 |                         case details::e_mul : bocnode->set_c(bocnode->c() * c); break; 
 35898 |                         case details::e_div : bocnode->set_c(bocnode->c() / c); break; 
 35899 |                         default             : return error_node(); 
 35900 |                      } 
 35901 |  
 35902 |                      result = bocnode; 
 35903 |                   } 
 35904 |                   else if (details::e_sub == bocnode->operation()) 
 35905 |                   { 
 35906 |                      if (details::e_add == operation) 
 35907 |                      { 
 35908 |                         result = expr_gen.node_allocator_-> 
 35909 |                                     template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > > 
 35910 |                                        (bocnode->move_branch(0), c - bocnode->c()); 
 35911 |  
 35912 |                         details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35913 |                      } 
 35914 |                      else if (details::e_sub == operation) 
 35915 |                      { 
 35916 |                         bocnode->set_c(bocnode->c() + c); 
 35917 |                         result = bocnode; 
 35918 |                      } 
 35919 |                   } 
 35920 |                   else if (details::e_div == bocnode->operation()) 
 35921 |                   { 
 35922 |                      switch (operation) 
 35923 |                      { 
 35924 |                         case details::e_div : bocnode->set_c(bocnode->c() * c); break; 
 35925 |                         case details::e_mul : bocnode->set_c(bocnode->c() / c); break; 
 35926 |                         default             : return error_node(); 
 35927 |                      } 
 35928 |  
 35929 |                      result = bocnode; 
 35930 |                   } 
 35931 |  
 35932 |                   if (result) 
 35933 |                   { 
 35934 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35935 |                   } 
 35936 |                } 
 35937 |  
 35938 |                // c o (boc) --> boc 
 35939 |                else if (details::is_boc_node(branch[1])) 
 35940 |                { 
 35941 |                   details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]); 
 35942 |  
 35943 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 35944 |  
 35945 |                   if (details::e_add == bocnode->operation()) 
 35946 |                   { 
 35947 |                      if (details::e_add == operation) 
 35948 |                      { 
 35949 |                         bocnode->set_c(c + bocnode->c()); 
 35950 |                         result = bocnode; 
 35951 |                      } 
 35952 |                      else if (details::e_sub == operation) 
 35953 |                      { 
 35954 |                         result = expr_gen.node_allocator_-> 
 35955 |                                     template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > > 
 35956 |                                        (c - bocnode->c(), bocnode->move_branch(0)); 
 35957 |  
 35958 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35959 |                      } 
 35960 |                   } 
 35961 |                   else if (details::e_sub == bocnode->operation()) 
 35962 |                   { 
 35963 |                      if (details::e_add == operation) 
 35964 |                      { 
 35965 |                         result = expr_gen.node_allocator_-> 
 35966 |                                     template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > > 
 35967 |                                        (bocnode->move_branch(0), c - bocnode->c()); 
 35968 |  
 35969 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35970 |                      } 
 35971 |                      else if (details::e_sub == operation) 
 35972 |                      { 
 35973 |                         result = expr_gen.node_allocator_-> 
 35974 |                                     template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > > 
 35975 |                                        (c + bocnode->c(), bocnode->move_branch(0)); 
 35976 |  
 35977 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35978 |                      } 
 35979 |                   } 
 35980 |                   else if (details::e_mul == bocnode->operation()) 
 35981 |                   { 
 35982 |                      if (details::e_mul == operation) 
 35983 |                      { 
 35984 |                         bocnode->set_c(c * bocnode->c()); 
 35985 |                         result = bocnode; 
 35986 |                      } 
 35987 |                      else if (details::e_div == operation) 
 35988 |                      { 
 35989 |                         result = expr_gen.node_allocator_-> 
 35990 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35991 |                                        (c / bocnode->c(), bocnode->move_branch(0)); 
 35992 |  
 35993 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35994 |                      } 
 35995 |                   } 
 35996 |                   else if (details::e_div == bocnode->operation()) 
 35997 |                   { 
 35998 |                      if (details::e_mul == operation) 
 35999 |                      { 
 36000 |                         bocnode->set_c(bocnode->c() / c); 
 36001 |                         result = bocnode; 
 36002 |                      } 
 36003 |                      else if (details::e_div == operation) 
 36004 |                      { 
 36005 |                         result = expr_gen.node_allocator_-> 
 36006 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 36007 |                                        (c * bocnode->c(), bocnode->move_branch(0)); 
 36008 |  
 36009 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 36010 |                      } 
 36011 |                   } 
 36012 |  
 36013 |                   if (result) 
 36014 |                   { 
 36015 |                      details::free_node(*expr_gen.node_allocator_,branch[0]); 
 36016 |                   } 
 36017 |                } 
 36018 |  
 36019 |                return result; 
 36020 |             } 
 36021 |          }; 
 36022 |  
 36023 |          #ifndef exprtk_disable_enhanced_features 
 36024 |          inline bool synthesize_expression(const details::operator_type& operation, 
 36025 |                                            expression_node_ptr (&branch)[2], 
 36026 |                                            expression_node_ptr& result) 
 36027 |          { 
 36028 |             result = error_node(); 
 36029 |  
 36030 |             if (!operation_optimisable(operation)) 
 36031 |                return false; 
 36032 |  
 36033 |             const std::string node_id = branch_to_id(branch); 
 36034 |  
 36035 |             const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id); 
 36036 |  
 36037 |             if (synthesize_map_.end() != itr) 
 36038 |             { 
 36039 |                result = itr->second((*this), operation, branch); 
 36040 |  
 36041 |                return true; 
 36042 |             } 
 36043 |             else 
 36044 |                return false; 
 36045 |          } 
 36046 |  
 36047 |          struct synthesize_vov_expression 
 36048 |          { 
 36049 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36050 |                                                       const details::operator_type& operation, 
 36051 |                                                       expression_node_ptr (&branch)[2]) 
 36052 |             { 
 36053 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36054 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 36055 |  
 36056 |                switch (operation) 
 36057 |                { 
 36058 |                   #define case_stmt(op0, op1)                                                      \ 
 36059 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 36060 |                                 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \ 
 36061 |                                    (v1, v2);                                                       \ 
 36062 |  
 36063 |                   basic_opr_switch_statements 
 36064 |                   extended_opr_switch_statements 
 36065 |                   #undef case_stmt 
 36066 |                   default : return error_node(); 
 36067 |                } 
 36068 |             } 
 36069 |          }; 
 36070 |  
 36071 |          struct synthesize_cov_expression 
 36072 |          { 
 36073 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36074 |                                                       const details::operator_type& operation, 
 36075 |                                                       expression_node_ptr (&branch)[2]) 
 36076 |             { 
 36077 |                const Type  c = static_cast<details::literal_node<Type>*> (branch[0])->value(); 
 36078 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref  (); 
 36079 |  
 36080 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36081 |  
 36082 |                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 36083 |                   return expr_gen(T(0)); 
 36084 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 36085 |                   return expr_gen(T(0)); 
 36086 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 36087 |                   return static_cast<details::variable_node<Type>*>(branch[1]); 
 36088 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 36089 |                   return static_cast<details::variable_node<Type>*>(branch[1]); 
 36090 |  
 36091 |                switch (operation) 
 36092 |                { 
 36093 |                   #define case_stmt(op0, op1)                                                      \ 
 36094 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 36095 |                                 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \ 
 36096 |                                    (c, v);                                                         \ 
 36097 |  
 36098 |                   basic_opr_switch_statements 
 36099 |                   extended_opr_switch_statements 
 36100 |                   #undef case_stmt 
 36101 |                   default : return error_node(); 
 36102 |                } 
 36103 |             } 
 36104 |          }; 
 36105 |  
 36106 |          struct synthesize_voc_expression 
 36107 |          { 
 36108 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36109 |                                                       const details::operator_type& operation, 
 36110 |                                                       expression_node_ptr (&branch)[2]) 
 36111 |             { 
 36112 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref  (); 
 36113 |                const Type  c = static_cast<details::literal_node<Type>*> (branch[1])->value(); 
 36114 |  
 36115 |                details::free_node(*(expr_gen.node_allocator_), branch[1]); 
 36116 |  
 36117 |                if (expr_gen.cardinal_pow_optimisable(operation,c)) 
 36118 |                { 
 36119 |                   if (std::equal_to<T>()(T(1),c)) 
 36120 |                      return branch[0]; 
 36121 |                   else 
 36122 |                      return expr_gen.cardinal_pow_optimisation(v,c); 
 36123 |                } 
 36124 |                else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 36125 |                   return expr_gen(T(0)); 
 36126 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 36127 |                   return expr_gen(std::numeric_limits<T>::quiet_NaN()); 
 36128 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 36129 |                   return static_cast<details::variable_node<Type>*>(branch[0]); 
 36130 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 36131 |                   return static_cast<details::variable_node<Type>*>(branch[0]); 
 36132 |                else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation)) 
 36133 |                   return static_cast<details::variable_node<Type>*>(branch[0]); 
 36134 |  
 36135 |                switch (operation) 
 36136 |                { 
 36137 |                   #define case_stmt(op0, op1)                                                      \ 
 36138 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 36139 |                                 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \ 
 36140 |                                    (v, c);                                                         \ 
 36141 |  
 36142 |                   basic_opr_switch_statements 
 36143 |                   extended_opr_switch_statements 
 36144 |                   #undef case_stmt 
 36145 |                   default : return error_node(); 
 36146 |                } 
 36147 |             } 
 36148 |          }; 
 36149 |  
 36150 |          struct synthesize_sf3ext_expression 
 36151 |          { 
 36152 |             template <typename T0, typename T1, typename T2> 
 36153 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36154 |                                                       const details::operator_type& sf3opr, 
 36155 |                                                       T0 t0, T1 t1, T2 t2) 
 36156 |             { 
 36157 |                switch (sf3opr) 
 36158 |                { 
 36159 |                   #define case_stmt(op)                                                                              \ 
 36160 |                   case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \ 
 36161 |                                 allocate(*(expr_gen.node_allocator_), t0, t1, t2);                                   \ 
 36162 |  
 36163 |                   case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 36164 |                   case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 36165 |                   case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 36166 |                   case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 36167 |                   case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 36168 |                   case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 36169 |                   case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 36170 |                   case_stmt(28) case_stmt(29) case_stmt(30) 
 36171 |                   #undef case_stmt 
 36172 |                   default : return error_node(); 
 36173 |                } 
 36174 |             } 
 36175 |  
 36176 |             template <typename T0, typename T1, typename T2> 
 36177 |             static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id, 
 36178 |                                        T0 t0, T1 t1, T2 t2, 
 36179 |                                        expression_node_ptr& result) 
 36180 |             { 
 36181 |                details::operator_type sf3opr; 
 36182 |  
 36183 |                if (!expr_gen.sf3_optimisable(id,sf3opr)) 
 36184 |                   return false; 
 36185 |                else 
 36186 |                   result = synthesize_sf3ext_expression::template process<T0, T1, T2> 
 36187 |                               (expr_gen, sf3opr, t0, t1, t2); 
 36188 |  
 36189 |                return true; 
 36190 |             } 
 36191 |          }; 
 36192 |  
 36193 |          struct synthesize_sf4ext_expression 
 36194 |          { 
 36195 |             template <typename T0, typename T1, typename T2, typename T3> 
 36196 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36197 |                                                       const details::operator_type& sf4opr, 
 36198 |                                                       T0 t0, T1 t1, T2 t2, T3 t3) 
 36199 |             { 
 36200 |                switch (sf4opr) 
 36201 |                { 
 36202 |                   #define case_stmt0(op)                                                                                      \ 
 36203 |                   case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \ 
 36204 |                                 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3);                                        \ 
 36205 |  
 36206 |                   #define case_stmt1(op)                                                                                             \ 
 36207 |                   case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \ 
 36208 |                                 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3);                                               \ 
 36209 |  
 36210 |                   case_stmt0(48) case_stmt0(49) case_stmt0(50) case_stmt0(51) 
 36211 |                   case_stmt0(52) case_stmt0(53) case_stmt0(54) case_stmt0(55) 
 36212 |                   case_stmt0(56) case_stmt0(57) case_stmt0(58) case_stmt0(59) 
 36213 |                   case_stmt0(60) case_stmt0(61) case_stmt0(62) case_stmt0(63) 
 36214 |                   case_stmt0(64) case_stmt0(65) case_stmt0(66) case_stmt0(67) 
 36215 |                   case_stmt0(68) case_stmt0(69) case_stmt0(70) case_stmt0(71) 
 36216 |                   case_stmt0(72) case_stmt0(73) case_stmt0(74) case_stmt0(75) 
 36217 |                   case_stmt0(76) case_stmt0(77) case_stmt0(78) case_stmt0(79) 
 36218 |                   case_stmt0(80) case_stmt0(81) case_stmt0(82) case_stmt0(83) 
 36219 |  
 36220 |                   case_stmt1(00) case_stmt1(01) case_stmt1(02) case_stmt1(03) 
 36221 |                   case_stmt1(04) case_stmt1(05) case_stmt1(06) case_stmt1(07) 
 36222 |                   case_stmt1(08) case_stmt1(09) case_stmt1(10) case_stmt1(11) 
 36223 |                   case_stmt1(12) case_stmt1(13) case_stmt1(14) case_stmt1(15) 
 36224 |                   case_stmt1(16) case_stmt1(17) case_stmt1(18) case_stmt1(19) 
 36225 |                   case_stmt1(20) case_stmt1(21) case_stmt1(22) case_stmt1(23) 
 36226 |                   case_stmt1(24) case_stmt1(25) case_stmt1(26) case_stmt1(27) 
 36227 |                   case_stmt1(28) case_stmt1(29) case_stmt1(30) case_stmt1(31) 
 36228 |                   case_stmt1(32) case_stmt1(33) case_stmt1(34) case_stmt1(35) 
 36229 |                   case_stmt1(36) case_stmt1(37) case_stmt1(38) case_stmt1(39) 
 36230 |                   case_stmt1(40) case_stmt1(41) case_stmt1(42) case_stmt1(43) 
 36231 |                   case_stmt1(44) case_stmt1(45) case_stmt1(46) case_stmt1(47) 
 36232 |                   case_stmt1(48) case_stmt1(49) case_stmt1(50) case_stmt1(51) 
 36233 |                   case_stmt1(52) case_stmt1(53) case_stmt1(54) case_stmt1(55) 
 36234 |                   case_stmt1(56) case_stmt1(57) case_stmt1(58) case_stmt1(59) 
 36235 |                   case_stmt1(60) case_stmt1(61) 
 36236 |  
 36237 |                   #undef case_stmt0 
 36238 |                   #undef case_stmt1 
 36239 |                   default : return error_node(); 
 36240 |                } 
 36241 |             } 
 36242 |  
 36243 |             template <typename T0, typename T1, typename T2, typename T3> 
 36244 |             static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id, 
 36245 |                                        T0 t0, T1 t1, T2 t2, T3 t3, 
 36246 |                                        expression_node_ptr& result) 
 36247 |             { 
 36248 |                details::operator_type sf4opr; 
 36249 |  
 36250 |                if (!expr_gen.sf4_optimisable(id,sf4opr)) 
 36251 |                   return false; 
 36252 |                else 
 36253 |                   result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3> 
 36254 |                               (expr_gen, sf4opr, t0, t1, t2, t3); 
 36255 |  
 36256 |                return true; 
 36257 |             } 
 36258 |  
 36259 |             // T o (sf3ext) 
 36260 |             template <typename ExternalType> 
 36261 |             static inline bool compile_right(expression_generator<Type>& expr_gen, 
 36262 |                                              ExternalType t, 
 36263 |                                              const details::operator_type& operation, 
 36264 |                                              expression_node_ptr& sf3node, 
 36265 |                                              expression_node_ptr& result) 
 36266 |             { 
 36267 |                if (!details::is_sf3ext_node(sf3node)) 
 36268 |                   return false; 
 36269 |  
 36270 |                typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr; 
 36271 |  
 36272 |                sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node); 
 36273 |                const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")" 
 36274 |  
 36275 |                switch (n->type()) 
 36276 |                { 
 36277 |                   case details::expression_node<Type>::e_covoc : return compile_right_impl 
 36278 |                                                                     <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype> 
 36279 |                                                                        (expr_gen, id, t, sf3node, result); 
 36280 |  
 36281 |                   case details::expression_node<Type>::e_covov : return compile_right_impl 
 36282 |                                                                     <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype> 
 36283 |                                                                        (expr_gen, id, t, sf3node, result); 
 36284 |  
 36285 |                   case details::expression_node<Type>::e_vocov : return compile_right_impl 
 36286 |                                                                     <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype> 
 36287 |                                                                        (expr_gen, id, t, sf3node, result); 
 36288 |  
 36289 |                   case details::expression_node<Type>::e_vovoc : return compile_right_impl 
 36290 |                                                                     <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype> 
 36291 |                                                                        (expr_gen, id, t, sf3node, result); 
 36292 |  
 36293 |                   case details::expression_node<Type>::e_vovov : return compile_right_impl 
 36294 |                                                                     <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype> 
 36295 |                                                                        (expr_gen, id, t, sf3node, result); 
 36296 |  
 36297 |                   default                                      : return false; 
 36298 |                } 
 36299 |             } 
 36300 |  
 36301 |             // (sf3ext) o T 
 36302 |             template <typename ExternalType> 
 36303 |             static inline bool compile_left(expression_generator<Type>& expr_gen, 
 36304 |                                             ExternalType t, 
 36305 |                                             const details::operator_type& operation, 
 36306 |                                             expression_node_ptr& sf3node, 
 36307 |                                             expression_node_ptr& result) 
 36308 |             { 
 36309 |                if (!details::is_sf3ext_node(sf3node)) 
 36310 |                   return false; 
 36311 |  
 36312 |                typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr; 
 36313 |  
 36314 |                sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node); 
 36315 |  
 36316 |                const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t" 
 36317 |  
 36318 |                switch (n->type()) 
 36319 |                { 
 36320 |                   case details::expression_node<Type>::e_covoc : return compile_left_impl 
 36321 |                                                                     <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype> 
 36322 |                                                                        (expr_gen, id, t, sf3node, result); 
 36323 |  
 36324 |                   case details::expression_node<Type>::e_covov : return compile_left_impl 
 36325 |                                                                     <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype> 
 36326 |                                                                        (expr_gen, id, t, sf3node, result); 
 36327 |  
 36328 |                   case details::expression_node<Type>::e_vocov : return compile_left_impl 
 36329 |                                                                     <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype> 
 36330 |                                                                        (expr_gen, id, t, sf3node, result); 
 36331 |  
 36332 |                   case details::expression_node<Type>::e_vovoc : return compile_left_impl 
 36333 |                                                                     <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype> 
 36334 |                                                                        (expr_gen, id, t, sf3node, result); 
 36335 |  
 36336 |                   case details::expression_node<Type>::e_vovov : return compile_left_impl 
 36337 |                                                                     <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype> 
 36338 |                                                                        (expr_gen, id, t, sf3node, result); 
 36339 |  
 36340 |                   default                                      : return false; 
 36341 |                } 
 36342 |             } 
 36343 |  
 36344 |             template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2> 
 36345 |             static inline bool compile_right_impl(expression_generator<Type>& expr_gen, 
 36346 |                                                   const std::string& id, 
 36347 |                                                   ExternalType t, 
 36348 |                                                   expression_node_ptr& node, 
 36349 |                                                   expression_node_ptr& result) 
 36350 |             { 
 36351 |                SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node); 
 36352 |  
 36353 |                if (n) 
 36354 |                { 
 36355 |                   T0 t0 = n->t0(); 
 36356 |                   T1 t1 = n->t1(); 
 36357 |                   T2 t2 = n->t2(); 
 36358 |  
 36359 |                   return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2> 
 36360 |                             (expr_gen, id, t, t0, t1, t2, result); 
 36361 |                } 
 36362 |                else 
 36363 |                   return false; 
 36364 |             } 
 36365 |  
 36366 |             template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2> 
 36367 |             static inline bool compile_left_impl(expression_generator<Type>& expr_gen, 
 36368 |                                                  const std::string& id, 
 36369 |                                                  ExternalType t, 
 36370 |                                                  expression_node_ptr& node, 
 36371 |                                                  expression_node_ptr& result) 
 36372 |             { 
 36373 |                SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node); 
 36374 |  
 36375 |                if (n) 
 36376 |                { 
 36377 |                   T0 t0 = n->t0(); 
 36378 |                   T1 t1 = n->t1(); 
 36379 |                   T2 t2 = n->t2(); 
 36380 |  
 36381 |                   return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType> 
 36382 |                             (expr_gen, id, t0, t1, t2, t, result); 
 36383 |                } 
 36384 |                else 
 36385 |                   return false; 
 36386 |             } 
 36387 |          }; 
 36388 |  
 36389 |          struct synthesize_vovov_expression0 
 36390 |          { 
 36391 |             typedef typename vovov_t::type0 node_type; 
 36392 |             typedef typename vovov_t::sf3_type sf3_type; 
 36393 |  
 36394 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36395 |                                                       const details::operator_type& operation, 
 36396 |                                                       expression_node_ptr (&branch)[2]) 
 36397 |             { 
 36398 |                // (v0 o0 v1) o1 (v2) 
 36399 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 36400 |                const Type& v0 = vov->v0(); 
 36401 |                const Type& v1 = vov->v1(); 
 36402 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 36403 |                const details::operator_type o0 = vov->operation(); 
 36404 |                const details::operator_type o1 = operation; 
 36405 |  
 36406 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36407 |  
 36408 |                expression_node_ptr result = error_node(); 
 36409 |  
 36410 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36411 |                { 
 36412 |                   // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2) 
 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, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result); 
 36418 |  
 36419 |                      exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\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, vtype> 
 36427 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, 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, v2, 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_vovov_expression1 
 36455 |          { 
 36456 |             typedef typename vovov_t::type1 node_type; 
 36457 |             typedef typename vovov_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 v2) 
 36464 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 36465 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36466 |                const Type& v1 = vov->v0(); 
 36467 |                const Type& v2 = vov->v1(); 
 36468 |                const details::operator_type o0 = operation; 
 36469 |                const details::operator_type o1 = vov->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 / v2) --> (vovov) (v0 * v2) / 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, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result); 
 36483 |  
 36484 |                      exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / 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, vtype> 
 36492 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, 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, v2, 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_vovoc_expression0 
 36520 |          { 
 36521 |             typedef typename vovoc_t::type0 node_type; 
 36522 |             typedef typename vovoc_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 v1) o1 (c) 
 36529 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 36530 |                const Type& v0 = vov->v0(); 
 36531 |                const Type& v1 = vov->v1(); 
 36532 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 36533 |                const details::operator_type o0 = vov->operation(); 
 36534 |                const details::operator_type o1 = operation; 
 36535 |  
 36536 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36537 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36538 |  
 36539 |                expression_node_ptr result = error_node(); 
 36540 |  
 36541 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36542 |                { 
 36543 |                   // (v0 / v1) / c --> (vovoc) v0 / (v1 * c) 
 36544 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36545 |                   { 
 36546 |                      const bool synthesis_result = 
 36547 |                         synthesize_sf3ext_expression:: 
 36548 |                            template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result); 
 36549 |  
 36550 |                      exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n")); 
 36551 |  
 36552 |                      return (synthesis_result) ? result : error_node(); 
 36553 |                   } 
 36554 |                } 
 36555 |  
 36556 |                const bool synthesis_result = 
 36557 |                   synthesize_sf3ext_expression::template compile<vtype, vtype, ctype> 
 36558 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result); 
 36559 |  
 36560 |                if (synthesis_result) 
 36561 |                   return result; 
 36562 |  
 36563 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36564 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36565 |  
 36566 |                if (!expr_gen.valid_operator(o0,f0)) 
 36567 |                   return error_node(); 
 36568 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36569 |                   return error_node(); 
 36570 |                else 
 36571 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1); 
 36572 |             } 
 36573 |  
 36574 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36575 |                                          const details::operator_type o0, 
 36576 |                                          const details::operator_type o1) 
 36577 |             { 
 36578 |                return details::build_string() 
 36579 |                   << "(t" << expr_gen.to_str(o0) 
 36580 |                   << "t)" << expr_gen.to_str(o1) 
 36581 |                   << "t" 
 36582 |             } 
 36583 |          }; 
 36584 |  
 36585 |          struct synthesize_vovoc_expression1 
 36586 |          { 
 36587 |             typedef typename vovoc_t::type1 node_type; 
 36588 |             typedef typename vovoc_t::sf3_type sf3_type; 
 36589 |  
 36590 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36591 |                                                       const details::operator_type& operation, 
 36592 |                                                       expression_node_ptr (&branch)[2]) 
 36593 |             { 
 36594 |                // (v0) o0 (v1 o1 c) 
 36595 |                const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]); 
 36596 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36597 |                const Type& v1 = voc->v(); 
 36598 |                const Type   c = voc->c(); 
 36599 |                const details::operator_type o0 = operation; 
 36600 |                const details::operator_type o1 = voc->operation(); 
 36601 |  
 36602 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36603 |  
 36604 |                expression_node_ptr result = error_node(); 
 36605 |  
 36606 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36607 |                { 
 36608 |                   // v0 / (v1 / c) --> (vocov) (v0 * c) / v1 
 36609 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36610 |                   { 
 36611 |                      const bool synthesis_result = 
 36612 |                         synthesize_sf3ext_expression:: 
 36613 |                            template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result); 
 36614 |  
 36615 |                      exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n")); 
 36616 |  
 36617 |                      return (synthesis_result) ? result : error_node(); 
 36618 |                   } 
 36619 |                } 
 36620 |  
 36621 |                const bool synthesis_result = 
 36622 |                   synthesize_sf3ext_expression::template compile<vtype, vtype, ctype> 
 36623 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result); 
 36624 |  
 36625 |                if (synthesis_result) 
 36626 |                   return result; 
 36627 |  
 36628 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36629 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36630 |  
 36631 |                if (!expr_gen.valid_operator(o0,f0)) 
 36632 |                   return error_node(); 
 36633 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36634 |                   return error_node(); 
 36635 |                else 
 36636 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1); 
 36637 |             } 
 36638 |  
 36639 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36640 |                                          const details::operator_type o0, 
 36641 |                                          const details::operator_type o1) 
 36642 |             { 
 36643 |                return details::build_string() 
 36644 |                   << "t"  << expr_gen.to_str(o0) 
 36645 |                   << "(t" << expr_gen.to_str(o1) 
 36646 |                   << "t)" 
 36647 |             } 
 36648 |          }; 
 36649 |  
 36650 |          struct synthesize_vocov_expression0 
 36651 |          { 
 36652 |             typedef typename vocov_t::type0 node_type; 
 36653 |             typedef typename vocov_t::sf3_type sf3_type; 
 36654 |  
 36655 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36656 |                                                       const details::operator_type& operation, 
 36657 |                                                       expression_node_ptr (&branch)[2]) 
 36658 |             { 
 36659 |                // (v0 o0 c) o1 (v1) 
 36660 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 36661 |                const Type& v0 = voc->v(); 
 36662 |                const Type   c = voc->c(); 
 36663 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 36664 |                const details::operator_type o0 = voc->operation(); 
 36665 |                const details::operator_type o1 = operation; 
 36666 |  
 36667 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36668 |  
 36669 |                expression_node_ptr result = error_node(); 
 36670 |  
 36671 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36672 |                { 
 36673 |                   // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c) 
 36674 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36675 |                   { 
 36676 |                      const bool synthesis_result = 
 36677 |                         synthesize_sf3ext_expression:: 
 36678 |                            template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result); 
 36679 |  
 36680 |                      exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n")); 
 36681 |  
 36682 |                      return (synthesis_result) ? result : error_node(); 
 36683 |                   } 
 36684 |                } 
 36685 |  
 36686 |                const bool synthesis_result = 
 36687 |                   synthesize_sf3ext_expression::template compile<vtype, ctype, vtype> 
 36688 |                      (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result); 
 36689 |  
 36690 |                if (synthesis_result) 
 36691 |                   return result; 
 36692 |  
 36693 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36694 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36695 |  
 36696 |                if (!expr_gen.valid_operator(o0,f0)) 
 36697 |                   return error_node(); 
 36698 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36699 |                   return error_node(); 
 36700 |                else 
 36701 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1); 
 36702 |             } 
 36703 |  
 36704 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36705 |                                          const details::operator_type o0, 
 36706 |                                          const details::operator_type o1) 
 36707 |             { 
 36708 |                return details::build_string() 
 36709 |                   << "(t" << expr_gen.to_str(o0) 
 36710 |                   << "t)" << expr_gen.to_str(o1) 
 36711 |                   << "t" 
 36712 |             } 
 36713 |          }; 
 36714 |  
 36715 |          struct synthesize_vocov_expression1 
 36716 |          { 
 36717 |             typedef typename vocov_t::type1 node_type; 
 36718 |             typedef typename vocov_t::sf3_type sf3_type; 
 36719 |  
 36720 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36721 |                                                       const details::operator_type& operation, 
 36722 |                                                       expression_node_ptr (&branch)[2]) 
 36723 |             { 
 36724 |                // (v0) o0 (c o1 v1) 
 36725 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 36726 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36727 |                const Type   c = cov->c(); 
 36728 |                const Type& v1 = cov->v(); 
 36729 |                const details::operator_type o0 = operation; 
 36730 |                const details::operator_type o1 = cov->operation(); 
 36731 |  
 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 |                   // v0 / (c / v1) --> (vovoc) (v0 * v1) / c 
 36739 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36740 |                   { 
 36741 |                      const bool synthesis_result = 
 36742 |                         synthesize_sf3ext_expression:: 
 36743 |                            template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result); 
 36744 |  
 36745 |                      exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n")); 
 36746 |  
 36747 |                      return (synthesis_result) ? result : error_node(); 
 36748 |                   } 
 36749 |                } 
 36750 |  
 36751 |                const bool synthesis_result = 
 36752 |                   synthesize_sf3ext_expression::template compile<vtype, ctype, vtype> 
 36753 |                      (expr_gen, id(expr_gen, o0, o1), v0, c, 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_), v0, c, 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_covov_expression0 
 36781 |          { 
 36782 |             typedef typename covov_t::type0 node_type; 
 36783 |             typedef typename covov_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 |                // (c o0 v0) o1 (v1) 
 36790 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 36791 |                const Type   c = cov->c(); 
 36792 |                const Type& v0 = cov->v(); 
 36793 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 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 |  
 36799 |                expression_node_ptr result = error_node(); 
 36800 |  
 36801 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36802 |                { 
 36803 |                   // (c / v0) / v1 --> (covov) c / (v0 * v1) 
 36804 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36805 |                   { 
 36806 |                      const bool synthesis_result = 
 36807 |                         synthesize_sf3ext_expression:: 
 36808 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result); 
 36809 |  
 36810 |                      exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n")); 
 36811 |  
 36812 |                      return (synthesis_result) ? result : error_node(); 
 36813 |                   } 
 36814 |                } 
 36815 |  
 36816 |                const bool synthesis_result = 
 36817 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, vtype> 
 36818 |                      (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result); 
 36819 |  
 36820 |                if (synthesis_result) 
 36821 |                   return result; 
 36822 |  
 36823 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36824 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36825 |  
 36826 |                if (!expr_gen.valid_operator(o0,f0)) 
 36827 |                   return error_node(); 
 36828 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36829 |                   return error_node(); 
 36830 |                else 
 36831 |                   return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1); 
 36832 |             } 
 36833 |  
 36834 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36835 |                                          const details::operator_type o0, 
 36836 |                                          const details::operator_type o1) 
 36837 |             { 
 36838 |                return details::build_string() 
 36839 |                   << "(t" << expr_gen.to_str(o0) 
 36840 |                   << "t)" << expr_gen.to_str(o1) 
 36841 |                   << "t" 
 36842 |             } 
 36843 |          }; 
 36844 |  
 36845 |          struct synthesize_covov_expression1 
 36846 |          { 
 36847 |             typedef typename covov_t::type1 node_type; 
 36848 |             typedef typename covov_t::sf3_type sf3_type; 
 36849 |  
 36850 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36851 |                                                       const details::operator_type& operation, 
 36852 |                                                       expression_node_ptr (&branch)[2]) 
 36853 |             { 
 36854 |                // (c) o0 (v0 o1 v1) 
 36855 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 36856 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 36857 |                const Type& v0 = vov->v0(); 
 36858 |                const Type& v1 = vov->v1(); 
 36859 |                const details::operator_type o0 = operation; 
 36860 |                const details::operator_type o1 = vov->operation(); 
 36861 |  
 36862 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36863 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36864 |  
 36865 |                expression_node_ptr result = error_node(); 
 36866 |  
 36867 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36868 |                { 
 36869 |                   // c / (v0 / v1) --> (covov) (c * v1) / v0 
 36870 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36871 |                   { 
 36872 |                      const bool synthesis_result = 
 36873 |                         synthesize_sf3ext_expression:: 
 36874 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result); 
 36875 |  
 36876 |                      exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n")); 
 36877 |  
 36878 |                      return (synthesis_result) ? result : error_node(); 
 36879 |                   } 
 36880 |                } 
 36881 |  
 36882 |                const bool synthesis_result = 
 36883 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, vtype> 
 36884 |                      (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result); 
 36885 |  
 36886 |                if (synthesis_result) 
 36887 |                   return result; 
 36888 |  
 36889 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36890 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36891 |  
 36892 |                if (!expr_gen.valid_operator(o0,f0)) 
 36893 |                   return error_node(); 
 36894 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36895 |                   return error_node(); 
 36896 |                else 
 36897 |                   return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1); 
 36898 |             } 
 36899 |  
 36900 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36901 |                                          const details::operator_type o0, 
 36902 |                                          const details::operator_type o1) 
 36903 |             { 
 36904 |                return details::build_string() 
 36905 |                   << "t"  << expr_gen.to_str(o0) 
 36906 |                   << "(t" << expr_gen.to_str(o1) 
 36907 |                   << "t)" 
 36908 |             } 
 36909 |          }; 
 36910 |  
 36911 |          struct synthesize_covoc_expression0 
 36912 |          { 
 36913 |             typedef typename covoc_t::type0 node_type; 
 36914 |             typedef typename covoc_t::sf3_type sf3_type; 
 36915 |  
 36916 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36917 |                                                       const details::operator_type& operation, 
 36918 |                                                       expression_node_ptr (&branch)[2]) 
 36919 |             { 
 36920 |                // (c0 o0 v) o1 (c1) 
 36921 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 36922 |                const Type  c0 = cov->c(); 
 36923 |                const Type&  v = cov->v(); 
 36924 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 36925 |                const details::operator_type o0 = cov->operation(); 
 36926 |                const details::operator_type o1 = operation; 
 36927 |  
 36928 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36929 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36930 |  
 36931 |                expression_node_ptr result = error_node(); 
 36932 |  
 36933 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36934 |                { 
 36935 |                   // (c0 + v) + c1 --> (cov) (c0 + c1) + v 
 36936 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 36937 |                   { 
 36938 |                      exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n")); 
 36939 |  
 36940 |                      return expr_gen.node_allocator_-> 
 36941 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v); 
 36942 |                   } 
 36943 |                   // (c0 + v) - c1 --> (cov) (c0 - c1) + v 
 36944 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 36945 |                   { 
 36946 |                      exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n")); 
 36947 |  
 36948 |                      return expr_gen.node_allocator_-> 
 36949 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v); 
 36950 |                   } 
 36951 |                   // (c0 - v) + c1 --> (cov) (c0 + c1) - v 
 36952 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 36953 |                   { 
 36954 |                      exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n")); 
 36955 |  
 36956 |                      return expr_gen.node_allocator_-> 
 36957 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v); 
 36958 |                   } 
 36959 |                   // (c0 - v) - c1 --> (cov) (c0 - c1) - v 
 36960 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 36961 |                   { 
 36962 |                      exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n")); 
 36963 |  
 36964 |                      return expr_gen.node_allocator_-> 
 36965 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v); 
 36966 |                   } 
 36967 |                   // (c0 * v) * c1 --> (cov) (c0 * c1) * v 
 36968 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 36969 |                   { 
 36970 |                      exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n")); 
 36971 |  
 36972 |                      return expr_gen.node_allocator_-> 
 36973 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v); 
 36974 |                   } 
 36975 |                   // (c0 * v) / c1 --> (cov) (c0 / c1) * v 
 36976 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 36977 |                   { 
 36978 |                      exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n")); 
 36979 |  
 36980 |                      return expr_gen.node_allocator_-> 
 36981 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v); 
 36982 |                   } 
 36983 |                   // (c0 / v) * c1 --> (cov) (c0 * c1) / v 
 36984 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 36985 |                   { 
 36986 |                      exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n")); 
 36987 |  
 36988 |                      return expr_gen.node_allocator_-> 
 36989 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v); 
 36990 |                   } 
 36991 |                   // (c0 / v) / c1 --> (cov) (c0 / c1) / v 
 36992 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 36993 |                   { 
 36994 |                      exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n")); 
 36995 |  
 36996 |                      return expr_gen.node_allocator_-> 
 36997 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v); 
 36998 |                   } 
 36999 |                } 
 37000 |  
 37001 |                const bool synthesis_result = 
 37002 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, ctype> 
 37003 |                      (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result); 
 37004 |  
 37005 |                if (synthesis_result) 
 37006 |                   return result; 
 37007 |  
 37008 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37009 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37010 |  
 37011 |                if (!expr_gen.valid_operator(o0,f0)) 
 37012 |                   return error_node(); 
 37013 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37014 |                   return error_node(); 
 37015 |                else 
 37016 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1); 
 37017 |             } 
 37018 |  
 37019 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37020 |                                          const details::operator_type o0, 
 37021 |                                          const details::operator_type o1) 
 37022 |             { 
 37023 |                return details::build_string() 
 37024 |                   << "(t" << expr_gen.to_str(o0) 
 37025 |                   << "t)" << expr_gen.to_str(o1) 
 37026 |                   << "t" 
 37027 |             } 
 37028 |          }; 
 37029 |  
 37030 |          struct synthesize_covoc_expression1 
 37031 |          { 
 37032 |             typedef typename covoc_t::type1 node_type; 
 37033 |             typedef typename covoc_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 (v o1 c1) 
 37040 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 37041 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 37042 |                const Type&  v = voc->v(); 
 37043 |                const Type  c1 = voc->c(); 
 37044 |                const details::operator_type o0 = operation; 
 37045 |                const details::operator_type o1 = voc->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) + (v + c1) --> (cov) (c0 + c1) + v 
 37055 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 37056 |                   { 
 37057 |                      exprtk_debug(("(c0) + (v + c1) --> (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) + (v - c1) --> (cov) (c0 - c1) + v 
 37063 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 37064 |                   { 
 37065 |                      exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n")); 
 37066 |  
 37067 |                      return expr_gen.node_allocator_-> 
 37068 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v); 
 37069 |                   } 
 37070 |                   // (c0) - (v + c1) --> (cov) (c0 - c1) - v 
 37071 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 37072 |                   { 
 37073 |                      exprtk_debug(("(c0) - (v + c1) --> (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) - (v - c1) --> (cov) (c0 + c1) - v 
 37079 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 37080 |                   { 
 37081 |                      exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n")); 
 37082 |  
 37083 |                      return expr_gen.node_allocator_-> 
 37084 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v); 
 37085 |                   } 
 37086 |                   // (c0) * (v * c1) --> (voc) v * (c0 * c1) 
 37087 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 37088 |                   { 
 37089 |                      exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\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) * (v / c1) --> (cov) (c0 / c1) * v 
 37095 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 37096 |                   { 
 37097 |                      exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n")); 
 37098 |  
 37099 |                      return expr_gen.node_allocator_-> 
 37100 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v); 
 37101 |                   } 
 37102 |                   // (c0) / (v * c1) --> (cov) (c0 / c1) / v 
 37103 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 37104 |                   { 
 37105 |                      exprtk_debug(("(c0) / (v * c1) --> (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) / (v / c1) --> (cov) (c0 * c1) / v 
 37111 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 37112 |                   { 
 37113 |                      exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n")); 
 37114 |  
 37115 |                      return expr_gen.node_allocator_-> 
 37116 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v); 
 37117 |                   } 
 37118 |                } 
 37119 |  
 37120 |                const bool synthesis_result = 
 37121 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, ctype> 
 37122 |                      (expr_gen, id(expr_gen, o0, o1), c0, v, c1, 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, v, c1, 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_cocov_expression0 
 37150 |          { 
 37151 |             typedef typename cocov_t::type0 node_type; 
 37152 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 37153 |                                                       const details::operator_type&, 
 37154 |                                                       expression_node_ptr (&)[2]) 
 37155 |             { 
 37156 |                // (c0 o0 c1) o1 (v) - Not possible. 
 37157 |                return error_node(); 
 37158 |             } 
 37159 |          }; 
 37160 |  
 37161 |          struct synthesize_cocov_expression1 
 37162 |          { 
 37163 |             typedef typename cocov_t::type1 node_type; 
 37164 |             typedef typename cocov_t::sf3_type sf3_type; 
 37165 |  
 37166 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37167 |                                                       const details::operator_type& operation, 
 37168 |                                                       expression_node_ptr (&branch)[2]) 
 37169 |             { 
 37170 |                // (c0) o0 (c1 o1 v) 
 37171 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 37172 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 37173 |                const Type  c1 = cov->c(); 
 37174 |                const Type&  v = cov->v(); 
 37175 |                const details::operator_type o0 = operation; 
 37176 |                const details::operator_type o1 = cov->operation(); 
 37177 |  
 37178 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37179 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37180 |  
 37181 |                expression_node_ptr result = error_node(); 
 37182 |  
 37183 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37184 |                { 
 37185 |                   // (c0) + (c1 + v) --> (cov) (c0 + c1) + v 
 37186 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 37187 |                   { 
 37188 |                      exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n")); 
 37189 |  
 37190 |                      return expr_gen.node_allocator_-> 
 37191 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v); 
 37192 |                   } 
 37193 |                   // (c0) + (c1 - v) --> (cov) (c0 + c1) - v 
 37194 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 37195 |                   { 
 37196 |                      exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n")); 
 37197 |  
 37198 |                      return expr_gen.node_allocator_-> 
 37199 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v); 
 37200 |                   } 
 37201 |                   // (c0) - (c1 + v) --> (cov) (c0 - c1) - v 
 37202 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 37203 |                   { 
 37204 |                      exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n")); 
 37205 |  
 37206 |                      return expr_gen.node_allocator_-> 
 37207 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v); 
 37208 |                   } 
 37209 |                   // (c0) - (c1 - v) --> (cov) (c0 - c1) + v 
 37210 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 37211 |                   { 
 37212 |                      exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n")); 
 37213 |  
 37214 |                      return expr_gen.node_allocator_-> 
 37215 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v); 
 37216 |                   } 
 37217 |                   // (c0) * (c1 * v) --> (cov) (c0 * c1) * v 
 37218 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 37219 |                   { 
 37220 |                      exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n")); 
 37221 |  
 37222 |                      return expr_gen.node_allocator_-> 
 37223 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v); 
 37224 |                   } 
 37225 |                   // (c0) * (c1 / v) --> (cov) (c0 * c1) / v 
 37226 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 37227 |                   { 
 37228 |                      exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n")); 
 37229 |  
 37230 |                      return expr_gen.node_allocator_-> 
 37231 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v); 
 37232 |                   } 
 37233 |                   // (c0) / (c1 * v) --> (cov) (c0 / c1) / v 
 37234 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 37235 |                   { 
 37236 |                      exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n")); 
 37237 |  
 37238 |                      return expr_gen.node_allocator_-> 
 37239 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v); 
 37240 |                   } 
 37241 |                   // (c0) / (c1 / v) --> (cov) (c0 / c1) * v 
 37242 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 37243 |                   { 
 37244 |                      exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n")); 
 37245 |  
 37246 |                      return expr_gen.node_allocator_-> 
 37247 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v); 
 37248 |                   } 
 37249 |                } 
 37250 |  
 37251 |                const bool synthesis_result = 
 37252 |                   synthesize_sf3ext_expression::template compile<ctype, ctype, vtype> 
 37253 |                      (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result); 
 37254 |  
 37255 |                if (synthesis_result) 
 37256 |                   return result; 
 37257 |  
 37258 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37259 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37260 |  
 37261 |                if (!expr_gen.valid_operator(o0,f0)) 
 37262 |                   return error_node(); 
 37263 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37264 |                   return error_node(); 
 37265 |                else 
 37266 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1); 
 37267 |             } 
 37268 |  
 37269 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37270 |                                          const details::operator_type o0, 
 37271 |                                          const details::operator_type o1) 
 37272 |             { 
 37273 |                return details::build_string() 
 37274 |                   << "t"  << expr_gen.to_str(o0) 
 37275 |                   << "(t" << expr_gen.to_str(o1) 
 37276 |                   << "t)" 
 37277 |             } 
 37278 |          }; 
 37279 |  
 37280 |          struct synthesize_vococ_expression0 
 37281 |          { 
 37282 |             typedef typename vococ_t::type0 node_type; 
 37283 |             typedef typename vococ_t::sf3_type sf3_type; 
 37284 |  
 37285 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37286 |                                                       const details::operator_type& operation, 
 37287 |                                                       expression_node_ptr (&branch)[2]) 
 37288 |             { 
 37289 |                // (v o0 c0) o1 (c1) 
 37290 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 37291 |                const Type&  v = voc->v(); 
 37292 |                const Type& c0 = voc->c(); 
 37293 |                const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 37294 |                const details::operator_type o0 = voc->operation(); 
 37295 |                const details::operator_type o1 = operation; 
 37296 |  
 37297 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37298 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37299 |  
 37300 |                expression_node_ptr result = error_node(); 
 37301 |  
 37302 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37303 |                { 
 37304 |                   // (v + c0) + c1 --> (voc) v + (c0 + c1) 
 37305 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 37306 |                   { 
 37307 |                      exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n")); 
 37308 |  
 37309 |                      return expr_gen.node_allocator_-> 
 37310 |                                template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1); 
 37311 |                   } 
 37312 |                   // (v + c0) - c1 --> (voc) v + (c0 - c1) 
 37313 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 37314 |                   { 
 37315 |                      exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n")); 
 37316 |  
 37317 |                      return expr_gen.node_allocator_-> 
 37318 |                                template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1); 
 37319 |                   } 
 37320 |                   // (v - c0) + c1 --> (voc) v - (c0 + c1) 
 37321 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 37322 |                   { 
 37323 |                      exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n")); 
 37324 |  
 37325 |                      return expr_gen.node_allocator_-> 
 37326 |                                template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0); 
 37327 |                   } 
 37328 |                   // (v - c0) - c1 --> (voc) v - (c0 + c1) 
 37329 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 37330 |                   { 
 37331 |                      exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n")); 
 37332 |  
 37333 |                      return expr_gen.node_allocator_-> 
 37334 |                                template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1); 
 37335 |                   } 
 37336 |                   // (v * c0) * c1 --> (voc) v * (c0 * c1) 
 37337 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 37338 |                   { 
 37339 |                      exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n")); 
 37340 |  
 37341 |                      return expr_gen.node_allocator_-> 
 37342 |                                template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1); 
 37343 |                   } 
 37344 |                   // (v * c0) / c1 --> (voc) v * (c0 / c1) 
 37345 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 37346 |                   { 
 37347 |                      exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n")); 
 37348 |  
 37349 |                      return expr_gen.node_allocator_-> 
 37350 |                                template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1); 
 37351 |                   } 
 37352 |                   // (v / c0) * c1 --> (voc) v * (c1 / c0) 
 37353 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 37354 |                   { 
 37355 |                      exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n")); 
 37356 |  
 37357 |                      return expr_gen.node_allocator_-> 
 37358 |                                template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0); 
 37359 |                   } 
 37360 |                   // (v / c0) / c1 --> (voc) v / (c0 * c1) 
 37361 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 37362 |                   { 
 37363 |                      exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n")); 
 37364 |  
 37365 |                      return expr_gen.node_allocator_-> 
 37366 |                                template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1); 
 37367 |                   } 
 37368 |                   // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1) 
 37369 |                   else if ((details::e_pow == o0) && (details::e_pow == o1)) 
 37370 |                   { 
 37371 |                      exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n")); 
 37372 |  
 37373 |                      return expr_gen.node_allocator_-> 
 37374 |                                template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1); 
 37375 |                   } 
 37376 |                } 
 37377 |  
 37378 |                const bool synthesis_result = 
 37379 |                   synthesize_sf3ext_expression::template compile<vtype, ctype, ctype> 
 37380 |                      (expr_gen, id(expr_gen, o0, o1), v, c0, c1, 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 |  
 37388 |                if (!expr_gen.valid_operator(o0,f0)) 
 37389 |                   return error_node(); 
 37390 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37391 |                   return error_node(); 
 37392 |                else 
 37393 |                   return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1); 
 37394 |             } 
 37395 |  
 37396 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37397 |                                          const details::operator_type o0, 
 37398 |                                          const details::operator_type o1) 
 37399 |             { 
 37400 |                return details::build_string() 
 37401 |                   << "(t" << expr_gen.to_str(o0) 
 37402 |                   << "t)" << expr_gen.to_str(o1) 
 37403 |                   << "t" 
 37404 |             } 
 37405 |          }; 
 37406 |  
 37407 |          struct synthesize_vococ_expression1 
 37408 |          { 
 37409 |             typedef typename vococ_t::type0 node_type; 
 37410 |  
 37411 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 37412 |                                                       const details::operator_type&, 
 37413 |                                                       expression_node_ptr (&)[2]) 
 37414 |             { 
 37415 |                // (v) o0 (c0 o1 c1) - Not possible. 
 37416 |                exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n")); 
 37417 |                return error_node(); 
 37418 |             } 
 37419 |          }; 
 37420 |  
 37421 |          struct synthesize_vovovov_expression0 
 37422 |          { 
 37423 |             typedef typename vovovov_t::type0 node_type; 
 37424 |             typedef typename vovovov_t::sf4_type sf4_type; 
 37425 |             typedef typename node_type::T0 T0; 
 37426 |             typedef typename node_type::T1 T1; 
 37427 |             typedef typename node_type::T2 T2; 
 37428 |             typedef typename node_type::T3 T3; 
 37429 |  
 37430 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37431 |                                                       const details::operator_type& operation, 
 37432 |                                                       expression_node_ptr (&branch)[2]) 
 37433 |             { 
 37434 |                // (v0 o0 v1) o1 (v2 o2 v3) 
 37435 |                const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 37436 |                const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 37437 |                const Type& v0 = vov0->v0(); 
 37438 |                const Type& v1 = vov0->v1(); 
 37439 |                const Type& v2 = vov1->v0(); 
 37440 |                const Type& v3 = vov1->v1(); 
 37441 |                const details::operator_type o0 = vov0->operation(); 
 37442 |                const details::operator_type o1 = operation; 
 37443 |                const details::operator_type o2 = vov1->operation(); 
 37444 |  
 37445 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37446 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37447 |  
 37448 |                expression_node_ptr result = error_node(); 
 37449 |  
 37450 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37451 |                { 
 37452 |                   // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3) 
 37453 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37454 |                   { 
 37455 |                      const bool synthesis_result = 
 37456 |                         synthesize_sf4ext_expression:: 
 37457 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result); 
 37458 |  
 37459 |                      exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n")); 
 37460 |  
 37461 |                      return (synthesis_result) ? result : error_node(); 
 37462 |                   } 
 37463 |                   // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2) 
 37464 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37465 |                   { 
 37466 |                      const bool synthesis_result = 
 37467 |                         synthesize_sf4ext_expression:: 
 37468 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result); 
 37469 |  
 37470 |                      exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n")); 
 37471 |  
 37472 |                      return (synthesis_result) ? result : error_node(); 
 37473 |                   } 
 37474 |                   // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2) 
 37475 |                   else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37476 |                   { 
 37477 |                      const bool synthesis_result = 
 37478 |                         synthesize_sf4ext_expression:: 
 37479 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result); 
 37480 |  
 37481 |                      exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n")); 
 37482 |  
 37483 |                      return (synthesis_result) ? result : error_node(); 
 37484 |                   } 
 37485 |                   // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2) 
 37486 |                   else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37487 |                   { 
 37488 |                      const bool synthesis_result = 
 37489 |                         synthesize_sf4ext_expression:: 
 37490 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result); 
 37491 |  
 37492 |                      exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n")); 
 37493 |  
 37494 |                      return (synthesis_result) ? result : error_node(); 
 37495 |                   } 
 37496 |                   // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2 
 37497 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37498 |                   { 
 37499 |                      const bool synthesis_result = 
 37500 |                         synthesize_sf4ext_expression:: 
 37501 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result); 
 37502 |  
 37503 |                      exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n")); 
 37504 |  
 37505 |                      return (synthesis_result) ? result : error_node(); 
 37506 |                   } 
 37507 |                } 
 37508 |  
 37509 |                const bool synthesis_result = 
 37510 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37511 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 37512 |  
 37513 |                if (synthesis_result) 
 37514 |                   return result; 
 37515 |  
 37516 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37517 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37518 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37519 |  
 37520 |                if (!expr_gen.valid_operator(o0,f0)) 
 37521 |                   return error_node(); 
 37522 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37523 |                   return error_node(); 
 37524 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37525 |                   return error_node(); 
 37526 |                else 
 37527 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 37528 |             } 
 37529 |  
 37530 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37531 |                                          const details::operator_type o0, 
 37532 |                                          const details::operator_type o1, 
 37533 |                                          const details::operator_type o2) 
 37534 |             { 
 37535 |                return details::build_string() 
 37536 |                   << "(t" << expr_gen.to_str(o0) 
 37537 |                   << "t)" << expr_gen.to_str(o1) 
 37538 |                   << "(t" << expr_gen.to_str(o2) 
 37539 |                   << "t)" 
 37540 |             } 
 37541 |          }; 
 37542 |  
 37543 |          struct synthesize_vovovoc_expression0 
 37544 |          { 
 37545 |             typedef typename vovovoc_t::type0 node_type; 
 37546 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 37547 |             typedef typename node_type::T0 T0; 
 37548 |             typedef typename node_type::T1 T1; 
 37549 |             typedef typename node_type::T2 T2; 
 37550 |             typedef typename node_type::T3 T3; 
 37551 |  
 37552 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37553 |                                                       const details::operator_type& operation, 
 37554 |                                                       expression_node_ptr (&branch)[2]) 
 37555 |             { 
 37556 |                // (v0 o0 v1) o1 (v2 o2 c) 
 37557 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 37558 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 37559 |                const Type& v0 = vov->v0(); 
 37560 |                const Type& v1 = vov->v1(); 
 37561 |                const Type& v2 = voc->v (); 
 37562 |                const Type   c = voc->c (); 
 37563 |                const details::operator_type o0 = vov->operation(); 
 37564 |                const details::operator_type o1 = operation; 
 37565 |                const details::operator_type o2 = voc->operation(); 
 37566 |  
 37567 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37568 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37569 |  
 37570 |                expression_node_ptr result = error_node(); 
 37571 |  
 37572 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37573 |                { 
 37574 |                   // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c) 
 37575 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37576 |                   { 
 37577 |                      const bool synthesis_result = 
 37578 |                         synthesize_sf4ext_expression:: 
 37579 |                            template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result); 
 37580 |  
 37581 |                      exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n")); 
 37582 |  
 37583 |                      return (synthesis_result) ? result : error_node(); 
 37584 |                   } 
 37585 |                   // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2) 
 37586 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37587 |                   { 
 37588 |                      const bool synthesis_result = 
 37589 |                         synthesize_sf4ext_expression:: 
 37590 |                            template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result); 
 37591 |  
 37592 |                      exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n")); 
 37593 |  
 37594 |                      return (synthesis_result) ? result : error_node(); 
 37595 |                   } 
 37596 |                } 
 37597 |  
 37598 |                const bool synthesis_result = 
 37599 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37600 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 37601 |  
 37602 |                if (synthesis_result) 
 37603 |                   return result; 
 37604 |  
 37605 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37606 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37607 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37608 |  
 37609 |                if (!expr_gen.valid_operator(o0,f0)) 
 37610 |                   return error_node(); 
 37611 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37612 |                   return error_node(); 
 37613 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37614 |                   return error_node(); 
 37615 |                else 
 37616 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 37617 |             } 
 37618 |  
 37619 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37620 |                                          const details::operator_type o0, 
 37621 |                                          const details::operator_type o1, 
 37622 |                                          const details::operator_type o2) 
 37623 |             { 
 37624 |                return details::build_string() 
 37625 |                   << "(t" << expr_gen.to_str(o0) 
 37626 |                   << "t)" << expr_gen.to_str(o1) 
 37627 |                   << "(t" << expr_gen.to_str(o2) 
 37628 |                   << "t)" 
 37629 |             } 
 37630 |          }; 
 37631 |  
 37632 |          struct synthesize_vovocov_expression0 
 37633 |          { 
 37634 |             typedef typename vovocov_t::type0 node_type; 
 37635 |             typedef typename vovocov_t::sf4_type sf4_type; 
 37636 |             typedef typename node_type::T0 T0; 
 37637 |             typedef typename node_type::T1 T1; 
 37638 |             typedef typename node_type::T2 T2; 
 37639 |             typedef typename node_type::T3 T3; 
 37640 |  
 37641 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37642 |                                                       const details::operator_type& operation, 
 37643 |                                                       expression_node_ptr (&branch)[2]) 
 37644 |             { 
 37645 |                // (v0 o0 v1) o1 (c o2 v2) 
 37646 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 37647 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 37648 |                const Type& v0 = vov->v0(); 
 37649 |                const Type& v1 = vov->v1(); 
 37650 |                const Type& v2 = cov->v (); 
 37651 |                const Type   c = cov->c (); 
 37652 |                const details::operator_type o0 = vov->operation(); 
 37653 |                const details::operator_type o1 = operation; 
 37654 |                const details::operator_type o2 = cov->operation(); 
 37655 |  
 37656 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37657 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37658 |  
 37659 |                expression_node_ptr result = error_node(); 
 37660 |  
 37661 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37662 |                { 
 37663 |                   // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2) 
 37664 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37665 |                   { 
 37666 |                      const bool synthesis_result = 
 37667 |                         synthesize_sf4ext_expression:: 
 37668 |                            template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result); 
 37669 |  
 37670 |                      exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n")); 
 37671 |  
 37672 |                      return (synthesis_result) ? result : error_node(); 
 37673 |                   } 
 37674 |                   // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c) 
 37675 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37676 |                   { 
 37677 |                      const bool synthesis_result = 
 37678 |                         synthesize_sf4ext_expression:: 
 37679 |                            template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result); 
 37680 |  
 37681 |                      exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n")); 
 37682 |  
 37683 |                      return (synthesis_result) ? result : error_node(); 
 37684 |                   } 
 37685 |                } 
 37686 |  
 37687 |                const bool synthesis_result = 
 37688 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37689 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 37690 |  
 37691 |                if (synthesis_result) 
 37692 |                   return result; 
 37693 |  
 37694 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37695 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37696 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37697 |  
 37698 |                if (!expr_gen.valid_operator(o0,f0)) 
 37699 |                   return error_node(); 
 37700 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37701 |                   return error_node(); 
 37702 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37703 |                   return error_node(); 
 37704 |                else 
 37705 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 37706 |             } 
 37707 |  
 37708 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37709 |                                          const details::operator_type o0, 
 37710 |                                          const details::operator_type o1, 
 37711 |                                          const details::operator_type o2) 
 37712 |             { 
 37713 |                return details::build_string() 
 37714 |                   << "(t" << expr_gen.to_str(o0) 
 37715 |                   << "t)" << expr_gen.to_str(o1) 
 37716 |                   << "(t" << expr_gen.to_str(o2) 
 37717 |                   << "t)" 
 37718 |             } 
 37719 |          }; 
 37720 |  
 37721 |          struct synthesize_vocovov_expression0 
 37722 |          { 
 37723 |             typedef typename vocovov_t::type0 node_type; 
 37724 |             typedef typename vocovov_t::sf4_type sf4_type; 
 37725 |             typedef typename node_type::T0 T0; 
 37726 |             typedef typename node_type::T1 T1; 
 37727 |             typedef typename node_type::T2 T2; 
 37728 |             typedef typename node_type::T3 T3; 
 37729 |  
 37730 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37731 |                                                       const details::operator_type& operation, 
 37732 |                                                       expression_node_ptr (&branch)[2]) 
 37733 |             { 
 37734 |                // (v0 o0 c) o1 (v1 o2 v2) 
 37735 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 37736 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 37737 |                const Type   c = voc->c (); 
 37738 |                const Type& v0 = voc->v (); 
 37739 |                const Type& v1 = vov->v0(); 
 37740 |                const Type& v2 = vov->v1(); 
 37741 |                const details::operator_type o0 = voc->operation(); 
 37742 |                const details::operator_type o1 = operation; 
 37743 |                const details::operator_type o2 = vov->operation(); 
 37744 |  
 37745 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37746 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37747 |  
 37748 |                expression_node_ptr result = error_node(); 
 37749 |  
 37750 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37751 |                { 
 37752 |                   // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2) 
 37753 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37754 |                   { 
 37755 |                      const bool synthesis_result = 
 37756 |                         synthesize_sf4ext_expression:: 
 37757 |                            template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result); 
 37758 |  
 37759 |                      exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n")); 
 37760 |  
 37761 |                      return (synthesis_result) ? result : error_node(); 
 37762 |                   } 
 37763 |                   // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1) 
 37764 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37765 |                   { 
 37766 |                      const bool synthesis_result = 
 37767 |                         synthesize_sf4ext_expression:: 
 37768 |                            template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result); 
 37769 |  
 37770 |                      exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n")); 
 37771 |  
 37772 |                      return (synthesis_result) ? result : error_node(); 
 37773 |                   } 
 37774 |                } 
 37775 |  
 37776 |                const bool synthesis_result = 
 37777 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37778 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 37779 |  
 37780 |                if (synthesis_result) 
 37781 |                   return result; 
 37782 |  
 37783 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37784 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37785 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37786 |  
 37787 |                if (!expr_gen.valid_operator(o0,f0)) 
 37788 |                   return error_node(); 
 37789 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37790 |                   return error_node(); 
 37791 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37792 |                   return error_node(); 
 37793 |                else 
 37794 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 37795 |             } 
 37796 |  
 37797 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37798 |                                          const details::operator_type o0, 
 37799 |                                          const details::operator_type o1, 
 37800 |                                          const details::operator_type o2) 
 37801 |             { 
 37802 |                return details::build_string() 
 37803 |                   << "(t" << expr_gen.to_str(o0) 
 37804 |                   << "t)" << expr_gen.to_str(o1) 
 37805 |                   << "(t" << expr_gen.to_str(o2) 
 37806 |                   << "t)" 
 37807 |             } 
 37808 |          }; 
 37809 |  
 37810 |          struct synthesize_covovov_expression0 
 37811 |          { 
 37812 |             typedef typename covovov_t::type0 node_type; 
 37813 |             typedef typename covovov_t::sf4_type sf4_type; 
 37814 |             typedef typename node_type::T0 T0; 
 37815 |             typedef typename node_type::T1 T1; 
 37816 |             typedef typename node_type::T2 T2; 
 37817 |             typedef typename node_type::T3 T3; 
 37818 |  
 37819 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37820 |                                                       const details::operator_type& operation, 
 37821 |                                                       expression_node_ptr (&branch)[2]) 
 37822 |             { 
 37823 |                // (c o0 v0) o1 (v1 o2 v2) 
 37824 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 37825 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 37826 |                const Type   c = cov->c (); 
 37827 |                const Type& v0 = cov->v (); 
 37828 |                const Type& v1 = vov->v0(); 
 37829 |                const Type& v2 = vov->v1(); 
 37830 |                const details::operator_type o0 = cov->operation(); 
 37831 |                const details::operator_type o1 = operation; 
 37832 |                const details::operator_type o2 = vov->operation(); 
 37833 |  
 37834 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37835 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37836 |  
 37837 |                expression_node_ptr result = error_node(); 
 37838 |  
 37839 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37840 |                { 
 37841 |                   // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2) 
 37842 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37843 |                   { 
 37844 |                      const bool synthesis_result = 
 37845 |                         synthesize_sf4ext_expression:: 
 37846 |                            template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result); 
 37847 |  
 37848 |                      exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n")); 
 37849 |  
 37850 |                      return (synthesis_result) ? result : error_node(); 
 37851 |                   } 
 37852 |                   // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1) 
 37853 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37854 |                   { 
 37855 |                      const bool synthesis_result = 
 37856 |                         synthesize_sf4ext_expression:: 
 37857 |                            template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result); 
 37858 |  
 37859 |                      exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n")); 
 37860 |  
 37861 |                      return (synthesis_result) ? result : error_node(); 
 37862 |                   } 
 37863 |                } 
 37864 |  
 37865 |                const bool synthesis_result = 
 37866 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37867 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 37868 |  
 37869 |                if (synthesis_result) 
 37870 |                   return result; 
 37871 |  
 37872 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37873 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37874 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37875 |  
 37876 |                if (!expr_gen.valid_operator(o0,f0)) 
 37877 |                   return error_node(); 
 37878 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37879 |                   return error_node(); 
 37880 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37881 |                   return error_node(); 
 37882 |                else 
 37883 |                   return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 37884 |             } 
 37885 |  
 37886 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37887 |                                          const details::operator_type o0, 
 37888 |                                          const details::operator_type o1, 
 37889 |                                          const details::operator_type o2) 
 37890 |             { 
 37891 |                return details::build_string() 
 37892 |                   << "(t" << expr_gen.to_str(o0) 
 37893 |                   << "t)" << expr_gen.to_str(o1) 
 37894 |                   << "(t" << expr_gen.to_str(o2) 
 37895 |                   << "t)" 
 37896 |             } 
 37897 |          }; 
 37898 |  
 37899 |          struct synthesize_covocov_expression0 
 37900 |          { 
 37901 |             typedef typename covocov_t::type0 node_type; 
 37902 |             typedef typename covocov_t::sf4_type sf4_type; 
 37903 |             typedef typename node_type::T0 T0; 
 37904 |             typedef typename node_type::T1 T1; 
 37905 |             typedef typename node_type::T2 T2; 
 37906 |             typedef typename node_type::T3 T3; 
 37907 |  
 37908 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37909 |                                                       const details::operator_type& operation, 
 37910 |                                                       expression_node_ptr (&branch)[2]) 
 37911 |             { 
 37912 |                // (c0 o0 v0) o1 (c1 o2 v1) 
 37913 |                const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 37914 |                const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 37915 |                const Type  c0 = cov0->c(); 
 37916 |                const Type& v0 = cov0->v(); 
 37917 |                const Type  c1 = cov1->c(); 
 37918 |                const Type& v1 = cov1->v(); 
 37919 |                const details::operator_type o0 = cov0->operation(); 
 37920 |                const details::operator_type o1 = operation; 
 37921 |                const details::operator_type o2 = cov1->operation(); 
 37922 |  
 37923 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37924 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37925 |  
 37926 |                expression_node_ptr result = error_node(); 
 37927 |  
 37928 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37929 |                { 
 37930 |                   // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1 
 37931 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 37932 |                   { 
 37933 |                      const bool synthesis_result = 
 37934 |                         synthesize_sf3ext_expression:: 
 37935 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 37936 |  
 37937 |                      exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 37938 |  
 37939 |                      return (synthesis_result) ? result : error_node(); 
 37940 |                   } 
 37941 |                   // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1 
 37942 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 37943 |                   { 
 37944 |                      const bool synthesis_result = 
 37945 |                         synthesize_sf3ext_expression:: 
 37946 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 37947 |  
 37948 |                      exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 37949 |  
 37950 |                      return (synthesis_result) ? result : error_node(); 
 37951 |                   } 
 37952 |                   // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1 
 37953 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 37954 |                   { 
 37955 |                      const bool synthesis_result = 
 37956 |                         synthesize_sf3ext_expression:: 
 37957 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result); 
 37958 |  
 37959 |                      exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n")); 
 37960 |  
 37961 |                      return (synthesis_result) ? result : error_node(); 
 37962 |                   } 
 37963 |                   // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1 
 37964 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 37965 |                   { 
 37966 |                      const bool synthesis_result = 
 37967 |                         synthesize_sf3ext_expression:: 
 37968 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 37969 |  
 37970 |                      exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 37971 |  
 37972 |                      return (synthesis_result) ? result : error_node(); 
 37973 |                   } 
 37974 |                   // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1) 
 37975 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 37976 |                   { 
 37977 |                      const bool synthesis_result = 
 37978 |                         synthesize_sf3ext_expression:: 
 37979 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 37980 |  
 37981 |                      exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n")); 
 37982 |  
 37983 |                      return (synthesis_result) ? result : error_node(); 
 37984 |                   } 
 37985 |                   // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1) 
 37986 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37987 |                   { 
 37988 |                      const bool synthesis_result = 
 37989 |                         synthesize_sf3ext_expression:: 
 37990 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result); 
 37991 |  
 37992 |                      exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n")); 
 37993 |  
 37994 |                      return (synthesis_result) ? result : error_node(); 
 37995 |                   } 
 37996 |                   // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0 
 37997 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37998 |                   { 
 37999 |                      const bool synthesis_result = 
 38000 |                         synthesize_sf3ext_expression:: 
 38001 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result); 
 38002 |  
 38003 |                      exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n")); 
 38004 |  
 38005 |                      return (synthesis_result) ? result : error_node(); 
 38006 |                   } 
 38007 |                   // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1) 
 38008 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38009 |                   { 
 38010 |                      const bool synthesis_result = 
 38011 |                         synthesize_sf3ext_expression:: 
 38012 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result); 
 38013 |  
 38014 |                      exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n")); 
 38015 |  
 38016 |                      return (synthesis_result) ? result : error_node(); 
 38017 |                   } 
 38018 |                   // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1) 
 38019 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38020 |                   { 
 38021 |                      const bool synthesis_result = 
 38022 |                         synthesize_sf3ext_expression:: 
 38023 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result); 
 38024 |  
 38025 |                      exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n")); 
 38026 |  
 38027 |                      return (synthesis_result) ? result : error_node(); 
 38028 |                   } 
 38029 |                   // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1) 
 38030 |                   else if ( 
 38031 |                             (std::equal_to<T>()(c0,c1)) && 
 38032 |                             (details::e_mul == o0)      && 
 38033 |                             (details::e_mul == o2)      && 
 38034 |                             ( 
 38035 |                               (details::e_add == o1) || 
 38036 |                               (details::e_sub == o1) 
 38037 |                             ) 
 38038 |                           ) 
 38039 |                   { 
 38040 |                      std::string specfunc; 
 38041 |  
 38042 |                      switch (o1) 
 38043 |                      { 
 38044 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38045 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38046 |                         default             : return error_node(); 
 38047 |                      } 
 38048 |  
 38049 |                      const bool synthesis_result = 
 38050 |                         synthesize_sf3ext_expression:: 
 38051 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38052 |  
 38053 |                      exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n")); 
 38054 |  
 38055 |                      return (synthesis_result) ? result : error_node(); 
 38056 |                   } 
 38057 |                } 
 38058 |  
 38059 |                const bool synthesis_result = 
 38060 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38061 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 38062 |  
 38063 |                if (synthesis_result) 
 38064 |                   return result; 
 38065 |  
 38066 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38067 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38068 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38069 |  
 38070 |                if (!expr_gen.valid_operator(o0,f0)) 
 38071 |                   return error_node(); 
 38072 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38073 |                   return error_node(); 
 38074 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38075 |                   return error_node(); 
 38076 |                else 
 38077 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 38078 |             } 
 38079 |  
 38080 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38081 |                                          const details::operator_type o0, 
 38082 |                                          const details::operator_type o1, 
 38083 |                                          const details::operator_type o2) 
 38084 |             { 
 38085 |                return details::build_string() 
 38086 |                   << "(t" << expr_gen.to_str(o0) 
 38087 |                   << "t)" << expr_gen.to_str(o1) 
 38088 |                   << "(t" << expr_gen.to_str(o2) 
 38089 |                   << "t)" 
 38090 |             } 
 38091 |          }; 
 38092 |  
 38093 |          struct synthesize_vocovoc_expression0 
 38094 |          { 
 38095 |             typedef typename vocovoc_t::type0 node_type; 
 38096 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 38097 |             typedef typename node_type::T0 T0; 
 38098 |             typedef typename node_type::T1 T1; 
 38099 |             typedef typename node_type::T2 T2; 
 38100 |             typedef typename node_type::T3 T3; 
 38101 |  
 38102 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38103 |                                                       const details::operator_type& operation, 
 38104 |                                                       expression_node_ptr (&branch)[2]) 
 38105 |             { 
 38106 |                // (v0 o0 c0) o1 (v1 o2 c1) 
 38107 |                const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 38108 |                const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 38109 |                const Type  c0 = voc0->c(); 
 38110 |                const Type& v0 = voc0->v(); 
 38111 |                const Type  c1 = voc1->c(); 
 38112 |                const Type& v1 = voc1->v(); 
 38113 |                const details::operator_type o0 = voc0->operation(); 
 38114 |                const details::operator_type o1 = operation; 
 38115 |                const details::operator_type o2 = voc1->operation(); 
 38116 |  
 38117 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38118 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38119 |  
 38120 |                expression_node_ptr result = error_node(); 
 38121 |  
 38122 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 38123 |                { 
 38124 |                   // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1 
 38125 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 38126 |                   { 
 38127 |                      const bool synthesis_result = 
 38128 |                         synthesize_sf3ext_expression:: 
 38129 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 38130 |  
 38131 |                      exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 38132 |  
 38133 |                      return (synthesis_result) ? result : error_node(); 
 38134 |                   } 
 38135 |                   // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1 
 38136 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 38137 |                   { 
 38138 |                      const bool synthesis_result = 
 38139 |                         synthesize_sf3ext_expression:: 
 38140 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 38141 |  
 38142 |                      exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 38143 |  
 38144 |                      return (synthesis_result) ? result : error_node(); 
 38145 |                   } 
 38146 |                   // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1 
 38147 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 38148 |                   { 
 38149 |                      const bool synthesis_result = 
 38150 |                         synthesize_sf3ext_expression:: 
 38151 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result); 
 38152 |  
 38153 |                      exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n")); 
 38154 |  
 38155 |                      return (synthesis_result) ? result : error_node(); 
 38156 |                   } 
 38157 |                   // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1 
 38158 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 38159 |                   { 
 38160 |                      const bool synthesis_result = 
 38161 |                         synthesize_sf3ext_expression:: 
 38162 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 38163 |  
 38164 |                      exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 38165 |  
 38166 |                      return (synthesis_result) ? result : error_node(); 
 38167 |                   } 
 38168 |                   // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1) 
 38169 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38170 |                   { 
 38171 |                      const bool synthesis_result = 
 38172 |                         synthesize_sf3ext_expression:: 
 38173 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 38174 |  
 38175 |                      exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n")); 
 38176 |  
 38177 |                      return (synthesis_result) ? result : error_node(); 
 38178 |                   } 
 38179 |                   // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1 
 38180 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 38181 |                   { 
 38182 |                      const bool synthesis_result = 
 38183 |                         synthesize_sf3ext_expression:: 
 38184 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result); 
 38185 |  
 38186 |                      exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n")); 
 38187 |  
 38188 |                      return (synthesis_result) ? result : error_node(); 
 38189 |                   } 
 38190 |                   // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1 
 38191 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38192 |                   { 
 38193 |                      const bool synthesis_result = 
 38194 |                         synthesize_sf3ext_expression:: 
 38195 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result); 
 38196 |  
 38197 |                      exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n")); 
 38198 |  
 38199 |                      return (synthesis_result) ? result : error_node(); 
 38200 |                   } 
 38201 |                   // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1) 
 38202 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38203 |                   { 
 38204 |                      const bool synthesis_result = 
 38205 |                         synthesize_sf3ext_expression:: 
 38206 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result); 
 38207 |  
 38208 |                      exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n")); 
 38209 |  
 38210 |                      return (synthesis_result) ? result : error_node(); 
 38211 |                   } 
 38212 |                   // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1 
 38213 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38214 |                   { 
 38215 |                      const bool synthesis_result = 
 38216 |                         synthesize_sf3ext_expression:: 
 38217 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result); 
 38218 |  
 38219 |                      exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n")); 
 38220 |  
 38221 |                      return (synthesis_result) ? result : error_node(); 
 38222 |                   } 
 38223 |                   // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1) 
 38224 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2)) 
 38225 |                   { 
 38226 |                      const bool synthesis_result = 
 38227 |                         synthesize_sf4ext_expression:: 
 38228 |                            template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result); 
 38229 |  
 38230 |                      exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n")); 
 38231 |  
 38232 |                      return (synthesis_result) ? result : error_node(); 
 38233 |                   } 
 38234 |                   // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1) 
 38235 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2)) 
 38236 |                   { 
 38237 |                      const bool synthesis_result = 
 38238 |                         synthesize_sf4ext_expression:: 
 38239 |                            template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result); 
 38240 |  
 38241 |                      exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n")); 
 38242 |  
 38243 |                      return (synthesis_result) ? result : error_node(); 
 38244 |                   } 
 38245 |                   // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1) 
 38246 |                   else if ( 
 38247 |                             (std::equal_to<T>()(c0,c1)) && 
 38248 |                             (details::e_mul == o0)      && 
 38249 |                             (details::e_mul == o2)      && 
 38250 |                             ( 
 38251 |                               (details::e_add == o1) || 
 38252 |                               (details::e_sub == o1) 
 38253 |                             ) 
 38254 |                           ) 
 38255 |                   { 
 38256 |                      std::string specfunc; 
 38257 |  
 38258 |                      switch (o1) 
 38259 |                      { 
 38260 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38261 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38262 |                         default             : return error_node(); 
 38263 |                      } 
 38264 |  
 38265 |                      const bool synthesis_result = 
 38266 |                         synthesize_sf3ext_expression:: 
 38267 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38268 |  
 38269 |                      exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n")); 
 38270 |  
 38271 |                      return (synthesis_result) ? result : error_node(); 
 38272 |                   } 
 38273 |                   // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c 
 38274 |                   else if ( 
 38275 |                             (std::equal_to<T>()(c0,c1)) && 
 38276 |                             (details::e_div == o0)      && 
 38277 |                             (details::e_div == o2)      && 
 38278 |                             ( 
 38279 |                               (details::e_add == o1) || 
 38280 |                               (details::e_sub == o1) 
 38281 |                             ) 
 38282 |                           ) 
 38283 |                   { 
 38284 |                      std::string specfunc; 
 38285 |  
 38286 |                      switch (o1) 
 38287 |                      { 
 38288 |                         case details::e_add : specfunc = "(t+t)/t" break; 
 38289 |                         case details::e_sub : specfunc = "(t-t)/t" break; 
 38290 |                         default             : return error_node(); 
 38291 |                      } 
 38292 |  
 38293 |                      const bool synthesis_result = 
 38294 |                         synthesize_sf3ext_expression:: 
 38295 |                            template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result); 
 38296 |  
 38297 |                      exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n")); 
 38298 |  
 38299 |                      return (synthesis_result) ? result : error_node(); 
 38300 |                   } 
 38301 |                } 
 38302 |  
 38303 |                const bool synthesis_result = 
 38304 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38305 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 38306 |  
 38307 |                if (synthesis_result) 
 38308 |                   return result; 
 38309 |  
 38310 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38311 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38312 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38313 |  
 38314 |                if (!expr_gen.valid_operator(o0,f0)) 
 38315 |                   return error_node(); 
 38316 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38317 |                   return error_node(); 
 38318 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38319 |                   return error_node(); 
 38320 |                else 
 38321 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 38322 |             } 
 38323 |  
 38324 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38325 |                                          const details::operator_type o0, 
 38326 |                                          const details::operator_type o1, 
 38327 |                                          const details::operator_type o2) 
 38328 |             { 
 38329 |                return details::build_string() 
 38330 |                   << "(t" << expr_gen.to_str(o0) 
 38331 |                   << "t)" << expr_gen.to_str(o1) 
 38332 |                   << "(t" << expr_gen.to_str(o2) 
 38333 |                   << "t)" 
 38334 |             } 
 38335 |          }; 
 38336 |  
 38337 |          struct synthesize_covovoc_expression0 
 38338 |          { 
 38339 |             typedef typename covovoc_t::type0 node_type; 
 38340 |             typedef typename covovoc_t::sf4_type sf4_type; 
 38341 |             typedef typename node_type::T0 T0; 
 38342 |             typedef typename node_type::T1 T1; 
 38343 |             typedef typename node_type::T2 T2; 
 38344 |             typedef typename node_type::T3 T3; 
 38345 |  
 38346 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38347 |                                                       const details::operator_type& operation, 
 38348 |                                                       expression_node_ptr (&branch)[2]) 
 38349 |             { 
 38350 |                // (c0 o0 v0) o1 (v1 o2 c1) 
 38351 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 38352 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 38353 |                const Type  c0 = cov->c(); 
 38354 |                const Type& v0 = cov->v(); 
 38355 |                const Type  c1 = voc->c(); 
 38356 |                const Type& v1 = voc->v(); 
 38357 |                const details::operator_type o0 = cov->operation(); 
 38358 |                const details::operator_type o1 = operation; 
 38359 |                const details::operator_type o2 = voc->operation(); 
 38360 |  
 38361 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38362 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38363 |  
 38364 |                expression_node_ptr result = error_node(); 
 38365 |  
 38366 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 38367 |                { 
 38368 |                   // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1 
 38369 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 38370 |                   { 
 38371 |                      const bool synthesis_result = 
 38372 |                         synthesize_sf3ext_expression:: 
 38373 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 38374 |  
 38375 |                      exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 38376 |  
 38377 |                      return (synthesis_result) ? result : error_node(); 
 38378 |                   } 
 38379 |                   // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1 
 38380 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 38381 |                   { 
 38382 |                      const bool synthesis_result = 
 38383 |                         synthesize_sf3ext_expression:: 
 38384 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 38385 |  
 38386 |                      exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 38387 |  
 38388 |                      return (synthesis_result) ? result : error_node(); 
 38389 |                   } 
 38390 |                   // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1 
 38391 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 38392 |                   { 
 38393 |                      const bool synthesis_result = 
 38394 |                         synthesize_sf3ext_expression:: 
 38395 |                            template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result); 
 38396 |  
 38397 |                      exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n")); 
 38398 |  
 38399 |                      return (synthesis_result) ? result : error_node(); 
 38400 |                   } 
 38401 |                   // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1 
 38402 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 38403 |                   { 
 38404 |                      const bool synthesis_result = 
 38405 |                         synthesize_sf3ext_expression:: 
 38406 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 38407 |  
 38408 |                      exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 38409 |  
 38410 |                      return (synthesis_result) ? result : error_node(); 
 38411 |                   } 
 38412 |                   // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1) 
 38413 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38414 |                   { 
 38415 |                      const bool synthesis_result = 
 38416 |                         synthesize_sf3ext_expression:: 
 38417 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 38418 |  
 38419 |                      exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n")); 
 38420 |  
 38421 |                      return (synthesis_result) ? result : error_node(); 
 38422 |                   } 
 38423 |                   // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0) 
 38424 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 38425 |                   { 
 38426 |                      const bool synthesis_result = 
 38427 |                         synthesize_sf3ext_expression:: 
 38428 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result); 
 38429 |  
 38430 |                      exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n")); 
 38431 |  
 38432 |                      return (synthesis_result) ? result : error_node(); 
 38433 |                   } 
 38434 |                   // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1) 
 38435 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38436 |                   { 
 38437 |                      const bool synthesis_result = 
 38438 |                         synthesize_sf3ext_expression:: 
 38439 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result); 
 38440 |  
 38441 |                      exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n")); 
 38442 |  
 38443 |                      return (synthesis_result) ? result : error_node(); 
 38444 |                   } 
 38445 |                   // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1) 
 38446 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38447 |                   { 
 38448 |                      const bool synthesis_result = 
 38449 |                         synthesize_sf3ext_expression:: 
 38450 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result); 
 38451 |  
 38452 |                      exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n")); 
 38453 |  
 38454 |                      return (synthesis_result) ? result : error_node(); 
 38455 |                   } 
 38456 |                   // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1) 
 38457 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38458 |                   { 
 38459 |                      const bool synthesis_result = 
 38460 |                         synthesize_sf3ext_expression:: 
 38461 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result); 
 38462 |  
 38463 |                      exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n")); 
 38464 |  
 38465 |                      return (synthesis_result) ? result : error_node(); 
 38466 |                   } 
 38467 |                   // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1) 
 38468 |                   else if ( 
 38469 |                             (std::equal_to<T>()(c0,c1)) && 
 38470 |                             (details::e_mul == o0)      && 
 38471 |                             (details::e_mul == o2)      && 
 38472 |                             ( 
 38473 |                               (details::e_add == o1) || 
 38474 |                               (details::e_sub == o1) 
 38475 |                             ) 
 38476 |                           ) 
 38477 |                   { 
 38478 |                      std::string specfunc; 
 38479 |  
 38480 |                      switch (o1) 
 38481 |                      { 
 38482 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38483 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38484 |                         default             : return error_node(); 
 38485 |                      } 
 38486 |  
 38487 |                      const bool synthesis_result = 
 38488 |                         synthesize_sf3ext_expression:: 
 38489 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38490 |  
 38491 |                      exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n")); 
 38492 |  
 38493 |                      return (synthesis_result) ? result : error_node(); 
 38494 |                   } 
 38495 |                } 
 38496 |  
 38497 |                const bool synthesis_result = 
 38498 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38499 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 38500 |  
 38501 |                if (synthesis_result) 
 38502 |                   return result; 
 38503 |  
 38504 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38505 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38506 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38507 |  
 38508 |                if (!expr_gen.valid_operator(o0,f0)) 
 38509 |                   return error_node(); 
 38510 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38511 |                   return error_node(); 
 38512 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38513 |                   return error_node(); 
 38514 |                else 
 38515 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 38516 |             } 
 38517 |  
 38518 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38519 |                                          const details::operator_type o0, 
 38520 |                                          const details::operator_type o1, 
 38521 |                                          const details::operator_type o2) 
 38522 |             { 
 38523 |                return details::build_string() 
 38524 |                   << "(t" << expr_gen.to_str(o0) 
 38525 |                   << "t)" << expr_gen.to_str(o1) 
 38526 |                   << "(t" << expr_gen.to_str(o2) 
 38527 |                   << "t)" 
 38528 |             } 
 38529 |          }; 
 38530 |  
 38531 |          struct synthesize_vococov_expression0 
 38532 |          { 
 38533 |             typedef typename vococov_t::type0 node_type; 
 38534 |             typedef typename vococov_t::sf4_type sf4_type; 
 38535 |             typedef typename node_type::T0 T0; 
 38536 |             typedef typename node_type::T1 T1; 
 38537 |             typedef typename node_type::T2 T2; 
 38538 |             typedef typename node_type::T3 T3; 
 38539 |  
 38540 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38541 |                                                       const details::operator_type& operation, 
 38542 |                                                       expression_node_ptr (&branch)[2]) 
 38543 |             { 
 38544 |                // (v0 o0 c0) o1 (c1 o2 v1) 
 38545 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 38546 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 38547 |                const Type  c0 = voc->c(); 
 38548 |                const Type& v0 = voc->v(); 
 38549 |                const Type  c1 = cov->c(); 
 38550 |                const Type& v1 = cov->v(); 
 38551 |                const details::operator_type o0 = voc->operation(); 
 38552 |                const details::operator_type o1 = operation; 
 38553 |                const details::operator_type o2 = cov->operation(); 
 38554 |  
 38555 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38556 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38557 |  
 38558 |                expression_node_ptr result = error_node(); 
 38559 |  
 38560 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 38561 |                { 
 38562 |                   // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1 
 38563 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 38564 |                   { 
 38565 |                      const bool synthesis_result = 
 38566 |                         synthesize_sf3ext_expression:: 
 38567 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 38568 |  
 38569 |                      exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 38570 |  
 38571 |                      return (synthesis_result) ? result : error_node(); 
 38572 |                   } 
 38573 |                   // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1 
 38574 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 38575 |                   { 
 38576 |                      const bool synthesis_result = 
 38577 |                         synthesize_sf3ext_expression:: 
 38578 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 38579 |  
 38580 |                      exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 38581 |  
 38582 |                      return (synthesis_result) ? result : error_node(); 
 38583 |                   } 
 38584 |                   // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0) 
 38585 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 38586 |                   { 
 38587 |                      const bool synthesis_result = 
 38588 |                         synthesize_sf3ext_expression:: 
 38589 |                            template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result); 
 38590 |  
 38591 |                      exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n")); 
 38592 |  
 38593 |                      return (synthesis_result) ? result : error_node(); 
 38594 |                   } 
 38595 |                   // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1 
 38596 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 38597 |                   { 
 38598 |                      const bool synthesis_result = 
 38599 |                         synthesize_sf3ext_expression:: 
 38600 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 38601 |  
 38602 |                      exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 38603 |  
 38604 |                      return (synthesis_result) ? result : error_node(); 
 38605 |                   } 
 38606 |                   // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1) 
 38607 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38608 |                   { 
 38609 |                      const bool synthesis_result = 
 38610 |                         synthesize_sf3ext_expression:: 
 38611 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 38612 |  
 38613 |                      exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n")); 
 38614 |  
 38615 |                      return (synthesis_result) ? result : error_node(); 
 38616 |                   } 
 38617 |                   // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1) 
 38618 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 38619 |                   { 
 38620 |                      const bool synthesis_result = 
 38621 |                         synthesize_sf3ext_expression:: 
 38622 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result); 
 38623 |  
 38624 |                      exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n")); 
 38625 |  
 38626 |                      return (synthesis_result) ? result : error_node(); 
 38627 |                   } 
 38628 |                   // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1) 
 38629 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38630 |                   { 
 38631 |                      const bool synthesis_result = 
 38632 |                         synthesize_sf3ext_expression:: 
 38633 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result); 
 38634 |  
 38635 |                      exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n")); 
 38636 |  
 38637 |                      return (synthesis_result) ? result : error_node(); 
 38638 |                   } 
 38639 |                   // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1) 
 38640 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38641 |                   { 
 38642 |                      const bool synthesis_result = 
 38643 |                         synthesize_sf3ext_expression:: 
 38644 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result); 
 38645 |  
 38646 |                      exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n")); 
 38647 |  
 38648 |                      return (synthesis_result) ? result : error_node(); 
 38649 |                   } 
 38650 |                   // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1)) 
 38651 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38652 |                   { 
 38653 |                      const bool synthesis_result = 
 38654 |                         synthesize_sf3ext_expression:: 
 38655 |                            template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result); 
 38656 |  
 38657 |                      exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n")); 
 38658 |  
 38659 |                      return (synthesis_result) ? result : error_node(); 
 38660 |                   } 
 38661 |                   // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1) 
 38662 |                   else if ( 
 38663 |                             (std::equal_to<T>()(c0,c1)) && 
 38664 |                             (details::e_mul == o0)      && 
 38665 |                             (details::e_mul == o2)      && 
 38666 |                             ( 
 38667 |                               (details::e_add == o1) || (details::e_sub == o1) 
 38668 |                             ) 
 38669 |                           ) 
 38670 |                   { 
 38671 |                      std::string specfunc; 
 38672 |  
 38673 |                      switch (o1) 
 38674 |                      { 
 38675 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38676 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38677 |                         default             : return error_node(); 
 38678 |                      } 
 38679 |  
 38680 |                      const bool synthesis_result = 
 38681 |                         synthesize_sf3ext_expression:: 
 38682 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38683 |  
 38684 |                      exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n")); 
 38685 |  
 38686 |                      return (synthesis_result) ? result : error_node(); 
 38687 |                   } 
 38688 |                } 
 38689 |  
 38690 |                const bool synthesis_result = 
 38691 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38692 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result); 
 38693 |  
 38694 |                if (synthesis_result) 
 38695 |                   return result; 
 38696 |  
 38697 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38698 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38699 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38700 |  
 38701 |                if (!expr_gen.valid_operator(o0,f0)) 
 38702 |                   return error_node(); 
 38703 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38704 |                   return error_node(); 
 38705 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38706 |                   return error_node(); 
 38707 |                else 
 38708 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2); 
 38709 |             } 
 38710 |  
 38711 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38712 |                                          const details::operator_type o0, 
 38713 |                                          const details::operator_type o1, 
 38714 |                                          const details::operator_type o2) 
 38715 |             { 
 38716 |                return details::build_string() 
 38717 |                   << "(t" << expr_gen.to_str(o0) 
 38718 |                   << "t)" << expr_gen.to_str(o1) 
 38719 |                   << "(t" << expr_gen.to_str(o2) 
 38720 |                   << "t)" 
 38721 |             } 
 38722 |          }; 
 38723 |  
 38724 |          struct synthesize_vovovov_expression1 
 38725 |          { 
 38726 |             typedef typename vovovov_t::type1 node_type; 
 38727 |             typedef typename vovovov_t::sf4_type sf4_type; 
 38728 |             typedef typename node_type::T0 T0; 
 38729 |             typedef typename node_type::T1 T1; 
 38730 |             typedef typename node_type::T2 T2; 
 38731 |             typedef typename node_type::T3 T3; 
 38732 |  
 38733 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38734 |                                                       const details::operator_type& operation, 
 38735 |                                                       expression_node_ptr (&branch)[2]) 
 38736 |             { 
 38737 |                // v0 o0 (v1 o1 (v2 o2 v3)) 
 38738 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 38739 |  
 38740 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 38741 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38742 |                const Type& v1 = vovov->t0(); 
 38743 |                const Type& v2 = vovov->t1(); 
 38744 |                const Type& v3 = vovov->t2(); 
 38745 |                const details::operator_type o0 = operation; 
 38746 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 38747 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 38748 |  
 38749 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38750 |                binary_functor_t f1 = vovov->f0(); 
 38751 |                binary_functor_t f2 = vovov->f1(); 
 38752 |  
 38753 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38754 |  
 38755 |                expression_node_ptr result = error_node(); 
 38756 |  
 38757 |                const bool synthesis_result = 
 38758 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38759 |                      (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 38760 |  
 38761 |                if (synthesis_result) 
 38762 |                   return result; 
 38763 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38764 |                   return error_node(); 
 38765 |  
 38766 |                exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n")); 
 38767 |  
 38768 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 38769 |             } 
 38770 |  
 38771 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38772 |                                          const details::operator_type o0, 
 38773 |                                          const details::operator_type o1, 
 38774 |                                          const details::operator_type o2) 
 38775 |             { 
 38776 |                return details::build_string() 
 38777 |                   << "t"  << expr_gen.to_str(o0) 
 38778 |                   << "(t" << expr_gen.to_str(o1) 
 38779 |                   << "(t" << expr_gen.to_str(o2) 
 38780 |                   << "t))" 
 38781 |             } 
 38782 |          }; 
 38783 |  
 38784 |          struct synthesize_vovovoc_expression1 
 38785 |          { 
 38786 |             typedef typename vovovoc_t::type1 node_type; 
 38787 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 38788 |             typedef typename node_type::T0 T0; 
 38789 |             typedef typename node_type::T1 T1; 
 38790 |             typedef typename node_type::T2 T2; 
 38791 |             typedef typename node_type::T3 T3; 
 38792 |  
 38793 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38794 |                                                       const details::operator_type& operation, 
 38795 |                                                       expression_node_ptr (&branch)[2]) 
 38796 |             { 
 38797 |                // v0 o0 (v1 o1 (v2 o2 c)) 
 38798 |                typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t; 
 38799 |  
 38800 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 38801 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38802 |                const Type& v1 = vovoc->t0(); 
 38803 |                const Type& v2 = vovoc->t1(); 
 38804 |                const Type   c = vovoc->t2(); 
 38805 |                const details::operator_type o0 = operation; 
 38806 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 38807 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 38808 |  
 38809 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38810 |                binary_functor_t f1 = vovoc->f0(); 
 38811 |                binary_functor_t f2 = vovoc->f1(); 
 38812 |  
 38813 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38814 |  
 38815 |                expression_node_ptr result = error_node(); 
 38816 |  
 38817 |                const bool synthesis_result = 
 38818 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38819 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 38820 |  
 38821 |                if (synthesis_result) 
 38822 |                   return result; 
 38823 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38824 |                   return error_node(); 
 38825 |  
 38826 |                exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n")); 
 38827 |  
 38828 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 38829 |             } 
 38830 |  
 38831 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38832 |                                          const details::operator_type o0, 
 38833 |                                          const details::operator_type o1, 
 38834 |                                          const details::operator_type o2) 
 38835 |             { 
 38836 |                return details::build_string() 
 38837 |                   << "t"  << expr_gen.to_str(o0) 
 38838 |                   << "(t" << expr_gen.to_str(o1) 
 38839 |                   << "(t" << expr_gen.to_str(o2) 
 38840 |                   << "t))" 
 38841 |             } 
 38842 |          }; 
 38843 |  
 38844 |          struct synthesize_vovocov_expression1 
 38845 |          { 
 38846 |             typedef typename vovocov_t::type1 node_type; 
 38847 |             typedef typename vovocov_t::sf4_type sf4_type; 
 38848 |             typedef typename node_type::T0 T0; 
 38849 |             typedef typename node_type::T1 T1; 
 38850 |             typedef typename node_type::T2 T2; 
 38851 |             typedef typename node_type::T3 T3; 
 38852 |  
 38853 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38854 |                                                       const details::operator_type& operation, 
 38855 |                                                       expression_node_ptr (&branch)[2]) 
 38856 |             { 
 38857 |                // v0 o0 (v1 o1 (c o2 v2)) 
 38858 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 38859 |  
 38860 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 38861 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38862 |                const Type& v1 = vocov->t0(); 
 38863 |                const Type   c = vocov->t1(); 
 38864 |                const Type& v2 = vocov->t2(); 
 38865 |                const details::operator_type o0 = operation; 
 38866 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 38867 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 38868 |  
 38869 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38870 |                binary_functor_t f1 = vocov->f0(); 
 38871 |                binary_functor_t f2 = vocov->f1(); 
 38872 |  
 38873 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38874 |  
 38875 |                expression_node_ptr result = error_node(); 
 38876 |  
 38877 |                const bool synthesis_result = 
 38878 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38879 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 38880 |  
 38881 |                if (synthesis_result) 
 38882 |                   return result; 
 38883 |                if (!expr_gen.valid_operator(o0,f0)) 
 38884 |                   return error_node(); 
 38885 |  
 38886 |                exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n")); 
 38887 |  
 38888 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 38889 |             } 
 38890 |  
 38891 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38892 |                                          const details::operator_type o0, 
 38893 |                                          const details::operator_type o1, 
 38894 |                                          const details::operator_type o2) 
 38895 |             { 
 38896 |                return details::build_string() 
 38897 |                   << "t"  << expr_gen.to_str(o0) 
 38898 |                   << "(t" << expr_gen.to_str(o1) 
 38899 |                   << "(t" << expr_gen.to_str(o2) 
 38900 |                   << "t))" 
 38901 |             } 
 38902 |          }; 
 38903 |  
 38904 |          struct synthesize_vocovov_expression1 
 38905 |          { 
 38906 |             typedef typename vocovov_t::type1 node_type; 
 38907 |             typedef typename vocovov_t::sf4_type sf4_type; 
 38908 |             typedef typename node_type::T0 T0; 
 38909 |             typedef typename node_type::T1 T1; 
 38910 |             typedef typename node_type::T2 T2; 
 38911 |             typedef typename node_type::T3 T3; 
 38912 |  
 38913 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38914 |                                                       const details::operator_type& operation, 
 38915 |                                                       expression_node_ptr (&branch)[2]) 
 38916 |             { 
 38917 |                // v0 o0 (c o1 (v1 o2 v2)) 
 38918 |                typedef typename synthesize_covov_expression1::node_type lcl_covov_t; 
 38919 |  
 38920 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]); 
 38921 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38922 |                const Type   c = covov->t0(); 
 38923 |                const Type& v1 = covov->t1(); 
 38924 |                const Type& v2 = covov->t2(); 
 38925 |                const details::operator_type o0 = operation; 
 38926 |                const details::operator_type o1 = expr_gen.get_operator(covov->f0()); 
 38927 |                const details::operator_type o2 = expr_gen.get_operator(covov->f1()); 
 38928 |  
 38929 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38930 |                binary_functor_t f1 = covov->f0(); 
 38931 |                binary_functor_t f2 = covov->f1(); 
 38932 |  
 38933 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38934 |  
 38935 |                expression_node_ptr result = error_node(); 
 38936 |  
 38937 |                const bool synthesis_result = 
 38938 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38939 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 38940 |  
 38941 |                if (synthesis_result) 
 38942 |                   return result; 
 38943 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38944 |                   return error_node(); 
 38945 |  
 38946 |                exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n")); 
 38947 |  
 38948 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 38949 |             } 
 38950 |  
 38951 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38952 |                                          const details::operator_type o0, 
 38953 |                                          const details::operator_type o1, 
 38954 |                                          const details::operator_type o2) 
 38955 |             { 
 38956 |                return details::build_string() 
 38957 |                   << "t"  << expr_gen.to_str(o0) 
 38958 |                   << "(t" << expr_gen.to_str(o1) 
 38959 |                   << "(t" << expr_gen.to_str(o2) 
 38960 |                   << "t))" 
 38961 |             } 
 38962 |          }; 
 38963 |  
 38964 |          struct synthesize_covovov_expression1 
 38965 |          { 
 38966 |             typedef typename covovov_t::type1 node_type; 
 38967 |             typedef typename covovov_t::sf4_type sf4_type; 
 38968 |             typedef typename node_type::T0 T0; 
 38969 |             typedef typename node_type::T1 T1; 
 38970 |             typedef typename node_type::T2 T2; 
 38971 |             typedef typename node_type::T3 T3; 
 38972 |  
 38973 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38974 |                                                       const details::operator_type& operation, 
 38975 |                                                       expression_node_ptr (&branch)[2]) 
 38976 |             { 
 38977 |                // c o0 (v0 o1 (v1 o2 v2)) 
 38978 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 38979 |  
 38980 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 38981 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 38982 |                const Type& v0 = vovov->t0(); 
 38983 |                const Type& v1 = vovov->t1(); 
 38984 |                const Type& v2 = vovov->t2(); 
 38985 |                const details::operator_type o0 = operation; 
 38986 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 38987 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 38988 |  
 38989 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38990 |                binary_functor_t f1 = vovov->f0(); 
 38991 |                binary_functor_t f2 = vovov->f1(); 
 38992 |  
 38993 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38994 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38995 |  
 38996 |                expression_node_ptr result = error_node(); 
 38997 |  
 38998 |                const bool synthesis_result = 
 38999 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39000 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 39001 |  
 39002 |                if (synthesis_result) 
 39003 |                   return result; 
 39004 |                if (!expr_gen.valid_operator(o0,f0)) 
 39005 |                   return error_node(); 
 39006 |  
 39007 |                exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n")); 
 39008 |  
 39009 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 39010 |             } 
 39011 |  
 39012 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39013 |                                          const details::operator_type o0, 
 39014 |                                          const details::operator_type o1, 
 39015 |                                          const details::operator_type o2) 
 39016 |             { 
 39017 |                return details::build_string() 
 39018 |                   << "t"  << expr_gen.to_str(o0) 
 39019 |                   << "(t" << expr_gen.to_str(o1) 
 39020 |                   << "(t" << expr_gen.to_str(o2) 
 39021 |                   << "t))" 
 39022 |             } 
 39023 |          }; 
 39024 |  
 39025 |          struct synthesize_covocov_expression1 
 39026 |          { 
 39027 |             typedef typename covocov_t::type1 node_type; 
 39028 |             typedef typename covocov_t::sf4_type sf4_type; 
 39029 |             typedef typename node_type::T0 T0; 
 39030 |             typedef typename node_type::T1 T1; 
 39031 |             typedef typename node_type::T2 T2; 
 39032 |             typedef typename node_type::T3 T3; 
 39033 |  
 39034 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39035 |                                                       const details::operator_type& operation, 
 39036 |                                                       expression_node_ptr (&branch)[2]) 
 39037 |             { 
 39038 |                // c0 o0 (v0 o1 (c1 o2 v1)) 
 39039 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 39040 |  
 39041 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 39042 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39043 |                const Type& v0 = vocov->t0(); 
 39044 |                const Type  c1 = vocov->t1(); 
 39045 |                const Type& v1 = vocov->t2(); 
 39046 |                const details::operator_type o0 = operation; 
 39047 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 39048 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 39049 |  
 39050 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39051 |                binary_functor_t f1 = vocov->f0(); 
 39052 |                binary_functor_t f2 = vocov->f1(); 
 39053 |  
 39054 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39055 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39056 |  
 39057 |                expression_node_ptr result = error_node(); 
 39058 |  
 39059 |                const bool synthesis_result = 
 39060 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39061 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 39062 |  
 39063 |                if (synthesis_result) 
 39064 |                   return result; 
 39065 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39066 |                   return error_node(); 
 39067 |  
 39068 |                exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n")); 
 39069 |  
 39070 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 39071 |             } 
 39072 |  
 39073 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39074 |                                          const details::operator_type o0, 
 39075 |                                          const details::operator_type o1, 
 39076 |                                          const details::operator_type o2) 
 39077 |             { 
 39078 |                return details::build_string() 
 39079 |                   << "t"  << expr_gen.to_str(o0) 
 39080 |                   << "(t" << expr_gen.to_str(o1) 
 39081 |                   << "(t" << expr_gen.to_str(o2) 
 39082 |                   << "t))" 
 39083 |             } 
 39084 |          }; 
 39085 |  
 39086 |          struct synthesize_vocovoc_expression1 
 39087 |          { 
 39088 |             typedef typename vocovoc_t::type1 node_type; 
 39089 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 39090 |             typedef typename node_type::T0 T0; 
 39091 |             typedef typename node_type::T1 T1; 
 39092 |             typedef typename node_type::T2 T2; 
 39093 |             typedef typename node_type::T3 T3; 
 39094 |  
 39095 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39096 |                                                       const details::operator_type& operation, 
 39097 |                                                       expression_node_ptr (&branch)[2]) 
 39098 |             { 
 39099 |                // v0 o0 (c0 o1 (v1 o2 c2)) 
 39100 |                typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t; 
 39101 |  
 39102 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]); 
 39103 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39104 |                const Type  c0 = covoc->t0(); 
 39105 |                const Type& v1 = covoc->t1(); 
 39106 |                const Type  c1 = covoc->t2(); 
 39107 |                const details::operator_type o0 = operation; 
 39108 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f0()); 
 39109 |                const details::operator_type o2 = expr_gen.get_operator(covoc->f1()); 
 39110 |  
 39111 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39112 |                binary_functor_t f1 = covoc->f0(); 
 39113 |                binary_functor_t f2 = covoc->f1(); 
 39114 |  
 39115 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39116 |  
 39117 |                expression_node_ptr result = error_node(); 
 39118 |  
 39119 |                const bool synthesis_result = 
 39120 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39121 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 39122 |  
 39123 |                if (synthesis_result) 
 39124 |                   return result; 
 39125 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39126 |                   return error_node(); 
 39127 |  
 39128 |                exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n")); 
 39129 |  
 39130 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 39131 |             } 
 39132 |  
 39133 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39134 |                                          const details::operator_type o0, 
 39135 |                                          const details::operator_type o1, 
 39136 |                                          const details::operator_type o2) 
 39137 |             { 
 39138 |                return details::build_string() 
 39139 |                   << "t"  << expr_gen.to_str(o0) 
 39140 |                   << "(t" << expr_gen.to_str(o1) 
 39141 |                   << "(t" << expr_gen.to_str(o2) 
 39142 |                   << "t))" 
 39143 |             } 
 39144 |          }; 
 39145 |  
 39146 |          struct synthesize_covovoc_expression1 
 39147 |          { 
 39148 |             typedef typename covovoc_t::type1 node_type; 
 39149 |             typedef typename covovoc_t::sf4_type sf4_type; 
 39150 |             typedef typename node_type::T0 T0; 
 39151 |             typedef typename node_type::T1 T1; 
 39152 |             typedef typename node_type::T2 T2; 
 39153 |             typedef typename node_type::T3 T3; 
 39154 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39155 |                                                       const details::operator_type& operation, 
 39156 |                                                       expression_node_ptr (&branch)[2]) 
 39157 |             { 
 39158 |                // c0 o0 (v0 o1 (v1 o2 c1)) 
 39159 |                typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t; 
 39160 |  
 39161 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 39162 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39163 |                const Type& v0 = vovoc->t0(); 
 39164 |                const Type& v1 = vovoc->t1(); 
 39165 |                const Type  c1 = vovoc->t2(); 
 39166 |                const details::operator_type o0 = operation; 
 39167 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 39168 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 39169 |  
 39170 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39171 |                binary_functor_t f1 = vovoc->f0(); 
 39172 |                binary_functor_t f2 = vovoc->f1(); 
 39173 |  
 39174 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39175 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39176 |  
 39177 |                expression_node_ptr result = error_node(); 
 39178 |  
 39179 |                const bool synthesis_result = 
 39180 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39181 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 39182 |  
 39183 |                if (synthesis_result) 
 39184 |                   return result; 
 39185 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39186 |                   return error_node(); 
 39187 |  
 39188 |                exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n")); 
 39189 |  
 39190 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 39191 |             } 
 39192 |  
 39193 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39194 |                                          const details::operator_type o0, 
 39195 |                                          const details::operator_type o1, 
 39196 |                                          const details::operator_type o2) 
 39197 |             { 
 39198 |                return details::build_string() 
 39199 |                   << "t"  << expr_gen.to_str(o0) 
 39200 |                   << "(t" << expr_gen.to_str(o1) 
 39201 |                   << "(t" << expr_gen.to_str(o2) 
 39202 |                   << "t))" 
 39203 |             } 
 39204 |          }; 
 39205 |  
 39206 |          struct synthesize_vococov_expression1 
 39207 |          { 
 39208 |             typedef typename vococov_t::type1 node_type; 
 39209 |             typedef typename vococov_t::sf4_type sf4_type; 
 39210 |             typedef typename node_type::T0 T0; 
 39211 |             typedef typename node_type::T1 T1; 
 39212 |             typedef typename node_type::T2 T2; 
 39213 |             typedef typename node_type::T3 T3; 
 39214 |  
 39215 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39216 |                                                       const details::operator_type& operation, 
 39217 |                                                       expression_node_ptr (&branch)[2]) 
 39218 |             { 
 39219 |                // v0 o0 (c0 o1 (c1 o2 v1)) 
 39220 |                typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t; 
 39221 |  
 39222 |                const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]); 
 39223 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39224 |                const Type  c0 = cocov->t0(); 
 39225 |                const Type  c1 = cocov->t1(); 
 39226 |                const Type& v1 = cocov->t2(); 
 39227 |                const details::operator_type o0 = operation; 
 39228 |                const details::operator_type o1 = expr_gen.get_operator(cocov->f0()); 
 39229 |                const details::operator_type o2 = expr_gen.get_operator(cocov->f1()); 
 39230 |  
 39231 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39232 |                binary_functor_t f1 = cocov->f0(); 
 39233 |                binary_functor_t f2 = cocov->f1(); 
 39234 |  
 39235 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39236 |  
 39237 |                expression_node_ptr result = error_node(); 
 39238 |  
 39239 |                const bool synthesis_result = 
 39240 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39241 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result); 
 39242 |  
 39243 |                if (synthesis_result) 
 39244 |                   return result; 
 39245 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39246 |                   return error_node(); 
 39247 |  
 39248 |                exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n")); 
 39249 |  
 39250 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2); 
 39251 |             } 
 39252 |  
 39253 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39254 |                                          const details::operator_type o0, 
 39255 |                                          const details::operator_type o1, 
 39256 |                                          const details::operator_type o2) 
 39257 |             { 
 39258 |                return details::build_string() 
 39259 |                   << "t"  << expr_gen.to_str(o0) 
 39260 |                   << "(t" << expr_gen.to_str(o1) 
 39261 |                   << "(t" << expr_gen.to_str(o2) 
 39262 |                   << "t))" 
 39263 |             } 
 39264 |          }; 
 39265 |  
 39266 |          struct synthesize_vovovov_expression2 
 39267 |          { 
 39268 |             typedef typename vovovov_t::type2 node_type; 
 39269 |             typedef typename vovovov_t::sf4_type sf4_type; 
 39270 |             typedef typename node_type::T0 T0; 
 39271 |             typedef typename node_type::T1 T1; 
 39272 |             typedef typename node_type::T2 T2; 
 39273 |             typedef typename node_type::T3 T3; 
 39274 |  
 39275 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39276 |                                                       const details::operator_type& operation, 
 39277 |                                                       expression_node_ptr (&branch)[2]) 
 39278 |             { 
 39279 |                // v0 o0 ((v1 o1 v2) o2 v3) 
 39280 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39281 |  
 39282 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 39283 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39284 |                const Type& v1 = vovov->t0(); 
 39285 |                const Type& v2 = vovov->t1(); 
 39286 |                const Type& v3 = vovov->t2(); 
 39287 |                const details::operator_type o0 = operation; 
 39288 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 39289 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 39290 |  
 39291 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39292 |                binary_functor_t f1 = vovov->f0(); 
 39293 |                binary_functor_t f2 = vovov->f1(); 
 39294 |  
 39295 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39296 |  
 39297 |                expression_node_ptr result = error_node(); 
 39298 |  
 39299 |                const bool synthesis_result = 
 39300 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39301 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 39302 |  
 39303 |                if (synthesis_result) 
 39304 |                   return result; 
 39305 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39306 |                   return error_node(); 
 39307 |  
 39308 |                exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n")); 
 39309 |  
 39310 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 39311 |             } 
 39312 |  
 39313 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39314 |                                          const details::operator_type o0, 
 39315 |                                          const details::operator_type o1, 
 39316 |                                          const details::operator_type o2) 
 39317 |             { 
 39318 |                return details::build_string() 
 39319 |                   << "t"   << expr_gen.to_str(o0) 
 39320 |                   << "((t" << expr_gen.to_str(o1) 
 39321 |                   << "t)"  << expr_gen.to_str(o2) 
 39322 |                   << "t)" 
 39323 |             } 
 39324 |          }; 
 39325 |  
 39326 |          struct synthesize_vovovoc_expression2 
 39327 |          { 
 39328 |             typedef typename vovovoc_t::type2 node_type; 
 39329 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 39330 |             typedef typename node_type::T0 T0; 
 39331 |             typedef typename node_type::T1 T1; 
 39332 |             typedef typename node_type::T2 T2; 
 39333 |             typedef typename node_type::T3 T3; 
 39334 |  
 39335 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39336 |                                                       const details::operator_type& operation, 
 39337 |                                                       expression_node_ptr (&branch)[2]) 
 39338 |             { 
 39339 |                // v0 o0 ((v1 o1 v2) o2 c) 
 39340 |                typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t; 
 39341 |  
 39342 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 39343 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39344 |                const Type& v1 = vovoc->t0(); 
 39345 |                const Type& v2 = vovoc->t1(); 
 39346 |                const Type   c = vovoc->t2(); 
 39347 |                const details::operator_type o0 = operation; 
 39348 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 39349 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 39350 |  
 39351 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39352 |                binary_functor_t f1 = vovoc->f0(); 
 39353 |                binary_functor_t f2 = vovoc->f1(); 
 39354 |  
 39355 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39356 |  
 39357 |                expression_node_ptr result = error_node(); 
 39358 |  
 39359 |                const bool synthesis_result = 
 39360 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39361 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 39362 |  
 39363 |                if (synthesis_result) 
 39364 |                   return result; 
 39365 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39366 |                   return error_node(); 
 39367 |  
 39368 |                exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n")); 
 39369 |  
 39370 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 39371 |             } 
 39372 |  
 39373 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39374 |                                          const details::operator_type o0, 
 39375 |                                          const details::operator_type o1, 
 39376 |                                          const details::operator_type o2) 
 39377 |             { 
 39378 |                return details::build_string() 
 39379 |                   << "t"   << expr_gen.to_str(o0) 
 39380 |                   << "((t" << expr_gen.to_str(o1) 
 39381 |                   << "t)"  << expr_gen.to_str(o2) 
 39382 |                   << "t)" 
 39383 |             } 
 39384 |          }; 
 39385 |  
 39386 |          struct synthesize_vovocov_expression2 
 39387 |          { 
 39388 |             typedef typename vovocov_t::type2 node_type; 
 39389 |             typedef typename vovocov_t::sf4_type sf4_type; 
 39390 |             typedef typename node_type::T0 T0; 
 39391 |             typedef typename node_type::T1 T1; 
 39392 |             typedef typename node_type::T2 T2; 
 39393 |             typedef typename node_type::T3 T3; 
 39394 |  
 39395 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39396 |                                                       const details::operator_type& operation, 
 39397 |                                                       expression_node_ptr (&branch)[2]) 
 39398 |             { 
 39399 |                // v0 o0 ((v1 o1 c) o2 v2) 
 39400 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 39401 |  
 39402 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 39403 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39404 |                const Type& v1 = vocov->t0(); 
 39405 |                const Type   c = vocov->t1(); 
 39406 |                const Type& v2 = vocov->t2(); 
 39407 |                const details::operator_type o0 = operation; 
 39408 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 39409 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 39410 |  
 39411 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39412 |                binary_functor_t f1 = vocov->f0(); 
 39413 |                binary_functor_t f2 = vocov->f1(); 
 39414 |  
 39415 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39416 |  
 39417 |                expression_node_ptr result = error_node(); 
 39418 |  
 39419 |                const bool synthesis_result = 
 39420 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39421 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 39422 |  
 39423 |                if (synthesis_result) 
 39424 |                   return result; 
 39425 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39426 |                   return error_node(); 
 39427 |  
 39428 |                exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n")); 
 39429 |  
 39430 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 39431 |             } 
 39432 |  
 39433 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39434 |                                          const details::operator_type o0, 
 39435 |                                          const details::operator_type o1, 
 39436 |                                          const details::operator_type o2) 
 39437 |             { 
 39438 |                return details::build_string() 
 39439 |                   << "t"   << expr_gen.to_str(o0) 
 39440 |                   << "((t" << expr_gen.to_str(o1) 
 39441 |                   << "t)"  << expr_gen.to_str(o2) 
 39442 |                   << "t)" 
 39443 |             } 
 39444 |          }; 
 39445 |  
 39446 |          struct synthesize_vocovov_expression2 
 39447 |          { 
 39448 |             typedef typename vocovov_t::type2 node_type; 
 39449 |             typedef typename vocovov_t::sf4_type sf4_type; 
 39450 |             typedef typename node_type::T0 T0; 
 39451 |             typedef typename node_type::T1 T1; 
 39452 |             typedef typename node_type::T2 T2; 
 39453 |             typedef typename node_type::T3 T3; 
 39454 |  
 39455 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39456 |                                                       const details::operator_type& operation, 
 39457 |                                                       expression_node_ptr (&branch)[2]) 
 39458 |             { 
 39459 |                // v0 o0 ((c o1 v1) o2 v2) 
 39460 |                typedef typename synthesize_covov_expression0::node_type lcl_covov_t; 
 39461 |  
 39462 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]); 
 39463 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39464 |                const Type   c = covov->t0(); 
 39465 |                const Type& v1 = covov->t1(); 
 39466 |                const Type& v2 = covov->t2(); 
 39467 |                const details::operator_type o0 = operation; 
 39468 |                const details::operator_type o1 = expr_gen.get_operator(covov->f0()); 
 39469 |                const details::operator_type o2 = expr_gen.get_operator(covov->f1()); 
 39470 |  
 39471 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39472 |                binary_functor_t f1 = covov->f0(); 
 39473 |                binary_functor_t f2 = covov->f1(); 
 39474 |  
 39475 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39476 |  
 39477 |                expression_node_ptr result = error_node(); 
 39478 |  
 39479 |                const bool synthesis_result = 
 39480 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39481 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 39482 |  
 39483 |                if (synthesis_result) 
 39484 |                   return result; 
 39485 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39486 |                   return error_node(); 
 39487 |  
 39488 |                exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n")); 
 39489 |  
 39490 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 39491 |             } 
 39492 |  
 39493 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39494 |                                          const details::operator_type o0, 
 39495 |                                          const details::operator_type o1, 
 39496 |                                          const details::operator_type o2) 
 39497 |             { 
 39498 |                return details::build_string() 
 39499 |                   << "t"   << expr_gen.to_str(o0) 
 39500 |                   << "((t" << expr_gen.to_str(o1) 
 39501 |                   << "t)"  << expr_gen.to_str(o2) 
 39502 |                   << "t)" 
 39503 |             } 
 39504 |          }; 
 39505 |  
 39506 |          struct synthesize_covovov_expression2 
 39507 |          { 
 39508 |             typedef typename covovov_t::type2 node_type; 
 39509 |             typedef typename covovov_t::sf4_type sf4_type; 
 39510 |             typedef typename node_type::T0 T0; 
 39511 |             typedef typename node_type::T1 T1; 
 39512 |             typedef typename node_type::T2 T2; 
 39513 |             typedef typename node_type::T3 T3; 
 39514 |  
 39515 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39516 |                                                       const details::operator_type& operation, 
 39517 |                                                       expression_node_ptr (&branch)[2]) 
 39518 |             { 
 39519 |                // c o0 ((v1 o1 v2) o2 v3) 
 39520 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39521 |  
 39522 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 39523 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39524 |                const Type& v0 = vovov->t0(); 
 39525 |                const Type& v1 = vovov->t1(); 
 39526 |                const Type& v2 = vovov->t2(); 
 39527 |                const details::operator_type o0 = operation; 
 39528 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 39529 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 39530 |  
 39531 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39532 |                binary_functor_t f1 = vovov->f0(); 
 39533 |                binary_functor_t f2 = vovov->f1(); 
 39534 |  
 39535 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39536 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39537 |  
 39538 |                expression_node_ptr result = error_node(); 
 39539 |  
 39540 |                const bool synthesis_result = 
 39541 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39542 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 39543 |  
 39544 |                if (synthesis_result) 
 39545 |                   return result; 
 39546 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39547 |                   return error_node(); 
 39548 |  
 39549 |                exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n")); 
 39550 |  
 39551 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 39552 |             } 
 39553 |  
 39554 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39555 |                                          const details::operator_type o0, 
 39556 |                                          const details::operator_type o1, 
 39557 |                                          const details::operator_type o2) 
 39558 |             { 
 39559 |                return details::build_string() 
 39560 |                   << "t"   << expr_gen.to_str(o0) 
 39561 |                   << "((t" << expr_gen.to_str(o1) 
 39562 |                   << "t)"  << expr_gen.to_str(o2) 
 39563 |                   << "t)" 
 39564 |             } 
 39565 |         }; 
 39566 |  
 39567 |          struct synthesize_covocov_expression2 
 39568 |          { 
 39569 |             typedef typename covocov_t::type2 node_type; 
 39570 |             typedef typename covocov_t::sf4_type sf4_type; 
 39571 |             typedef typename node_type::T0 T0; 
 39572 |             typedef typename node_type::T1 T1; 
 39573 |             typedef typename node_type::T2 T2; 
 39574 |             typedef typename node_type::T3 T3; 
 39575 |  
 39576 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39577 |                                                       const details::operator_type& operation, 
 39578 |                                                       expression_node_ptr (&branch)[2]) 
 39579 |             { 
 39580 |                // c0 o0 ((v0 o1 c1) o2 v1) 
 39581 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 39582 |  
 39583 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 39584 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39585 |                const Type& v0 = vocov->t0(); 
 39586 |                const Type  c1 = vocov->t1(); 
 39587 |                const Type& v1 = vocov->t2(); 
 39588 |                const details::operator_type o0 = operation; 
 39589 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 39590 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 39591 |  
 39592 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39593 |                binary_functor_t f1 = vocov->f0(); 
 39594 |                binary_functor_t f2 = vocov->f1(); 
 39595 |  
 39596 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39597 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39598 |  
 39599 |                expression_node_ptr result = error_node(); 
 39600 |  
 39601 |                const bool synthesis_result = 
 39602 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39603 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 39604 |  
 39605 |                if (synthesis_result) 
 39606 |                   return result; 
 39607 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39608 |                   return error_node(); 
 39609 |  
 39610 |                exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n")); 
 39611 |  
 39612 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 39613 |             } 
 39614 |  
 39615 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39616 |                                          const details::operator_type o0, 
 39617 |                                          const details::operator_type o1, 
 39618 |                                          const details::operator_type o2) 
 39619 |             { 
 39620 |                return details::build_string() 
 39621 |                   << "t"   << expr_gen.to_str(o0) 
 39622 |                   << "((t" << expr_gen.to_str(o1) 
 39623 |                   << "t)"  << expr_gen.to_str(o2) 
 39624 |                   << "t)" 
 39625 |             } 
 39626 |          }; 
 39627 |  
 39628 |          struct synthesize_vocovoc_expression2 
 39629 |          { 
 39630 |             typedef typename vocovoc_t::type2 node_type; 
 39631 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 39632 |             typedef typename node_type::T0 T0; 
 39633 |             typedef typename node_type::T1 T1; 
 39634 |             typedef typename node_type::T2 T2; 
 39635 |             typedef typename node_type::T3 T3; 
 39636 |  
 39637 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39638 |                                                       const details::operator_type& operation, 
 39639 |                                                       expression_node_ptr (&branch)[2]) 
 39640 |             { 
 39641 |                // v0 o0 ((c0 o1 v1) o2 c1) 
 39642 |                typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t; 
 39643 |  
 39644 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]); 
 39645 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39646 |                const Type  c0 = covoc->t0(); 
 39647 |                const Type& v1 = covoc->t1(); 
 39648 |                const Type  c1 = covoc->t2(); 
 39649 |                const details::operator_type o0 = operation; 
 39650 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f0()); 
 39651 |                const details::operator_type o2 = expr_gen.get_operator(covoc->f1()); 
 39652 |  
 39653 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39654 |                binary_functor_t f1 = covoc->f0(); 
 39655 |                binary_functor_t f2 = covoc->f1(); 
 39656 |  
 39657 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39658 |  
 39659 |                expression_node_ptr result = error_node(); 
 39660 |  
 39661 |                const bool synthesis_result = 
 39662 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39663 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 39664 |  
 39665 |                if (synthesis_result) 
 39666 |                   return result; 
 39667 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39668 |                   return error_node(); 
 39669 |  
 39670 |                exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n")); 
 39671 |  
 39672 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 39673 |             } 
 39674 |  
 39675 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39676 |                                          const details::operator_type o0, 
 39677 |                                          const details::operator_type o1, 
 39678 |                                          const details::operator_type o2) 
 39679 |             { 
 39680 |                return details::build_string() 
 39681 |                   << "t"   << expr_gen.to_str(o0) 
 39682 |                   << "((t" << expr_gen.to_str(o1) 
 39683 |                   << "t)"  << expr_gen.to_str(o2) 
 39684 |                   << "t)" 
 39685 |             } 
 39686 |          }; 
 39687 |  
 39688 |          struct synthesize_covovoc_expression2 
 39689 |          { 
 39690 |             typedef typename covovoc_t::type2 node_type; 
 39691 |             typedef typename covovoc_t::sf4_type sf4_type; 
 39692 |             typedef typename node_type::T0 T0; 
 39693 |             typedef typename node_type::T1 T1; 
 39694 |             typedef typename node_type::T2 T2; 
 39695 |             typedef typename node_type::T3 T3; 
 39696 |  
 39697 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39698 |                                                       const details::operator_type& operation, 
 39699 |                                                       expression_node_ptr (&branch)[2]) 
 39700 |             { 
 39701 |                // c0 o0 ((v0 o1 v1) o2 c1) 
 39702 |                typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t; 
 39703 |  
 39704 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 39705 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39706 |                const Type& v0 = vovoc->t0(); 
 39707 |                const Type& v1 = vovoc->t1(); 
 39708 |                const Type  c1 = vovoc->t2(); 
 39709 |                const details::operator_type o0 = operation; 
 39710 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 39711 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 39712 |  
 39713 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39714 |                binary_functor_t f1 = vovoc->f0(); 
 39715 |                binary_functor_t f2 = vovoc->f1(); 
 39716 |  
 39717 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39718 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39719 |  
 39720 |                expression_node_ptr result = error_node(); 
 39721 |  
 39722 |                const bool synthesis_result = 
 39723 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39724 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 39725 |  
 39726 |                if (synthesis_result) 
 39727 |                   return result; 
 39728 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39729 |                   return error_node(); 
 39730 |  
 39731 |                exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n")); 
 39732 |  
 39733 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 39734 |             } 
 39735 |  
 39736 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39737 |                                          const details::operator_type o0, 
 39738 |                                          const details::operator_type o1, 
 39739 |                                          const details::operator_type o2) 
 39740 |             { 
 39741 |                return details::build_string() 
 39742 |                   << "t"   << expr_gen.to_str(o0) 
 39743 |                   << "((t" << expr_gen.to_str(o1) 
 39744 |                   << "t)"  << expr_gen.to_str(o2) 
 39745 |                   << "t)" 
 39746 |             } 
 39747 |          }; 
 39748 |  
 39749 |          struct synthesize_vococov_expression2 
 39750 |          { 
 39751 |             typedef typename vococov_t::type2 node_type; 
 39752 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 39753 |                                                       const details::operator_type&, 
 39754 |                                                       expression_node_ptr (&)[2]) 
 39755 |             { 
 39756 |                // v0 o0 ((c0 o1 c1) o2 v1) - Not possible 
 39757 |                exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n")); 
 39758 |                return error_node(); 
 39759 |             } 
 39760 |  
 39761 |             static inline std::string id(expression_generator<Type>&, 
 39762 |                                          const details::operator_type, 
 39763 |                                          const details::operator_type, 
 39764 |                                          const details::operator_type) 
 39765 |             { 
 39766 |                return "INVALID" 
 39767 |             } 
 39768 |          }; 
 39769 |  
 39770 |          struct synthesize_vovovov_expression3 
 39771 |          { 
 39772 |             typedef typename vovovov_t::type3 node_type; 
 39773 |             typedef typename vovovov_t::sf4_type sf4_type; 
 39774 |             typedef typename node_type::T0 T0; 
 39775 |             typedef typename node_type::T1 T1; 
 39776 |             typedef typename node_type::T2 T2; 
 39777 |             typedef typename node_type::T3 T3; 
 39778 |  
 39779 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39780 |                                                       const details::operator_type& operation, 
 39781 |                                                       expression_node_ptr (&branch)[2]) 
 39782 |             { 
 39783 |                // ((v0 o0 v1) o1 v2) o2 v3 
 39784 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39785 |  
 39786 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 39787 |                const Type& v0 = vovov->t0(); 
 39788 |                const Type& v1 = vovov->t1(); 
 39789 |                const Type& v2 = vovov->t2(); 
 39790 |                const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39791 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 39792 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 39793 |                const details::operator_type o2 = operation; 
 39794 |  
 39795 |                binary_functor_t f0 = vovov->f0(); 
 39796 |                binary_functor_t f1 = vovov->f1(); 
 39797 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39798 |  
 39799 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39800 |  
 39801 |                expression_node_ptr result = error_node(); 
 39802 |  
 39803 |                const bool synthesis_result = 
 39804 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39805 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 39806 |  
 39807 |                if (synthesis_result) 
 39808 |                   return result; 
 39809 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39810 |                   return error_node(); 
 39811 |  
 39812 |                exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n")); 
 39813 |  
 39814 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 39815 |             } 
 39816 |  
 39817 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39818 |                                          const details::operator_type o0, 
 39819 |                                          const details::operator_type o1, 
 39820 |                                          const details::operator_type o2) 
 39821 |             { 
 39822 |                return details::build_string() 
 39823 |                   << "((t" << expr_gen.to_str(o0) 
 39824 |                   << "t)"  << expr_gen.to_str(o1) 
 39825 |                   << "t)"  << expr_gen.to_str(o2) 
 39826 |                   << "t" 
 39827 |             } 
 39828 |          }; 
 39829 |  
 39830 |          struct synthesize_vovovoc_expression3 
 39831 |          { 
 39832 |             typedef typename vovovoc_t::type3 node_type; 
 39833 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 39834 |             typedef typename node_type::T0 T0; 
 39835 |             typedef typename node_type::T1 T1; 
 39836 |             typedef typename node_type::T2 T2; 
 39837 |             typedef typename node_type::T3 T3; 
 39838 |  
 39839 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39840 |                                                       const details::operator_type& operation, 
 39841 |                                                       expression_node_ptr (&branch)[2]) 
 39842 |             { 
 39843 |                // ((v0 o0 v1) o1 v2) o2 c 
 39844 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39845 |  
 39846 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 39847 |                const Type& v0 = vovov->t0(); 
 39848 |                const Type& v1 = vovov->t1(); 
 39849 |                const Type& v2 = vovov->t2(); 
 39850 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 39851 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 39852 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 39853 |                const details::operator_type o2 = operation; 
 39854 |  
 39855 |                binary_functor_t f0 = vovov->f0(); 
 39856 |                binary_functor_t f1 = vovov->f1(); 
 39857 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39858 |  
 39859 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39860 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39861 |  
 39862 |                expression_node_ptr result = error_node(); 
 39863 |  
 39864 |                const bool synthesis_result = 
 39865 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39866 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 39867 |  
 39868 |                if (synthesis_result) 
 39869 |                   return result; 
 39870 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39871 |                   return error_node(); 
 39872 |  
 39873 |                exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n")); 
 39874 |  
 39875 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 39876 |             } 
 39877 |  
 39878 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39879 |                                          const details::operator_type o0, 
 39880 |                                          const details::operator_type o1, 
 39881 |                                          const details::operator_type o2) 
 39882 |             { 
 39883 |                return details::build_string() 
 39884 |                   << "((t" << expr_gen.to_str(o0) 
 39885 |                   << "t)"  << expr_gen.to_str(o1) 
 39886 |                   << "t)"  << expr_gen.to_str(o2) 
 39887 |                   << "t" 
 39888 |             } 
 39889 |          }; 
 39890 |  
 39891 |          struct synthesize_vovocov_expression3 
 39892 |          { 
 39893 |             typedef typename vovocov_t::type3 node_type; 
 39894 |             typedef typename vovocov_t::sf4_type sf4_type; 
 39895 |             typedef typename node_type::T0 T0; 
 39896 |             typedef typename node_type::T1 T1; 
 39897 |             typedef typename node_type::T2 T2; 
 39898 |             typedef typename node_type::T3 T3; 
 39899 |  
 39900 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39901 |                                                       const details::operator_type& operation, 
 39902 |                                                       expression_node_ptr (&branch)[2]) 
 39903 |             { 
 39904 |                // ((v0 o0 v1) o1 c) o2 v2 
 39905 |                typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t; 
 39906 |  
 39907 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]); 
 39908 |                const Type& v0 = vovoc->t0(); 
 39909 |                const Type& v1 = vovoc->t1(); 
 39910 |                const Type   c = vovoc->t2(); 
 39911 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39912 |                const details::operator_type o0 = expr_gen.get_operator(vovoc->f0()); 
 39913 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f1()); 
 39914 |                const details::operator_type o2 = operation; 
 39915 |  
 39916 |                binary_functor_t f0 = vovoc->f0(); 
 39917 |                binary_functor_t f1 = vovoc->f1(); 
 39918 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39919 |  
 39920 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39921 |  
 39922 |                expression_node_ptr result = error_node(); 
 39923 |  
 39924 |                const bool synthesis_result = 
 39925 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39926 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 39927 |  
 39928 |                if (synthesis_result) 
 39929 |                   return result; 
 39930 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39931 |                   return error_node(); 
 39932 |  
 39933 |                exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n")); 
 39934 |  
 39935 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 39936 |             } 
 39937 |  
 39938 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39939 |                                          const details::operator_type o0, 
 39940 |                                          const details::operator_type o1, 
 39941 |                                          const details::operator_type o2) 
 39942 |             { 
 39943 |                return details::build_string() 
 39944 |                   << "((t" << expr_gen.to_str(o0) 
 39945 |                   << "t)"  << expr_gen.to_str(o1) 
 39946 |                   << "t)"  << expr_gen.to_str(o2) 
 39947 |                   << "t" 
 39948 |             } 
 39949 |          }; 
 39950 |  
 39951 |          struct synthesize_vocovov_expression3 
 39952 |          { 
 39953 |             typedef typename vocovov_t::type3 node_type; 
 39954 |             typedef typename vocovov_t::sf4_type sf4_type; 
 39955 |             typedef typename node_type::T0 T0; 
 39956 |             typedef typename node_type::T1 T1; 
 39957 |             typedef typename node_type::T2 T2; 
 39958 |             typedef typename node_type::T3 T3; 
 39959 |  
 39960 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39961 |                                                       const details::operator_type& operation, 
 39962 |                                                       expression_node_ptr (&branch)[2]) 
 39963 |             { 
 39964 |                // ((v0 o0 c) o1 v1) o2 v2 
 39965 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 39966 |  
 39967 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 39968 |                const Type& v0 = vocov->t0(); 
 39969 |                const Type   c = vocov->t1(); 
 39970 |                const Type& v1 = vocov->t2(); 
 39971 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39972 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 39973 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 39974 |                const details::operator_type o2 = operation; 
 39975 |  
 39976 |                binary_functor_t f0 = vocov->f0(); 
 39977 |                binary_functor_t f1 = vocov->f1(); 
 39978 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39979 |  
 39980 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39981 |  
 39982 |                expression_node_ptr result = error_node(); 
 39983 |  
 39984 |                const bool synthesis_result = 
 39985 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39986 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 39987 |  
 39988 |                if (synthesis_result) 
 39989 |                   return result; 
 39990 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39991 |                   return error_node(); 
 39992 |  
 39993 |                exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n")); 
 39994 |  
 39995 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 39996 |             } 
 39997 |  
 39998 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39999 |                                          const details::operator_type o0, 
 40000 |                                          const details::operator_type o1, 
 40001 |                                          const details::operator_type o2) 
 40002 |             { 
 40003 |                return details::build_string() 
 40004 |                   << "((t" << expr_gen.to_str(o0) 
 40005 |                   << "t)"  << expr_gen.to_str(o1) 
 40006 |                   << "t)"  << expr_gen.to_str(o2) 
 40007 |                   << "t" 
 40008 |             } 
 40009 |          }; 
 40010 |  
 40011 |          struct synthesize_covovov_expression3 
 40012 |          { 
 40013 |             typedef typename covovov_t::type3 node_type; 
 40014 |             typedef typename covovov_t::sf4_type sf4_type; 
 40015 |             typedef typename node_type::T0 T0; 
 40016 |             typedef typename node_type::T1 T1; 
 40017 |             typedef typename node_type::T2 T2; 
 40018 |             typedef typename node_type::T3 T3; 
 40019 |  
 40020 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40021 |                                                       const details::operator_type& operation, 
 40022 |                                                       expression_node_ptr (&branch)[2]) 
 40023 |             { 
 40024 |                // ((c o0 v0) o1 v1) o2 v2 
 40025 |                typedef typename synthesize_covov_expression0::node_type lcl_covov_t; 
 40026 |  
 40027 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40028 |                const Type   c = covov->t0(); 
 40029 |                const Type& v0 = covov->t1(); 
 40030 |                const Type& v1 = covov->t2(); 
 40031 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40032 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40033 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40034 |                const details::operator_type o2 = operation; 
 40035 |  
 40036 |                binary_functor_t f0 = covov->f0(); 
 40037 |                binary_functor_t f1 = covov->f1(); 
 40038 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40039 |  
 40040 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40041 |  
 40042 |                expression_node_ptr result = error_node(); 
 40043 |  
 40044 |                const bool synthesis_result = 
 40045 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40046 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 40047 |  
 40048 |                if (synthesis_result) 
 40049 |                   return result; 
 40050 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40051 |                   return error_node(); 
 40052 |  
 40053 |                exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n")); 
 40054 |  
 40055 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 40056 |             } 
 40057 |  
 40058 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40059 |                                          const details::operator_type o0, 
 40060 |                                          const details::operator_type o1, 
 40061 |                                          const details::operator_type o2) 
 40062 |             { 
 40063 |                return details::build_string() 
 40064 |                   << "((t" << expr_gen.to_str(o0) 
 40065 |                   << "t)"  << expr_gen.to_str(o1) 
 40066 |                   << "t)"  << expr_gen.to_str(o2) 
 40067 |                   << "t" 
 40068 |             } 
 40069 |          }; 
 40070 |  
 40071 |          struct synthesize_covocov_expression3 
 40072 |          { 
 40073 |             typedef typename covocov_t::type3 node_type; 
 40074 |             typedef typename covocov_t::sf4_type sf4_type; 
 40075 |             typedef typename node_type::T0 T0; 
 40076 |             typedef typename node_type::T1 T1; 
 40077 |             typedef typename node_type::T2 T2; 
 40078 |             typedef typename node_type::T3 T3; 
 40079 |  
 40080 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40081 |                                                       const details::operator_type& operation, 
 40082 |                                                       expression_node_ptr (&branch)[2]) 
 40083 |             { 
 40084 |                // ((c0 o0 v0) o1 c1) o2 v1 
 40085 |                typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t; 
 40086 |  
 40087 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]); 
 40088 |                const Type  c0 = covoc->t0(); 
 40089 |                const Type& v0 = covoc->t1(); 
 40090 |                const Type  c1 = covoc->t2(); 
 40091 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40092 |                const details::operator_type o0 = expr_gen.get_operator(covoc->f0()); 
 40093 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f1()); 
 40094 |                const details::operator_type o2 = operation; 
 40095 |  
 40096 |                binary_functor_t f0 = covoc->f0(); 
 40097 |                binary_functor_t f1 = covoc->f1(); 
 40098 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40099 |  
 40100 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40101 |  
 40102 |                expression_node_ptr result = error_node(); 
 40103 |  
 40104 |                const bool synthesis_result = 
 40105 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40106 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 40107 |  
 40108 |                if (synthesis_result) 
 40109 |                   return result; 
 40110 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40111 |                   return error_node(); 
 40112 |  
 40113 |                exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n")); 
 40114 |  
 40115 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 40116 |             } 
 40117 |  
 40118 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40119 |                                          const details::operator_type o0, 
 40120 |                                          const details::operator_type o1, 
 40121 |                                          const details::operator_type o2) 
 40122 |             { 
 40123 |                return details::build_string() 
 40124 |                   << "((t" << expr_gen.to_str(o0) 
 40125 |                   << "t)"  << expr_gen.to_str(o1) 
 40126 |                   << "t)"  << expr_gen.to_str(o2) 
 40127 |                   << "t" 
 40128 |             } 
 40129 |          }; 
 40130 |  
 40131 |          struct synthesize_vocovoc_expression3 
 40132 |          { 
 40133 |             typedef typename vocovoc_t::type3 node_type; 
 40134 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 40135 |             typedef typename node_type::T0 T0; 
 40136 |             typedef typename node_type::T1 T1; 
 40137 |             typedef typename node_type::T2 T2; 
 40138 |             typedef typename node_type::T3 T3; 
 40139 |  
 40140 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40141 |                                                       const details::operator_type& operation, 
 40142 |                                                       expression_node_ptr (&branch)[2]) 
 40143 |             { 
 40144 |                // ((v0 o0 c0) o1 v1) o2 c1 
 40145 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 40146 |  
 40147 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 40148 |                const Type& v0 = vocov->t0(); 
 40149 |                const Type  c0 = vocov->t1(); 
 40150 |                const Type& v1 = vocov->t2(); 
 40151 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40152 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 40153 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 40154 |                const details::operator_type o2 = operation; 
 40155 |  
 40156 |                binary_functor_t f0 = vocov->f0(); 
 40157 |                binary_functor_t f1 = vocov->f1(); 
 40158 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40159 |  
 40160 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40161 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40162 |  
 40163 |                expression_node_ptr result = error_node(); 
 40164 |  
 40165 |                const bool synthesis_result = 
 40166 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40167 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 40168 |  
 40169 |                if (synthesis_result) 
 40170 |                   return result; 
 40171 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40172 |                   return error_node(); 
 40173 |  
 40174 |                exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n")); 
 40175 |  
 40176 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 40177 |             } 
 40178 |  
 40179 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40180 |                                          const details::operator_type o0, 
 40181 |                                          const details::operator_type o1, 
 40182 |                                          const details::operator_type o2) 
 40183 |             { 
 40184 |                return details::build_string() 
 40185 |                   << "((t" << expr_gen.to_str(o0) 
 40186 |                   << "t)"  << expr_gen.to_str(o1) 
 40187 |                   << "t)"  << expr_gen.to_str(o2) 
 40188 |                   << "t" 
 40189 |             } 
 40190 |          }; 
 40191 |  
 40192 |          struct synthesize_covovoc_expression3 
 40193 |          { 
 40194 |             typedef typename covovoc_t::type3 node_type; 
 40195 |             typedef typename covovoc_t::sf4_type sf4_type; 
 40196 |             typedef typename node_type::T0 T0; 
 40197 |             typedef typename node_type::T1 T1; 
 40198 |             typedef typename node_type::T2 T2; 
 40199 |             typedef typename node_type::T3 T3; 
 40200 |  
 40201 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40202 |                                                       const details::operator_type& operation, 
 40203 |                                                       expression_node_ptr (&branch)[2]) 
 40204 |             { 
 40205 |                // ((c0 o0 v0) o1 v1) o2 c1 
 40206 |                typedef typename synthesize_covov_expression0::node_type lcl_covov_t; 
 40207 |  
 40208 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40209 |                const Type  c0 = covov->t0(); 
 40210 |                const Type& v0 = covov->t1(); 
 40211 |                const Type& v1 = covov->t2(); 
 40212 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40213 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40214 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40215 |                const details::operator_type o2 = operation; 
 40216 |  
 40217 |                binary_functor_t f0 = covov->f0(); 
 40218 |                binary_functor_t f1 = covov->f1(); 
 40219 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40220 |  
 40221 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40222 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40223 |  
 40224 |                expression_node_ptr result = error_node(); 
 40225 |  
 40226 |                const bool synthesis_result = 
 40227 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40228 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 40229 |  
 40230 |                if (synthesis_result) 
 40231 |                   return result; 
 40232 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40233 |                   return error_node(); 
 40234 |  
 40235 |                exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n")); 
 40236 |  
 40237 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 40238 |             } 
 40239 |  
 40240 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40241 |                                          const details::operator_type o0, 
 40242 |                                          const details::operator_type o1, 
 40243 |                                          const details::operator_type o2) 
 40244 |             { 
 40245 |                return details::build_string() 
 40246 |                   << "((t" << expr_gen.to_str(o0) 
 40247 |                   << "t)"  << expr_gen.to_str(o1) 
 40248 |                   << "t)"  << expr_gen.to_str(o2) 
 40249 |                   << "t" 
 40250 |             } 
 40251 |          }; 
 40252 |  
 40253 |          struct synthesize_vococov_expression3 
 40254 |          { 
 40255 |             typedef typename vococov_t::type3 node_type; 
 40256 |             typedef typename vococov_t::sf4_type sf4_type; 
 40257 |             typedef typename node_type::T0 T0; 
 40258 |             typedef typename node_type::T1 T1; 
 40259 |             typedef typename node_type::T2 T2; 
 40260 |             typedef typename node_type::T3 T3; 
 40261 |  
 40262 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40263 |                                                       const details::operator_type& operation, 
 40264 |                                                       expression_node_ptr (&branch)[2]) 
 40265 |             { 
 40266 |                // ((v0 o0 c0) o1 c1) o2 v1 
 40267 |                typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t; 
 40268 |  
 40269 |                const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]); 
 40270 |                const Type& v0 = vococ->t0(); 
 40271 |                const Type  c0 = vococ->t1(); 
 40272 |                const Type  c1 = vococ->t2(); 
 40273 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40274 |                const details::operator_type o0 = expr_gen.get_operator(vococ->f0()); 
 40275 |                const details::operator_type o1 = expr_gen.get_operator(vococ->f1()); 
 40276 |                const details::operator_type o2 = operation; 
 40277 |  
 40278 |                binary_functor_t f0 = vococ->f0(); 
 40279 |                binary_functor_t f1 = vococ->f1(); 
 40280 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40281 |  
 40282 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40283 |  
 40284 |                expression_node_ptr result = error_node(); 
 40285 |  
 40286 |                const bool synthesis_result = 
 40287 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40288 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result); 
 40289 |  
 40290 |                if (synthesis_result) 
 40291 |                   return result; 
 40292 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40293 |                   return error_node(); 
 40294 |  
 40295 |                exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n")); 
 40296 |  
 40297 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2); 
 40298 |             } 
 40299 |  
 40300 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40301 |                                          const details::operator_type o0, 
 40302 |                                          const details::operator_type o1, 
 40303 |                                          const details::operator_type o2) 
 40304 |             { 
 40305 |                return details::build_string() 
 40306 |                   << "((t" << expr_gen.to_str(o0) 
 40307 |                   << "t)"  << expr_gen.to_str(o1) 
 40308 |                   << "t)"  << expr_gen.to_str(o2) 
 40309 |                   << "t" 
 40310 |             } 
 40311 |          }; 
 40312 |  
 40313 |          struct synthesize_vovovov_expression4 
 40314 |          { 
 40315 |             typedef typename vovovov_t::type4 node_type; 
 40316 |             typedef typename vovovov_t::sf4_type sf4_type; 
 40317 |             typedef typename node_type::T0 T0; 
 40318 |             typedef typename node_type::T1 T1; 
 40319 |             typedef typename node_type::T2 T2; 
 40320 |             typedef typename node_type::T3 T3; 
 40321 |  
 40322 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40323 |                                                       const details::operator_type& operation, 
 40324 |                                                       expression_node_ptr (&branch)[2]) 
 40325 |             { 
 40326 |                // (v0 o0 (v1 o1 v2)) o2 v3 
 40327 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 40328 |  
 40329 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 40330 |                const Type& v0 = vovov->t0(); 
 40331 |                const Type& v1 = vovov->t1(); 
 40332 |                const Type& v2 = vovov->t2(); 
 40333 |                const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40334 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 40335 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 40336 |                const details::operator_type o2 = operation; 
 40337 |  
 40338 |                binary_functor_t f0 = vovov->f0(); 
 40339 |                binary_functor_t f1 = vovov->f1(); 
 40340 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40341 |  
 40342 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40343 |  
 40344 |                expression_node_ptr result = error_node(); 
 40345 |  
 40346 |                const bool synthesis_result = 
 40347 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40348 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 40349 |  
 40350 |                if (synthesis_result) 
 40351 |                   return result; 
 40352 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40353 |                   return error_node(); 
 40354 |  
 40355 |                exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n")); 
 40356 |  
 40357 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 40358 |             } 
 40359 |  
 40360 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40361 |                                          const details::operator_type o0, 
 40362 |                                          const details::operator_type o1, 
 40363 |                                          const details::operator_type o2) 
 40364 |             { 
 40365 |                return details::build_string() 
 40366 |                   << "(t" << expr_gen.to_str(o0) 
 40367 |                   << "(t" << expr_gen.to_str(o1) 
 40368 |                   << "t)" << expr_gen.to_str(o2) 
 40369 |                   << "t" 
 40370 |             } 
 40371 |          }; 
 40372 |  
 40373 |          struct synthesize_vovovoc_expression4 
 40374 |          { 
 40375 |             typedef typename vovovoc_t::type4 node_type; 
 40376 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 40377 |             typedef typename node_type::T0 T0; 
 40378 |             typedef typename node_type::T1 T1; 
 40379 |             typedef typename node_type::T2 T2; 
 40380 |             typedef typename node_type::T3 T3; 
 40381 |  
 40382 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40383 |                                                       const details::operator_type& operation, 
 40384 |                                                       expression_node_ptr (&branch)[2]) 
 40385 |             { 
 40386 |                // ((v0 o0 (v1 o1 v2)) o2 c) 
 40387 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 40388 |  
 40389 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 40390 |                const Type& v0 = vovov->t0(); 
 40391 |                const Type& v1 = vovov->t1(); 
 40392 |                const Type& v2 = vovov->t2(); 
 40393 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40394 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 40395 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 40396 |                const details::operator_type o2 = operation; 
 40397 |  
 40398 |                binary_functor_t f0 = vovov->f0(); 
 40399 |                binary_functor_t f1 = vovov->f1(); 
 40400 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40401 |  
 40402 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40403 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40404 |  
 40405 |                expression_node_ptr result = error_node(); 
 40406 |  
 40407 |                const bool synthesis_result = 
 40408 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40409 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 40410 |  
 40411 |                if (synthesis_result) 
 40412 |                   return result; 
 40413 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40414 |                   return error_node(); 
 40415 |  
 40416 |                exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n")); 
 40417 |  
 40418 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 40419 |             } 
 40420 |  
 40421 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40422 |                                          const details::operator_type o0, 
 40423 |                                          const details::operator_type o1, 
 40424 |                                          const details::operator_type o2) 
 40425 |             { 
 40426 |                return details::build_string() 
 40427 |                   << "(t" << expr_gen.to_str(o0) 
 40428 |                   << "(t" << expr_gen.to_str(o1) 
 40429 |                   << "t)" << expr_gen.to_str(o2) 
 40430 |                   << "t" 
 40431 |             } 
 40432 |          }; 
 40433 |  
 40434 |          struct synthesize_vovocov_expression4 
 40435 |          { 
 40436 |             typedef typename vovocov_t::type4 node_type; 
 40437 |             typedef typename vovocov_t::sf4_type sf4_type; 
 40438 |             typedef typename node_type::T0 T0; 
 40439 |             typedef typename node_type::T1 T1; 
 40440 |             typedef typename node_type::T2 T2; 
 40441 |             typedef typename node_type::T3 T3; 
 40442 |  
 40443 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40444 |                                                       const details::operator_type& operation, 
 40445 |                                                       expression_node_ptr (&branch)[2]) 
 40446 |             { 
 40447 |                // ((v0 o0 (v1 o1 c)) o2 v1) 
 40448 |                typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t; 
 40449 |  
 40450 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]); 
 40451 |                const Type& v0 = vovoc->t0(); 
 40452 |                const Type& v1 = vovoc->t1(); 
 40453 |                const Type   c = vovoc->t2(); 
 40454 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40455 |                const details::operator_type o0 = expr_gen.get_operator(vovoc->f0()); 
 40456 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f1()); 
 40457 |                const details::operator_type o2 = operation; 
 40458 |  
 40459 |                binary_functor_t f0 = vovoc->f0(); 
 40460 |                binary_functor_t f1 = vovoc->f1(); 
 40461 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40462 |  
 40463 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40464 |  
 40465 |                expression_node_ptr result = error_node(); 
 40466 |  
 40467 |                const bool synthesis_result = 
 40468 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40469 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 40470 |  
 40471 |                if (synthesis_result) 
 40472 |                   return result; 
 40473 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40474 |                   return error_node(); 
 40475 |  
 40476 |                exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n")); 
 40477 |  
 40478 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 40479 |             } 
 40480 |  
 40481 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40482 |                                          const details::operator_type o0, 
 40483 |                                          const details::operator_type o1, 
 40484 |                                          const details::operator_type o2) 
 40485 |             { 
 40486 |                return details::build_string() 
 40487 |                   << "(t" << expr_gen.to_str(o0) 
 40488 |                   << "(t" << expr_gen.to_str(o1) 
 40489 |                   << "t)" << expr_gen.to_str(o2) 
 40490 |                   << "t" 
 40491 |             } 
 40492 |          }; 
 40493 |  
 40494 |          struct synthesize_vocovov_expression4 
 40495 |          { 
 40496 |             typedef typename vocovov_t::type4 node_type; 
 40497 |             typedef typename vocovov_t::sf4_type sf4_type; 
 40498 |             typedef typename node_type::T0 T0; 
 40499 |             typedef typename node_type::T1 T1; 
 40500 |             typedef typename node_type::T2 T2; 
 40501 |             typedef typename node_type::T3 T3; 
 40502 |  
 40503 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40504 |                                                       const details::operator_type& operation, 
 40505 |                                                       expression_node_ptr (&branch)[2]) 
 40506 |             { 
 40507 |                // ((v0 o0 (c o1 v1)) o2 v2) 
 40508 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 40509 |  
 40510 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 40511 |                const Type& v0 = vocov->t0(); 
 40512 |                const Type   c = vocov->t1(); 
 40513 |                const Type& v1 = vocov->t2(); 
 40514 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40515 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 40516 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 40517 |                const details::operator_type o2 = operation; 
 40518 |  
 40519 |                binary_functor_t f0 = vocov->f0(); 
 40520 |                binary_functor_t f1 = vocov->f1(); 
 40521 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40522 |  
 40523 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40524 |                expression_node_ptr result = error_node(); 
 40525 |  
 40526 |                const bool synthesis_result = 
 40527 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40528 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 40529 |  
 40530 |                if (synthesis_result) 
 40531 |                   return result; 
 40532 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40533 |                   return error_node(); 
 40534 |  
 40535 |                exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n")); 
 40536 |  
 40537 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 40538 |             } 
 40539 |  
 40540 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40541 |                                          const details::operator_type o0, 
 40542 |                                          const details::operator_type o1, 
 40543 |                                          const details::operator_type o2) 
 40544 |             { 
 40545 |                return details::build_string() 
 40546 |                   << "(t" << expr_gen.to_str(o0) 
 40547 |                   << "(t" << expr_gen.to_str(o1) 
 40548 |                   << "t)" << expr_gen.to_str(o2) 
 40549 |                   << "t" 
 40550 |             } 
 40551 |          }; 
 40552 |  
 40553 |          struct synthesize_covovov_expression4 
 40554 |          { 
 40555 |             typedef typename covovov_t::type4 node_type; 
 40556 |             typedef typename covovov_t::sf4_type sf4_type; 
 40557 |             typedef typename node_type::T0 T0; 
 40558 |             typedef typename node_type::T1 T1; 
 40559 |             typedef typename node_type::T2 T2; 
 40560 |             typedef typename node_type::T3 T3; 
 40561 |  
 40562 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40563 |                                                       const details::operator_type& operation, 
 40564 |                                                       expression_node_ptr (&branch)[2]) 
 40565 |             { 
 40566 |                // ((c o0 (v0 o1 v1)) o2 v2) 
 40567 |                typedef typename synthesize_covov_expression1::node_type lcl_covov_t; 
 40568 |  
 40569 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40570 |                const Type   c = covov->t0(); 
 40571 |                const Type& v0 = covov->t1(); 
 40572 |                const Type& v1 = covov->t2(); 
 40573 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40574 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40575 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40576 |                const details::operator_type o2 = operation; 
 40577 |  
 40578 |                binary_functor_t f0 = covov->f0(); 
 40579 |                binary_functor_t f1 = covov->f1(); 
 40580 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40581 |  
 40582 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40583 |  
 40584 |                expression_node_ptr result = error_node(); 
 40585 |  
 40586 |                const bool synthesis_result = 
 40587 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40588 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 40589 |  
 40590 |                if (synthesis_result) 
 40591 |                   return result; 
 40592 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40593 |                   return error_node(); 
 40594 |  
 40595 |                exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n")); 
 40596 |  
 40597 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 40598 |             } 
 40599 |  
 40600 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40601 |                                          const details::operator_type o0, 
 40602 |                                          const details::operator_type o1, 
 40603 |                                          const details::operator_type o2) 
 40604 |             { 
 40605 |                return details::build_string() 
 40606 |                   << "(t" << expr_gen.to_str(o0) 
 40607 |                   << "(t" << expr_gen.to_str(o1) 
 40608 |                   << "t)" << expr_gen.to_str(o2) 
 40609 |                   << "t" 
 40610 |             } 
 40611 |          }; 
 40612 |  
 40613 |          struct synthesize_covocov_expression4 
 40614 |          { 
 40615 |             typedef typename covocov_t::type4 node_type; 
 40616 |             typedef typename covocov_t::sf4_type sf4_type; 
 40617 |             typedef typename node_type::T0 T0; 
 40618 |             typedef typename node_type::T1 T1; 
 40619 |             typedef typename node_type::T2 T2; 
 40620 |             typedef typename node_type::T3 T3; 
 40621 |  
 40622 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40623 |                                                       const details::operator_type& operation, 
 40624 |                                                       expression_node_ptr (&branch)[2]) 
 40625 |             { 
 40626 |                // ((c0 o0 (v0 o1 c1)) o2 v1) 
 40627 |                typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t; 
 40628 |  
 40629 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]); 
 40630 |                const Type  c0 = covoc->t0(); 
 40631 |                const Type& v0 = covoc->t1(); 
 40632 |                const Type  c1 = covoc->t2(); 
 40633 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40634 |                const details::operator_type o0 = expr_gen.get_operator(covoc->f0()); 
 40635 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f1()); 
 40636 |                const details::operator_type o2 = operation; 
 40637 |  
 40638 |                binary_functor_t f0 = covoc->f0(); 
 40639 |                binary_functor_t f1 = covoc->f1(); 
 40640 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40641 |  
 40642 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40643 |  
 40644 |                expression_node_ptr result = error_node(); 
 40645 |  
 40646 |                const bool synthesis_result = 
 40647 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40648 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 40649 |  
 40650 |                if (synthesis_result) 
 40651 |                   return result; 
 40652 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40653 |                   return error_node(); 
 40654 |  
 40655 |                exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n")); 
 40656 |  
 40657 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 40658 |             } 
 40659 |  
 40660 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40661 |                                          const details::operator_type o0, 
 40662 |                                          const details::operator_type o1, 
 40663 |                                          const details::operator_type o2) 
 40664 |             { 
 40665 |                return details::build_string() 
 40666 |                   << "(t" << expr_gen.to_str(o0) 
 40667 |                   << "(t" << expr_gen.to_str(o1) 
 40668 |                   << "t)" << expr_gen.to_str(o2) 
 40669 |                   << "t" 
 40670 |             } 
 40671 |          }; 
 40672 |  
 40673 |          struct synthesize_vocovoc_expression4 
 40674 |          { 
 40675 |             typedef typename vocovoc_t::type4 node_type; 
 40676 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 40677 |             typedef typename node_type::T0 T0; 
 40678 |             typedef typename node_type::T1 T1; 
 40679 |             typedef typename node_type::T2 T2; 
 40680 |             typedef typename node_type::T3 T3; 
 40681 |  
 40682 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40683 |                                                       const details::operator_type& operation, 
 40684 |                                                       expression_node_ptr (&branch)[2]) 
 40685 |             { 
 40686 |                // ((v0 o0 (c0 o1 v1)) o2 c1) 
 40687 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 40688 |  
 40689 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 40690 |                const Type& v0 = vocov->t0(); 
 40691 |                const Type  c0 = vocov->t1(); 
 40692 |                const Type& v1 = vocov->t2(); 
 40693 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40694 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 40695 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 40696 |                const details::operator_type o2 = operation; 
 40697 |  
 40698 |                binary_functor_t f0 = vocov->f0(); 
 40699 |                binary_functor_t f1 = vocov->f1(); 
 40700 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40701 |  
 40702 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40703 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40704 |  
 40705 |                expression_node_ptr result = error_node(); 
 40706 |  
 40707 |                const bool synthesis_result = 
 40708 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40709 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 40710 |  
 40711 |                if (synthesis_result) 
 40712 |                   return result; 
 40713 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40714 |                   return error_node(); 
 40715 |  
 40716 |                exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n")); 
 40717 |  
 40718 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 40719 |             } 
 40720 |  
 40721 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40722 |                                          const details::operator_type o0, 
 40723 |                                          const details::operator_type o1, 
 40724 |                                          const details::operator_type o2) 
 40725 |             { 
 40726 |                return details::build_string() 
 40727 |                   << "(t" << expr_gen.to_str(o0) 
 40728 |                   << "(t" << expr_gen.to_str(o1) 
 40729 |                   << "t)" << expr_gen.to_str(o2) 
 40730 |                   << "t" 
 40731 |             } 
 40732 |          }; 
 40733 |  
 40734 |          struct synthesize_covovoc_expression4 
 40735 |          { 
 40736 |             typedef typename covovoc_t::type4 node_type; 
 40737 |             typedef typename covovoc_t::sf4_type sf4_type; 
 40738 |             typedef typename node_type::T0 T0; 
 40739 |             typedef typename node_type::T1 T1; 
 40740 |             typedef typename node_type::T2 T2; 
 40741 |             typedef typename node_type::T3 T3; 
 40742 |  
 40743 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40744 |                                                       const details::operator_type& operation, 
 40745 |                                                       expression_node_ptr (&branch)[2]) 
 40746 |             { 
 40747 |                // ((c0 o0 (v0 o1 v1)) o2 c1) 
 40748 |                typedef typename synthesize_covov_expression1::node_type lcl_covov_t; 
 40749 |  
 40750 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40751 |                const Type  c0 = covov->t0(); 
 40752 |                const Type& v0 = covov->t1(); 
 40753 |                const Type& v1 = covov->t2(); 
 40754 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40755 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40756 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40757 |                const details::operator_type o2 = operation; 
 40758 |  
 40759 |                binary_functor_t f0 = covov->f0(); 
 40760 |                binary_functor_t f1 = covov->f1(); 
 40761 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40762 |  
 40763 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40764 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40765 |  
 40766 |                expression_node_ptr result = error_node(); 
 40767 |  
 40768 |                const bool synthesis_result = 
 40769 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40770 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 40771 |  
 40772 |                if (synthesis_result) 
 40773 |                   return result; 
 40774 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40775 |                   return error_node(); 
 40776 |  
 40777 |                exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n")); 
 40778 |  
 40779 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 40780 |             } 
 40781 |  
 40782 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40783 |                                          const details::operator_type o0, 
 40784 |                                          const details::operator_type o1, 
 40785 |                                          const details::operator_type o2) 
 40786 |             { 
 40787 |                return details::build_string() 
 40788 |                   << "(t" << expr_gen.to_str(o0) 
 40789 |                   << "(t" << expr_gen.to_str(o1) 
 40790 |                   << "t)" << expr_gen.to_str(o2) 
 40791 |                   << "t" 
 40792 |             } 
 40793 |          }; 
 40794 |  
 40795 |          struct synthesize_vococov_expression4 
 40796 |          { 
 40797 |             typedef typename vococov_t::type4 node_type; 
 40798 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 40799 |                                                       const details::operator_type&, 
 40800 |                                                       expression_node_ptr (&)[2]) 
 40801 |             { 
 40802 |                // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible 
 40803 |                exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n")); 
 40804 |                return error_node(); 
 40805 |             } 
 40806 |  
 40807 |             static inline std::string id(expression_generator<Type>&, 
 40808 |                                          const details::operator_type, 
 40809 |                                          const details::operator_type, 
 40810 |                                          const details::operator_type) 
 40811 |             { 
 40812 |                return "INVALID" 
 40813 |             } 
 40814 |          }; 
 40815 |          #endif 
 40816 |  
 40817 |          inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 40818 |          { 
 40819 |             // Definition: uv o uv 
 40820 |             details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation(); 
 40821 |             details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation(); 
 40822 |             const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v(); 
 40823 |             const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v(); 
 40824 |             unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0); 
 40825 |             unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0); 
 40826 |             binary_functor_t f = reinterpret_cast<binary_functor_t>(0); 
 40827 |  
 40828 |             if (!valid_operator(o0,u0)) 
 40829 |                return error_node(); 
 40830 |             else if (!valid_operator(o1,u1)) 
 40831 |                return error_node(); 
 40832 |             else if (!valid_operator(operation,f)) 
 40833 |                return error_node(); 
 40834 |  
 40835 |             expression_node_ptr result = error_node(); 
 40836 |  
 40837 |             if ( 
 40838 |                  (details::e_neg == o0) && 
 40839 |                  (details::e_neg == o1) 
 40840 |                ) 
 40841 |             { 
 40842 |                switch (operation) 
 40843 |                { 
 40844 |                   // (-v0 + -v1) --> -(v0 + v1) 
 40845 |                   case details::e_add : result = (*this)(details::e_neg, 
 40846 |                                                     node_allocator_-> 
 40847 |                                                        allocate_rr<typename details:: 
 40848 |                                                           vov_node<Type,details::add_op<Type> > >(v0, v1)); 
 40849 |                                         exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n")); 
 40850 |                                         break; 
 40851 |  
 40852 |                   // (-v0 - -v1) --> (v1 - v0) 
 40853 |                   case details::e_sub : result = node_allocator_-> 
 40854 |                                                     allocate_rr<typename details:: 
 40855 |                                                        vov_node<Type,details::sub_op<Type> > >(v1, v0); 
 40856 |                                         exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n")); 
 40857 |                                         break; 
 40858 |  
 40859 |                   // (-v0 * -v1) --> (v0 * v1) 
 40860 |                   case details::e_mul : result = node_allocator_-> 
 40861 |                                                     allocate_rr<typename details:: 
 40862 |                                                        vov_node<Type,details::mul_op<Type> > >(v0, v1); 
 40863 |                                         exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n")); 
 40864 |                                         break; 
 40865 |  
 40866 |                   // (-v0 / -v1) --> (v0 / v1) 
 40867 |                   case details::e_div : result = node_allocator_-> 
 40868 |                                                     allocate_rr<typename details:: 
 40869 |                                                        vov_node<Type,details::div_op<Type> > >(v0, v1); 
 40870 |                                         exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n")); 
 40871 |                                         break; 
 40872 |  
 40873 |                   default             : break; 
 40874 |                } 
 40875 |             } 
 40876 |  
 40877 |             if (0 == result) 
 40878 |             { 
 40879 |                result = node_allocator_-> 
 40880 |                             allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f); 
 40881 |             } 
 40882 |  
 40883 |             details::free_all_nodes(*node_allocator_,branch); 
 40884 |             return result; 
 40885 |          } 
 40886 |  
 40887 |          #undef basic_opr_switch_statements 
 40888 |          #undef extended_opr_switch_statements 
 40889 |          #undef unary_opr_switch_statements 
 40890 |  
 40891 |          #ifndef exprtk_disable_string_capabilities 
 40892 |  
 40893 |          #define string_opr_switch_statements            \ 
 40894 |          case_stmt(details::e_lt    , details::lt_op   ) \ 
 40895 |          case_stmt(details::e_lte   , details::lte_op  ) \ 
 40896 |          case_stmt(details::e_gt    , details::gt_op   ) \ 
 40897 |          case_stmt(details::e_gte   , details::gte_op  ) \ 
 40898 |          case_stmt(details::e_eq    , details::eq_op   ) \ 
 40899 |          case_stmt(details::e_ne    , details::ne_op   ) \ 
 40900 |          case_stmt(details::e_in    , details::in_op   ) \ 
 40901 |          case_stmt(details::e_like  , details::like_op ) \ 
 40902 |          case_stmt(details::e_ilike , details::ilike_op) \ 
 40903 |  
 40904 |          template <typename T0, typename T1> 
 40905 |          inline expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type& opr, 
 40906 |                                                                         T0 s0, T1 s1, 
 40907 |                                                                         range_t rp0) 
 40908 |          { 
 40909 |             switch (opr) 
 40910 |             { 
 40911 |                #define case_stmt(op0, op1)                                                                      \ 
 40912 |                case op0 : return node_allocator_->                                                              \ 
 40913 |                              allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \ 
 40914 |                                 (s0, s1, rp0);                                                                  \ 
 40915 |  
 40916 |                string_opr_switch_statements 
 40917 |                #undef case_stmt 
 40918 |                default : return error_node(); 
 40919 |             } 
 40920 |          } 
 40921 |  
 40922 |          template <typename T0, typename T1> 
 40923 |          inline expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type& opr, 
 40924 |                                                                         T0 s0, T1 s1, 
 40925 |                                                                         range_t rp1) 
 40926 |          { 
 40927 |             switch (opr) 
 40928 |             { 
 40929 |                #define case_stmt(op0, op1)                                                                      \ 
 40930 |                case op0 : return node_allocator_->                                                              \ 
 40931 |                              allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \ 
 40932 |                                 (s0, s1, rp1);                                                                  \ 
 40933 |  
 40934 |                string_opr_switch_statements 
 40935 |                #undef case_stmt 
 40936 |                default : return error_node(); 
 40937 |             } 
 40938 |          } 
 40939 |  
 40940 |          template <typename T0, typename T1> 
 40941 |          inline expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type& opr, 
 40942 |                                                                          T0 s0, T1 s1, 
 40943 |                                                                          range_t rp0, range_t rp1) 
 40944 |          { 
 40945 |             switch (opr) 
 40946 |             { 
 40947 |                #define case_stmt(op0, op1)                                                                        \ 
 40948 |                case op0 : return node_allocator_->                                                                \ 
 40949 |                              allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \ 
 40950 |                                 (s0, s1, rp0, rp1);                                                               \ 
 40951 |  
 40952 |                string_opr_switch_statements 
 40953 |                #undef case_stmt 
 40954 |                default : return error_node(); 
 40955 |             } 
 40956 |          } 
 40957 |  
 40958 |          template <typename T0, typename T1> 
 40959 |          inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1) 
 40960 |          { 
 40961 |             switch (opr) 
 40962 |             { 
 40963 |                #define case_stmt(op0, op1)                                                                 \ 
 40964 |                case op0 : return node_allocator_->                                                         \ 
 40965 |                              allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \ 
 40966 |  
 40967 |                string_opr_switch_statements 
 40968 |                #undef case_stmt 
 40969 |                default : return error_node(); 
 40970 |             } 
 40971 |          } 
 40972 |  
 40973 |          inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40974 |          { 
 40975 |             std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref(); 
 40976 |             std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref(); 
 40977 |  
 40978 |             return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1); 
 40979 |          } 
 40980 |  
 40981 |          inline expression_node_ptr synthesize_sros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40982 |          { 
 40983 |             std::string&  s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref  (); 
 40984 |             std::string&  s1 = static_cast<details::stringvar_node<Type>*>   (branch[1])->ref  (); 
 40985 |             range_t      rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range(); 
 40986 |  
 40987 |             static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 40988 |  
 40989 |             details::free_node(*node_allocator_,branch[0]); 
 40990 |  
 40991 |             return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0); 
 40992 |          } 
 40993 |  
 40994 |          inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40995 |          { 
 40996 |             std::string&  s0 = static_cast<details::stringvar_node<Type>*>   (branch[0])->ref  (); 
 40997 |             std::string&  s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref  (); 
 40998 |             range_t      rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range(); 
 40999 |  
 41000 |             static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41001 |  
 41002 |             details::free_node(*node_allocator_,branch[1]); 
 41003 |  
 41004 |             return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1); 
 41005 |          } 
 41006 |  
 41007 |          inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41008 |          { 
 41009 |             std::string&  s0 = static_cast<details::stringvar_node<Type>*>         (branch[0])->ref  (); 
 41010 |             std::string   s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 41011 |             range_t      rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 41012 |  
 41013 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41014 |  
 41015 |             details::free_node(*node_allocator_,branch[1]); 
 41016 |  
 41017 |             return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1); 
 41018 |          } 
 41019 |  
 41020 |          inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41021 |          { 
 41022 |             std::string&  s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref  (); 
 41023 |             std::string&  s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref  (); 
 41024 |             range_t      rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range(); 
 41025 |             range_t      rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range(); 
 41026 |  
 41027 |             static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41028 |             static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41029 |  
 41030 |             details::free_node(*node_allocator_,branch[0]); 
 41031 |             details::free_node(*node_allocator_,branch[1]); 
 41032 |  
 41033 |             return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1); 
 41034 |          } 
 41035 |  
 41036 |          inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41037 |          { 
 41038 |             std::string& s0 = static_cast<     details::stringvar_node<Type>*>(branch[0])->ref(); 
 41039 |             std::string  s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 41040 |  
 41041 |             details::free_node(*node_allocator_,branch[1]); 
 41042 |  
 41043 |             return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1); 
 41044 |          } 
 41045 |  
 41046 |          inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41047 |          { 
 41048 |             std::string  s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41049 |             std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41050 |  
 41051 |             details::free_node(*node_allocator_,branch[0]); 
 41052 |  
 41053 |             return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1); 
 41054 |          } 
 41055 |  
 41056 |          inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41057 |          { 
 41058 |             std::string  s0  = static_cast<details::string_literal_node<Type>*>(branch[0])->str  (); 
 41059 |             std::string& s1  = static_cast<details::string_range_node<Type>*  >(branch[1])->ref  (); 
 41060 |             range_t      rp1 = static_cast<details::string_range_node<Type>*  >(branch[1])->range(); 
 41061 |  
 41062 |             static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41063 |  
 41064 |             details::free_node(*node_allocator_,branch[0]); 
 41065 |             details::free_node(*node_allocator_,branch[1]); 
 41066 |  
 41067 |             return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1); 
 41068 |          } 
 41069 |  
 41070 |          inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41071 |          { 
 41072 |             std::string&  s0 = static_cast<details::string_range_node<Type>*  >(branch[0])->ref  (); 
 41073 |             std::string   s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str  (); 
 41074 |             range_t      rp0 = static_cast<details::string_range_node<Type>*  >(branch[0])->range(); 
 41075 |  
 41076 |             static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41077 |  
 41078 |             details::free_node(*node_allocator_,branch[0]); 
 41079 |             details::free_node(*node_allocator_,branch[1]); 
 41080 |  
 41081 |             return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0); 
 41082 |          } 
 41083 |  
 41084 |          inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41085 |          { 
 41086 |             std::string&  s0 = static_cast<details::string_range_node<Type>*      >(branch[0])->ref  (); 
 41087 |             std::string   s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 41088 |             range_t      rp0 = static_cast<details::string_range_node<Type>*      >(branch[0])->range(); 
 41089 |             range_t      rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 41090 |  
 41091 |             static_cast<details::string_range_node<Type>*>      (branch[0])->range_ref().clear(); 
 41092 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41093 |  
 41094 |             details::free_node(*node_allocator_,branch[0]); 
 41095 |             details::free_node(*node_allocator_,branch[1]); 
 41096 |  
 41097 |             return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1); 
 41098 |          } 
 41099 |  
 41100 |          inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41101 |          { 
 41102 |             const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41103 |             const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 41104 |  
 41105 |             expression_node_ptr result = error_node(); 
 41106 |  
 41107 |             if (details::e_add == opr) 
 41108 |                result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1); 
 41109 |             else if (details::e_in == opr) 
 41110 |                result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op   <Type>::process(s0,s1)); 
 41111 |             else if (details::e_like == opr) 
 41112 |                result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1)); 
 41113 |             else if (details::e_ilike == opr) 
 41114 |                result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1)); 
 41115 |             else 
 41116 |             { 
 41117 |                expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1); 
 41118 |  
 41119 |                const Type v = temp->value(); 
 41120 |  
 41121 |                details::free_node(*node_allocator_,temp); 
 41122 |  
 41123 |                result = node_allocator_->allocate<literal_node_t>(v); 
 41124 |             } 
 41125 |  
 41126 |             details::free_all_nodes(*node_allocator_,branch); 
 41127 |  
 41128 |             return result; 
 41129 |          } 
 41130 |  
 41131 |          inline expression_node_ptr synthesize_csocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41132 |          { 
 41133 |             const std::string s0 = static_cast<details::string_literal_node<Type>*    >(branch[0])->str  (); 
 41134 |                   std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 41135 |             range_t          rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 41136 |  
 41137 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41138 |  
 41139 |             details::free_node(*node_allocator_,branch[0]); 
 41140 |             details::free_node(*node_allocator_,branch[1]); 
 41141 |  
 41142 |             return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1); 
 41143 |          } 
 41144 |  
 41145 |          inline expression_node_ptr synthesize_csros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41146 |          { 
 41147 |             std::string   s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41148 |             std::string&  s1 = static_cast<details::stringvar_node<Type>*         >(branch[1])->ref  (); 
 41149 |             range_t      rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41150 |  
 41151 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41152 |  
 41153 |             details::free_node(*node_allocator_,branch[0]); 
 41154 |  
 41155 |             return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0); 
 41156 |          } 
 41157 |  
 41158 |          inline expression_node_ptr synthesize_csrosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41159 |          { 
 41160 |             const std::string  s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41161 |                   std::string& s1 = static_cast<details::string_range_node<Type>*      >(branch[1])->ref  (); 
 41162 |             const range_t     rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41163 |             const range_t     rp1 = static_cast<details::string_range_node<Type>*      >(branch[1])->range(); 
 41164 |  
 41165 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41166 |             static_cast<details::string_range_node<Type>*>      (branch[1])->range_ref().clear(); 
 41167 |  
 41168 |             details::free_node(*node_allocator_,branch[0]); 
 41169 |             details::free_node(*node_allocator_,branch[1]); 
 41170 |  
 41171 |             return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1); 
 41172 |          } 
 41173 |  
 41174 |          inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41175 |          { 
 41176 |             const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41177 |             const std::string s1 = static_cast<details::string_literal_node<Type>*    >(branch[1])->str  (); 
 41178 |             const range_t    rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41179 |  
 41180 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41181 |  
 41182 |             details::free_all_nodes(*node_allocator_,branch); 
 41183 |  
 41184 |             return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0); 
 41185 |          } 
 41186 |  
 41187 |          inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41188 |          { 
 41189 |             const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41190 |             const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 41191 |             const range_t    rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41192 |             const range_t    rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 41193 |  
 41194 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41195 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41196 |  
 41197 |             details::free_all_nodes(*node_allocator_,branch); 
 41198 |  
 41199 |             return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1); 
 41200 |          } 
 41201 |  
 41202 |          inline expression_node_ptr synthesize_strogen_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41203 |          { 
 41204 |             switch (opr) 
 41205 |             { 
 41206 |                #define case_stmt(op0, op1)                                                      \ 
 41207 |                case op0 : return node_allocator_->                                              \ 
 41208 |                              allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > >  \ 
 41209 |                                 (opr, branch[0], branch[1]);                                    \ 
 41210 |  
 41211 |                string_opr_switch_statements 
 41212 |                #undef case_stmt 
 41213 |                default : return error_node(); 
 41214 |             } 
 41215 |          } 
 41216 |  
 41217 |          #undef string_opr_switch_statements 
 41218 |          #endif 
 41219 |  
 41220 |          #ifndef exprtk_disable_string_capabilities 
 41221 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41222 |          { 
 41223 |             if ((0 == branch[0]) || (0 == branch[1])) 
 41224 |             { 
 41225 |                details::free_all_nodes(*node_allocator_,branch); 
 41226 |  
 41227 |                return error_node(); 
 41228 |             } 
 41229 |  
 41230 |             const bool b0_is_s   = details::is_string_node            (branch[0]); 
 41231 |             const bool b0_is_cs  = details::is_const_string_node      (branch[0]); 
 41232 |             const bool b0_is_sr  = details::is_string_range_node      (branch[0]); 
 41233 |             const bool b0_is_csr = details::is_const_string_range_node(branch[0]); 
 41234 |  
 41235 |             const bool b1_is_s   = details::is_string_node            (branch[1]); 
 41236 |             const bool b1_is_cs  = details::is_const_string_node      (branch[1]); 
 41237 |             const bool b1_is_sr  = details::is_string_range_node      (branch[1]); 
 41238 |             const bool b1_is_csr = details::is_const_string_range_node(branch[1]); 
 41239 |  
 41240 |             const bool b0_is_gen = details::is_string_assignment_node (branch[0]) || 
 41241 |                                    details::is_genricstring_range_node(branch[0]) || 
 41242 |                                    details::is_string_concat_node     (branch[0]) || 
 41243 |                                    details::is_string_function_node   (branch[0]) || 
 41244 |                                    details::is_string_condition_node  (branch[0]) || 
 41245 |                                    details::is_string_ccondition_node (branch[0]) || 
 41246 |                                    details::is_string_vararg_node     (branch[0]) ; 
 41247 |  
 41248 |             const bool b1_is_gen = details::is_string_assignment_node (branch[1]) || 
 41249 |                                    details::is_genricstring_range_node(branch[1]) || 
 41250 |                                    details::is_string_concat_node     (branch[1]) || 
 41251 |                                    details::is_string_function_node   (branch[1]) || 
 41252 |                                    details::is_string_condition_node  (branch[1]) || 
 41253 |                                    details::is_string_ccondition_node (branch[1]) || 
 41254 |                                    details::is_string_vararg_node     (branch[1]) ; 
 41255 |  
 41256 |             if (details::e_add == opr) 
 41257 |             { 
 41258 |                if (!b0_is_cs || !b1_is_cs) 
 41259 |                { 
 41260 |                   return synthesize_expression<string_concat_node_t,2>(opr,branch); 
 41261 |                } 
 41262 |             } 
 41263 |  
 41264 |             if (b0_is_gen || b1_is_gen) 
 41265 |             { 
 41266 |                return synthesize_strogen_expression(opr,branch); 
 41267 |             } 
 41268 |             else if (b0_is_s) 
 41269 |             { 
 41270 |                if      (b1_is_s  ) return synthesize_sos_expression   (opr,branch); 
 41271 |                else if (b1_is_cs ) return synthesize_socs_expression  (opr,branch); 
 41272 |                else if (b1_is_sr ) return synthesize_sosr_expression  (opr,branch); 
 41273 |                else if (b1_is_csr) return synthesize_socsr_expression (opr,branch); 
 41274 |             } 
 41275 |             else if (b0_is_cs) 
 41276 |             { 
 41277 |                if      (b1_is_s  ) return synthesize_csos_expression  (opr,branch); 
 41278 |                else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch); 
 41279 |                else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch); 
 41280 |                else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch); 
 41281 |             } 
 41282 |             else if (b0_is_sr) 
 41283 |             { 
 41284 |                if      (b1_is_s  ) return synthesize_sros_expression  (opr,branch); 
 41285 |                else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch); 
 41286 |                else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch); 
 41287 |                else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch); 
 41288 |             } 
 41289 |             else if (b0_is_csr) 
 41290 |             { 
 41291 |                if      (b1_is_s  ) return synthesize_csros_expression  (opr,branch); 
 41292 |                else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch); 
 41293 |                else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch); 
 41294 |                else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch); 
 41295 |             } 
 41296 |  
 41297 |             return error_node(); 
 41298 |          } 
 41299 |          #else 
 41300 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2]) 
 41301 |          { 
 41302 |             details::free_all_nodes(*node_allocator_,branch); 
 41303 |             return error_node(); 
 41304 |          } 
 41305 |          #endif 
 41306 |  
 41307 |          #ifndef exprtk_disable_string_capabilities 
 41308 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3]) 
 41309 |          { 
 41310 |             if (details::e_inrange != opr) 
 41311 |                return error_node(); 
 41312 |             else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2])) 
 41313 |             { 
 41314 |                details::free_all_nodes(*node_allocator_,branch); 
 41315 |  
 41316 |                return error_node(); 
 41317 |             } 
 41318 |             else if ( 
 41319 |                       details::is_const_string_node(branch[0]) && 
 41320 |                       details::is_const_string_node(branch[1]) && 
 41321 |                       details::is_const_string_node(branch[2]) 
 41322 |                     ) 
 41323 |             { 
 41324 |                const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41325 |                const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 41326 |                const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str(); 
 41327 |  
 41328 |                const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0)); 
 41329 |  
 41330 |                details::free_all_nodes(*node_allocator_,branch); 
 41331 |  
 41332 |                return node_allocator_->allocate_c<details::literal_node<Type> >(v); 
 41333 |             } 
 41334 |             else if ( 
 41335 |                       details::is_string_node(branch[0]) && 
 41336 |                       details::is_string_node(branch[1]) && 
 41337 |                       details::is_string_node(branch[2]) 
 41338 |                     ) 
 41339 |             { 
 41340 |                std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref(); 
 41341 |                std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref(); 
 41342 |                std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref(); 
 41343 |  
 41344 |                typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t; 
 41345 |  
 41346 |                return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2); 
 41347 |             } 
 41348 |             else if ( 
 41349 |                       details::is_const_string_node(branch[0]) && 
 41350 |                             details::is_string_node(branch[1]) && 
 41351 |                       details::is_const_string_node(branch[2]) 
 41352 |                     ) 
 41353 |             { 
 41354 |                std::string  s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41355 |                std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41356 |                std::string  s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str(); 
 41357 |  
 41358 |                typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t; 
 41359 |  
 41360 |                details::free_node(*node_allocator_,branch[0]); 
 41361 |                details::free_node(*node_allocator_,branch[2]); 
 41362 |  
 41363 |                return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2); 
 41364 |             } 
 41365 |             else if ( 
 41366 |                             details::is_string_node(branch[0]) && 
 41367 |                       details::is_const_string_node(branch[1]) && 
 41368 |                             details::is_string_node(branch[2]) 
 41369 |                     ) 
 41370 |             { 
 41371 |                std::string&  s0 = static_cast<details::stringvar_node<Type>*     >(branch[0])->ref(); 
 41372 |                std::string   s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 41373 |                std::string&  s2 = static_cast<details::stringvar_node<Type>*     >(branch[2])->ref(); 
 41374 |  
 41375 |                typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t; 
 41376 |  
 41377 |                details::free_node(*node_allocator_,branch[1]); 
 41378 |  
 41379 |                return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2); 
 41380 |             } 
 41381 |             else if ( 
 41382 |                       details::is_string_node(branch[0]) && 
 41383 |                       details::is_string_node(branch[1]) && 
 41384 |                       details::is_const_string_node(branch[2]) 
 41385 |                     ) 
 41386 |             { 
 41387 |                std::string& s0 = static_cast<details::stringvar_node<Type>*     >(branch[0])->ref(); 
 41388 |                std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41389 |                std::string  s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str(); 
 41390 |  
 41391 |                typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t; 
 41392 |  
 41393 |                details::free_node(*node_allocator_,branch[2]); 
 41394 |  
 41395 |                return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2); 
 41396 |             } 
 41397 |             else if ( 
 41398 |                       details::is_const_string_node(branch[0]) && 
 41399 |                       details::      is_string_node(branch[1]) && 
 41400 |                       details::      is_string_node(branch[2]) 
 41401 |                     ) 
 41402 |             { 
 41403 |                std::string  s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41404 |                std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41405 |                std::string& s2 = static_cast<details::stringvar_node<Type>*     >(branch[2])->ref(); 
 41406 |  
 41407 |                typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t; 
 41408 |  
 41409 |                details::free_node(*node_allocator_,branch[0]); 
 41410 |  
 41411 |                return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2); 
 41412 |             } 
 41413 |             else 
 41414 |                return error_node(); 
 41415 |          } 
 41416 |          #else 
 41417 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3]) 
 41418 |          { 
 41419 |             details::free_all_nodes(*node_allocator_,branch); 
 41420 |             return error_node(); 
 41421 |          } 
 41422 |          #endif 
 41423 |  
 41424 |          inline expression_node_ptr synthesize_null_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 41425 |          { 
 41426 |             /* 
 41427 |              Note: The following are the type promotion rules 
 41428 |              that relate to operations that include 'null': 
 41429 |              0. null ==/!=     null --> true false 
 41430 |              1. null operation null --> null 
 41431 |              2. x    ==/!=     null --> true/false 
 41432 |              3. null ==/!=     x    --> true/false 
 41433 |              4. x   operation  null --> x 
 41434 |              5. null operation x    --> x 
 41435 |             */ 
 41436 |  
 41437 |             typedef typename details::null_eq_node<T> nulleq_node_t; 
 41438 |  
 41439 |             const bool b0_null = details::is_null_node(branch[0]); 
 41440 |             const bool b1_null = details::is_null_node(branch[1]); 
 41441 |  
 41442 |             if (b0_null && b1_null) 
 41443 |             { 
 41444 |                expression_node_ptr result = error_node(); 
 41445 |  
 41446 |                if (details::e_eq == operation) 
 41447 |                   result = node_allocator_->allocate_c<literal_node_t>(T(1)); 
 41448 |                else if (details::e_ne == operation) 
 41449 |                   result = node_allocator_->allocate_c<literal_node_t>(T(0)); 
 41450 |  
 41451 |                if (result) 
 41452 |                { 
 41453 |                   details::free_node(*node_allocator_,branch[0]); 
 41454 |                   details::free_node(*node_allocator_,branch[1]); 
 41455 |  
 41456 |                   return result; 
 41457 |                } 
 41458 |  
 41459 |                details::free_node(*node_allocator_,branch[1]); 
 41460 |  
 41461 |                return branch[0]; 
 41462 |             } 
 41463 |             else if (details::e_eq == operation) 
 41464 |             { 
 41465 |                expression_node_ptr result = node_allocator_-> 
 41466 |                                                 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true); 
 41467 |  
 41468 |                details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]); 
 41469 |  
 41470 |                return result; 
 41471 |             } 
 41472 |             else if (details::e_ne == operation) 
 41473 |             { 
 41474 |                expression_node_ptr result = node_allocator_-> 
 41475 |                                                 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false); 
 41476 |  
 41477 |                details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]); 
 41478 |  
 41479 |                return result; 
 41480 |             } 
 41481 |             else if (b0_null) 
 41482 |             { 
 41483 |                details::free_node(*node_allocator_,branch[0]); 
 41484 |                branch[0] = branch[1]; 
 41485 |                branch[1] = error_node(); 
 41486 |             } 
 41487 |             else if (b1_null) 
 41488 |             { 
 41489 |                details::free_node(*node_allocator_,branch[1]); 
 41490 |                branch[1] = error_node(); 
 41491 |             } 
 41492 |  
 41493 |             if ( 
 41494 |                  (details::e_add == operation) || (details::e_sub == operation) || 
 41495 |                  (details::e_mul == operation) || (details::e_div == operation) || 
 41496 |                  (details::e_mod == operation) || (details::e_pow == operation) 
 41497 |                ) 
 41498 |             { 
 41499 |                return branch[0]; 
 41500 |             } 
 41501 |  
 41502 |             details::free_node(*node_allocator_, branch[0]); 
 41503 |  
 41504 |             if ( 
 41505 |                  (details::e_lt    == operation) || (details::e_lte  == operation) || 
 41506 |                  (details::e_gt    == operation) || (details::e_gte  == operation) || 
 41507 |                  (details::e_and   == operation) || (details::e_nand == operation) || 
 41508 |                  (details::e_or    == operation) || (details::e_nor  == operation) || 
 41509 |                  (details::e_xor   == operation) || (details::e_xnor == operation) || 
 41510 |                  (details::e_in    == operation) || (details::e_like == operation) || 
 41511 |                  (details::e_ilike == operation) 
 41512 |                ) 
 41513 |             { 
 41514 |                return node_allocator_->allocate_c<literal_node_t>(T(0)); 
 41515 |             } 
 41516 |  
 41517 |             return node_allocator_->allocate<details::null_node<Type> >(); 
 41518 |          } 
 41519 |  
 41520 |          template <typename NodeType, std::size_t N> 
 41521 |          inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N]) 
 41522 |          { 
 41523 |             if ( 
 41524 |                  (details::e_in    == operation) || 
 41525 |                  (details::e_like  == operation) || 
 41526 |                  (details::e_ilike == operation) 
 41527 |                ) 
 41528 |             { 
 41529 |                free_all_nodes(*node_allocator_,branch); 
 41530 |  
 41531 |                return error_node(); 
 41532 |             } 
 41533 |             else if (!details::all_nodes_valid<N>(branch)) 
 41534 |             { 
 41535 |                free_all_nodes(*node_allocator_,branch); 
 41536 |  
 41537 |                return error_node(); 
 41538 |             } 
 41539 |             else if ((details::e_default != operation)) 
 41540 |             { 
 41541 |                // Attempt simple constant folding optimisation. 
 41542 |                expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch); 
 41543 |  
 41544 |                if (is_constant_foldable<N>(branch)) 
 41545 |                { 
 41546 |                   const Type v = expression_point->value(); 
 41547 |                   details::free_node(*node_allocator_,expression_point); 
 41548 |  
 41549 |                   return node_allocator_->allocate<literal_node_t>(v); 
 41550 |                } 
 41551 |  
 41552 |                if (expression_point && expression_point->valid()) 
 41553 |                { 
 41554 |                   return expression_point; 
 41555 |                } 
 41556 |  
 41557 |                parser_->set_error(parser_error::make_error( 
 41558 |                   parser_error::e_parser, 
 41559 |                   token_t(), 
 41560 |                   "ERR280 - Failed to synthesize node: NodeType", 
 41561 |                   exprtk_error_location)); 
 41562 |  
 41563 |                details::free_node(*node_allocator_, expression_point); 
 41564 |             } 
 41565 |  
 41566 |             return error_node(); 
 41567 |          } 
 41568 |  
 41569 |          template <typename NodeType, std::size_t N> 
 41570 |          inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N]) 
 41571 |          { 
 41572 |             if (!details::all_nodes_valid<N>(branch)) 
 41573 |             { 
 41574 |                free_all_nodes(*node_allocator_,branch); 
 41575 |  
 41576 |                return error_node(); 
 41577 |             } 
 41578 |  
 41579 |             typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t; 
 41580 |  
 41581 |             // Attempt simple constant folding optimisation. 
 41582 |  
 41583 |             expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f); 
 41584 |             function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point); 
 41585 |  
 41586 |             if (0 == func_node_ptr) 
 41587 |             { 
 41588 |                free_all_nodes(*node_allocator_,branch); 
 41589 |  
 41590 |                return error_node(); 
 41591 |             } 
 41592 |             else 
 41593 |                func_node_ptr->init_branches(branch); 
 41594 |  
 41595 |             if (is_constant_foldable<N>(branch) && !f->has_side_effects()) 
 41596 |             { 
 41597 |                Type v = expression_point->value(); 
 41598 |                details::free_node(*node_allocator_,expression_point); 
 41599 |  
 41600 |                return node_allocator_->allocate<literal_node_t>(v); 
 41601 |             } 
 41602 |  
 41603 |             parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)"); 
 41604 |  
 41605 |             return expression_point; 
 41606 |          } 
 41607 |  
 41608 |          bool                     strength_reduction_enabled_; 
 41609 |          details::node_allocator* node_allocator_; 
 41610 |          synthesize_map_t         synthesize_map_; 
 41611 |          unary_op_map_t*          unary_op_map_; 
 41612 |          binary_op_map_t*         binary_op_map_; 
 41613 |          inv_binary_op_map_t*     inv_binary_op_map_; 
 41614 |          sf3_map_t*               sf3_map_; 
 41615 |          sf4_map_t*               sf4_map_; 
 41616 |          parser_t*                parser_; 
 41617 |       }; // class expression_generator 
 41618 |  
 41619 |       inline void set_error(const parser_error::type& error_type) 
 41620 |       { 
 41621 |          error_list_.push_back(error_type); 
 41622 |       } 
 41623 |  
 41624 |       inline void remove_last_error() 
 41625 |       { 
 41626 |          if (!error_list_.empty()) 
 41627 |          { 
 41628 |             error_list_.pop_back(); 
 41629 |          } 
 41630 |       } 
 41631 |  
 41632 |       inline void set_synthesis_error(const std::string& synthesis_error_message) 
 41633 |       { 
 41634 |          if (synthesis_error_.empty()) 
 41635 |          { 
 41636 |             synthesis_error_ = synthesis_error_message; 
 41637 |          } 
 41638 |       } 
 41639 |  
 41640 |       inline void register_local_vars(expression<T>& e) 
 41641 |       { 
 41642 |          for (std::size_t i = 0; i < sem_.size(); ++i) 
 41643 |          { 
 41644 |             scope_element& se = sem_.get_element(i); 
 41645 |  
 41646 |             exprtk_debug(("register_local_vars() - se[%s]\n", se.name.c_str())); 
 41647 |  
 41648 |             if ( 
 41649 |                  (scope_element::e_variable == se.type) || 
 41650 |                  (scope_element::e_literal  == se.type) || 
 41651 |                  (scope_element::e_vecelem  == se.type) 
 41652 |                ) 
 41653 |             { 
 41654 |                if (se.var_node) 
 41655 |                { 
 41656 |                   e.register_local_var(se.var_node); 
 41657 |                } 
 41658 |  
 41659 |                if (se.data) 
 41660 |                { 
 41661 |                   e.register_local_data(se.data, 1, 0); 
 41662 |                } 
 41663 |             } 
 41664 |             else if (scope_element::e_vector == se.type) 
 41665 |             { 
 41666 |                if (se.vec_node) 
 41667 |                { 
 41668 |                   e.register_local_var(se.vec_node); 
 41669 |                } 
 41670 |  
 41671 |                if (se.data) 
 41672 |                { 
 41673 |                   e.register_local_data(se.data, se.size, 1); 
 41674 |                } 
 41675 |             } 
 41676 |             #ifndef exprtk_disable_string_capabilities 
 41677 |             else if (scope_element::e_string == se.type) 
 41678 |             { 
 41679 |                if (se.str_node) 
 41680 |                { 
 41681 |                   e.register_local_var(se.str_node); 
 41682 |                } 
 41683 |  
 41684 |                if (se.data) 
 41685 |                { 
 41686 |                   e.register_local_data(se.data, se.size, 2); 
 41687 |                } 
 41688 |             } 
 41689 |             #endif 
 41690 |  
 41691 |             se.var_node  = 0; 
 41692 |             se.vec_node  = 0; 
 41693 |             #ifndef exprtk_disable_string_capabilities 
 41694 |             se.str_node  = 0; 
 41695 |             #endif 
 41696 |             se.data      = 0; 
 41697 |             se.ref_count = 0; 
 41698 |             se.active    = false; 
 41699 |          } 
 41700 |       } 
 41701 |  
 41702 |       inline void register_return_results(expression<T>& e) 
 41703 |       { 
 41704 |          e.register_return_results(results_context_); 
 41705 |          results_context_ = 0; 
 41706 |       } 
 41707 |  
 41708 |       inline void load_unary_operations_map(unary_op_map_t& m) 
 41709 |       { 
 41710 |          #define register_unary_op(Op, UnaryFunctor)            \ 
 41711 |          m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \ 
 41712 |  
 41713 |          register_unary_op(details::e_abs   , details::abs_op  ) 
 41714 |          register_unary_op(details::e_acos  , details::acos_op ) 
 41715 |          register_unary_op(details::e_acosh , details::acosh_op) 
 41716 |          register_unary_op(details::e_asin  , details::asin_op ) 
 41717 |          register_unary_op(details::e_asinh , details::asinh_op) 
 41718 |          register_unary_op(details::e_atanh , details::atanh_op) 
 41719 |          register_unary_op(details::e_ceil  , details::ceil_op ) 
 41720 |          register_unary_op(details::e_cos   , details::cos_op  ) 
 41721 |          register_unary_op(details::e_cosh  , details::cosh_op ) 
 41722 |          register_unary_op(details::e_exp   , details::exp_op  ) 
 41723 |          register_unary_op(details::e_expm1 , details::expm1_op) 
 41724 |          register_unary_op(details::e_floor , details::floor_op) 
 41725 |          register_unary_op(details::e_log   , details::log_op  ) 
 41726 |          register_unary_op(details::e_log10 , details::log10_op) 
 41727 |          register_unary_op(details::e_log2  , details::log2_op ) 
 41728 |          register_unary_op(details::e_log1p , details::log1p_op) 
 41729 |          register_unary_op(details::e_neg   , details::neg_op  ) 
 41730 |          register_unary_op(details::e_pos   , details::pos_op  ) 
 41731 |          register_unary_op(details::e_round , details::round_op) 
 41732 |          register_unary_op(details::e_sin   , details::sin_op  ) 
 41733 |          register_unary_op(details::e_sinc  , details::sinc_op ) 
 41734 |          register_unary_op(details::e_sinh  , details::sinh_op ) 
 41735 |          register_unary_op(details::e_sqrt  , details::sqrt_op ) 
 41736 |          register_unary_op(details::e_tan   , details::tan_op  ) 
 41737 |          register_unary_op(details::e_tanh  , details::tanh_op ) 
 41738 |          register_unary_op(details::e_cot   , details::cot_op  ) 
 41739 |          register_unary_op(details::e_sec   , details::sec_op  ) 
 41740 |          register_unary_op(details::e_csc   , details::csc_op  ) 
 41741 |          register_unary_op(details::e_r2d   , details::r2d_op  ) 
 41742 |          register_unary_op(details::e_d2r   , details::d2r_op  ) 
 41743 |          register_unary_op(details::e_d2g   , details::d2g_op  ) 
 41744 |          register_unary_op(details::e_g2d   , details::g2d_op  ) 
 41745 |          register_unary_op(details::e_notl  , details::notl_op ) 
 41746 |          register_unary_op(details::e_sgn   , details::sgn_op  ) 
 41747 |          register_unary_op(details::e_erf   , details::erf_op  ) 
 41748 |          register_unary_op(details::e_erfc  , details::erfc_op ) 
 41749 |          register_unary_op(details::e_ncdf  , details::ncdf_op ) 
 41750 |          register_unary_op(details::e_frac  , details::frac_op ) 
 41751 |          register_unary_op(details::e_trunc , details::trunc_op) 
 41752 |          #undef register_unary_op 
 41753 |       } 
 41754 |  
 41755 |       inline void load_binary_operations_map(binary_op_map_t& m) 
 41756 |       { 
 41757 |          typedef typename binary_op_map_t::value_type value_type; 
 41758 |  
 41759 |          #define register_binary_op(Op, BinaryFunctor)       \ 
 41760 |          m.insert(value_type(Op,BinaryFunctor<T>::process)); \ 
 41761 |  
 41762 |          register_binary_op(details::e_add  , details::add_op ) 
 41763 |          register_binary_op(details::e_sub  , details::sub_op ) 
 41764 |          register_binary_op(details::e_mul  , details::mul_op ) 
 41765 |          register_binary_op(details::e_div  , details::div_op ) 
 41766 |          register_binary_op(details::e_mod  , details::mod_op ) 
 41767 |          register_binary_op(details::e_pow  , details::pow_op ) 
 41768 |          register_binary_op(details::e_lt   , details::lt_op  ) 
 41769 |          register_binary_op(details::e_lte  , details::lte_op ) 
 41770 |          register_binary_op(details::e_gt   , details::gt_op  ) 
 41771 |          register_binary_op(details::e_gte  , details::gte_op ) 
 41772 |          register_binary_op(details::e_eq   , details::eq_op  ) 
 41773 |          register_binary_op(details::e_ne   , details::ne_op  ) 
 41774 |          register_binary_op(details::e_and  , details::and_op ) 
 41775 |          register_binary_op(details::e_nand , details::nand_op) 
 41776 |          register_binary_op(details::e_or   , details::or_op  ) 
 41777 |          register_binary_op(details::e_nor  , details::nor_op ) 
 41778 |          register_binary_op(details::e_xor  , details::xor_op ) 
 41779 |          register_binary_op(details::e_xnor , details::xnor_op) 
 41780 |          #undef register_binary_op 
 41781 |       } 
 41782 |  
 41783 |       inline void load_inv_binary_operations_map(inv_binary_op_map_t& m) 
 41784 |       { 
 41785 |          typedef typename inv_binary_op_map_t::value_type value_type; 
 41786 |  
 41787 |          #define register_binary_op(Op, BinaryFunctor)       \ 
 41788 |          m.insert(value_type(BinaryFunctor<T>::process,Op)); \ 
 41789 |  
 41790 |          register_binary_op(details::e_add  , details::add_op ) 
 41791 |          register_binary_op(details::e_sub  , details::sub_op ) 
 41792 |          register_binary_op(details::e_mul  , details::mul_op ) 
 41793 |          register_binary_op(details::e_div  , details::div_op ) 
 41794 |          register_binary_op(details::e_mod  , details::mod_op ) 
 41795 |          register_binary_op(details::e_pow  , details::pow_op ) 
 41796 |          register_binary_op(details::e_lt   , details::lt_op  ) 
 41797 |          register_binary_op(details::e_lte  , details::lte_op ) 
 41798 |          register_binary_op(details::e_gt   , details::gt_op  ) 
 41799 |          register_binary_op(details::e_gte  , details::gte_op ) 
 41800 |          register_binary_op(details::e_eq   , details::eq_op  ) 
 41801 |          register_binary_op(details::e_ne   , details::ne_op  ) 
 41802 |          register_binary_op(details::e_and  , details::and_op ) 
 41803 |          register_binary_op(details::e_nand , details::nand_op) 
 41804 |          register_binary_op(details::e_or   , details::or_op  ) 
 41805 |          register_binary_op(details::e_nor  , details::nor_op ) 
 41806 |          register_binary_op(details::e_xor  , details::xor_op ) 
 41807 |          register_binary_op(details::e_xnor , details::xnor_op) 
 41808 |          #undef register_binary_op 
 41809 |       } 
 41810 |  
 41811 |       inline void load_sf3_map(sf3_map_t& sf3_map) 
 41812 |       { 
 41813 |          typedef std::pair<trinary_functor_t,details::operator_type> pair_t; 
 41814 |  
 41815 |          #define register_sf3(Op)                                                                             \ 
 41816 |          sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \ 
 41817 |  
 41818 |          register_sf3(00) register_sf3(01) register_sf3(02) register_sf3(03) 
 41819 |          register_sf3(04) register_sf3(05) register_sf3(06) register_sf3(07) 
 41820 |          register_sf3(08) register_sf3(09) register_sf3(10) register_sf3(11) 
 41821 |          register_sf3(12) register_sf3(13) register_sf3(14) register_sf3(15) 
 41822 |          register_sf3(16) register_sf3(17) register_sf3(18) register_sf3(19) 
 41823 |          register_sf3(20) register_sf3(21) register_sf3(22) register_sf3(23) 
 41824 |          register_sf3(24) register_sf3(25) register_sf3(26) register_sf3(27) 
 41825 |          register_sf3(28) register_sf3(29) register_sf3(30) 
 41826 |          #undef register_sf3 
 41827 |  
 41828 |          #define register_sf3_extid(Id, Op)                                        \ 
 41829 |          sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \ 
 41830 |  
 41831 |          register_sf3_extid("(t-t)-t",23)  // (t-t)-t --> t-(t+t) 
 41832 |          #undef register_sf3_extid 
 41833 |       } 
 41834 |  
 41835 |       inline void load_sf4_map(sf4_map_t& sf4_map) 
 41836 |       { 
 41837 |          typedef std::pair<quaternary_functor_t,details::operator_type> pair_t; 
 41838 |  
 41839 |          #define register_sf4(Op)                                                                             \ 
 41840 |          sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \ 
 41841 |  
 41842 |          register_sf4(48) register_sf4(49) register_sf4(50) register_sf4(51) 
 41843 |          register_sf4(52) register_sf4(53) register_sf4(54) register_sf4(55) 
 41844 |          register_sf4(56) register_sf4(57) register_sf4(58) register_sf4(59) 
 41845 |          register_sf4(60) register_sf4(61) register_sf4(62) register_sf4(63) 
 41846 |          register_sf4(64) register_sf4(65) register_sf4(66) register_sf4(67) 
 41847 |          register_sf4(68) register_sf4(69) register_sf4(70) register_sf4(71) 
 41848 |          register_sf4(72) register_sf4(73) register_sf4(74) register_sf4(75) 
 41849 |          register_sf4(76) register_sf4(77) register_sf4(78) register_sf4(79) 
 41850 |          register_sf4(80) register_sf4(81) register_sf4(82) register_sf4(83) 
 41851 |          #undef register_sf4 
 41852 |  
 41853 |          #define register_sf4ext(Op)                                                                                    \ 
 41854 |          sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \ 
 41855 |  
 41856 |          register_sf4ext(00) register_sf4ext(01) register_sf4ext(02) register_sf4ext(03) 
 41857 |          register_sf4ext(04) register_sf4ext(05) register_sf4ext(06) register_sf4ext(07) 
 41858 |          register_sf4ext(08) register_sf4ext(09) register_sf4ext(10) register_sf4ext(11) 
 41859 |          register_sf4ext(12) register_sf4ext(13) register_sf4ext(14) register_sf4ext(15) 
 41860 |          register_sf4ext(16) register_sf4ext(17) register_sf4ext(18) register_sf4ext(19) 
 41861 |          register_sf4ext(20) register_sf4ext(21) register_sf4ext(22) register_sf4ext(23) 
 41862 |          register_sf4ext(24) register_sf4ext(25) register_sf4ext(26) register_sf4ext(27) 
 41863 |          register_sf4ext(28) register_sf4ext(29) register_sf4ext(30) register_sf4ext(31) 
 41864 |          register_sf4ext(32) register_sf4ext(33) register_sf4ext(34) register_sf4ext(35) 
 41865 |          register_sf4ext(36) register_sf4ext(36) register_sf4ext(38) register_sf4ext(39) 
 41866 |          register_sf4ext(40) register_sf4ext(41) register_sf4ext(42) register_sf4ext(43) 
 41867 |          register_sf4ext(44) register_sf4ext(45) register_sf4ext(46) register_sf4ext(47) 
 41868 |          register_sf4ext(48) register_sf4ext(49) register_sf4ext(50) register_sf4ext(51) 
 41869 |          register_sf4ext(52) register_sf4ext(53) register_sf4ext(54) register_sf4ext(55) 
 41870 |          register_sf4ext(56) register_sf4ext(57) register_sf4ext(58) register_sf4ext(59) 
 41871 |          register_sf4ext(60) register_sf4ext(61) 
 41872 |          #undef register_sf4ext 
 41873 |       } 
 41874 |  
 41875 |       inline results_context_t& results_ctx() 
 41876 |       { 
 41877 |          if (0 == results_context_) 
 41878 |          { 
 41879 |             results_context_ = new results_context_t(); 
 41880 |          } 
 41881 |  
 41882 |          return (*results_context_); 
 41883 |       } 
 41884 |  
 41885 |       inline void return_cleanup() 
 41886 |       { 
 41887 |          #ifndef exprtk_disable_return_statement 
 41888 |          if (results_context_) 
 41889 |          { 
 41890 |             delete results_context_; 
 41891 |             results_context_ = 0; 
 41892 |          } 
 41893 |  
 41894 |          state_.return_stmt_present = false; 
 41895 |          #endif 
 41896 |       } 
 41897 |  
 41898 |       inline bool valid_settings() 
 41899 |       { 
 41900 |          const std::size_t max_local_vector_size_bytes = sizeof(T) * settings_.max_local_vector_size(); 
 41901 |  
 41902 |          if (max_local_vector_size_bytes > settings_.max_total_local_symbol_size_bytes()) 
 41903 |          { 
 41904 |             set_error(make_error( 
 41905 |                parser_error::e_parser, 
 41906 |                "ERR281 - Max local vector size of " + details::to_str(max_local_vector_size_bytes) + " bytes " 
 41907 |                "is larger than max total local symbol size of " + details::to_str(settings_.max_total_local_symbol_size_bytes()) + " bytes", 
 41908 |                exprtk_error_location)); 
 41909 |  
 41910 |             return false; 
 41911 |          } 
 41912 |  
 41913 |          return true; 
 41914 |       } 
 41915 |  
 41916 |    private: 
 41917 |  
 41918 |       parser(const parser<T>&) exprtk_delete; 
 41919 |       parser<T>& operator=(const parser<T>&) exprtk_delete; 
 41920 |  
 41921 |       settings_store settings_; 
 41922 |       expression_generator<T> expression_generator_; 
 41923 |       details::node_allocator node_allocator_; 
 41924 |       symtab_store symtab_store_; 
 41925 |       dependent_entity_collector dec_; 
 41926 |       std::deque<parser_error::type> error_list_; 
 41927 |       std::deque<bool> brkcnt_list_; 
 41928 |       parser_state state_; 
 41929 |       bool resolve_unknown_symbol_; 
 41930 |       results_context_t* results_context_; 
 41931 |       unknown_symbol_resolver* unknown_symbol_resolver_; 
 41932 |       unknown_symbol_resolver default_usr_; 
 41933 |       base_ops_map_t base_ops_map_; 
 41934 |       unary_op_map_t unary_op_map_; 
 41935 |       binary_op_map_t binary_op_map_; 
 41936 |       inv_binary_op_map_t inv_binary_op_map_; 
 41937 |       sf3_map_t sf3_map_; 
 41938 |       sf4_map_t sf4_map_; 
 41939 |       std::string synthesis_error_; 
 41940 |       scope_element_manager sem_; 
 41941 |       std::vector<state_t> current_state_stack_; 
 41942 |  
 41943 |       immutable_memory_map_t immutable_memory_map_; 
 41944 |       immutable_symtok_map_t immutable_symtok_map_; 
 41945 |  
 41946 |       lexer::helper::helper_assembly helper_assembly_; 
 41947 |  
 41948 |       lexer::helper::commutative_inserter       commutative_inserter_; 
 41949 |       lexer::helper::operator_joiner            operator_joiner_2_; 
 41950 |       lexer::helper::operator_joiner            operator_joiner_3_; 
 41951 |       lexer::helper::symbol_replacer            symbol_replacer_; 
 41952 |       lexer::helper::bracket_checker            bracket_checker_; 
 41953 |       lexer::helper::numeric_checker<T>         numeric_checker_; 
 41954 |       lexer::helper::sequence_validator         sequence_validator_; 
 41955 |       lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_; 
 41956 |  
 41957 |       loop_runtime_check_ptr          loop_runtime_check_; 
 41958 |       vector_access_runtime_check_ptr vector_access_runtime_check_; 
 41959 |       compilation_check_ptr           compilation_check_ptr_; 
 41960 |       assert_check_ptr                assert_check_; 
 41961 |       std::set<std::string>           assert_ids_; 
 41962 |  
 41963 |       template <typename ParserType> 
 41964 |       friend void details::disable_type_checking(ParserType& p); 
 41965 |    }; // class parser 
 41966 |  
 41967 |    namespace details 
 41968 |    { 
 41969 |       template <typename T> 
 41970 |       struct collector_helper 
 41971 |       { 
 41972 |          typedef exprtk::symbol_table<T> symbol_table_t; 
 41973 |          typedef exprtk::expression<T>   expression_t; 
 41974 |          typedef exprtk::parser<T>       parser_t; 
 41975 |          typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t; 
 41976 |          typedef typename parser_t::unknown_symbol_resolver usr_t; 
 41977 |  
 41978 |          struct resolve_as_vector : public usr_t 
 41979 |          { 
 41980 |             typedef exprtk::parser<T> parser_t; 
 41981 |  
 41982 |             using usr_t::process; 
 41983 |  
 41984 |             resolve_as_vector() 
 41985 |             : usr_t(usr_t::e_usrmode_extended) 
 41986 |             {} 
 41987 |  
 41988 |             virtual bool process(const std::string& unknown_symbol, 
 41989 |                                  symbol_table_t& symbol_table, 
 41990 |                                  std::string&) exprtk_override 
 41991 |             { 
 41992 |                static T v[1]; 
 41993 |                symbol_table.add_vector(unknown_symbol,v); 
 41994 |                return true; 
 41995 |             } 
 41996 |          }; 
 41997 |  
 41998 |          static inline bool collection_pass(const std::string& expression_string, 
 41999 |                                             std::set<std::string>& symbol_set, 
 42000 |                                             const bool collect_variables, 
 42001 |                                             const bool collect_functions, 
 42002 |                                             const bool vector_pass, 
 42003 |                                             symbol_table_t& ext_symbol_table) 
 42004 |          { 
 42005 |             symbol_table_t symbol_table; 
 42006 |             expression_t   expression; 
 42007 |             parser_t       parser; 
 42008 |  
 42009 |             resolve_as_vector vect_resolver; 
 42010 |  
 42011 |             expression.register_symbol_table(symbol_table    ); 
 42012 |             expression.register_symbol_table(ext_symbol_table); 
 42013 |  
 42014 |             if (vector_pass) 
 42015 |                parser.enable_unknown_symbol_resolver(&vect_resolver); 
 42016 |             else 
 42017 |                parser.enable_unknown_symbol_resolver(); 
 42018 |  
 42019 |             if (collect_variables) 
 42020 |                parser.dec().collect_variables() = true; 
 42021 |  
 42022 |             if (collect_functions) 
 42023 |                parser.dec().collect_functions() = true; 
 42024 |  
 42025 |             bool pass_result = false; 
 42026 |  
 42027 |             details::disable_type_checking(parser); 
 42028 |  
 42029 |             if (parser.compile(expression_string, expression)) 
 42030 |             { 
 42031 |                pass_result = true; 
 42032 |  
 42033 |                std::deque<symbol_t> symb_list; 
 42034 |                parser.dec().symbols(symb_list); 
 42035 |  
 42036 |                for (std::size_t i = 0; i < symb_list.size(); ++i) 
 42037 |                { 
 42038 |                   symbol_set.insert(symb_list[i].first); 
 42039 |                } 
 42040 |             } 
 42041 |  
 42042 |             return pass_result; 
 42043 |          } 
 42044 |       }; 
 42045 |    } 
 42046 |  
 42047 |    template <typename Allocator, 
 42048 |              template <typename, typename> class Sequence> 
 42049 |    inline bool collect_variables(const std::string& expression, 
 42050 |                                  Sequence<std::string, Allocator>& symbol_list) 
 42051 |    { 
 42052 |       typedef double T; 
 42053 |       typedef details::collector_helper<T> collect_t; 
 42054 |  
 42055 |       collect_t::symbol_table_t null_symbol_table; 
 42056 |  
 42057 |       std::set<std::string> symbol_set; 
 42058 |  
 42059 |       const bool variable_pass = collect_t::collection_pass 
 42060 |                                     (expression, symbol_set, true, false, false, null_symbol_table); 
 42061 |       const bool vector_pass   = collect_t::collection_pass 
 42062 |                                     (expression, symbol_set, true, false,  true, null_symbol_table); 
 42063 |  
 42064 |       if (!variable_pass && !vector_pass) 
 42065 |          return false; 
 42066 |  
 42067 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 42068 |  
 42069 |       while (symbol_set.end() != itr) 
 42070 |       { 
 42071 |          symbol_list.push_back(*itr); 
 42072 |          ++itr; 
 42073 |       } 
 42074 |  
 42075 |       return true; 
 42076 |    } 
 42077 |  
 42078 |    template <typename T, 
 42079 |              typename Allocator, 
 42080 |              template <typename, typename> class Sequence> 
 42081 |    inline bool collect_variables(const std::string& expression, 
 42082 |                                  exprtk::symbol_table<T>& extrnl_symbol_table, 
 42083 |                                  Sequence<std::string, Allocator>& symbol_list) 
 42084 |    { 
 42085 |       typedef details::collector_helper<T> collect_t; 
 42086 |  
 42087 |       std::set<std::string> symbol_set; 
 42088 |  
 42089 |       const bool variable_pass = collect_t::collection_pass 
 42090 |                                     (expression, symbol_set, true, false, false, extrnl_symbol_table); 
 42091 |       const bool vector_pass   = collect_t::collection_pass 
 42092 |                                     (expression, symbol_set, true, false,  true, extrnl_symbol_table); 
 42093 |  
 42094 |       if (!variable_pass && !vector_pass) 
 42095 |          return false; 
 42096 |  
 42097 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 42098 |  
 42099 |       while (symbol_set.end() != itr) 
 42100 |       { 
 42101 |          symbol_list.push_back(*itr); 
 42102 |          ++itr; 
 42103 |       } 
 42104 |  
 42105 |       return true; 
 42106 |    } 
 42107 |  
 42108 |    template <typename Allocator, 
 42109 |              template <typename, typename> class Sequence> 
 42110 |    inline bool collect_functions(const std::string& expression, 
 42111 |                                  Sequence<std::string, Allocator>& symbol_list) 
 42112 |    { 
 42113 |       typedef double T; 
 42114 |       typedef details::collector_helper<T> collect_t; 
 42115 |  
 42116 |       collect_t::symbol_table_t null_symbol_table; 
 42117 |  
 42118 |       std::set<std::string> symbol_set; 
 42119 |  
 42120 |       const bool variable_pass = collect_t::collection_pass 
 42121 |                                     (expression, symbol_set, false, true, false, null_symbol_table); 
 42122 |       const bool vector_pass   = collect_t::collection_pass 
 42123 |                                     (expression, symbol_set, false, true,  true, null_symbol_table); 
 42124 |  
 42125 |       if (!variable_pass && !vector_pass) 
 42126 |          return false; 
 42127 |  
 42128 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 42129 |  
 42130 |       while (symbol_set.end() != itr) 
 42131 |       { 
 42132 |          symbol_list.push_back(*itr); 
 42133 |          ++itr; 
 42134 |       } 
 42135 |  
 42136 |       return true; 
 42137 |    } 
 42138 |  
 42139 |    template <typename T, 
 42140 |              typename Allocator, 
 42141 |              template <typename, typename> class Sequence> 
 42142 |    inline bool collect_functions(const std::string& expression, 
 42143 |                                  exprtk::symbol_table<T>& extrnl_symbol_table, 
 42144 |                                  Sequence<std::string, Allocator>& symbol_list) 
 42145 |    { 
 42146 |       typedef details::collector_helper<T> collect_t; 
 42147 |  
 42148 |       std::set<std::string> symbol_set; 
 42149 |  
 42150 |       const bool variable_pass = collect_t::collection_pass 
 42151 |                                     (expression, symbol_set, false, true, false, extrnl_symbol_table); 
 42152 |       const bool vector_pass   = collect_t::collection_pass 
 42153 |                                     (expression, symbol_set, false, true,  true, extrnl_symbol_table); 
 42154 |  
 42155 |       if (!variable_pass && !vector_pass) 
 42156 |          return false; 
 42157 |  
 42158 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 42159 |  
 42160 |       while (symbol_set.end() != itr) 
 42161 |       { 
 42162 |          symbol_list.push_back(*itr); 
 42163 |          ++itr; 
 42164 |       } 
 42165 |  
 42166 |       return true; 
 42167 |    } 
 42168 |  
 42169 |    template <typename T> 
 42170 |    inline T integrate(const expression<T>& e, 
 42171 |                       T& x, 
 42172 |                       const T& r0, const T& r1, 
 42173 |                       const std::size_t number_of_intervals = 1000000) 
 42174 |    { 
 42175 |       if (r0 > r1) 
 42176 |          return T(0); 
 42177 |  
 42178 |       const T h = (r1 - r0) / (T(2) * number_of_intervals); 
 42179 |       T total_area = T(0); 
 42180 |  
 42181 |       for (std::size_t i = 0; i < number_of_intervals; ++i) 
 42182 |       { 
 42183 |          x = r0 + T(2) * i * h; 
 42184 |          const T y0 = e.value(); x += h; 
 42185 |          const T y1 = e.value(); x += h; 
 42186 |          const T y2 = e.value(); x += h; 
 42187 |          total_area += h * (y0 + T(4) * y1 + y2) / T(3); 
 42188 |       } 
 42189 |  
 42190 |       return total_area; 
 42191 |    } 
 42192 |  
 42193 |    template <typename T> 
 42194 |    inline T integrate(const expression<T>& e, 
 42195 |                       const std::string& variable_name, 
 42196 |                       const T& r0, const T& r1, 
 42197 |                       const std::size_t number_of_intervals = 1000000) 
 42198 |    { 
 42199 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42200 |  
 42201 |       if (!sym_table.valid()) 
 42202 |       { 
 42203 |          return std::numeric_limits<T>::quiet_NaN(); 
 42204 |       } 
 42205 |  
 42206 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42207 |  
 42208 |       if (var) 
 42209 |       { 
 42210 |          T& x = var->ref(); 
 42211 |          const T x_original = x; 
 42212 |          const T result = integrate(e, x, r0, r1, number_of_intervals); 
 42213 |          x = x_original; 
 42214 |  
 42215 |          return result; 
 42216 |       } 
 42217 |  
 42218 |       return std::numeric_limits<T>::quiet_NaN(); 
 42219 |    } 
 42220 |  
 42221 |    template <typename T> 
 42222 |    inline T derivative(const expression<T>& e, 
 42223 |                        T& x, 
 42224 |                        const T& h = T(0.00000001)) 
 42225 |    { 
 42226 |       const T x_init = x; 
 42227 |       const T _2h    = T(2) * h; 
 42228 |  
 42229 |       x = x_init + _2h; 
 42230 |       const T y0 = e.value(); 
 42231 |       x = x_init + h; 
 42232 |       const T y1 = e.value(); 
 42233 |       x = x_init - h; 
 42234 |       const T y2 = e.value(); 
 42235 |       x = x_init - _2h; 
 42236 |       const T y3 = e.value(); 
 42237 |       x = x_init; 
 42238 |  
 42239 |       return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h); 
 42240 |    } 
 42241 |  
 42242 |    template <typename T> 
 42243 |    inline T second_derivative(const expression<T>& e, 
 42244 |                               T& x, 
 42245 |                               const T& h = T(0.00001)) 
 42246 |    { 
 42247 |       const T x_init = x; 
 42248 |       const T _2h    = T(2) * h; 
 42249 |  
 42250 |       const T y = e.value(); 
 42251 |       x = x_init + _2h; 
 42252 |       const T y0 = e.value(); 
 42253 |       x = x_init + h; 
 42254 |       const T y1 = e.value(); 
 42255 |       x = x_init - h; 
 42256 |       const T y2 = e.value(); 
 42257 |       x = x_init - _2h; 
 42258 |       const T y3 = e.value(); 
 42259 |       x = x_init; 
 42260 |  
 42261 |       return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h); 
 42262 |    } 
 42263 |  
 42264 |    template <typename T> 
 42265 |    inline T third_derivative(const expression<T>& e, 
 42266 |                              T& x, 
 42267 |                              const T& h = T(0.0001)) 
 42268 |    { 
 42269 |       const T x_init = x; 
 42270 |       const T _2h    = T(2) * h; 
 42271 |  
 42272 |       x = x_init + _2h; 
 42273 |       const T y0 = e.value(); 
 42274 |       x = x_init + h; 
 42275 |       const T y1 = e.value(); 
 42276 |       x = x_init - h; 
 42277 |       const T y2 = e.value(); 
 42278 |       x = x_init - _2h; 
 42279 |       const T y3 = e.value(); 
 42280 |       x = x_init; 
 42281 |  
 42282 |       return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h); 
 42283 |    } 
 42284 |  
 42285 |    template <typename T> 
 42286 |    inline T derivative(const expression<T>& e, 
 42287 |                        const std::string& variable_name, 
 42288 |                        const T& h = T(0.00000001)) 
 42289 |    { 
 42290 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42291 |  
 42292 |       if (!sym_table.valid()) 
 42293 |       { 
 42294 |          return std::numeric_limits<T>::quiet_NaN(); 
 42295 |       } 
 42296 |  
 42297 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42298 |  
 42299 |       if (var) 
 42300 |       { 
 42301 |          T& x = var->ref(); 
 42302 |          const T x_original = x; 
 42303 |          const T result = derivative(e, x, h); 
 42304 |          x = x_original; 
 42305 |  
 42306 |          return result; 
 42307 |       } 
 42308 |  
 42309 |       return std::numeric_limits<T>::quiet_NaN(); 
 42310 |    } 
 42311 |  
 42312 |    template <typename T> 
 42313 |    inline T second_derivative(const expression<T>& e, 
 42314 |                               const std::string& variable_name, 
 42315 |                               const T& h = T(0.00001)) 
 42316 |    { 
 42317 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42318 |  
 42319 |       if (!sym_table.valid()) 
 42320 |       { 
 42321 |          return std::numeric_limits<T>::quiet_NaN(); 
 42322 |       } 
 42323 |  
 42324 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42325 |  
 42326 |       if (var) 
 42327 |       { 
 42328 |          T& x = var->ref(); 
 42329 |          const T x_original = x; 
 42330 |          const T result = second_derivative(e, x, h); 
 42331 |          x = x_original; 
 42332 |  
 42333 |          return result; 
 42334 |       } 
 42335 |  
 42336 |       return std::numeric_limits<T>::quiet_NaN(); 
 42337 |    } 
 42338 |  
 42339 |    template <typename T> 
 42340 |    inline T third_derivative(const expression<T>& e, 
 42341 |                              const std::string& variable_name, 
 42342 |                              const T& h = T(0.0001)) 
 42343 |    { 
 42344 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42345 |  
 42346 |       if (!sym_table.valid()) 
 42347 |       { 
 42348 |          return std::numeric_limits<T>::quiet_NaN(); 
 42349 |       } 
 42350 |  
 42351 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42352 |  
 42353 |       if (var) 
 42354 |       { 
 42355 |          T& x = var->ref(); 
 42356 |          const T x_original = x; 
 42357 |          const T result = third_derivative(e, x, h); 
 42358 |          x = x_original; 
 42359 |  
 42360 |          return result; 
 42361 |       } 
 42362 |  
 42363 |       return std::numeric_limits<T>::quiet_NaN(); 
 42364 |    } 
 42365 |  
 42366 |    /* 
 42367 |       Note: The following 'compute' routines are simple helpers, 
 42368 |       for quickly setting up the required pieces of code in order 
 42369 |       to evaluate an expression. By virtue of how they operate 
 42370 |       there will be an overhead with regards to their setup and 
 42371 |       teardown and hence should not be used in time critical 
 42372 |       sections of code. 
 42373 |       Furthermore they only assume a small sub set of variables, 
 42374 |       no string variables or user defined functions. 
 42375 |    */ 
 42376 |    template <typename T> 
 42377 |    inline bool compute(const std::string& expression_string, T& result) 
 42378 |    { 
 42379 |       // No variables 
 42380 |       symbol_table<T> symbol_table; 
 42381 |       symbol_table.add_constants(); 
 42382 |  
 42383 |       expression<T> expression; 
 42384 |       expression.register_symbol_table(symbol_table); 
 42385 |  
 42386 |       parser<T> parser; 
 42387 |  
 42388 |       if (parser.compile(expression_string,expression)) 
 42389 |       { 
 42390 |          result = expression.value(); 
 42391 |  
 42392 |          return true; 
 42393 |       } 
 42394 |       else 
 42395 |          return false; 
 42396 |    } 
 42397 |  
 42398 |    template <typename T> 
 42399 |    inline bool compute(const std::string& expression_string, 
 42400 |                        const T& x, 
 42401 |                        T& result) 
 42402 |    { 
 42403 |       // Only 'x' 
 42404 |       static const std::string x_var("x"); 
 42405 |  
 42406 |       symbol_table<T> symbol_table; 
 42407 |       symbol_table.add_constants(); 
 42408 |       symbol_table.add_constant(x_var,x); 
 42409 |  
 42410 |       expression<T> expression; 
 42411 |       expression.register_symbol_table(symbol_table); 
 42412 |  
 42413 |       parser<T> parser; 
 42414 |  
 42415 |       if (parser.compile(expression_string,expression)) 
 42416 |       { 
 42417 |          result = expression.value(); 
 42418 |  
 42419 |          return true; 
 42420 |       } 
 42421 |       else 
 42422 |          return false; 
 42423 |    } 
 42424 |  
 42425 |    template <typename T> 
 42426 |    inline bool compute(const std::string& expression_string, 
 42427 |                        const T&x, const T& y, 
 42428 |                        T& result) 
 42429 |    { 
 42430 |       // Only 'x' and 'y' 
 42431 |       static const std::string x_var("x"); 
 42432 |       static const std::string y_var("y"); 
 42433 |  
 42434 |       symbol_table<T> symbol_table; 
 42435 |       symbol_table.add_constants(); 
 42436 |       symbol_table.add_constant(x_var,x); 
 42437 |       symbol_table.add_constant(y_var,y); 
 42438 |  
 42439 |       expression<T> expression; 
 42440 |       expression.register_symbol_table(symbol_table); 
 42441 |  
 42442 |       parser<T> parser; 
 42443 |  
 42444 |       if (parser.compile(expression_string,expression)) 
 42445 |       { 
 42446 |          result = expression.value(); 
 42447 |  
 42448 |          return true; 
 42449 |       } 
 42450 |       else 
 42451 |          return false; 
 42452 |    } 
 42453 |  
 42454 |    template <typename T> 
 42455 |    inline bool compute(const std::string& expression_string, 
 42456 |                        const T& x, const T& y, const T& z, 
 42457 |                        T& result) 
 42458 |    { 
 42459 |       // Only 'x', 'y' or 'z' 
 42460 |       static const std::string x_var("x"); 
 42461 |       static const std::string y_var("y"); 
 42462 |       static const std::string z_var("z"); 
 42463 |  
 42464 |       symbol_table<T> symbol_table; 
 42465 |       symbol_table.add_constants(); 
 42466 |       symbol_table.add_constant(x_var,x); 
 42467 |       symbol_table.add_constant(y_var,y); 
 42468 |       symbol_table.add_constant(z_var,z); 
 42469 |  
 42470 |       expression<T> expression; 
 42471 |       expression.register_symbol_table(symbol_table); 
 42472 |  
 42473 |       parser<T> parser; 
 42474 |  
 42475 |       if (parser.compile(expression_string,expression)) 
 42476 |       { 
 42477 |          result = expression.value(); 
 42478 |  
 42479 |          return true; 
 42480 |       } 
 42481 |       else 
 42482 |          return false; 
 42483 |    } 
 42484 |  
 42485 |    template <typename T, std::size_t N> 
 42486 |    class polynomial : public ifunction<T> 
 42487 |    { 
 42488 |    private: 
 42489 |  
 42490 |       template <typename Type, std::size_t NumberOfCoefficients> 
 42491 |       struct poly_impl { }; 
 42492 |  
 42493 |       template <typename Type> 
 42494 |       struct poly_impl <Type,12> 
 42495 |       { 
 42496 |          static inline T evaluate(const Type x, 
 42497 |                                   const Type c12, const Type c11, const Type c10, const Type c9, const Type c8, 
 42498 |                                   const Type  c7, const Type  c6, const Type  c5, const Type c4, const Type c3, 
 42499 |                                   const Type  c2, const Type  c1, const Type  c0) 
 42500 |          { 
 42501 |             // 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 
 42502 |             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); 
 42503 |          } 
 42504 |       }; 
 42505 |  
 42506 |       template <typename Type> 
 42507 |       struct poly_impl <Type,11> 
 42508 |       { 
 42509 |          static inline T evaluate(const Type x, 
 42510 |                                   const Type c11, const Type c10, const Type c9, const Type c8, const Type c7, 
 42511 |                                   const Type c6,  const Type  c5, const Type c4, const Type c3, const Type c2, 
 42512 |                                   const Type c1,  const Type  c0) 
 42513 |          { 
 42514 |             // 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 
 42515 |             return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42516 |          } 
 42517 |       }; 
 42518 |  
 42519 |       template <typename Type> 
 42520 |       struct poly_impl <Type,10> 
 42521 |       { 
 42522 |          static inline T evaluate(const Type x, 
 42523 |                                   const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, 
 42524 |                                   const Type c5,  const Type c4, const Type c3, const Type c2, const Type c1, 
 42525 |                                   const Type c0) 
 42526 |          { 
 42527 |             // 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 
 42528 |             return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42529 |          } 
 42530 |       }; 
 42531 |  
 42532 |       template <typename Type> 
 42533 |       struct poly_impl <Type,9> 
 42534 |       { 
 42535 |          static inline T evaluate(const Type x, 
 42536 |                                   const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, 
 42537 |                                   const Type c4, const Type c3, const Type c2, const Type c1, const Type c0) 
 42538 |          { 
 42539 |             // 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 
 42540 |             return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42541 |          } 
 42542 |       }; 
 42543 |  
 42544 |       template <typename Type> 
 42545 |       struct poly_impl <Type,8> 
 42546 |       { 
 42547 |          static inline T evaluate(const Type x, 
 42548 |                                   const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, 
 42549 |                                   const Type c3, const Type c2, const Type c1, const Type c0) 
 42550 |          { 
 42551 |             // 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 
 42552 |             return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42553 |          } 
 42554 |       }; 
 42555 |  
 42556 |       template <typename Type> 
 42557 |       struct poly_impl <Type,7> 
 42558 |       { 
 42559 |          static inline T evaluate(const Type x, 
 42560 |                                   const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, 
 42561 |                                   const Type c2, const Type c1, const Type c0) 
 42562 |          { 
 42563 |             // 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 
 42564 |             return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42565 |          } 
 42566 |       }; 
 42567 |  
 42568 |       template <typename Type> 
 42569 |       struct poly_impl <Type,6> 
 42570 |       { 
 42571 |          static inline T evaluate(const Type x, 
 42572 |                                   const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, 
 42573 |                                   const Type c1, const Type c0) 
 42574 |          { 
 42575 |             // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42576 |             return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42577 |          } 
 42578 |       }; 
 42579 |  
 42580 |       template <typename Type> 
 42581 |       struct poly_impl <Type,5> 
 42582 |       { 
 42583 |          static inline T evaluate(const Type x, 
 42584 |                                   const Type c5, const Type c4, const Type c3, const Type c2, 
 42585 |                                   const Type c1, const Type c0) 
 42586 |          { 
 42587 |             // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42588 |             return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42589 |          } 
 42590 |       }; 
 42591 |  
 42592 |       template <typename Type> 
 42593 |       struct poly_impl <Type,4> 
 42594 |       { 
 42595 |          static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0) 
 42596 |          { 
 42597 |             // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42598 |             return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0); 
 42599 |          } 
 42600 |       }; 
 42601 |  
 42602 |       template <typename Type> 
 42603 |       struct poly_impl <Type,3> 
 42604 |       { 
 42605 |          static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0) 
 42606 |          { 
 42607 |             // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42608 |             return (((c3 * x + c2) * x + c1) * x + c0); 
 42609 |          } 
 42610 |       }; 
 42611 |  
 42612 |       template <typename Type> 
 42613 |       struct poly_impl <Type,2> 
 42614 |       { 
 42615 |          static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0) 
 42616 |          { 
 42617 |             // p(x) = c_2x^2 + c_1x^1 + c_0x^0 
 42618 |             return ((c2 * x + c1) * x + c0); 
 42619 |          } 
 42620 |       }; 
 42621 |  
 42622 |       template <typename Type> 
 42623 |       struct poly_impl <Type,1> 
 42624 |       { 
 42625 |          static inline T evaluate(const Type x, const Type c1, const Type c0) 
 42626 |          { 
 42627 |             // p(x) = c_1x^1 + c_0x^0 
 42628 |             return (c1 * x + c0); 
 42629 |          } 
 42630 |       }; 
 42631 |  
 42632 |    public: 
 42633 |  
 42634 |       using ifunction<T>::operator(); 
 42635 |  
 42636 |       polynomial() 
 42637 |       : ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max()) 
 42638 |       { 
 42639 |          disable_has_side_effects(*this); 
 42640 |       } 
 42641 |  
 42642 |       virtual ~polynomial() exprtk_override 
 42643 |       {} 
 42644 |  
 42645 |       #define poly_rtrn(NN) \ 
 42646 |       return (NN != N) ? std::numeric_limits<T>::quiet_NaN() : 
 42647 |  
 42648 |       inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override 
 42649 |       { 
 42650 |          poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0)); 
 42651 |       } 
 42652 |  
 42653 |       inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override 
 42654 |       { 
 42655 |          poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0)); 
 42656 |       } 
 42657 |  
 42658 |       inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42659 |       { 
 42660 |          poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0)); 
 42661 |       } 
 42662 |  
 42663 |       inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1, 
 42664 |                                    const T& c0) exprtk_override 
 42665 |       { 
 42666 |          poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0)); 
 42667 |       } 
 42668 |  
 42669 |       inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2, 
 42670 |                                    const T& c1, const T& c0) exprtk_override 
 42671 |       { 
 42672 |          poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0)); 
 42673 |       } 
 42674 |  
 42675 |       inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3, 
 42676 |                                    const T& c2, const T& c1, const T& c0) exprtk_override 
 42677 |       { 
 42678 |          poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0)); 
 42679 |       } 
 42680 |  
 42681 |       inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4, 
 42682 |                                    const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42683 |       { 
 42684 |          poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42685 |       } 
 42686 |  
 42687 |       inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5, 
 42688 |                                    const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42689 |       { 
 42690 |          poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42691 |       } 
 42692 |  
 42693 |       inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6, 
 42694 |                                    const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, 
 42695 |                                    const T& c0) exprtk_override 
 42696 |       { 
 42697 |          poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42698 |       } 
 42699 |  
 42700 |       inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7, 
 42701 |                                    const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, 
 42702 |                                    const T& c1, const T& c0) exprtk_override 
 42703 |       { 
 42704 |          poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42705 |       } 
 42706 |  
 42707 |       inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8, 
 42708 |                                    const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, 
 42709 |                                    const T& c2, const T& c1, const T& c0) exprtk_override 
 42710 |       { 
 42711 |          poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42712 |       } 
 42713 |  
 42714 |       inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9, 
 42715 |                                    const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, 
 42716 |                                    const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42717 |       { 
 42718 |          poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42719 |       } 
 42720 |  
 42721 |       #undef poly_rtrn 
 42722 |  
 42723 |       inline virtual T operator() () exprtk_override 
 42724 |       { 
 42725 |          return std::numeric_limits<T>::quiet_NaN(); 
 42726 |       } 
 42727 |  
 42728 |       inline virtual T operator() (const T&) exprtk_override 
 42729 |       { 
 42730 |          return std::numeric_limits<T>::quiet_NaN(); 
 42731 |       } 
 42732 |  
 42733 |       inline virtual T operator() (const T&, const T&) exprtk_override 
 42734 |       { 
 42735 |          return std::numeric_limits<T>::quiet_NaN(); 
 42736 |       } 
 42737 |    }; 
 42738 |  
 42739 |    template <typename T> 
 42740 |    class function_compositor 
 42741 |    { 
 42742 |    public: 
 42743 |  
 42744 |       typedef exprtk::expression<T>             expression_t; 
 42745 |       typedef exprtk::symbol_table<T>           symbol_table_t; 
 42746 |       typedef exprtk::parser<T>                 parser_t; 
 42747 |       typedef typename parser_t::settings_store settings_t; 
 42748 |  
 42749 |       struct function 
 42750 |       { 
 42751 |          function() 
 42752 |          {} 
 42753 |  
 42754 |          explicit function(const std::string& n) 
 42755 |          : name_(n) 
 42756 |          {} 
 42757 |  
 42758 |          function(const std::string& name, 
 42759 |                   const std::string& expression) 
 42760 |          : name_(name) 
 42761 |          , expression_(expression) 
 42762 |          {} 
 42763 |  
 42764 |          function(const std::string& name, 
 42765 |                   const std::string& expression, 
 42766 |                   const std::string& v0) 
 42767 |          : name_(name) 
 42768 |          , expression_(expression) 
 42769 |          { 
 42770 |             v_.push_back(v0); 
 42771 |          } 
 42772 |  
 42773 |          function(const std::string& name, 
 42774 |                   const std::string& expression, 
 42775 |                   const std::string& v0, const std::string& v1) 
 42776 |          : name_(name) 
 42777 |          , expression_(expression) 
 42778 |          { 
 42779 |             v_.push_back(v0); v_.push_back(v1); 
 42780 |          } 
 42781 |  
 42782 |          function(const std::string& name, 
 42783 |                   const std::string& expression, 
 42784 |                   const std::string& v0, const std::string& v1, 
 42785 |                   const std::string& v2) 
 42786 |          : name_(name) 
 42787 |          , expression_(expression) 
 42788 |          { 
 42789 |             v_.push_back(v0); v_.push_back(v1); 
 42790 |             v_.push_back(v2); 
 42791 |          } 
 42792 |  
 42793 |          function(const std::string& name, 
 42794 |                   const std::string& expression, 
 42795 |                   const std::string& v0, const std::string& v1, 
 42796 |                   const std::string& v2, const std::string& v3) 
 42797 |          : name_(name) 
 42798 |          , expression_(expression) 
 42799 |          { 
 42800 |             v_.push_back(v0); v_.push_back(v1); 
 42801 |             v_.push_back(v2); v_.push_back(v3); 
 42802 |          } 
 42803 |  
 42804 |          function(const std::string& name, 
 42805 |                   const std::string& expression, 
 42806 |                   const std::string& v0, const std::string& v1, 
 42807 |                   const std::string& v2, const std::string& v3, 
 42808 |                   const std::string& v4) 
 42809 |          : name_(name) 
 42810 |          , expression_(expression) 
 42811 |          { 
 42812 |             v_.push_back(v0); v_.push_back(v1); 
 42813 |             v_.push_back(v2); v_.push_back(v3); 
 42814 |             v_.push_back(v4); 
 42815 |          } 
 42816 |  
 42817 |          inline function& name(const std::string& n) 
 42818 |          { 
 42819 |             name_ = n; 
 42820 |             return (*this); 
 42821 |          } 
 42822 |  
 42823 |          inline function& expression(const std::string& e) 
 42824 |          { 
 42825 |             expression_ = e; 
 42826 |             return (*this); 
 42827 |          } 
 42828 |  
 42829 |          inline function& var(const std::string& v) 
 42830 |          { 
 42831 |             v_.push_back(v); 
 42832 |             return (*this); 
 42833 |          } 
 42834 |  
 42835 |          inline function& vars(const std::string& v0, 
 42836 |                                const std::string& v1) 
 42837 |          { 
 42838 |             v_.push_back(v0); 
 42839 |             v_.push_back(v1); 
 42840 |             return (*this); 
 42841 |          } 
 42842 |  
 42843 |          inline function& vars(const std::string& v0, 
 42844 |                                const std::string& v1, 
 42845 |                                const std::string& v2) 
 42846 |          { 
 42847 |             v_.push_back(v0); 
 42848 |             v_.push_back(v1); 
 42849 |             v_.push_back(v2); 
 42850 |             return (*this); 
 42851 |          } 
 42852 |  
 42853 |          inline function& vars(const std::string& v0, 
 42854 |                                const std::string& v1, 
 42855 |                                const std::string& v2, 
 42856 |                                const std::string& v3) 
 42857 |          { 
 42858 |             v_.push_back(v0); 
 42859 |             v_.push_back(v1); 
 42860 |             v_.push_back(v2); 
 42861 |             v_.push_back(v3); 
 42862 |             return (*this); 
 42863 |          } 
 42864 |  
 42865 |          inline function& vars(const std::string& v0, 
 42866 |                                const std::string& v1, 
 42867 |                                const std::string& v2, 
 42868 |                                const std::string& v3, 
 42869 |                                const std::string& v4) 
 42870 |          { 
 42871 |             v_.push_back(v0); 
 42872 |             v_.push_back(v1); 
 42873 |             v_.push_back(v2); 
 42874 |             v_.push_back(v3); 
 42875 |             v_.push_back(v4); 
 42876 |             return (*this); 
 42877 |          } 
 42878 |  
 42879 |          std::string name_; 
 42880 |          std::string expression_; 
 42881 |          std::deque<std::string> v_; 
 42882 |       }; 
 42883 |  
 42884 |    private: 
 42885 |  
 42886 |       struct base_func : public exprtk::ifunction<T> 
 42887 |       { 
 42888 |          typedef const T&                  type; 
 42889 |          typedef exprtk::ifunction<T>      function_t; 
 42890 |          typedef std::vector<T*>           varref_t; 
 42891 |          typedef std::vector<T>            var_t; 
 42892 |          typedef std::vector<std::string>  str_t; 
 42893 |          typedef std::pair<T*,std::size_t> lvarref_t; 
 42894 |          typedef std::vector<lvarref_t>    lvr_vec_t; 
 42895 |          typedef std::vector<std::string*> lstr_vec_t; 
 42896 |  
 42897 |          using exprtk::ifunction<T>::operator(); 
 42898 |  
 42899 |          explicit base_func(const std::size_t& pc = 0) 
 42900 |          : exprtk::ifunction<T>(pc) 
 42901 |          , local_var_stack_size(0) 
 42902 |          , stack_depth(0) 
 42903 |          { 
 42904 |             v.resize(pc); 
 42905 |          } 
 42906 |  
 42907 |          virtual ~base_func() 
 42908 |          {} 
 42909 |  
 42910 |          #define exprtk_assign(Index) \ 
 42911 |          (*v[Index]) = v##Index;      \ 
 42912 |  
 42913 |          inline void update(const T& v0) 
 42914 |          { 
 42915 |             exprtk_assign(0) 
 42916 |          } 
 42917 |  
 42918 |          inline void update(const T& v0, const T& v1) 
 42919 |          { 
 42920 |             exprtk_assign(0) exprtk_assign(1) 
 42921 |          } 
 42922 |  
 42923 |          inline void update(const T& v0, const T& v1, const T& v2) 
 42924 |          { 
 42925 |             exprtk_assign(0) exprtk_assign(1) 
 42926 |             exprtk_assign(2) 
 42927 |          } 
 42928 |  
 42929 |          inline void update(const T& v0, const T& v1, const T& v2, const T& v3) 
 42930 |          { 
 42931 |             exprtk_assign(0) exprtk_assign(1) 
 42932 |             exprtk_assign(2) exprtk_assign(3) 
 42933 |          } 
 42934 |  
 42935 |          inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) 
 42936 |          { 
 42937 |             exprtk_assign(0) exprtk_assign(1) 
 42938 |             exprtk_assign(2) exprtk_assign(3) 
 42939 |             exprtk_assign(4) 
 42940 |          } 
 42941 |  
 42942 |          inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) 
 42943 |          { 
 42944 |             exprtk_assign(0) exprtk_assign(1) 
 42945 |             exprtk_assign(2) exprtk_assign(3) 
 42946 |             exprtk_assign(4) exprtk_assign(5) 
 42947 |          } 
 42948 |  
 42949 |          #ifdef exprtk_assign 
 42950 |          #undef exprtk_assign 
 42951 |          #endif 
 42952 |  
 42953 |          inline function_t& setup(expression_t& expr) 
 42954 |          { 
 42955 |             expression = expr; 
 42956 |  
 42957 |             typedef typename expression_t::control_block  ctrlblk_t; 
 42958 |             typedef typename ctrlblk_t::local_data_list_t ldl_t; 
 42959 |             typedef typename ctrlblk_t::data_type         data_t; 
 42960 |             typedef typename ldl_t::value_type            ldl_value_type; 
 42961 |  
 42962 |             const ldl_t ldl = expr.local_data_list(); 
 42963 |  
 42964 |             std::vector<std::pair<std::size_t,data_t> > index_list; 
 42965 |  
 42966 |             for (std::size_t i = 0; i < ldl.size(); ++i) 
 42967 |             { 
 42968 |                exprtk_debug(("base_func::setup() - element[%02d] type: %s size: %d\n", 
 42969 |                              static_cast<int>(i), 
 42970 |                              expression_t::control_block::to_str(ldl[i].type).c_str(), 
 42971 |                              static_cast<int>(ldl[i].size))); 
 42972 |  
 42973 |                switch (ldl[i].type) 
 42974 |                { 
 42975 |                   case ctrlblk_t::e_unknown   : continue; 
 42976 |                   case ctrlblk_t::e_expr      : continue; 
 42977 |                   case ctrlblk_t::e_vecholder : continue; 
 42978 |                   default                     : break; 
 42979 |                } 
 42980 |  
 42981 |                if (ldl[i].size) 
 42982 |                { 
 42983 |                   index_list.push_back(std::make_pair(i,ldl[i].type)); 
 42984 |                } 
 42985 |             } 
 42986 |  
 42987 |             std::size_t input_param_count = 0; 
 42988 |  
 42989 |             for (std::size_t i = 0; i < index_list.size(); ++i) 
 42990 |             { 
 42991 |                const std::size_t index         = index_list[i].first; 
 42992 |                const ldl_value_type& local_var = ldl[index]; 
 42993 |  
 42994 |                assert(local_var.pointer); 
 42995 |  
 42996 |                if (i < (index_list.size() - v.size())) 
 42997 |                { 
 42998 |                   if (local_var.type == ctrlblk_t::e_string) 
 42999 |                   { 
 43000 |                      local_str_vars.push_back( 
 43001 |                         reinterpret_cast<std::string*>(local_var.pointer)); 
 43002 |                   } 
 43003 |                   else if ( 
 43004 |                             (local_var.type == ctrlblk_t::e_data   ) || 
 43005 |                             (local_var.type == ctrlblk_t::e_vecdata) 
 43006 |                           ) 
 43007 |                   { 
 43008 |                      local_vars.push_back(std::make_pair( 
 43009 |                         reinterpret_cast<T*>(local_var.pointer), 
 43010 |                         local_var.size)); 
 43011 |  
 43012 |                      local_var_stack_size += local_var.size; 
 43013 |                   } 
 43014 |                } 
 43015 |                else 
 43016 |                { 
 43017 |                   v[input_param_count++] = reinterpret_cast<T*>(local_var.pointer); 
 43018 |                } 
 43019 |             } 
 43020 |  
 43021 |             clear_stack(); 
 43022 |  
 43023 |             return (*this); 
 43024 |          } 
 43025 |  
 43026 |          inline void pre() 
 43027 |          { 
 43028 |             if (stack_depth++) 
 43029 |             { 
 43030 |                if (!v.empty()) 
 43031 |                { 
 43032 |                   var_t var_stack(v.size(),T(0)); 
 43033 |                   copy(v,var_stack); 
 43034 |                   input_params_stack.push_back(var_stack); 
 43035 |                } 
 43036 |  
 43037 |                if (!local_vars.empty()) 
 43038 |                { 
 43039 |                   var_t local_vec_frame(local_var_stack_size,T(0)); 
 43040 |                   copy(local_vars,local_vec_frame); 
 43041 |                   local_var_stack.push_back(local_vec_frame); 
 43042 |                } 
 43043 |  
 43044 |                if (!local_str_vars.empty()) 
 43045 |                { 
 43046 |                   str_t local_str_frame(local_str_vars.size()); 
 43047 |                   copy(local_str_vars,local_str_frame); 
 43048 |                   local_str_stack.push_back(local_str_frame); 
 43049 |                } 
 43050 |             } 
 43051 |          } 
 43052 |  
 43053 |          inline void post() 
 43054 |          { 
 43055 |             if (--stack_depth) 
 43056 |             { 
 43057 |                if (!v.empty()) 
 43058 |                { 
 43059 |                   copy(input_params_stack.back(), v); 
 43060 |                   input_params_stack.pop_back(); 
 43061 |                } 
 43062 |  
 43063 |                if (!local_vars.empty()) 
 43064 |                { 
 43065 |                   copy(local_var_stack.back(), local_vars); 
 43066 |                   local_var_stack.pop_back(); 
 43067 |                } 
 43068 |  
 43069 |                if (!local_str_vars.empty()) 
 43070 |                { 
 43071 |                   copy(local_str_stack.back(), local_str_vars); 
 43072 |                   local_str_stack.pop_back(); 
 43073 |                } 
 43074 |             } 
 43075 |          } 
 43076 |  
 43077 |          void copy(const varref_t& src_v, var_t& dest_v) 
 43078 |          { 
 43079 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 43080 |             { 
 43081 |                dest_v[i] = (*src_v[i]); 
 43082 |             } 
 43083 |          } 
 43084 |  
 43085 |          void copy(const lstr_vec_t& src_v, str_t& dest_v) 
 43086 |          { 
 43087 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 43088 |             { 
 43089 |                dest_v[i] = (*src_v[i]); 
 43090 |             } 
 43091 |          } 
 43092 |  
 43093 |          void copy(const var_t& src_v, varref_t& dest_v) 
 43094 |          { 
 43095 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 43096 |             { 
 43097 |                (*dest_v[i]) = src_v[i]; 
 43098 |             } 
 43099 |          } 
 43100 |  
 43101 |          void copy(const lvr_vec_t& src_v, var_t& dest_v) 
 43102 |          { 
 43103 |             typename var_t::iterator itr = dest_v.begin(); 
 43104 |             typedef  typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t; 
 43105 |  
 43106 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 43107 |             { 
 43108 |                lvarref_t vr = src_v[i]; 
 43109 |  
 43110 |                if (1 == vr.second) 
 43111 |                   *itr++ = (*vr.first); 
 43112 |                else 
 43113 |                { 
 43114 |                   std::copy(vr.first, vr.first + vr.second, itr); 
 43115 |                   itr += static_cast<diff_t>(vr.second); 
 43116 |                } 
 43117 |             } 
 43118 |          } 
 43119 |  
 43120 |          void copy(const var_t& src_v, lvr_vec_t& dest_v) 
 43121 |          { 
 43122 |             typename var_t::const_iterator itr = src_v.begin(); 
 43123 |             typedef  typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t; 
 43124 |  
 43125 |             for (std::size_t i = 0; i < dest_v.size(); ++i) 
 43126 |             { 
 43127 |                lvarref_t& vr = dest_v[i]; 
 43128 |  
 43129 |                assert(vr.first != 0); 
 43130 |                assert(vr.second > 0); 
 43131 |  
 43132 |                if (1 == vr.second) 
 43133 |                   (*vr.first) = *itr++; 
 43134 |                else 
 43135 |                { 
 43136 |                   std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first); 
 43137 |                   itr += static_cast<diff_t>(vr.second); 
 43138 |                } 
 43139 |             } 
 43140 |          } 
 43141 |  
 43142 |          void copy(const str_t& src_str, lstr_vec_t& dest_str) 
 43143 |          { 
 43144 |             assert(src_str.size() == dest_str.size()); 
 43145 |  
 43146 |             for (std::size_t i = 0; i < dest_str.size(); ++i) 
 43147 |             { 
 43148 |                *dest_str[i] = src_str[i]; 
 43149 |             } 
 43150 |          } 
 43151 |  
 43152 |          inline void clear_stack() 
 43153 |          { 
 43154 |             for (std::size_t i = 0; i < v.size(); ++i) 
 43155 |             { 
 43156 |                (*v[i]) = 0; 
 43157 |             } 
 43158 |          } 
 43159 |  
 43160 |          inline virtual T value(expression_t& e) 
 43161 |          { 
 43162 |             return e.value(); 
 43163 |          } 
 43164 |  
 43165 |          expression_t      expression; 
 43166 |          varref_t          v; 
 43167 |          lvr_vec_t         local_vars; 
 43168 |          lstr_vec_t        local_str_vars; 
 43169 |          std::size_t       local_var_stack_size; 
 43170 |          std::size_t       stack_depth; 
 43171 |          std::deque<var_t> input_params_stack; 
 43172 |          std::deque<var_t> local_var_stack; 
 43173 |          std::deque<str_t> local_str_stack; 
 43174 |       }; 
 43175 |  
 43176 |       typedef std::map<std::string,base_func*> funcparam_t; 
 43177 |  
 43178 |       typedef const T& type; 
 43179 |  
 43180 |       template <typename BaseFuncType> 
 43181 |       struct scoped_bft 
 43182 |       { 
 43183 |          explicit scoped_bft(BaseFuncType& bft) 
 43184 |          : bft_(bft) 
 43185 |          { 
 43186 |             bft_.pre (); 
 43187 |          } 
 43188 |  
 43189 |         ~scoped_bft() 
 43190 |          { 
 43191 |             bft_.post(); 
 43192 |          } 
 43193 |  
 43194 |          BaseFuncType& bft_; 
 43195 |  
 43196 |       private: 
 43197 |  
 43198 |          scoped_bft(const scoped_bft&) exprtk_delete; 
 43199 |          scoped_bft& operator=(const scoped_bft&) exprtk_delete; 
 43200 |       }; 
 43201 |  
 43202 |       struct func_0param : public base_func 
 43203 |       { 
 43204 |          using exprtk::ifunction<T>::operator(); 
 43205 |  
 43206 |          func_0param() : base_func(0) {} 
 43207 |  
 43208 |          inline T operator() () exprtk_override 
 43209 |          { 
 43210 |             scoped_bft<func_0param> sb(*this); 
 43211 |             return this->value(base_func::expression); 
 43212 |          } 
 43213 |       }; 
 43214 |  
 43215 |       struct func_1param : public base_func 
 43216 |       { 
 43217 |          using exprtk::ifunction<T>::operator(); 
 43218 |  
 43219 |          func_1param() : base_func(1) {} 
 43220 |  
 43221 |          inline T operator() (type v0) exprtk_override 
 43222 |          { 
 43223 |             scoped_bft<func_1param> sb(*this); 
 43224 |             base_func::update(v0); 
 43225 |             return this->value(base_func::expression); 
 43226 |          } 
 43227 |       }; 
 43228 |  
 43229 |       struct func_2param : public base_func 
 43230 |       { 
 43231 |          using exprtk::ifunction<T>::operator(); 
 43232 |  
 43233 |          func_2param() : base_func(2) {} 
 43234 |  
 43235 |          inline T operator() (type v0, type v1) exprtk_override 
 43236 |          { 
 43237 |             scoped_bft<func_2param> sb(*this); 
 43238 |             base_func::update(v0, v1); 
 43239 |             return this->value(base_func::expression); 
 43240 |          } 
 43241 |       }; 
 43242 |  
 43243 |       struct func_3param : public base_func 
 43244 |       { 
 43245 |          using exprtk::ifunction<T>::operator(); 
 43246 |  
 43247 |          func_3param() : base_func(3) {} 
 43248 |  
 43249 |          inline T operator() (type v0, type v1, type v2) exprtk_override 
 43250 |          { 
 43251 |             scoped_bft<func_3param> sb(*this); 
 43252 |             base_func::update(v0, v1, v2); 
 43253 |             return this->value(base_func::expression); 
 43254 |          } 
 43255 |       }; 
 43256 |  
 43257 |       struct func_4param : public base_func 
 43258 |       { 
 43259 |          using exprtk::ifunction<T>::operator(); 
 43260 |  
 43261 |          func_4param() : base_func(4) {} 
 43262 |  
 43263 |          inline T operator() (type v0, type v1, type v2, type v3) exprtk_override 
 43264 |          { 
 43265 |             scoped_bft<func_4param> sb(*this); 
 43266 |             base_func::update(v0, v1, v2, v3); 
 43267 |             return this->value(base_func::expression); 
 43268 |          } 
 43269 |       }; 
 43270 |  
 43271 |       struct func_5param : public base_func 
 43272 |       { 
 43273 |          using exprtk::ifunction<T>::operator(); 
 43274 |  
 43275 |          func_5param() : base_func(5) {} 
 43276 |  
 43277 |          inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override 
 43278 |          { 
 43279 |             scoped_bft<func_5param> sb(*this); 
 43280 |             base_func::update(v0, v1, v2, v3, v4); 
 43281 |             return this->value(base_func::expression); 
 43282 |          } 
 43283 |       }; 
 43284 |  
 43285 |       struct func_6param : public base_func 
 43286 |       { 
 43287 |          using exprtk::ifunction<T>::operator(); 
 43288 |  
 43289 |          func_6param() : base_func(6) {} 
 43290 |  
 43291 |          inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override 
 43292 |          { 
 43293 |             scoped_bft<func_6param> sb(*this); 
 43294 |             base_func::update(v0, v1, v2, v3, v4, v5); 
 43295 |             return this->value(base_func::expression); 
 43296 |          } 
 43297 |       }; 
 43298 |  
 43299 |       static T return_value(expression_t& e) 
 43300 |       { 
 43301 |          typedef exprtk::results_context<T> results_context_t; 
 43302 |          typedef typename results_context_t::type_store_t type_t; 
 43303 |          typedef typename type_t::scalar_view scalar_t; 
 43304 |  
 43305 |          const T result = e.value(); 
 43306 |  
 43307 |          if (e.return_invoked()) 
 43308 |          { 
 43309 |             // Due to the post compilation checks, it can be safely 
 43310 |             // assumed that there will be at least one parameter 
 43311 |             // and that the first parameter will always be scalar. 
 43312 |             return scalar_t(e.results()[0])(); 
 43313 |          } 
 43314 |  
 43315 |          return result; 
 43316 |       } 
 43317 |  
 43318 |       #define def_fp_retval(N)                                            \ 
 43319 |       struct func_##N##param_retval exprtk_final : public func_##N##param \ 
 43320 |       {                                                                   \ 
 43321 |          inline T value(expression_t& e) exprtk_override                  \ 
 43322 |          {                                                                \ 
 43323 |             return return_value(e);                                       \ 
 43324 |          }                                                                \ 
 43325 |       };                                                                  \ 
 43326 |  
 43327 |       def_fp_retval(0) 
 43328 |       def_fp_retval(1) 
 43329 |       def_fp_retval(2) 
 43330 |       def_fp_retval(3) 
 43331 |       def_fp_retval(4) 
 43332 |       def_fp_retval(5) 
 43333 |       def_fp_retval(6) 
 43334 |  
 43335 |       #undef def_fp_retval 
 43336 |  
 43337 |       template <typename Allocator, 
 43338 |                 template <typename, typename> class Sequence> 
 43339 |       inline bool add(const std::string& name, 
 43340 |                       const std::string& expression, 
 43341 |                       const Sequence<std::string,Allocator>& var_list, 
 43342 |                       const bool override = false) 
 43343 |       { 
 43344 |          const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name); 
 43345 |  
 43346 |          if (expr_map_.end() != itr) 
 43347 |          { 
 43348 |             if (!override) 
 43349 |             { 
 43350 |                exprtk_debug(("Compositor error(add): function '%s' already defined\n", 
 43351 |                              name.c_str())); 
 43352 |  
 43353 |                return false; 
 43354 |             } 
 43355 |  
 43356 |             remove(name, var_list.size()); 
 43357 |          } 
 43358 |  
 43359 |          if (compile_expression(name, expression, var_list)) 
 43360 |          { 
 43361 |             const std::size_t n = var_list.size(); 
 43362 |  
 43363 |             fp_map_[n][name]->setup(expr_map_[name]); 
 43364 |  
 43365 |             return true; 
 43366 |          } 
 43367 |          else 
 43368 |          { 
 43369 |             exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n", 
 43370 |                           name.c_str())); 
 43371 |  
 43372 |             return false; 
 43373 |          } 
 43374 |       } 
 43375 |  
 43376 |    public: 
 43377 |  
 43378 |       function_compositor() 
 43379 |       : parser_(settings_t::default_compile_all_opts + 
 43380 |                 settings_t::e_disable_zero_return) 
 43381 |       , fp_map_(7) 
 43382 |       , load_variables_(false) 
 43383 |       , load_vectors_(false) 
 43384 |       {} 
 43385 |  
 43386 |       explicit function_compositor(const symbol_table_t& st) 
 43387 |       : symbol_table_(st) 
 43388 |       , parser_(settings_t::default_compile_all_opts + 
 43389 |                 settings_t::e_disable_zero_return) 
 43390 |       , fp_map_(7) 
 43391 |       , load_variables_(false) 
 43392 |       , load_vectors_(false) 
 43393 |       {} 
 43394 |  
 43395 |      ~function_compositor() 
 43396 |       { 
 43397 |          clear(); 
 43398 |       } 
 43399 |  
 43400 |       inline symbol_table_t& symbol_table() 
 43401 |       { 
 43402 |          return symbol_table_; 
 43403 |       } 
 43404 |  
 43405 |       inline const symbol_table_t& symbol_table() const 
 43406 |       { 
 43407 |          return symbol_table_; 
 43408 |       } 
 43409 |  
 43410 |       inline void add_auxiliary_symtab(symbol_table_t& symtab) 
 43411 |       { 
 43412 |          auxiliary_symtab_list_.push_back(&symtab); 
 43413 |       } 
 43414 |  
 43415 |       void load_variables(const bool load = true) 
 43416 |       { 
 43417 |          load_variables_ = load; 
 43418 |       } 
 43419 |  
 43420 |       void load_vectors(const bool load = true) 
 43421 |       { 
 43422 |          load_vectors_ = load; 
 43423 |       } 
 43424 |  
 43425 |       inline void register_loop_runtime_check(loop_runtime_check& lrtchk) 
 43426 |       { 
 43427 |          parser_.register_loop_runtime_check(lrtchk); 
 43428 |       } 
 43429 |  
 43430 |       inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk) 
 43431 |       { 
 43432 |          parser_.register_vector_access_runtime_check(vartchk); 
 43433 |       } 
 43434 |  
 43435 |       inline void register_compilation_timeout_check(compilation_check& compchk) 
 43436 |       { 
 43437 |          parser_.register_compilation_timeout_check(compchk); 
 43438 |       } 
 43439 |  
 43440 |       inline void clear_loop_runtime_check() 
 43441 |       { 
 43442 |          parser_.clear_loop_runtime_check(); 
 43443 |       } 
 43444 |  
 43445 |       inline void clear_vector_access_runtime_check() 
 43446 |       { 
 43447 |          parser_.clear_vector_access_runtime_check(); 
 43448 |       } 
 43449 |  
 43450 |       inline void clear_compilation_timeout_check() 
 43451 |       { 
 43452 |          parser_.clear_compilation_timeout_check(); 
 43453 |       } 
 43454 |  
 43455 |       void clear() 
 43456 |       { 
 43457 |          symbol_table_.clear(); 
 43458 |          expr_map_    .clear(); 
 43459 |  
 43460 |          for (std::size_t i = 0; i < fp_map_.size(); ++i) 
 43461 |          { 
 43462 |             typename funcparam_t::iterator itr = fp_map_[i].begin(); 
 43463 |             typename funcparam_t::iterator end = fp_map_[i].end  (); 
 43464 |  
 43465 |             while (itr != end) 
 43466 |             { 
 43467 |                delete itr->second; 
 43468 |                ++itr; 
 43469 |             } 
 43470 |  
 43471 |             fp_map_[i].clear(); 
 43472 |          } 
 43473 |  
 43474 |          clear_loop_runtime_check         (); 
 43475 |          clear_vector_access_runtime_check(); 
 43476 |          clear_compilation_timeout_check  (); 
 43477 |       } 
 43478 |  
 43479 |       inline bool add(const function& f, const bool override = false) 
 43480 |       { 
 43481 |          return add(f.name_, f.expression_, f.v_,override); 
 43482 |       } 
 43483 |  
 43484 |       inline std::string error() const 
 43485 |       { 
 43486 |          if (!error_list_.empty()) 
 43487 |          { 
 43488 |             return error_list_[0].diagnostic; 
 43489 |          } 
 43490 |          else 
 43491 |             return std::string("No Error"); 
 43492 |       } 
 43493 |  
 43494 |       inline std::size_t error_count() const 
 43495 |       { 
 43496 |          return error_list_.size(); 
 43497 |       } 
 43498 |  
 43499 |       inline parser_error::type get_error(const std::size_t& index) const 
 43500 |       { 
 43501 |          if (index < error_list_.size()) 
 43502 |          { 
 43503 |             return error_list_[index]; 
 43504 |          } 
 43505 |  
 43506 |          throw std::invalid_argument("compositor::get_error() - Invalid error index specified"); 
 43507 |       } 
 43508 |  
 43509 |    private: 
 43510 |  
 43511 |       template <typename Allocator, 
 43512 |                 template <typename, typename> class Sequence> 
 43513 |       bool compile_expression(const std::string& name, 
 43514 |                               const std::string& expression, 
 43515 |                               const Sequence<std::string,Allocator>& input_var_list, 
 43516 |                               bool  return_present = false) 
 43517 |       { 
 43518 |          expression_t compiled_expression; 
 43519 |          symbol_table_t local_symbol_table; 
 43520 |  
 43521 |          local_symbol_table.load_from(symbol_table_); 
 43522 |          local_symbol_table.add_constants(); 
 43523 |  
 43524 |          if (load_variables_) 
 43525 |          { 
 43526 |             local_symbol_table.load_variables_from(symbol_table_); 
 43527 |          } 
 43528 |  
 43529 |          if (load_vectors_) 
 43530 |          { 
 43531 |             local_symbol_table.load_vectors_from(symbol_table_); 
 43532 |          } 
 43533 |  
 43534 |          error_list_.clear(); 
 43535 |  
 43536 |          if (!valid(name,input_var_list.size())) 
 43537 |          { 
 43538 |             parser_error::type error = 
 43539 |                parser_error::make_error( 
 43540 |                   parser_error::e_parser, 
 43541 |                   lexer::token(), 
 43542 |                   "ERR282 - Function '" + name + "' is an invalid overload", 
 43543 |                   exprtk_error_location); 
 43544 |  
 43545 |             error_list_.push_back(error); 
 43546 |             return false; 
 43547 |          } 
 43548 |  
 43549 |          if (!forward(name, 
 43550 |                       input_var_list.size(), 
 43551 |                       local_symbol_table, 
 43552 |                       return_present)) 
 43553 |             return false; 
 43554 |  
 43555 |          compiled_expression.register_symbol_table(local_symbol_table); 
 43556 |  
 43557 |          for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i) 
 43558 |          { 
 43559 |             compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i])); 
 43560 |          } 
 43561 |  
 43562 |          std::string mod_expression; 
 43563 |  
 43564 |          for (std::size_t i = 0; i < input_var_list.size(); ++i) 
 43565 |          { 
 43566 |             mod_expression += " var " + input_var_list[i] + "{};\n" 
 43567 |          } 
 43568 |  
 43569 |          if ( 
 43570 |               ('{' == details::front(expression)) && 
 43571 |               ('}' == details::back (expression)) 
 43572 |             ) 
 43573 |             mod_expression += "~" + expression + "" 
 43574 |          else 
 43575 |             mod_expression += "~{" + expression + "};" 
 43576 |  
 43577 |          if (!parser_.compile(mod_expression,compiled_expression)) 
 43578 |          { 
 43579 |             exprtk_debug(("Compositor Error: %s\n", parser_.error().c_str())); 
 43580 |             exprtk_debug(("Compositor modified expression: \n%s\n", mod_expression.c_str())); 
 43581 |  
 43582 |             remove(name,input_var_list.size()); 
 43583 |  
 43584 |             for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index) 
 43585 |             { 
 43586 |                error_list_.push_back(parser_.get_error(err_index)); 
 43587 |             } 
 43588 |  
 43589 |             return false; 
 43590 |          } 
 43591 |  
 43592 |          if (!return_present && parser_.dec().return_present()) 
 43593 |          { 
 43594 |             remove(name,input_var_list.size()); 
 43595 |             return compile_expression(name, expression, input_var_list, true); 
 43596 |          } 
 43597 |  
 43598 |          // Make sure every return point has a scalar as its first parameter 
 43599 |          if (parser_.dec().return_present()) 
 43600 |          { 
 43601 |             typedef std::vector<std::string> str_list_t; 
 43602 |  
 43603 |             str_list_t ret_param_list = parser_.dec().return_param_type_list(); 
 43604 |  
 43605 |             for (std::size_t i = 0; i < ret_param_list.size(); ++i) 
 43606 |             { 
 43607 |                const std::string& params = ret_param_list[i]; 
 43608 |  
 43609 |                if (params.empty() || ('T' != params[0])) 
 43610 |                { 
 43611 |                   exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n", 
 43612 |                                 name.c_str())); 
 43613 |  
 43614 |                   remove(name,input_var_list.size()); 
 43615 |  
 43616 |                   return false; 
 43617 |                } 
 43618 |             } 
 43619 |          } 
 43620 |  
 43621 |          expr_map_[name] = compiled_expression; 
 43622 |  
 43623 |          exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]); 
 43624 |  
 43625 |          if (symbol_table_.add_function(name,ifunc)) 
 43626 |             return true; 
 43627 |          else 
 43628 |          { 
 43629 |             exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n", 
 43630 |                           name.c_str())); 
 43631 |             return false; 
 43632 |          } 
 43633 |       } 
 43634 |  
 43635 |       inline bool symbol_used(const std::string& symbol) const 
 43636 |       { 
 43637 |          return ( 
 43638 |                   symbol_table_.is_variable       (symbol) || 
 43639 |                   symbol_table_.is_stringvar      (symbol) || 
 43640 |                   symbol_table_.is_function       (symbol) || 
 43641 |                   symbol_table_.is_vector         (symbol) || 
 43642 |                   symbol_table_.is_vararg_function(symbol) 
 43643 |                 ); 
 43644 |       } 
 43645 |  
 43646 |       inline bool valid(const std::string& name, 
 43647 |                         const std::size_t& arg_count) const 
 43648 |       { 
 43649 |          if (arg_count > 6) 
 43650 |             return false; 
 43651 |          else if (symbol_used(name)) 
 43652 |             return false; 
 43653 |          else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name)) 
 43654 |             return false; 
 43655 |          else 
 43656 |             return true; 
 43657 |       } 
 43658 |  
 43659 |       inline bool forward(const std::string& name, 
 43660 |                           const std::size_t& arg_count, 
 43661 |                           symbol_table_t& sym_table, 
 43662 |                           const bool ret_present = false) 
 43663 |       { 
 43664 |          switch (arg_count) 
 43665 |          { 
 43666 |             #define case_stmt(N)                                     \ 
 43667 |             case N : (fp_map_[arg_count])[name] =                    \ 
 43668 |                      (!ret_present) ? static_cast<base_func*>        \ 
 43669 |                                       (new func_##N##param) :        \ 
 43670 |                                       static_cast<base_func*>        \ 
 43671 |                                       (new func_##N##param_retval) ; \ 
 43672 |                      break;                                          \ 
 43673 |  
 43674 |             case_stmt(0) case_stmt(1) case_stmt(2) 
 43675 |             case_stmt(3) case_stmt(4) case_stmt(5) 
 43676 |             case_stmt(6) 
 43677 |             #undef case_stmt 
 43678 |          } 
 43679 |  
 43680 |          exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]); 
 43681 |  
 43682 |          return sym_table.add_function(name,ifunc); 
 43683 |       } 
 43684 |  
 43685 |       inline void remove(const std::string& name, const std::size_t& arg_count) 
 43686 |       { 
 43687 |          if (arg_count > 6) 
 43688 |             return; 
 43689 |  
 43690 |          const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name); 
 43691 |  
 43692 |          if (expr_map_.end() != em_itr) 
 43693 |          { 
 43694 |             expr_map_.erase(em_itr); 
 43695 |          } 
 43696 |  
 43697 |          const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name); 
 43698 |  
 43699 |          if (fp_map_[arg_count].end() != fp_itr) 
 43700 |          { 
 43701 |             delete fp_itr->second; 
 43702 |             fp_map_[arg_count].erase(fp_itr); 
 43703 |          } 
 43704 |  
 43705 |          symbol_table_.remove_function(name); 
 43706 |       } 
 43707 |  
 43708 |    private: 
 43709 |  
 43710 |       symbol_table_t symbol_table_; 
 43711 |       parser_t parser_; 
 43712 |       std::map<std::string,expression_t> expr_map_; 
 43713 |       std::vector<funcparam_t> fp_map_; 
 43714 |       std::vector<symbol_table_t*> auxiliary_symtab_list_; 
 43715 |       std::deque<parser_error::type> error_list_; 
 43716 |       bool load_variables_; 
 43717 |       bool load_vectors_; 
 43718 |    }; // class function_compositor 
 43719 |  
 43720 | } // namespace exprtk 
 43721 |  
 43722 | #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 
 43723 | #   ifndef NOMINMAX 
 43724 | #      define NOMINMAX 
 43725 | #   endif 
 43726 | #   ifndef WIN32_LEAN_AND_MEAN 
 43727 | #      define WIN32_LEAN_AND_MEAN 
 43728 | #   endif 
 43729 | #   include  
 43730 | #   include  
 43731 | #else 
 43732 | #   include  
 43733 | #   include  
 43734 | #   include  
 43735 | #endif 
 43736 |  
 43737 | namespace exprtk 
 43738 | { 
 43739 |    class timer 
 43740 |    { 
 43741 |    public: 
 43742 |  
 43743 |       #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 
 43744 |       timer() 
 43745 |       : in_use_(false) 
 43746 |       , start_time_{ {0, 0} } 
 43747 |       , stop_time_ { {0, 0} } 
 43748 |       { 
 43749 |          QueryPerformanceFrequency(&clock_frequency_); 
 43750 |       } 
 43751 |  
 43752 |       inline void start() 
 43753 |       { 
 43754 |          in_use_ = true; 
 43755 |          QueryPerformanceCounter(&start_time_); 
 43756 |       } 
 43757 |  
 43758 |       inline void stop() 
 43759 |       { 
 43760 |          QueryPerformanceCounter(&stop_time_); 
 43761 |          in_use_ = false; 
 43762 |       } 
 43763 |  
 43764 |       inline double time() const 
 43765 |       { 
 43766 |          return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart); 
 43767 |       } 
 43768 |  
 43769 |       #else 
 43770 |  
 43771 |       timer() 
 43772 |       : in_use_(false) 
 43773 |       { 
 43774 |          start_time_.tv_sec  = 0; 
 43775 |          start_time_.tv_usec = 0; 
 43776 |  
 43777 |          stop_time_.tv_sec   = 0; 
 43778 |          stop_time_.tv_usec  = 0; 
 43779 |       } 
 43780 |  
 43781 |       inline void start() 
 43782 |       { 
 43783 |          in_use_ = true; 
 43784 |          gettimeofday(&start_time_,0); 
 43785 |       } 
 43786 |  
 43787 |       inline void stop() 
 43788 |       { 
 43789 |          gettimeofday(&stop_time_, 0); 
 43790 |          in_use_ = false; 
 43791 |       } 
 43792 |  
 43793 |       inline unsigned long long int usec_time() const 
 43794 |       { 
 43795 |          if (!in_use_) 
 43796 |          { 
 43797 |             if (stop_time_.tv_sec >= start_time_.tv_sec) 
 43798 |             { 
 43799 |                return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec  - start_time_.tv_sec ) + 
 43800 |                                    static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ; 
 43801 |             } 
 43802 |             else 
 43803 |                return std::numeric_limits<details::_uint64_t>::max(); 
 43804 |          } 
 43805 |          else 
 43806 |             return std::numeric_limits<details::_uint64_t>::max(); 
 43807 |       } 
 43808 |  
 43809 |       inline double time() const 
 43810 |       { 
 43811 |          return usec_time() * 0.000001; 
 43812 |       } 
 43813 |  
 43814 |       #endif 
 43815 |  
 43816 |       inline bool in_use() const 
 43817 |       { 
 43818 |          return in_use_; 
 43819 |       } 
 43820 |  
 43821 |    private: 
 43822 |  
 43823 |       bool in_use_; 
 43824 |  
 43825 |       #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 
 43826 |          LARGE_INTEGER start_time_; 
 43827 |          LARGE_INTEGER stop_time_; 
 43828 |          LARGE_INTEGER clock_frequency_; 
 43829 |       #else 
 43830 |          struct timeval start_time_; 
 43831 |          struct timeval stop_time_; 
 43832 |       #endif 
 43833 |    }; 
 43834 |  
 43835 |    template <typename T> 
 43836 |    struct type_defs 
 43837 |    { 
 43838 |       typedef symbol_table<T>         symbol_table_t; 
 43839 |       typedef expression<T>           expression_t; 
 43840 |       typedef parser<T>               parser_t; 
 43841 |       typedef parser_error::type      error_t; 
 43842 |       typedef function_compositor<T>  compositor_t; 
 43843 |       typedef typename compositor_t::function function_t; 
 43844 |    }; 
 43845 |  
 43846 | } // namespace exprtk 
 43847 |  
 43848 | #ifndef exprtk_disable_rtl_io 
 43849 | namespace exprtk 
 43850 | { 
 43851 |    namespace rtl { namespace io { namespace details 
 43852 |    { 
 43853 |       template <typename T> 
 43854 |       inline void print_type(const std::string& fmt, 
 43855 |                              const T v, 
 43856 |                              exprtk::details::numeric::details::real_type_tag) 
 43857 |       { 
 43858 |          #if defined(__clang__) 
 43859 |             #pragma clang diagnostic push 
 43860 |             #pragma clang diagnostic ignored "-Wformat-nonliteral" 
 43861 |          #elif defined(__GNUC__) || defined(__GNUG__) 
 43862 |             #pragma GCC diagnostic push 
 43863 |             #pragma GCC diagnostic ignored "-Wformat-nonliteral" 
 43864 |          #elif defined(_MSC_VER) 
 43865 |          #endif 
 43866 |  
 43867 |          printf(fmt.c_str(), v); 
 43868 |  
 43869 |          #if defined(__clang__) 
 43870 |             #pragma clang diagnostic pop 
 43871 |          #elif defined(__GNUC__) || defined(__GNUG__) 
 43872 |             #pragma GCC diagnostic pop 
 43873 |          #elif defined(_MSC_VER) 
 43874 |          #endif 
 43875 |       } 
 43876 |  
 43877 |       template <typename T> 
 43878 |       struct print_impl 
 43879 |       { 
 43880 |          typedef typename igeneric_function<T>::generic_type generic_type; 
 43881 |          typedef typename igeneric_function<T>::parameter_list_t parameter_list_t; 
 43882 |          typedef typename generic_type::scalar_view scalar_t; 
 43883 |          typedef typename generic_type::vector_view vector_t; 
 43884 |          typedef typename generic_type::string_view string_t; 
 43885 |          typedef typename exprtk::details::numeric::details::number_type<T>::type num_type; 
 43886 |  
 43887 |          static void process(const std::string& scalar_format, parameter_list_t parameters) 
 43888 |          { 
 43889 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 43890 |             { 
 43891 |                generic_type& gt = parameters[i]; 
 43892 |  
 43893 |                switch (gt.type) 
 43894 |                { 
 43895 |                   case generic_type::e_scalar : print(scalar_format,scalar_t(gt)); 
 43896 |                                                 break; 
 43897 |  
 43898 |                   case generic_type::e_vector : print(scalar_format,vector_t(gt)); 
 43899 |                                                 break; 
 43900 |  
 43901 |                   case generic_type::e_string : print(string_t(gt)); 
 43902 |                                                 break; 
 43903 |  
 43904 |                   default                     : continue; 
 43905 |                } 
 43906 |             } 
 43907 |          } 
 43908 |  
 43909 |          static inline void print(const std::string& scalar_format, const scalar_t& s) 
 43910 |          { 
 43911 |             print_type(scalar_format,s(),num_type()); 
 43912 |          } 
 43913 |  
 43914 |          static inline void print(const std::string& scalar_format, const vector_t& v) 
 43915 |          { 
 43916 |             for (std::size_t i = 0; i < v.size(); ++i) 
 43917 |             { 
 43918 |                print_type(scalar_format,v[i],num_type()); 
 43919 |  
 43920 |                if ((i + 1) < v.size()) 
 43921 |                   printf(" "); 
 43922 |             } 
 43923 |          } 
 43924 |  
 43925 |          static inline void print(const string_t& s) 
 43926 |          { 
 43927 |             printf("%s",to_str(s).c_str()); 
 43928 |          } 
 43929 |       }; 
 43930 |  
 43931 |    } // namespace exprtk::rtl::io::details 
 43932 |  
 43933 |    template <typename T> 
 43934 |    struct print exprtk_final : public exprtk::igeneric_function<T> 
 43935 |    { 
 43936 |       typedef typename igeneric_function<T>::parameter_list_t parameter_list_t; 
 43937 |  
 43938 |       using exprtk::igeneric_function<T>::operator(); 
 43939 |  
 43940 |       explicit print(const std::string& scalar_format = "%10.5f") 
 43941 |       : scalar_format_(scalar_format) 
 43942 |       { 
 43943 |          exprtk::enable_zero_parameters(*this); 
 43944 |       } 
 43945 |  
 43946 |       inline T operator() (parameter_list_t parameters) exprtk_override 
 43947 |       { 
 43948 |          details::print_impl<T>::process(scalar_format_,parameters); 
 43949 |          return T(0); 
 43950 |       } 
 43951 |  
 43952 |       std::string scalar_format_; 
 43953 |    }; 
 43954 |  
 43955 |    template <typename T> 
 43956 |    struct println exprtk_final : public exprtk::igeneric_function<T> 
 43957 |    { 
 43958 |       typedef typename igeneric_function<T>::parameter_list_t parameter_list_t; 
 43959 |  
 43960 |       using exprtk::igeneric_function<T>::operator(); 
 43961 |  
 43962 |       explicit println(const std::string& scalar_format = "%10.5f") 
 43963 |       : scalar_format_(scalar_format) 
 43964 |       { 
 43965 |          exprtk::enable_zero_parameters(*this); 
 43966 |       } 
 43967 |  
 43968 |       inline T operator() (parameter_list_t parameters) exprtk_override 
 43969 |       { 
 43970 |          details::print_impl<T>::process(scalar_format_,parameters); 
 43971 |          printf("\n"); 
 43972 |          return T(0); 
 43973 |       } 
 43974 |  
 43975 |       std::string scalar_format_; 
 43976 |    }; 
 43977 |  
 43978 |    template <typename T> 
 43979 |    struct package 
 43980 |    { 
 43981 |       print  <T> p; 
 43982 |       println<T> pl; 
 43983 |  
 43984 |       bool register_package(exprtk::symbol_table<T>& symtab) 
 43985 |       { 
 43986 |          #define exprtk_register_function(FunctionName, FunctionType)             \ 
 43987 |          if (!symtab.add_function(FunctionName,FunctionType))                     \ 
 43988 |          {                                                                        \ 
 43989 |             exprtk_debug((                                                        \ 
 43990 |               "exprtk::rtl::io::register_package - Failed to add function: %s\n", \ 
 43991 |               FunctionName));                                                     \ 
 43992 |             return false;                                                         \ 
 43993 |          }                                                                        \ 
 43994 |  
 43995 |          exprtk_register_function("print"  , p ) 
 43996 |          exprtk_register_function("println", pl) 
 43997 |          #undef exprtk_register_function 
 43998 |  
 43999 |          return true; 
 44000 |       } 
 44001 |    }; 
 44002 |  
 44003 |    } // namespace exprtk::rtl::io 
 44004 |    } // namespace exprtk::rtl 
 44005 | }    // namespace exprtk 
 44006 | #endif 
 44007 |  
 44008 | #ifndef exprtk_disable_rtl_io_file 
 44009 | #include  
 44010 | namespace exprtk 
 44011 | { 
 44012 |    namespace rtl { namespace io { namespace file { namespace details 
 44013 |    { 
 44014 |       using ::exprtk::details::char_ptr; 
 44015 |       using ::exprtk::details::char_cptr; 
 44016 |  
 44017 |       enum file_mode 
 44018 |       { 
 44019 |          e_error = 0, 
 44020 |          e_read  = 1, 
 44021 |          e_write = 2, 
 44022 |          e_rdwrt = 4 
 44023 |       }; 
 44024 |  
 44025 |       struct file_descriptor 
 44026 |       { 
 44027 |          file_descriptor(const std::string& fname, const std::string& access) 
 44028 |          : stream_ptr(0) 
 44029 |          , mode(get_file_mode(access)) 
 44030 |          , file_name(fname) 
 44031 |          {} 
 44032 |  
 44033 |          void*       stream_ptr; 
 44034 |          file_mode   mode; 
 44035 |          std::string file_name; 
 44036 |  
 44037 |          bool open() 
 44038 |          { 
 44039 |             if (e_read == mode) 
 44040 |             { 
 44041 |                std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary); 
 44042 |  
 44043 |                if (!(*stream)) 
 44044 |                { 
 44045 |                   file_name.clear(); 
 44046 |                   delete stream; 
 44047 |  
 44048 |                   return false; 
 44049 |                } 
 44050 |  
 44051 |                stream_ptr = stream; 
 44052 |  
 44053 |                return true; 
 44054 |             } 
 44055 |             else if (e_write == mode) 
 44056 |             { 
 44057 |                std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary); 
 44058 |  
 44059 |                if (!(*stream)) 
 44060 |                { 
 44061 |                   file_name.clear(); 
 44062 |                   delete stream; 
 44063 |  
 44064 |                   return false; 
 44065 |                } 
 44066 |  
 44067 |                stream_ptr = stream; 
 44068 |  
 44069 |                return true; 
 44070 |             } 
 44071 |             else if (e_rdwrt == mode) 
 44072 |             { 
 44073 |                std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary); 
 44074 |  
 44075 |                if (!(*stream)) 
 44076 |                { 
 44077 |                   file_name.clear(); 
 44078 |                   delete stream; 
 44079 |  
 44080 |                   return false; 
 44081 |                } 
 44082 |  
 44083 |                stream_ptr = stream; 
 44084 |  
 44085 |                return true; 
 44086 |             } 
 44087 |  
 44088 |             return false; 
 44089 |          } 
 44090 |  
 44091 |          template <typename Stream, typename Ptr> 
 44092 |          void close(Ptr& p) 
 44093 |          { 
 44094 |             Stream* stream = reinterpret_cast<Stream*>(p); 
 44095 |             stream->close(); 
 44096 |             delete stream; 
 44097 |             p = reinterpret_cast<Ptr>(0); 
 44098 |          } 
 44099 |  
 44100 |          bool close() 
 44101 |          { 
 44102 |             switch (mode) 
 44103 |             { 
 44104 |                case e_read  : close<std::ifstream>(stream_ptr); 
 44105 |                               break; 
 44106 |  
 44107 |                case e_write : close<std::ofstream>(stream_ptr); 
 44108 |                               break; 
 44109 |  
 44110 |                case e_rdwrt : close<std::fstream> (stream_ptr); 
 44111 |                               break; 
 44112 |  
 44113 |                default      : return false; 
 44114 |             } 
 44115 |  
 44116 |             return true; 
 44117 |          } 
 44118 |  
 44119 |          template <typename View> 
 44120 |          bool write(const View& view, const std::size_t amount, const std::size_t offset = 0) 
 44121 |          { 
 44122 |             switch (mode) 
 44123 |             { 
 44124 |                case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)-> 
 44125 |                                  write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t)); 
 44126 |                               break; 
 44127 |  
 44128 |                case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)-> 
 44129 |                                  write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t)); 
 44130 |                               break; 
 44131 |  
 44132 |                default      : return false; 
 44133 |             } 
 44134 |  
 44135 |             return true; 
 44136 |          } 
 44137 |  
 44138 |          template <typename View> 
 44139 |          bool read(View& view, const std::size_t amount, const std::size_t offset = 0) 
 44140 |          { 
 44141 |             switch (mode) 
 44142 |             { 
 44143 |                case e_read  : reinterpret_cast<std::ifstream*>(stream_ptr)-> 
 44144 |                                  read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t)); 
 44145 |                               break; 
 44146 |  
 44147 |                case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)-> 
 44148 |                                  read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t)); 
 44149 |                               break; 
 44150 |  
 44151 |                default      : return false; 
 44152 |             } 
 44153 |  
 44154 |             return true; 
 44155 |          } 
 44156 |  
 44157 |          bool getline(std::string& s) 
 44158 |          { 
 44159 |             switch (mode) 
 44160 |             { 
 44161 |                case e_read  : return (!!std::getline(*reinterpret_cast<std::ifstream*>(stream_ptr),s)); 
 44162 |                case e_rdwrt : return (!!std::getline(*reinterpret_cast<std::fstream* >(stream_ptr),s)); 
 44163 |                default      : return false; 
 44164 |             } 
 44165 |          } 
 44166 |  
 44167 |          bool eof() const 
 44168 |          { 
 44169 |             switch (mode) 
 44170 |             { 
 44171 |                case e_read  : return reinterpret_cast<std::ifstream*>(stream_ptr)->eof(); 
 44172 |                case e_write : return reinterpret_cast<std::ofstream*>(stream_ptr)->eof(); 
 44173 |                case e_rdwrt : return reinterpret_cast<std::fstream* >(stream_ptr)->eof(); 
 44174 |                default      : return true; 
 44175 |             } 
 44176 |          } 
 44177 |  
 44178 |          file_mode get_file_mode(const std::string& access) const 
 44179 |          { 
 44180 |             if (access.empty() || access.size() > 2) 
 44181 |                return e_error; 
 44182 |  
 44183 |             std::size_t w_cnt = 0; 
 44184 |             std::size_t r_cnt = 0; 
 44185 |  
 44186 |             for (std::size_t i = 0; i < access.size(); ++i) 
 44187 |             { 
 44188 |                switch (std::tolower(access[i])) 
 44189 |                { 
 44190 |                   case 'r' : r_cnt++; break; 
 44191 |                   case 'w' : w_cnt++; break; 
 44192 |                   default  : return e_error; 
 44193 |                } 
 44194 |             } 
 44195 |  
 44196 |             if ((0 == r_cnt) && (0 == w_cnt)) 
 44197 |                return e_error; 
 44198 |             else if ((r_cnt > 1) || (w_cnt > 1)) 
 44199 |                return e_error; 
 44200 |             else if ((1 == r_cnt) && (1 == w_cnt)) 
 44201 |                return e_rdwrt; 
 44202 |             else if (1 == r_cnt) 
 44203 |                return e_read; 
 44204 |             else 
 44205 |                return e_write; 
 44206 |          } 
 44207 |       }; 
 44208 |  
 44209 |       template <typename T> 
 44210 |       file_descriptor* make_handle(T v) 
 44211 |       { 
 44212 |          const std::size_t fd_size    = sizeof(details::file_descriptor*); 
 44213 |          details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0); 
 44214 |  
 44215 |          std::memcpy(reinterpret_cast<char_ptr >(&fd), 
 44216 |                      reinterpret_cast<char_cptr>(&v ), 
 44217 |                      fd_size); 
 44218 |          return fd; 
 44219 |       } 
 44220 |  
 44221 |       template <typename T> 
 44222 |       void perform_check() 
 44223 |       { 
 44224 |          #ifdef _MSC_VER 
 44225 |          #pragma warning(push) 
 44226 |          #pragma warning(disable: 4127) 
 44227 |          #endif 
 44228 |          if (sizeof(T) < sizeof(void*)) 
 44229 |          { 
 44230 |             throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder."); 
 44231 |          } 
 44232 |          #ifdef _MSC_VER 
 44233 |          #pragma warning(pop) 
 44234 |          #endif 
 44235 |          assert(sizeof(T) <= sizeof(void*)); 
 44236 |       } 
 44237 |  
 44238 |    } // namespace exprtk::rtl::io::file::details 
 44239 |  
 44240 |    template <typename T> 
 44241 |    class open exprtk_final : public exprtk::igeneric_function<T> 
 44242 |    { 
 44243 |    public: 
 44244 |  
 44245 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44246 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44247 |       typedef typename igfun_t::generic_type        generic_type; 
 44248 |       typedef typename generic_type::string_view    string_t; 
 44249 |  
 44250 |       using igfun_t::operator(); 
 44251 |  
 44252 |       open() 
 44253 |       : exprtk::igeneric_function<T>("S|SS") 
 44254 |       { details::perform_check<T>(); } 
 44255 |  
 44256 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44257 |       { 
 44258 |          const std::string file_name = to_str(string_t(parameters[0])); 
 44259 |  
 44260 |          if (file_name.empty()) 
 44261 |          { 
 44262 |             return T(0); 
 44263 |          } 
 44264 |  
 44265 |          if ((1 == ps_index) && (0 == string_t(parameters[1]).size())) 
 44266 |          { 
 44267 |             return T(0); 
 44268 |          } 
 44269 |  
 44270 |          const std::string access = 
 44271 |             (0 == ps_index) ? "r" : to_str(string_t(parameters[1])); 
 44272 |  
 44273 |          details::file_descriptor* fd = new details::file_descriptor(file_name,access); 
 44274 |  
 44275 |          if (fd->open()) 
 44276 |          { 
 44277 |             T t = T(0); 
 44278 |  
 44279 |             const std::size_t fd_size = sizeof(details::file_descriptor*); 
 44280 |  
 44281 |             std::memcpy(reinterpret_cast<char*>(&t ), 
 44282 |                         reinterpret_cast<char*>(&fd), 
 44283 |                         fd_size); 
 44284 |             return t; 
 44285 |          } 
 44286 |          else 
 44287 |          { 
 44288 |             delete fd; 
 44289 |             return T(0); 
 44290 |          } 
 44291 |       } 
 44292 |    }; 
 44293 |  
 44294 |    template <typename T> 
 44295 |    struct close exprtk_final : public exprtk::ifunction<T> 
 44296 |    { 
 44297 |       using exprtk::ifunction<T>::operator(); 
 44298 |  
 44299 |       close() 
 44300 |       : exprtk::ifunction<T>(1) 
 44301 |       { details::perform_check<T>(); } 
 44302 |  
 44303 |       inline T operator() (const T& v) exprtk_override 
 44304 |       { 
 44305 |          details::file_descriptor* fd = details::make_handle(v); 
 44306 |  
 44307 |          if (!fd->close()) 
 44308 |             return T(0); 
 44309 |  
 44310 |          delete fd; 
 44311 |  
 44312 |          return T(1); 
 44313 |       } 
 44314 |    }; 
 44315 |  
 44316 |    template <typename T> 
 44317 |    class write exprtk_final : public exprtk::igeneric_function<T> 
 44318 |    { 
 44319 |    public: 
 44320 |  
 44321 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44322 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44323 |       typedef typename igfun_t::generic_type        generic_type; 
 44324 |       typedef typename generic_type::string_view    string_t; 
 44325 |       typedef typename generic_type::scalar_view    scalar_t; 
 44326 |       typedef typename generic_type::vector_view    vector_t; 
 44327 |  
 44328 |       using igfun_t::operator(); 
 44329 |  
 44330 |       write() 
 44331 |       : igfun_t("TS|TST|TV|TVT") 
 44332 |       { details::perform_check<T>(); } 
 44333 |  
 44334 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44335 |       { 
 44336 |          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); 
 44337 |  
 44338 |          switch (ps_index) 
 44339 |          { 
 44340 |             case 0  : { 
 44341 |                          const string_t buffer(parameters[1]); 
 44342 |                          const std::size_t amount = buffer.size(); 
 44343 |                          return T(fd->write(buffer, amount) ? 1 : 0); 
 44344 |                       } 
 44345 |  
 44346 |             case 1  : { 
 44347 |                          const string_t buffer(parameters[1]); 
 44348 |                          const std::size_t amount = 
 44349 |                                   std::min(buffer.size(), 
 44350 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44351 |                          return T(fd->write(buffer, amount) ? 1 : 0); 
 44352 |                       } 
 44353 |  
 44354 |             case 2  : { 
 44355 |                          const vector_t vec(parameters[1]); 
 44356 |                          const std::size_t amount = vec.size(); 
 44357 |                          return T(fd->write(vec, amount) ? 1 : 0); 
 44358 |                       } 
 44359 |  
 44360 |             case 3  : { 
 44361 |                          const vector_t vec(parameters[1]); 
 44362 |                          const std::size_t amount = 
 44363 |                                   std::min(vec.size(), 
 44364 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44365 |                          return T(fd->write(vec, amount) ? 1 : 0); 
 44366 |                       } 
 44367 |          } 
 44368 |  
 44369 |          return T(0); 
 44370 |       } 
 44371 |    }; 
 44372 |  
 44373 |    template <typename T> 
 44374 |    class read exprtk_final : public exprtk::igeneric_function<T> 
 44375 |    { 
 44376 |    public: 
 44377 |  
 44378 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44379 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44380 |       typedef typename igfun_t::generic_type        generic_type; 
 44381 |       typedef typename generic_type::string_view    string_t; 
 44382 |       typedef typename generic_type::scalar_view    scalar_t; 
 44383 |       typedef typename generic_type::vector_view    vector_t; 
 44384 |  
 44385 |       using igfun_t::operator(); 
 44386 |  
 44387 |       read() 
 44388 |       : igfun_t("TS|TST|TV|TVT") 
 44389 |       { details::perform_check<T>(); } 
 44390 |  
 44391 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44392 |       { 
 44393 |          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); 
 44394 |  
 44395 |          switch (ps_index) 
 44396 |          { 
 44397 |             case 0  : { 
 44398 |                          string_t buffer(parameters[1]); 
 44399 |                          const std::size_t amount = buffer.size(); 
 44400 |                          return T(fd->read(buffer,amount) ? 1 : 0); 
 44401 |                       } 
 44402 |  
 44403 |             case 1  : { 
 44404 |                          string_t buffer(parameters[1]); 
 44405 |                          const std::size_t amount = 
 44406 |                                   std::min(buffer.size(), 
 44407 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44408 |                          return T(fd->read(buffer,amount) ? 1 : 0); 
 44409 |                       } 
 44410 |  
 44411 |             case 2  : { 
 44412 |                          vector_t vec(parameters[1]); 
 44413 |                          const std::size_t amount = vec.size(); 
 44414 |                          return T(fd->read(vec,amount) ? 1 : 0); 
 44415 |                       } 
 44416 |  
 44417 |             case 3  : { 
 44418 |                          vector_t vec(parameters[1]); 
 44419 |                          const std::size_t amount = 
 44420 |                                   std::min(vec.size(), 
 44421 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44422 |                          return T(fd->read(vec,amount) ? 1 : 0); 
 44423 |                       } 
 44424 |          } 
 44425 |  
 44426 |          return T(0); 
 44427 |       } 
 44428 |    }; 
 44429 |  
 44430 |    template <typename T> 
 44431 |    class getline exprtk_final : public exprtk::igeneric_function<T> 
 44432 |    { 
 44433 |    public: 
 44434 |  
 44435 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44436 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44437 |       typedef typename igfun_t::generic_type        generic_type; 
 44438 |       typedef typename generic_type::string_view    string_t; 
 44439 |       typedef typename generic_type::scalar_view    scalar_t; 
 44440 |  
 44441 |       using igfun_t::operator(); 
 44442 |  
 44443 |       getline() 
 44444 |       : igfun_t("T",igfun_t::e_rtrn_string) 
 44445 |       { details::perform_check<T>(); } 
 44446 |  
 44447 |       inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override 
 44448 |       { 
 44449 |          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); 
 44450 |          return T(fd->getline(result) ? 1 : 0); 
 44451 |       } 
 44452 |    }; 
 44453 |  
 44454 |    template <typename T> 
 44455 |    struct eof exprtk_final : public exprtk::ifunction<T> 
 44456 |    { 
 44457 |       using exprtk::ifunction<T>::operator(); 
 44458 |  
 44459 |       eof() 
 44460 |       : exprtk::ifunction<T>(1) 
 44461 |       { details::perform_check<T>(); } 
 44462 |  
 44463 |       inline T operator() (const T& v) exprtk_override 
 44464 |       { 
 44465 |          details::file_descriptor* fd = details::make_handle(v); 
 44466 |          return (fd->eof() ? T(1) : T(0)); 
 44467 |       } 
 44468 |    }; 
 44469 |  
 44470 |    template <typename T> 
 44471 |    struct package 
 44472 |    { 
 44473 |       open   <T> o; 
 44474 |       close  <T> c; 
 44475 |       write  <T> w; 
 44476 |       read   <T> r; 
 44477 |       getline<T> g; 
 44478 |       eof    <T> e; 
 44479 |  
 44480 |       bool register_package(exprtk::symbol_table<T>& symtab) 
 44481 |       { 
 44482 |          #define exprtk_register_function(FunctionName, FunctionType)                   \ 
 44483 |          if (!symtab.add_function(FunctionName,FunctionType))                           \ 
 44484 |          {                                                                              \ 
 44485 |             exprtk_debug((                                                              \ 
 44486 |               "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \ 
 44487 |               FunctionName));                                                           \ 
 44488 |             return false;                                                               \ 
 44489 |          }                                                                              \ 
 44490 |  
 44491 |          exprtk_register_function("open"    , o) 
 44492 |          exprtk_register_function("close"   , c) 
 44493 |          exprtk_register_function("write"   , w) 
 44494 |          exprtk_register_function("read"    , r) 
 44495 |          exprtk_register_function("getline" , g) 
 44496 |          exprtk_register_function("eof"     , e) 
 44497 |          #undef exprtk_register_function 
 44498 |  
 44499 |          return true; 
 44500 |       } 
 44501 |    }; 
 44502 |  
 44503 |    } // namespace exprtk::rtl::io::file 
 44504 |    } // namespace exprtk::rtl::io 
 44505 |    } // namespace exprtk::rtl 
 44506 | }    // namespace exprtk 
 44507 | #endif 
 44508 |  
 44509 | #ifndef exprtk_disable_rtl_vecops 
 44510 | namespace exprtk 
 44511 | { 
 44512 |    namespace rtl { namespace vecops { 
 44513 |  
 44514 |    namespace helper 
 44515 |    { 
 44516 |       template <typename Vector> 
 44517 |       inline bool invalid_range(const Vector& v, const std::size_t r0, const std::size_t r1) 
 44518 |       { 
 44519 |          if (r0 > (v.size() - 1)) 
 44520 |             return true; 
 44521 |          else if (r1 > (v.size() - 1)) 
 44522 |             return true; 
 44523 |          else if (r1 < r0) 
 44524 |             return true; 
 44525 |          else 
 44526 |             return false; 
 44527 |       } 
 44528 |  
 44529 |       template <typename T> 
 44530 |       struct load_vector_range 
 44531 |       { 
 44532 |          typedef typename exprtk::igeneric_function<T> igfun_t; 
 44533 |          typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44534 |          typedef typename igfun_t::generic_type        generic_type; 
 44535 |          typedef typename generic_type::scalar_view    scalar_t; 
 44536 |          typedef typename generic_type::vector_view    vector_t; 
 44537 |  
 44538 |          static inline bool process(parameter_list_t& parameters, 
 44539 |                                     std::size_t& r0, std::size_t& r1, 
 44540 |                                     const std::size_t& r0_prmidx, 
 44541 |                                     const std::size_t& r1_prmidx, 
 44542 |                                     const std::size_t vec_idx = 0) 
 44543 |          { 
 44544 |             if (r0_prmidx >= parameters.size()) 
 44545 |                return false; 
 44546 |  
 44547 |             if (r1_prmidx >= parameters.size()) 
 44548 |                return false; 
 44549 |  
 44550 |             if (!scalar_t(parameters[r0_prmidx]).to_uint(r0)) 
 44551 |                return false; 
 44552 |  
 44553 |             if (!scalar_t(parameters[r1_prmidx]).to_uint(r1)) 
 44554 |                return false; 
 44555 |  
 44556 |             return !invalid_range(vector_t(parameters[vec_idx]), r0, r1); 
 44557 |          } 
 44558 |       }; 
 44559 |    } 
 44560 |  
 44561 |    namespace details 
 44562 |    { 
 44563 |       template <typename T> 
 44564 |       inline void kahan_sum(T& sum, T& error, const T v) 
 44565 |       { 
 44566 |          const T x = v - error; 
 44567 |          const T y = sum + x; 
 44568 |          error = (y - sum) - x; 
 44569 |          sum = y; 
 44570 |       } 
 44571 |  
 44572 |    } // namespace exprtk::rtl::details 
 44573 |  
 44574 |    template <typename T> 
 44575 |    class all_true exprtk_final : public exprtk::igeneric_function<T> 
 44576 |    { 
 44577 |    public: 
 44578 |  
 44579 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44580 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44581 |       typedef typename igfun_t::generic_type        generic_type; 
 44582 |       typedef typename generic_type::scalar_view    scalar_t; 
 44583 |       typedef typename generic_type::vector_view    vector_t; 
 44584 |  
 44585 |       using igfun_t::operator(); 
 44586 |  
 44587 |       all_true() 
 44588 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44589 |         /* 
 44590 |            Overloads: 
 44591 |            0. V   - vector 
 44592 |            1. VTT - vector, r0, r1 
 44593 |            2. T*  - T....T 
 44594 |         */ 
 44595 |       {} 
 44596 |  
 44597 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44598 |       { 
 44599 |          if (2 == ps_index) 
 44600 |          { 
 44601 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44602 |             { 
 44603 |                if (scalar_t(parameters[i])() == T(0)) 
 44604 |                { 
 44605 |                   return T(0); 
 44606 |                } 
 44607 |             } 
 44608 |          } 
 44609 |          else 
 44610 |          { 
 44611 |             const vector_t vec(parameters[0]); 
 44612 |  
 44613 |             std::size_t r0 = 0; 
 44614 |             std::size_t r1 = vec.size() - 1; 
 44615 |  
 44616 |             if ( 
 44617 |                  (1 == ps_index) && 
 44618 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44619 |                ) 
 44620 |             { 
 44621 |                return std::numeric_limits<T>::quiet_NaN(); 
 44622 |             } 
 44623 |  
 44624 |             for (std::size_t i = r0; i <= r1; ++i) 
 44625 |             { 
 44626 |                if (vec[i] == T(0)) 
 44627 |                { 
 44628 |                   return T(0); 
 44629 |                } 
 44630 |             } 
 44631 |          } 
 44632 |  
 44633 |          return T(1); 
 44634 |       } 
 44635 |    }; 
 44636 |  
 44637 |    template <typename T> 
 44638 |    class all_false exprtk_final : public exprtk::igeneric_function<T> 
 44639 |    { 
 44640 |    public: 
 44641 |  
 44642 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44643 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44644 |       typedef typename igfun_t::generic_type        generic_type; 
 44645 |       typedef typename generic_type::scalar_view    scalar_t; 
 44646 |       typedef typename generic_type::vector_view    vector_t; 
 44647 |  
 44648 |       using igfun_t::operator(); 
 44649 |  
 44650 |       all_false() 
 44651 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44652 |         /* 
 44653 |            Overloads: 
 44654 |            0. V   - vector 
 44655 |            1. VTT - vector, r0, r1 
 44656 |            2. T*  - T....T 
 44657 |         */ 
 44658 |       {} 
 44659 |  
 44660 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44661 |       { 
 44662 |          if (2 == ps_index) 
 44663 |          { 
 44664 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44665 |             { 
 44666 |                if (scalar_t(parameters[i])() != T(0)) 
 44667 |                { 
 44668 |                   return T(0); 
 44669 |                } 
 44670 |             } 
 44671 |          } 
 44672 |          else 
 44673 |          { 
 44674 |             const vector_t vec(parameters[0]); 
 44675 |  
 44676 |             std::size_t r0 = 0; 
 44677 |             std::size_t r1 = vec.size() - 1; 
 44678 |  
 44679 |             if ( 
 44680 |                  (1 == ps_index) && 
 44681 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44682 |                ) 
 44683 |             { 
 44684 |                return std::numeric_limits<T>::quiet_NaN(); 
 44685 |             } 
 44686 |  
 44687 |             for (std::size_t i = r0; i <= r1; ++i) 
 44688 |             { 
 44689 |                if (vec[i] != T(0)) 
 44690 |                { 
 44691 |                   return T(0); 
 44692 |                } 
 44693 |             } 
 44694 |          } 
 44695 |  
 44696 |          return T(1); 
 44697 |       } 
 44698 |    }; 
 44699 |  
 44700 |    template <typename T> 
 44701 |    class any_true exprtk_final : public exprtk::igeneric_function<T> 
 44702 |    { 
 44703 |    public: 
 44704 |  
 44705 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44706 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44707 |       typedef typename igfun_t::generic_type        generic_type; 
 44708 |       typedef typename generic_type::scalar_view    scalar_t; 
 44709 |       typedef typename generic_type::vector_view    vector_t; 
 44710 |  
 44711 |       using igfun_t::operator(); 
 44712 |  
 44713 |       any_true() 
 44714 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44715 |         /* 
 44716 |            Overloads: 
 44717 |            0. V   - vector 
 44718 |            1. VTT - vector, r0, r1 
 44719 |            2. T*  - T....T 
 44720 |         */ 
 44721 |       {} 
 44722 |  
 44723 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44724 |       { 
 44725 |          if (2 == ps_index) 
 44726 |          { 
 44727 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44728 |             { 
 44729 |                if (scalar_t(parameters[i])() != T(0)) 
 44730 |                { 
 44731 |                   return T(1); 
 44732 |                } 
 44733 |             } 
 44734 |          } 
 44735 |          else 
 44736 |          { 
 44737 |             const vector_t vec(parameters[0]); 
 44738 |  
 44739 |             std::size_t r0 = 0; 
 44740 |             std::size_t r1 = vec.size() - 1; 
 44741 |  
 44742 |             if ( 
 44743 |                  (1 == ps_index) && 
 44744 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44745 |                ) 
 44746 |             { 
 44747 |                return std::numeric_limits<T>::quiet_NaN(); 
 44748 |             } 
 44749 |  
 44750 |             for (std::size_t i = r0; i <= r1; ++i) 
 44751 |             { 
 44752 |                if (vec[i] != T(0)) 
 44753 |                { 
 44754 |                   return T(1); 
 44755 |                } 
 44756 |             } 
 44757 |          } 
 44758 |  
 44759 |          return T(0); 
 44760 |       } 
 44761 |    }; 
 44762 |  
 44763 |    template <typename T> 
 44764 |    class any_false exprtk_final : public exprtk::igeneric_function<T> 
 44765 |    { 
 44766 |    public: 
 44767 |  
 44768 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44769 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44770 |       typedef typename igfun_t::generic_type        generic_type; 
 44771 |       typedef typename generic_type::scalar_view    scalar_t; 
 44772 |       typedef typename generic_type::vector_view    vector_t; 
 44773 |  
 44774 |       using igfun_t::operator(); 
 44775 |  
 44776 |       any_false() 
 44777 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44778 |         /* 
 44779 |            Overloads: 
 44780 |            0. V   - vector 
 44781 |            1. VTT - vector, r0, r1 
 44782 |            2. T*  - T....T 
 44783 |         */ 
 44784 |       {} 
 44785 |  
 44786 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44787 |       { 
 44788 |          if (2 == ps_index) 
 44789 |          { 
 44790 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44791 |             { 
 44792 |                if (scalar_t(parameters[i])() == T(0)) 
 44793 |                { 
 44794 |                   return T(1); 
 44795 |                } 
 44796 |             } 
 44797 |          } 
 44798 |          else 
 44799 |          { 
 44800 |             const vector_t vec(parameters[0]); 
 44801 |  
 44802 |             std::size_t r0 = 0; 
 44803 |             std::size_t r1 = vec.size() - 1; 
 44804 |  
 44805 |             if ( 
 44806 |                  (1 == ps_index) && 
 44807 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44808 |                ) 
 44809 |             { 
 44810 |                return std::numeric_limits<T>::quiet_NaN(); 
 44811 |             } 
 44812 |  
 44813 |             for (std::size_t i = r0; i <= r1; ++i) 
 44814 |             { 
 44815 |                if (vec[i] == T(0)) 
 44816 |                { 
 44817 |                   return T(1); 
 44818 |                } 
 44819 |             } 
 44820 |          } 
 44821 |  
 44822 |          return T(0); 
 44823 |       } 
 44824 |    }; 
 44825 |  
 44826 |    template <typename T> 
 44827 |    class count exprtk_final : public exprtk::igeneric_function<T> 
 44828 |    { 
 44829 |    public: 
 44830 |  
 44831 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44832 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44833 |       typedef typename igfun_t::generic_type        generic_type; 
 44834 |       typedef typename generic_type::scalar_view    scalar_t; 
 44835 |       typedef typename generic_type::vector_view    vector_t; 
 44836 |  
 44837 |       using igfun_t::operator(); 
 44838 |  
 44839 |       count() 
 44840 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44841 |         /* 
 44842 |            Overloads: 
 44843 |            0. V   - vector 
 44844 |            1. VTT - vector, r0, r1 
 44845 |            2. T*  - T....T 
 44846 |         */ 
 44847 |       {} 
 44848 |  
 44849 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44850 |       { 
 44851 |          std::size_t cnt = 0; 
 44852 |  
 44853 |          if (2 == ps_index) 
 44854 |          { 
 44855 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44856 |             { 
 44857 |                if (scalar_t(parameters[i])() != T(0)) ++cnt; 
 44858 |             } 
 44859 |          } 
 44860 |          else 
 44861 |          { 
 44862 |             const vector_t vec(parameters[0]); 
 44863 |  
 44864 |             std::size_t r0 = 0; 
 44865 |             std::size_t r1 = vec.size() - 1; 
 44866 |  
 44867 |             if ( 
 44868 |                  (1 == ps_index) && 
 44869 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44870 |                ) 
 44871 |             { 
 44872 |                return std::numeric_limits<T>::quiet_NaN(); 
 44873 |             } 
 44874 |  
 44875 |             for (std::size_t i = r0; i <= r1; ++i) 
 44876 |             { 
 44877 |                if (vec[i] != T(0)) ++cnt; 
 44878 |             } 
 44879 |          } 
 44880 |  
 44881 |          return T(cnt); 
 44882 |       } 
 44883 |    }; 
 44884 |  
 44885 |    template <typename T> 
 44886 |    class copy exprtk_final : public exprtk::igeneric_function<T> 
 44887 |    { 
 44888 |    public: 
 44889 |  
 44890 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44891 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44892 |       typedef typename igfun_t::generic_type        generic_type; 
 44893 |       typedef typename generic_type::scalar_view    scalar_t; 
 44894 |       typedef typename generic_type::vector_view    vector_t; 
 44895 |  
 44896 |       using igfun_t::operator(); 
 44897 |  
 44898 |       copy() 
 44899 |       : exprtk::igeneric_function<T>("VV|VTTVTT") 
 44900 |         /* 
 44901 |            Overloads: 
 44902 |            0. VV     - x(vector), y(vector) 
 44903 |            1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1, 
 44904 |         */ 
 44905 |       {} 
 44906 |  
 44907 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44908 |       { 
 44909 |          const vector_t x(parameters[0]); 
 44910 |                vector_t y(parameters[(0 == ps_index) ? 1 : 3]); 
 44911 |  
 44912 |          std::size_t xr0 = 0; 
 44913 |          std::size_t xr1 = x.size() - 1; 
 44914 |  
 44915 |          std::size_t yr0 = 0; 
 44916 |          std::size_t yr1 = y.size() - 1; 
 44917 |  
 44918 |          if (1 == ps_index) 
 44919 |          { 
 44920 |             if ( 
 44921 |                  !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) || 
 44922 |                  !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3) 
 44923 |                ) 
 44924 |                return T(0); 
 44925 |          } 
 44926 |  
 44927 |          const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1); 
 44928 |  
 44929 |          std::copy( 
 44930 |             x.begin() + xr0, 
 44931 |             x.begin() + xr0 + n, 
 44932 |             y.begin() + yr0); 
 44933 |  
 44934 |          return T(n); 
 44935 |       } 
 44936 |    }; 
 44937 |  
 44938 |    template <typename T> 
 44939 |    class rol exprtk_final : public exprtk::igeneric_function<T> 
 44940 |    { 
 44941 |    public: 
 44942 |  
 44943 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44944 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44945 |       typedef typename igfun_t::generic_type        generic_type; 
 44946 |       typedef typename generic_type::scalar_view    scalar_t; 
 44947 |       typedef typename generic_type::vector_view    vector_t; 
 44948 |  
 44949 |       using igfun_t::operator(); 
 44950 |  
 44951 |       rol() 
 44952 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 44953 |         /* 
 44954 |            Overloads: 
 44955 |            0. VT   - vector, N 
 44956 |            1. VTTT - vector, N, r0, r1 
 44957 |         */ 
 44958 |       {} 
 44959 |  
 44960 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44961 |       { 
 44962 |          vector_t vec(parameters[0]); 
 44963 |  
 44964 |          std::size_t n  = 0; 
 44965 |          std::size_t r0 = 0; 
 44966 |          std::size_t r1 = vec.size() - 1; 
 44967 |  
 44968 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 44969 |             return T(0); 
 44970 |  
 44971 |          if ( 
 44972 |               (1 == ps_index) && 
 44973 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 44974 |             ) 
 44975 |             return T(0); 
 44976 |  
 44977 |          const std::size_t dist  = r1 - r0 + 1; 
 44978 |          const std::size_t shift = n % dist; 
 44979 |  
 44980 |          std::rotate( 
 44981 |             vec.begin() + r0, 
 44982 |             vec.begin() + r0 + shift, 
 44983 |             vec.begin() + r1 + 1); 
 44984 |  
 44985 |          return T(1); 
 44986 |       } 
 44987 |    }; 
 44988 |  
 44989 |    template <typename T> 
 44990 |    class ror exprtk_final : public exprtk::igeneric_function<T> 
 44991 |    { 
 44992 |    public: 
 44993 |  
 44994 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44995 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44996 |       typedef typename igfun_t::generic_type        generic_type; 
 44997 |       typedef typename generic_type::scalar_view    scalar_t; 
 44998 |       typedef typename generic_type::vector_view    vector_t; 
 44999 |  
 45000 |       using igfun_t::operator(); 
 45001 |  
 45002 |       ror() 
 45003 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 45004 |         /* 
 45005 |            Overloads: 
 45006 |            0. VT   - vector, N 
 45007 |            1. VTTT - vector, N, r0, r1 
 45008 |         */ 
 45009 |       {} 
 45010 |  
 45011 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45012 |       { 
 45013 |          vector_t vec(parameters[0]); 
 45014 |  
 45015 |          std::size_t n  = 0; 
 45016 |          std::size_t r0 = 0; 
 45017 |          std::size_t r1 = vec.size() - 1; 
 45018 |  
 45019 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 45020 |             return T(0); 
 45021 |  
 45022 |          if ( 
 45023 |               (1 == ps_index) && 
 45024 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 45025 |             ) 
 45026 |             return T(0); 
 45027 |  
 45028 |          const std::size_t dist  = r1 - r0 + 1; 
 45029 |          const std::size_t shift = (dist - (n % dist)) % dist; 
 45030 |  
 45031 |          std::rotate( 
 45032 |             vec.begin() + r0, 
 45033 |             vec.begin() + r0 + shift, 
 45034 |             vec.begin() + r1 + 1); 
 45035 |  
 45036 |          return T(1); 
 45037 |       } 
 45038 |    }; 
 45039 |  
 45040 |    template <typename T> 
 45041 |    class reverse exprtk_final : public exprtk::igeneric_function<T> 
 45042 |    { 
 45043 |    public: 
 45044 |  
 45045 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45046 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45047 |       typedef typename igfun_t::generic_type        generic_type; 
 45048 |       typedef typename generic_type::scalar_view    scalar_t; 
 45049 |       typedef typename generic_type::vector_view    vector_t; 
 45050 |  
 45051 |       using igfun_t::operator(); 
 45052 |  
 45053 |       reverse() 
 45054 |       : exprtk::igeneric_function<T>("V|VTT") 
 45055 |         /* 
 45056 |            Overloads: 
 45057 |            0. V   - vector 
 45058 |            1. VTT - vector, r0, r1 
 45059 |         */ 
 45060 |       {} 
 45061 |  
 45062 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45063 |       { 
 45064 |          vector_t vec(parameters[0]); 
 45065 |  
 45066 |          std::size_t r0 = 0; 
 45067 |          std::size_t r1 = vec.size() - 1; 
 45068 |  
 45069 |          if ( 
 45070 |               (1 == ps_index) && 
 45071 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45072 |             ) 
 45073 |             return T(0); 
 45074 |  
 45075 |          std::reverse(vec.begin() + r0, vec.begin() + r1 + 1); 
 45076 |  
 45077 |          return T(1); 
 45078 |       } 
 45079 |    }; 
 45080 |  
 45081 |    template <typename T> 
 45082 |    class shift_left exprtk_final : public exprtk::igeneric_function<T> 
 45083 |    { 
 45084 |    public: 
 45085 |  
 45086 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45087 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45088 |       typedef typename igfun_t::generic_type        generic_type; 
 45089 |       typedef typename generic_type::scalar_view    scalar_t; 
 45090 |       typedef typename generic_type::vector_view    vector_t; 
 45091 |  
 45092 |       using igfun_t::operator(); 
 45093 |  
 45094 |       shift_left() 
 45095 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 45096 |         /* 
 45097 |            Overloads: 
 45098 |            0. VT   - vector, N 
 45099 |            1. VTTT - vector, N, r0, r1 
 45100 |         */ 
 45101 |       {} 
 45102 |  
 45103 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45104 |       { 
 45105 |          vector_t vec(parameters[0]); 
 45106 |  
 45107 |          std::size_t n  = 0; 
 45108 |          std::size_t r0 = 0; 
 45109 |          std::size_t r1 = vec.size() - 1; 
 45110 |  
 45111 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 45112 |             return T(0); 
 45113 |  
 45114 |          if ( 
 45115 |               (1 == ps_index) && 
 45116 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 45117 |             ) 
 45118 |             return T(0); 
 45119 |  
 45120 |          const std::size_t dist = r1 - r0 + 1; 
 45121 |  
 45122 |          if (n > dist) 
 45123 |             return T(0); 
 45124 |  
 45125 |          std::rotate( 
 45126 |             vec.begin() + r0, 
 45127 |             vec.begin() + r0 + n, 
 45128 |             vec.begin() + r1 + 1); 
 45129 |  
 45130 |          for (std::size_t i = r1 - n + 1ULL; i <= r1; ++i) 
 45131 |          { 
 45132 |             vec[i] = T(0); 
 45133 |          } 
 45134 |  
 45135 |          return T(1); 
 45136 |       } 
 45137 |    }; 
 45138 |  
 45139 |    template <typename T> 
 45140 |    class shift_right exprtk_final : public exprtk::igeneric_function<T> 
 45141 |    { 
 45142 |    public: 
 45143 |  
 45144 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45145 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45146 |       typedef typename igfun_t::generic_type        generic_type; 
 45147 |       typedef typename generic_type::scalar_view    scalar_t; 
 45148 |       typedef typename generic_type::vector_view    vector_t; 
 45149 |  
 45150 |       using igfun_t::operator(); 
 45151 |  
 45152 |       shift_right() 
 45153 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 45154 |         /* 
 45155 |            Overloads: 
 45156 |            0. VT   - vector, N 
 45157 |            1. VTTT - vector, N, r0, r1 
 45158 |         */ 
 45159 |       {} 
 45160 |  
 45161 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45162 |       { 
 45163 |          vector_t vec(parameters[0]); 
 45164 |  
 45165 |          std::size_t n  = 0; 
 45166 |          std::size_t r0 = 0; 
 45167 |          std::size_t r1 = vec.size() - 1; 
 45168 |  
 45169 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 45170 |             return T(0); 
 45171 |  
 45172 |          if ( 
 45173 |               (1 == ps_index) && 
 45174 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 45175 |             ) 
 45176 |             return T(0); 
 45177 |  
 45178 |          const std::size_t dist = r1 - r0 + 1; 
 45179 |  
 45180 |          if (n > dist) 
 45181 |             return T(0); 
 45182 |  
 45183 |          const std::size_t shift = (dist - (n % dist)) % dist; 
 45184 |  
 45185 |          std::rotate( 
 45186 |             vec.begin() + r0, 
 45187 |             vec.begin() + r0 + shift, 
 45188 |             vec.begin() + r1 + 1); 
 45189 |  
 45190 |          for (std::size_t i = r0; i < r0 + n; ++i) 
 45191 |          { 
 45192 |             vec[i] = T(0); 
 45193 |          } 
 45194 |  
 45195 |          return T(1); 
 45196 |       } 
 45197 |    }; 
 45198 |  
 45199 |    template <typename T> 
 45200 |    class sort exprtk_final : public exprtk::igeneric_function<T> 
 45201 |    { 
 45202 |    public: 
 45203 |  
 45204 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45205 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45206 |       typedef typename igfun_t::generic_type        generic_type; 
 45207 |       typedef typename generic_type::string_view    string_t; 
 45208 |       typedef typename generic_type::vector_view    vector_t; 
 45209 |  
 45210 |       using igfun_t::operator(); 
 45211 |  
 45212 |       sort() 
 45213 |       : exprtk::igeneric_function<T>("V|VTT|VS|VSTT") 
 45214 |         /* 
 45215 |            Overloads: 
 45216 |            0. V    - vector 
 45217 |            1. VTT  - vector, r0, r1 
 45218 |            2. VS   - vector, string 
 45219 |            3. VSTT - vector, string, r0, r1 
 45220 |         */ 
 45221 |       {} 
 45222 |  
 45223 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45224 |       { 
 45225 |          vector_t vec(parameters[0]); 
 45226 |  
 45227 |          std::size_t r0 = 0; 
 45228 |          std::size_t r1 = vec.size() - 1; 
 45229 |  
 45230 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)) 
 45231 |             return T(0); 
 45232 |          if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45233 |             return T(0); 
 45234 |  
 45235 |          bool ascending = true; 
 45236 |  
 45237 |          if ((2 == ps_index) || (3 == ps_index)) 
 45238 |          { 
 45239 |             if (exprtk::details::imatch(to_str(string_t(parameters[1])),"ascending")) 
 45240 |                ascending = true; 
 45241 |             else if (exprtk::details::imatch(to_str(string_t(parameters[1])),"descending")) 
 45242 |                ascending = false; 
 45243 |             else 
 45244 |                return T(0); 
 45245 |          } 
 45246 |  
 45247 |          if (ascending) 
 45248 |             std::sort( 
 45249 |                vec.begin() + r0, 
 45250 |                vec.begin() + r1 + 1, 
 45251 |                std::less<T>()); 
 45252 |          else 
 45253 |             std::sort( 
 45254 |                vec.begin() + r0, 
 45255 |                vec.begin() + r1 + 1, 
 45256 |                std::greater<T>()); 
 45257 |  
 45258 |          return T(1); 
 45259 |       } 
 45260 |    }; 
 45261 |  
 45262 |    template <typename T> 
 45263 |    class nthelement exprtk_final : public exprtk::igeneric_function<T> 
 45264 |    { 
 45265 |    public: 
 45266 |  
 45267 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45268 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45269 |       typedef typename igfun_t::generic_type        generic_type; 
 45270 |       typedef typename generic_type::scalar_view    scalar_t; 
 45271 |       typedef typename generic_type::vector_view    vector_t; 
 45272 |  
 45273 |       using igfun_t::operator(); 
 45274 |  
 45275 |       nthelement() 
 45276 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 45277 |         /* 
 45278 |            Overloads: 
 45279 |            0. VT   - vector, nth-element 
 45280 |            1. VTTT - vector, nth-element, r0, r1 
 45281 |         */ 
 45282 |       {} 
 45283 |  
 45284 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45285 |       { 
 45286 |          vector_t vec(parameters[0]); 
 45287 |  
 45288 |          std::size_t n  = 0; 
 45289 |          std::size_t r0 = 0; 
 45290 |          std::size_t r1 = vec.size() - 1; 
 45291 |  
 45292 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 45293 |             return T(0); 
 45294 |  
 45295 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45296 |          { 
 45297 |             return std::numeric_limits<T>::quiet_NaN(); 
 45298 |          } 
 45299 |  
 45300 |          std::nth_element( 
 45301 |             vec.begin() + r0, 
 45302 |             vec.begin() + r0 + n , 
 45303 |             vec.begin() + r1 + 1); 
 45304 |  
 45305 |          return T(1); 
 45306 |       } 
 45307 |    }; 
 45308 |  
 45309 |    template <typename T> 
 45310 |    class assign exprtk_final : public exprtk::igeneric_function<T> 
 45311 |    { 
 45312 |    public: 
 45313 |  
 45314 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45315 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45316 |       typedef typename igfun_t::generic_type        generic_type; 
 45317 |       typedef typename generic_type::scalar_view    scalar_t; 
 45318 |       typedef typename generic_type::vector_view    vector_t; 
 45319 |  
 45320 |       using igfun_t::operator(); 
 45321 |  
 45322 |       assign() 
 45323 |       : exprtk::igeneric_function<T>("VT|VTTT|VTTTT") 
 45324 |         /* 
 45325 |            Overloads: 
 45326 |            0. VT    - vector, V 
 45327 |            1. VTTT  - vector, V, r0, r1 
 45328 |            2. VTTTT - vector, V, r0, r1, SS 
 45329 |         */ 
 45330 |       {} 
 45331 |  
 45332 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45333 |       { 
 45334 |          vector_t vec(parameters[0]); 
 45335 |  
 45336 |          const T assign_value = scalar_t(parameters[1]); 
 45337 |  
 45338 |          const std::size_t step_size = (2 != ps_index) ? 1 : 
 45339 |                                        static_cast<std::size_t>(scalar_t(parameters.back())()); 
 45340 |  
 45341 |          std::size_t r0 = 0; 
 45342 |          std::size_t r1 = vec.size() - 1; 
 45343 |  
 45344 |          if ( 
 45345 |               ((ps_index == 1) || (ps_index == 2)) && 
 45346 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 45347 |             ) 
 45348 |          { 
 45349 |             return T(0); 
 45350 |          } 
 45351 |  
 45352 |          for (std::size_t i = r0; i <= r1; i += step_size) 
 45353 |          { 
 45354 |             vec[i] = assign_value; 
 45355 |          } 
 45356 |  
 45357 |          return T(1); 
 45358 |       } 
 45359 |    }; 
 45360 |  
 45361 |    template <typename T> 
 45362 |    class iota exprtk_final : public exprtk::igeneric_function<T> 
 45363 |    { 
 45364 |    public: 
 45365 |  
 45366 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45367 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45368 |       typedef typename igfun_t::generic_type        generic_type; 
 45369 |       typedef typename generic_type::scalar_view    scalar_t; 
 45370 |       typedef typename generic_type::vector_view    vector_t; 
 45371 |  
 45372 |       using igfun_t::operator(); 
 45373 |  
 45374 |       iota() 
 45375 |       : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT") 
 45376 |         /* 
 45377 |            Overloads: 
 45378 |            0. VTT  - vector, SV, SS 
 45379 |            1. VT   - vector, SV, SS (+1) 
 45380 |            2. VTTT - vector, r0, r1, SV, SS 
 45381 |            3. VTT  - vector, r0, r1, SV, SS (+1) 
 45382 |  
 45383 |            Where: 
 45384 |            1. SV - Start value 
 45385 |            2. SS - Step size 
 45386 |         */ 
 45387 |       {} 
 45388 |  
 45389 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45390 |       { 
 45391 |          vector_t vec(parameters[0]); 
 45392 |  
 45393 |          const T start_value = (ps_index <= 1) ? 
 45394 |                                scalar_t(parameters[1]) : 
 45395 |                                scalar_t(parameters[3]) ; 
 45396 |  
 45397 |          const T step_size = ((0 == ps_index) || (2 == ps_index)) ? 
 45398 |                              scalar_t(parameters.back())() : 
 45399 |                              T(1) ; 
 45400 |  
 45401 |          std::size_t r0 = 0; 
 45402 |          std::size_t r1 = vec.size() - 1; 
 45403 |  
 45404 |          if ( 
 45405 |               ((ps_index == 2) || (ps_index == 3)) && 
 45406 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45407 |             ) 
 45408 |          { 
 45409 |             return T(0); 
 45410 |          } 
 45411 |  
 45412 |          for (std::size_t i = r0; i <= r1; ++i) 
 45413 |          { 
 45414 |             vec[i] = start_value + ((i - r0) * step_size); 
 45415 |          } 
 45416 |  
 45417 |          return T(1); 
 45418 |       } 
 45419 |    }; 
 45420 |  
 45421 |    template <typename T> 
 45422 |    class sumk exprtk_final : public exprtk::igeneric_function<T> 
 45423 |    { 
 45424 |    public: 
 45425 |  
 45426 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45427 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45428 |       typedef typename igfun_t::generic_type        generic_type; 
 45429 |       typedef typename generic_type::scalar_view    scalar_t; 
 45430 |       typedef typename generic_type::vector_view    vector_t; 
 45431 |  
 45432 |       using igfun_t::operator(); 
 45433 |  
 45434 |       sumk() 
 45435 |       : exprtk::igeneric_function<T>("V|VTT|VTTT") 
 45436 |         /* 
 45437 |            Overloads: 
 45438 |            0. V    - vector 
 45439 |            1. VTT  - vector, r0, r1 
 45440 |            2. VTTT - vector, r0, r1, stride 
 45441 |         */ 
 45442 |       {} 
 45443 |  
 45444 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45445 |       { 
 45446 |          const vector_t vec(parameters[0]); 
 45447 |  
 45448 |          const std::size_t stride = (2 != ps_index) ? 1 : 
 45449 |                                     static_cast<std::size_t>(scalar_t(parameters[3])()); 
 45450 |  
 45451 |          std::size_t r0 = 0; 
 45452 |          std::size_t r1 = vec.size() - 1; 
 45453 |  
 45454 |          if ( 
 45455 |               ((1 == ps_index) || (2 == ps_index)) && 
 45456 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45457 |             ) 
 45458 |          { 
 45459 |             return std::numeric_limits<T>::quiet_NaN(); 
 45460 |          } 
 45461 |  
 45462 |          T result = T(0); 
 45463 |          T error  = T(0); 
 45464 |  
 45465 |          for (std::size_t i = r0; i <= r1; i += stride) 
 45466 |          { 
 45467 |             details::kahan_sum(result, error, vec[i]); 
 45468 |          } 
 45469 |  
 45470 |          return result; 
 45471 |       } 
 45472 |    }; 
 45473 |  
 45474 |    template <typename T> 
 45475 |    class axpy exprtk_final : public exprtk::igeneric_function<T> 
 45476 |    { 
 45477 |    public: 
 45478 |  
 45479 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45480 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45481 |       typedef typename igfun_t::generic_type        generic_type; 
 45482 |       typedef typename generic_type::scalar_view    scalar_t; 
 45483 |       typedef typename generic_type::vector_view    vector_t; 
 45484 |  
 45485 |       using igfun_t::operator(); 
 45486 |  
 45487 |       axpy() 
 45488 |       : exprtk::igeneric_function<T>("TVV|TVVTT") 
 45489 |         /* 
 45490 |            y <- ax + y 
 45491 |            Overloads: 
 45492 |            0. TVV   - a, x(vector), y(vector) 
 45493 |            1. TVVTT - a, x(vector), y(vector), r0, r1 
 45494 |         */ 
 45495 |       {} 
 45496 |  
 45497 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45498 |       { 
 45499 |          const vector_t x(parameters[1]); 
 45500 |                vector_t y(parameters[2]); 
 45501 |  
 45502 |          std::size_t r0 = 0; 
 45503 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45504 |  
 45505 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1)) 
 45506 |             return std::numeric_limits<T>::quiet_NaN(); 
 45507 |          else if (helper::invalid_range(y, r0, r1)) 
 45508 |             return std::numeric_limits<T>::quiet_NaN(); 
 45509 |  
 45510 |          const T a = scalar_t(parameters[0])(); 
 45511 |  
 45512 |          for (std::size_t i = r0; i <= r1; ++i) 
 45513 |          { 
 45514 |             y[i] = (a * x[i]) + y[i]; 
 45515 |          } 
 45516 |  
 45517 |          return T(1); 
 45518 |       } 
 45519 |    }; 
 45520 |  
 45521 |    template <typename T> 
 45522 |    class axpby 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 |       axpby() 
 45535 |       : exprtk::igeneric_function<T>("TVTV|TVTVTT") 
 45536 |         /* 
 45537 |            y <- ax + by 
 45538 |            Overloads: 
 45539 |            0. TVTV   - a, x(vector), b, y(vector) 
 45540 |            1. TVTVTT - a, x(vector), b, y(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[3]); 
 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, 4, 5, 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 |          for (std::size_t i = r0; i <= r1; ++i) 
 45561 |          { 
 45562 |             y[i] = (a * x[i]) + (b * y[i]); 
 45563 |          } 
 45564 |  
 45565 |          return T(1); 
 45566 |       } 
 45567 |    }; 
 45568 |  
 45569 |    template <typename T> 
 45570 |    class axpyz exprtk_final : public exprtk::igeneric_function<T> 
 45571 |    { 
 45572 |    public: 
 45573 |  
 45574 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45575 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45576 |       typedef typename igfun_t::generic_type        generic_type; 
 45577 |       typedef typename generic_type::scalar_view    scalar_t; 
 45578 |       typedef typename generic_type::vector_view    vector_t; 
 45579 |  
 45580 |       using igfun_t::operator(); 
 45581 |  
 45582 |       axpyz() 
 45583 |       : exprtk::igeneric_function<T>("TVVV|TVVVTT") 
 45584 |         /* 
 45585 |            z <- ax + y 
 45586 |            Overloads: 
 45587 |            0. TVVV   - a, x(vector), y(vector), z(vector) 
 45588 |            1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1 
 45589 |         */ 
 45590 |       {} 
 45591 |  
 45592 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45593 |       { 
 45594 |          const vector_t x(parameters[1]); 
 45595 |          const vector_t y(parameters[2]); 
 45596 |                vector_t z(parameters[3]); 
 45597 |  
 45598 |          std::size_t r0 = 0; 
 45599 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45600 |  
 45601 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1)) 
 45602 |             return std::numeric_limits<T>::quiet_NaN(); 
 45603 |          else if (helper::invalid_range(y, r0, r1)) 
 45604 |             return std::numeric_limits<T>::quiet_NaN(); 
 45605 |          else if (helper::invalid_range(z, r0, r1)) 
 45606 |             return std::numeric_limits<T>::quiet_NaN(); 
 45607 |  
 45608 |          const T a = scalar_t(parameters[0])(); 
 45609 |  
 45610 |          for (std::size_t i = r0; i <= r1; ++i) 
 45611 |          { 
 45612 |             z[i] = (a * x[i]) + y[i]; 
 45613 |          } 
 45614 |  
 45615 |          return T(1); 
 45616 |       } 
 45617 |    }; 
 45618 |  
 45619 |    template <typename T> 
 45620 |    class axpbyz exprtk_final : public exprtk::igeneric_function<T> 
 45621 |    { 
 45622 |    public: 
 45623 |  
 45624 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45625 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45626 |       typedef typename igfun_t::generic_type        generic_type; 
 45627 |       typedef typename generic_type::scalar_view    scalar_t; 
 45628 |       typedef typename generic_type::vector_view    vector_t; 
 45629 |  
 45630 |       using igfun_t::operator(); 
 45631 |  
 45632 |       axpbyz() 
 45633 |       : exprtk::igeneric_function<T>("TVTVV|TVTVVTT") 
 45634 |         /* 
 45635 |            z <- ax + by 
 45636 |            Overloads: 
 45637 |            0. TVTVV   - a, x(vector), b, y(vector), z(vector) 
 45638 |            1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1 
 45639 |         */ 
 45640 |       {} 
 45641 |  
 45642 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45643 |       { 
 45644 |          const vector_t x(parameters[1]); 
 45645 |          const vector_t y(parameters[3]); 
 45646 |                vector_t z(parameters[4]); 
 45647 |  
 45648 |          std::size_t r0 = 0; 
 45649 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45650 |  
 45651 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1)) 
 45652 |             return std::numeric_limits<T>::quiet_NaN(); 
 45653 |          else if (helper::invalid_range(y, r0, r1)) 
 45654 |             return std::numeric_limits<T>::quiet_NaN(); 
 45655 |          else if (helper::invalid_range(z, r0, r1)) 
 45656 |             return std::numeric_limits<T>::quiet_NaN(); 
 45657 |  
 45658 |          const T a = scalar_t(parameters[0])(); 
 45659 |          const T b = scalar_t(parameters[2])(); 
 45660 |  
 45661 |          for (std::size_t i = r0; i <= r1; ++i) 
 45662 |          { 
 45663 |             z[i] = (a * x[i]) + (b * y[i]); 
 45664 |          } 
 45665 |  
 45666 |          return T(1); 
 45667 |       } 
 45668 |    }; 
 45669 |  
 45670 |    template <typename T> 
 45671 |    class axpbsy exprtk_final : public exprtk::igeneric_function<T> 
 45672 |    { 
 45673 |    public: 
 45674 |  
 45675 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45676 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45677 |       typedef typename igfun_t::generic_type        generic_type; 
 45678 |       typedef typename generic_type::scalar_view    scalar_t; 
 45679 |       typedef typename generic_type::vector_view    vector_t; 
 45680 |  
 45681 |       using igfun_t::operator(); 
 45682 |  
 45683 |       axpbsy() 
 45684 |       : exprtk::igeneric_function<T>("TVTTV|TVTTVTT") 
 45685 |         /* 
 45686 |            y <- ax + by 
 45687 |            Overloads: 
 45688 |            0. TVTVV   - a, x(vector), b, shift, y(vector), z(vector) 
 45689 |            1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1 
 45690 |         */ 
 45691 |       {} 
 45692 |  
 45693 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45694 |       { 
 45695 |          const vector_t x(parameters[1]); 
 45696 |                vector_t y(parameters[4]); 
 45697 |  
 45698 |          std::size_t r0 = 0; 
 45699 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45700 |  
 45701 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1)) 
 45702 |             return std::numeric_limits<T>::quiet_NaN(); 
 45703 |          else if (helper::invalid_range(y, r0, r1)) 
 45704 |             return std::numeric_limits<T>::quiet_NaN(); 
 45705 |  
 45706 |          const T a = scalar_t(parameters[0])(); 
 45707 |          const T b = scalar_t(parameters[2])(); 
 45708 |  
 45709 |          const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])()); 
 45710 |  
 45711 |          for (std::size_t i = r0; i <= r1; ++i) 
 45712 |          { 
 45713 |             y[i] = (a * x[i]) + (b * y[i + s]); 
 45714 |          } 
 45715 |  
 45716 |          return T(1); 
 45717 |       } 
 45718 |    }; 
 45719 |  
 45720 |    template <typename T> 
 45721 |    class axpbsyz 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 |       axpbsyz() 
 45734 |       : exprtk::igeneric_function<T>("TVTTVV|TVTTVVTT") 
 45735 |         /* 
 45736 |            z <- ax + by 
 45737 |            Overloads: 
 45738 |            0. TVTVV   - a, x(vector), b, shift, y(vector), z(vector) 
 45739 |            1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1 
 45740 |         */ 
 45741 |       {} 
 45742 |  
 45743 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45744 |       { 
 45745 |          const vector_t x(parameters[1]); 
 45746 |          const vector_t y(parameters[4]); 
 45747 |                vector_t z(parameters[5]); 
 45748 |  
 45749 |          std::size_t r0 = 0; 
 45750 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45751 |  
 45752 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1)) 
 45753 |             return std::numeric_limits<T>::quiet_NaN(); 
 45754 |          else if (helper::invalid_range(y, r0, r1)) 
 45755 |             return std::numeric_limits<T>::quiet_NaN(); 
 45756 |          else if (helper::invalid_range(z, r0, r1)) 
 45757 |             return std::numeric_limits<T>::quiet_NaN(); 
 45758 |  
 45759 |          const T a = scalar_t(parameters[0])(); 
 45760 |          const T b = scalar_t(parameters[2])(); 
 45761 |  
 45762 |          const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])()); 
 45763 |  
 45764 |          for (std::size_t i = r0; i <= r1; ++i) 
 45765 |          { 
 45766 |             z[i] = (a * x[i]) + (b * y[i + s]); 
 45767 |          } 
 45768 |  
 45769 |          return T(1); 
 45770 |       } 
 45771 |    }; 
 45772 |  
 45773 |    template <typename T> 
 45774 |    class axpbz exprtk_final : public exprtk::igeneric_function<T> 
 45775 |    { 
 45776 |    public: 
 45777 |  
 45778 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45779 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45780 |       typedef typename igfun_t::generic_type        generic_type; 
 45781 |       typedef typename generic_type::scalar_view    scalar_t; 
 45782 |       typedef typename generic_type::vector_view    vector_t; 
 45783 |  
 45784 |       using igfun_t::operator(); 
 45785 |  
 45786 |       axpbz() 
 45787 |       : exprtk::igeneric_function<T>("TVTV|TVTVTT") 
 45788 |         /* 
 45789 |            z <- ax + b 
 45790 |            Overloads: 
 45791 |            0. TVTV   - a, x(vector), b, z(vector) 
 45792 |            1. TVTVTT - a, x(vector), b, z(vector), r0, r1 
 45793 |         */ 
 45794 |       {} 
 45795 |  
 45796 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45797 |       { 
 45798 |          const vector_t x(parameters[1]); 
 45799 |                vector_t z(parameters[3]); 
 45800 |  
 45801 |          std::size_t r0 = 0; 
 45802 |          std::size_t r1 = x.size() - 1; 
 45803 |  
 45804 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1)) 
 45805 |             return std::numeric_limits<T>::quiet_NaN(); 
 45806 |          else if (helper::invalid_range(z, r0, r1)) 
 45807 |             return std::numeric_limits<T>::quiet_NaN(); 
 45808 |  
 45809 |          const T a = scalar_t(parameters[0])(); 
 45810 |          const T b = scalar_t(parameters[2])(); 
 45811 |  
 45812 |          for (std::size_t i = r0; i <= r1; ++i) 
 45813 |          { 
 45814 |             z[i] = (a * x[i]) + b; 
 45815 |          } 
 45816 |  
 45817 |          return T(1); 
 45818 |       } 
 45819 |    }; 
 45820 |  
 45821 |    template <typename T> 
 45822 |    class diff exprtk_final : public exprtk::igeneric_function<T> 
 45823 |    { 
 45824 |    public: 
 45825 |  
 45826 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45827 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45828 |       typedef typename igfun_t::generic_type        generic_type; 
 45829 |       typedef typename generic_type::scalar_view    scalar_t; 
 45830 |       typedef typename generic_type::vector_view    vector_t; 
 45831 |  
 45832 |       using igfun_t::operator(); 
 45833 |  
 45834 |       diff() 
 45835 |       : exprtk::igeneric_function<T>("VV|VVT") 
 45836 |         /* 
 45837 |            x_(i - stride) - x_i 
 45838 |            Overloads: 
 45839 |            0. VV  - x(vector), y(vector) 
 45840 |            1. VVT - x(vector), y(vector), stride 
 45841 |         */ 
 45842 |       {} 
 45843 |  
 45844 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45845 |       { 
 45846 |          const vector_t x(parameters[0]); 
 45847 |                vector_t y(parameters[1]); 
 45848 |  
 45849 |          const std::size_t r0 = 0; 
 45850 |          const std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45851 |  
 45852 |          const std::size_t stride = (1 != ps_index) ? 1 : 
 45853 |                                     std::min(r1,static_cast<std::size_t>(scalar_t(parameters[2])())); 
 45854 |  
 45855 |          for (std::size_t i = 0; i < stride; ++i) 
 45856 |          { 
 45857 |             y[i] = std::numeric_limits<T>::quiet_NaN(); 
 45858 |          } 
 45859 |  
 45860 |          for (std::size_t i = (r0 + stride); i <= r1; ++i) 
 45861 |          { 
 45862 |             y[i] = x[i] - x[i - stride]; 
 45863 |          } 
 45864 |  
 45865 |          return T(1); 
 45866 |       } 
 45867 |    }; 
 45868 |  
 45869 |    template <typename T> 
 45870 |    class dot exprtk_final : public exprtk::igeneric_function<T> 
 45871 |    { 
 45872 |    public: 
 45873 |  
 45874 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45875 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45876 |       typedef typename igfun_t::generic_type        generic_type; 
 45877 |       typedef typename generic_type::scalar_view    scalar_t; 
 45878 |       typedef typename generic_type::vector_view    vector_t; 
 45879 |  
 45880 |       using igfun_t::operator(); 
 45881 |  
 45882 |       dot() 
 45883 |       : exprtk::igeneric_function<T>("VV|VVTT") 
 45884 |         /* 
 45885 |            Overloads: 
 45886 |            0. VV   - x(vector), y(vector) 
 45887 |            1. VVTT - x(vector), y(vector), r0, r1 
 45888 |         */ 
 45889 |       {} 
 45890 |  
 45891 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45892 |       { 
 45893 |          const vector_t x(parameters[0]); 
 45894 |          const vector_t y(parameters[1]); 
 45895 |  
 45896 |          std::size_t r0 = 0; 
 45897 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45898 |  
 45899 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45900 |             return std::numeric_limits<T>::quiet_NaN(); 
 45901 |          else if (helper::invalid_range(y, r0, r1)) 
 45902 |             return std::numeric_limits<T>::quiet_NaN(); 
 45903 |  
 45904 |          T result = T(0); 
 45905 |  
 45906 |          for (std::size_t i = r0; i <= r1; ++i) 
 45907 |          { 
 45908 |             result += (x[i] * y[i]); 
 45909 |          } 
 45910 |  
 45911 |          return result; 
 45912 |       } 
 45913 |    }; 
 45914 |  
 45915 |    template <typename T> 
 45916 |    class dotk exprtk_final : public exprtk::igeneric_function<T> 
 45917 |    { 
 45918 |    public: 
 45919 |  
 45920 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45921 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45922 |       typedef typename igfun_t::generic_type        generic_type; 
 45923 |       typedef typename generic_type::scalar_view    scalar_t; 
 45924 |       typedef typename generic_type::vector_view    vector_t; 
 45925 |  
 45926 |       using igfun_t::operator(); 
 45927 |  
 45928 |       dotk() 
 45929 |       : exprtk::igeneric_function<T>("VV|VVTT") 
 45930 |         /* 
 45931 |            Overloads: 
 45932 |            0. VV   - x(vector), y(vector) 
 45933 |            1. VVTT - x(vector), y(vector), r0, r1 
 45934 |         */ 
 45935 |       {} 
 45936 |  
 45937 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45938 |       { 
 45939 |          const vector_t x(parameters[0]); 
 45940 |          const vector_t y(parameters[1]); 
 45941 |  
 45942 |          std::size_t r0 = 0; 
 45943 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45944 |  
 45945 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45946 |             return std::numeric_limits<T>::quiet_NaN(); 
 45947 |          else if (helper::invalid_range(y, r0, r1)) 
 45948 |             return std::numeric_limits<T>::quiet_NaN(); 
 45949 |  
 45950 |          T result = T(0); 
 45951 |          T error  = T(0); 
 45952 |  
 45953 |          for (std::size_t i = r0; i <= r1; ++i) 
 45954 |          { 
 45955 |             details::kahan_sum(result, error, (x[i] * y[i])); 
 45956 |          } 
 45957 |  
 45958 |          return result; 
 45959 |       } 
 45960 |    }; 
 45961 |  
 45962 |    template <typename T> 
 45963 |    class threshold_below exprtk_final : public exprtk::igeneric_function<T> 
 45964 |    { 
 45965 |    public: 
 45966 |  
 45967 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45968 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45969 |       typedef typename igfun_t::generic_type        generic_type; 
 45970 |       typedef typename generic_type::scalar_view    scalar_t; 
 45971 |       typedef typename generic_type::vector_view    vector_t; 
 45972 |  
 45973 |       using igfun_t::operator(); 
 45974 |  
 45975 |       threshold_below() 
 45976 |       : exprtk::igeneric_function<T>("VTT|VTTTT") 
 45977 |       /* 
 45978 |          Overloads: 
 45979 |          0. VTT   - vector, TV, SV 
 45980 |          1. VTTTT - vector, r0, r1, TV, SV 
 45981 |  
 45982 |          Where: 
 45983 |          TV - Threshold value 
 45984 |          SV - Snap-to value 
 45985 |       */ 
 45986 |       {} 
 45987 |  
 45988 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45989 |       { 
 45990 |          vector_t vec(parameters[0]); 
 45991 |  
 45992 |          const T threshold_value = (0 == ps_index) ? 
 45993 |                                    scalar_t(parameters[1]) : 
 45994 |                                    scalar_t(parameters[3]) ; 
 45995 |  
 45996 |          const T snap_value = scalar_t(parameters.back()); 
 45997 |  
 45998 |          std::size_t r0 = 0; 
 45999 |          std::size_t r1 = vec.size() - 1; 
 46000 |  
 46001 |          if ( 
 46002 |               (1 == ps_index) && 
 46003 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 46004 |             ) 
 46005 |          { 
 46006 |             return T(0); 
 46007 |          } 
 46008 |  
 46009 |          for (std::size_t i = r0; i <= r1; ++i) 
 46010 |          { 
 46011 |             if (vec[i] < threshold_value) 
 46012 |             { 
 46013 |                vec[i] = snap_value; 
 46014 |             } 
 46015 |          } 
 46016 |  
 46017 |          return T(1); 
 46018 |       } 
 46019 |    }; 
 46020 |  
 46021 |    template <typename T> 
 46022 |    class threshold_above exprtk_final : public exprtk::igeneric_function<T> 
 46023 |    { 
 46024 |    public: 
 46025 |  
 46026 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 46027 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 46028 |       typedef typename igfun_t::generic_type        generic_type; 
 46029 |       typedef typename generic_type::scalar_view    scalar_t; 
 46030 |       typedef typename generic_type::vector_view    vector_t; 
 46031 |  
 46032 |       using igfun_t::operator(); 
 46033 |  
 46034 |       threshold_above() 
 46035 |       : exprtk::igeneric_function<T>("VTT|VTTTT") 
 46036 |       /* 
 46037 |          Overloads: 
 46038 |          0. VTT   - vector, TV, SV 
 46039 |          1. VTTTT - vector, r0, r1, TV, SV 
 46040 |  
 46041 |          Where: 
 46042 |          TV - Threshold value 
 46043 |          SV - Snap-to value 
 46044 |       */ 
 46045 |       {} 
 46046 |  
 46047 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 46048 |       { 
 46049 |          vector_t vec(parameters[0]); 
 46050 |  
 46051 |          const T threshold_value = (0 == ps_index) ? 
 46052 |                                    scalar_t(parameters[1]) : 
 46053 |                                    scalar_t(parameters[3]) ; 
 46054 |  
 46055 |          const T snap_value = scalar_t(parameters.back()); 
 46056 |  
 46057 |          std::size_t r0 = 0; 
 46058 |          std::size_t r1 = vec.size() - 1; 
 46059 |  
 46060 |          if ( 
 46061 |               (1 == ps_index) && 
 46062 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 46063 |             ) 
 46064 |          { 
 46065 |             return T(0); 
 46066 |          } 
 46067 |  
 46068 |          for (std::size_t i = r0; i <= r1; ++i) 
 46069 |          { 
 46070 |             if (vec[i] > threshold_value) 
 46071 |             { 
 46072 |                vec[i] = snap_value; 
 46073 |             } 
 46074 |          } 
 46075 |  
 46076 |          return T(1); 
 46077 |       } 
 46078 |    }; 
 46079 |  
 46080 |    template <typename T> 
 46081 |    struct package 
 46082 |    { 
 46083 |       all_true       <T> at; 
 46084 |       all_false      <T> af; 
 46085 |       any_true       <T> nt; 
 46086 |       any_false      <T> nf; 
 46087 |       count          <T>  c; 
 46088 |       copy           <T> cp; 
 46089 |       rol            <T> rl; 
 46090 |       ror            <T> rr; 
 46091 |       reverse        <T> rev; 
 46092 |       shift_left     <T> sl; 
 46093 |       shift_right    <T> sr; 
 46094 |       sort           <T> st; 
 46095 |       nthelement     <T> ne; 
 46096 |       assign         <T> an; 
 46097 |       iota           <T> ia; 
 46098 |       sumk           <T> sk; 
 46099 |       axpy           <T> b1_axpy; 
 46100 |       axpby          <T> b1_axpby; 
 46101 |       axpyz          <T> b1_axpyz; 
 46102 |       axpbyz         <T> b1_axpbyz; 
 46103 |       axpbsy         <T> b1_axpbsy; 
 46104 |       axpbsyz        <T> b1_axpbsyz; 
 46105 |       axpbz          <T> b1_axpbz; 
 46106 |       diff           <T> df; 
 46107 |       dot            <T> dt; 
 46108 |       dotk           <T> dtk; 
 46109 |       threshold_above<T> ta; 
 46110 |       threshold_below<T> tb; 
 46111 |  
 46112 |       bool register_package(exprtk::symbol_table<T>& symtab) 
 46113 |       { 
 46114 |          #define exprtk_register_function(FunctionName, FunctionType)                 \ 
 46115 |          if (!symtab.add_function(FunctionName,FunctionType))                         \ 
 46116 |          {                                                                            \ 
 46117 |             exprtk_debug((                                                            \ 
 46118 |               "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \ 
 46119 |               FunctionName));                                                         \ 
 46120 |             return false;                                                             \ 
 46121 |          }                                                                            \ 
 46122 |  
 46123 |          exprtk_register_function("all_true"        , at        ) 
 46124 |          exprtk_register_function("all_false"       , af        ) 
 46125 |          exprtk_register_function("any_true"        , nt        ) 
 46126 |          exprtk_register_function("any_false"       , nf        ) 
 46127 |          exprtk_register_function("count"           , c         ) 
 46128 |          exprtk_register_function("copy"            , cp        ) 
 46129 |          exprtk_register_function("rotate_left"     , rl        ) 
 46130 |          exprtk_register_function("rol"             , rl        ) 
 46131 |          exprtk_register_function("rotate_right"    , rr        ) 
 46132 |          exprtk_register_function("ror"             , rr        ) 
 46133 |          exprtk_register_function("reverse"         , rev       ) 
 46134 |          exprtk_register_function("shftl"           , sl        ) 
 46135 |          exprtk_register_function("shftr"           , sr        ) 
 46136 |          exprtk_register_function("sort"            , st        ) 
 46137 |          exprtk_register_function("nth_element"     , ne        ) 
 46138 |          exprtk_register_function("assign"          , an        ) 
 46139 |          exprtk_register_function("iota"            , ia        ) 
 46140 |          exprtk_register_function("sumk"            , sk        ) 
 46141 |          exprtk_register_function("axpy"            , b1_axpy   ) 
 46142 |          exprtk_register_function("axpby"           , b1_axpby  ) 
 46143 |          exprtk_register_function("axpyz"           , b1_axpyz  ) 
 46144 |          exprtk_register_function("axpbyz"          , b1_axpbyz ) 
 46145 |          exprtk_register_function("axpbsy"          , b1_axpbsy ) 
 46146 |          exprtk_register_function("axpbsyz"         , b1_axpbsyz) 
 46147 |          exprtk_register_function("axpbz"           , b1_axpbz  ) 
 46148 |          exprtk_register_function("diff"            , df        ) 
 46149 |          exprtk_register_function("dot"             , dt        ) 
 46150 |          exprtk_register_function("dotk"            , dtk       ) 
 46151 |          exprtk_register_function("threshold_above" , ta        ) 
 46152 |          exprtk_register_function("threshold_below" , tb        ) 
 46153 |          #undef exprtk_register_function 
 46154 |  
 46155 |          return true; 
 46156 |       } 
 46157 |    }; 
 46158 |  
 46159 |    } // namespace exprtk::rtl::vecops 
 46160 |    } // namespace exprtk::rtl 
 46161 | }    // namespace exprtk 
 46162 | #endif 
 46163 |  
 46164 | namespace exprtk 
 46165 | { 
 46166 |    namespace information 
 46167 |    { 
 46168 |       using ::exprtk::details::char_cptr; 
 46169 |  
 46170 |       static char_cptr library = "Mathematical Expression Toolkit" 
 46171 |       static char_cptr version = "2.718281828459045235360287471352662497757" 
 46172 |                                  "24709369995957496696762772407663035354759" 
 46173 |                                  "45713821785251664274274663919320030599218" 
 46174 |                                  "17413596629043572900334295260595630738132" 
 46175 |       static char_cptr date    = "20240101" 
 46176 |       static char_cptr min_cpp = "199711L" 
 46177 |  
 46178 |       static inline std::string data() 
 46179 |       { 
 46180 |          static const std::string info_str = std::string(library) + 
 46181 |                                              std::string(" v") + std::string(version) + 
 46182 |                                              std::string(" (") + date + std::string(")") + 
 46183 |                                              std::string(" (") + min_cpp + std::string(")"); 
 46184 |          return info_str; 
 46185 |       } 
 46186 |  
 46187 |    } // namespace information 
 46188 |  
 46189 |    #ifdef exprtk_debug 
 46190 |    #undef exprtk_debug 
 46191 |    #endif 
 46192 |  
 46193 |    #ifdef exprtk_error_location 
 46194 |    #undef exprtk_error_location 
 46195 |    #endif 
 46196 |  
 46197 |    #ifdef exprtk_fallthrough 
 46198 |    #undef exprtk_fallthrough 
 46199 |    #endif 
 46200 |  
 46201 |    #ifdef exprtk_override 
 46202 |    #undef exprtk_override 
 46203 |    #endif 
 46204 |  
 46205 |    #ifdef exprtk_final 
 46206 |    #undef exprtk_final 
 46207 |    #endif 
 46208 |  
 46209 |    #ifdef exprtk_delete 
 46210 |    #undef exprtk_delete 
 46211 |    #endif 
 46212 |  
 46213 | } // namespace exprtk 
 46214 |  
 46215 | #endif