You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

30167 lines
1.1 MiB

  1. /*
  2. ******************************************************************
  3. * C++ Mathematical Expression Toolkit Library *
  4. * *
  5. * Author: Arash Partow (1999-2015) *
  6. * URL: http://www.partow.net/programming/exprtk/index.html *
  7. * *
  8. * Copyright notice: *
  9. * Free use of the C++ Mathematical Expression Toolkit Library is *
  10. * permitted under the guidelines and in accordance with the most *
  11. * current version of the Common Public License. *
  12. * http://www.opensource.org/licenses/cpl1.0.php *
  13. * *
  14. * Example expressions: *
  15. * (00) (y + x / y) * (x - y / x) *
  16. * (01) (x^2 / sin(2 * pi / y)) - x / 2 *
  17. * (02) sqrt(1 - (x^2)) *
  18. * (03) 1 - sin(2 * x) + cos(pi / y) *
  19. * (04) a * exp(2 * t) + c *
  20. * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) *
  21. * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x *
  22. * (07) z := x + sin(2 * pi / y) *
  23. * (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) *
  24. * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1) *
  25. * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0) *
  26. * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
  27. * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
  28. * *
  29. ******************************************************************
  30. */
  31. #ifndef INCLUDE_EXPRTK_HPP
  32. #define INCLUDE_EXPRTK_HPP
  33. #include <algorithm>
  34. #include <cctype>
  35. #include <cmath>
  36. #include <cstdio>
  37. #include <cstdlib>
  38. #include <deque>
  39. #include <exception>
  40. #include <functional>
  41. #include <iterator>
  42. #include <limits>
  43. #include <list>
  44. #include <map>
  45. #include <set>
  46. #include <stack>
  47. #include <stdexcept>
  48. #include <string>
  49. #include <utility>
  50. #include <vector>
  51. namespace exprtk
  52. {
  53. #if exprtk_enable_debugging
  54. #define exprtk_debug(params) printf params
  55. #else
  56. #define exprtk_debug(params) (void)0
  57. #endif
  58. namespace details
  59. {
  60. inline bool is_whitespace(const char c)
  61. {
  62. return (' ' == c) || ('\n' == c) ||
  63. ('\r' == c) || ('\t' == c) ||
  64. ('\b' == c) || ('\v' == c) ||
  65. ('\f' == c) ;
  66. }
  67. inline bool is_operator_char(const char c)
  68. {
  69. return ('+' == c) || ('-' == c) ||
  70. ('*' == c) || ('/' == c) ||
  71. ('^' == c) || ('<' == c) ||
  72. ('>' == c) || ('=' == c) ||
  73. (',' == c) || ('!' == c) ||
  74. ('(' == c) || (')' == c) ||
  75. ('[' == c) || (']' == c) ||
  76. ('{' == c) || ('}' == c) ||
  77. ('%' == c) || (':' == c) ||
  78. ('?' == c) || ('&' == c) ||
  79. ('|' == c) || (';' == c) ;
  80. }
  81. inline bool is_letter(const char c)
  82. {
  83. return (('a' <= c) && (c <= 'z')) ||
  84. (('A' <= c) && (c <= 'Z')) ;
  85. }
  86. inline bool is_digit(const char c)
  87. {
  88. return ('0' <= c) && (c <= '9');
  89. }
  90. inline bool is_letter_or_digit(const char c)
  91. {
  92. return is_letter(c) || is_digit(c);
  93. }
  94. inline bool is_left_bracket(const char c)
  95. {
  96. return ('(' == c) || ('[' == c) || ('{' == c);
  97. }
  98. inline bool is_right_bracket(const char c)
  99. {
  100. return (')' == c) || (']' == c) || ('}' == c);
  101. }
  102. inline bool is_bracket(const char c)
  103. {
  104. return is_left_bracket(c) || is_right_bracket(c);
  105. }
  106. inline bool is_sign(const char c)
  107. {
  108. return ('+' == c) || ('-' == c);
  109. }
  110. inline bool is_invalid(const char c)
  111. {
  112. return !is_whitespace (c) &&
  113. !is_operator_char(c) &&
  114. !is_letter (c) &&
  115. !is_digit (c) &&
  116. ('.' != c) &&
  117. ('_' != c) &&
  118. ('$' != c) &&
  119. ('~' != c) &&
  120. ('\'' != c);
  121. }
  122. inline bool imatch(const char c1, const char c2)
  123. {
  124. return std::tolower(c1) == std::tolower(c2);
  125. }
  126. inline bool imatch(const std::string& s1, const std::string& s2)
  127. {
  128. if (s1.size() == s2.size())
  129. {
  130. for (std::size_t i = 0; i < s1.size(); ++i)
  131. {
  132. if (std::tolower(s1[i]) != std::tolower(s2[i]))
  133. {
  134. return false;
  135. }
  136. }
  137. return true;
  138. }
  139. return false;
  140. }
  141. inline bool is_valid_sf_symbol(const std::string& symbol)
  142. {
  143. // Special function: $f12 or $F34
  144. return (4 == symbol.size()) &&
  145. ('$' == symbol[0]) &&
  146. imatch('f',symbol[1]) &&
  147. is_digit(symbol[2]) &&
  148. is_digit(symbol[3]);
  149. }
  150. inline std::string to_str(int i)
  151. {
  152. if (0 == i)
  153. return std::string("0");
  154. std::string result;
  155. bool negative = (i < 0);
  156. if (negative) i *= -1;
  157. while (i)
  158. {
  159. char digit = '0' + char(i % 10);
  160. result = (digit + result);
  161. i /= 10;
  162. }
  163. if (negative)
  164. result = "-" + result;
  165. return result;
  166. }
  167. inline bool is_hex_digit(const std::string::value_type digit)
  168. {
  169. return (('0' <= digit) && (digit <= '9')) ||
  170. (('A' <= digit) && (digit <= 'F')) ||
  171. (('a' <= digit) && (digit <= 'f')) ;
  172. }
  173. inline unsigned char hex_to_bin(unsigned char h)
  174. {
  175. if (('0' <= h) && (h <= '9'))
  176. return (h - '0');
  177. else
  178. return (std::toupper(h) - 'A');
  179. }
  180. template <typename Iterator>
  181. inline void parse_hex(Iterator& itr, Iterator end, std::string::value_type& result)
  182. {
  183. if (
  184. (end != (itr )) &&
  185. (end != (itr + 1)) &&
  186. (end != (itr + 2)) &&
  187. (end != (itr + 3)) &&
  188. ('0' == *(itr )) &&
  189. (
  190. ('x' == *(itr + 1)) ||
  191. ('X' == *(itr + 1))
  192. ) &&
  193. (is_hex_digit(*(itr + 2))) &&
  194. (is_hex_digit(*(itr + 3)))
  195. )
  196. {
  197. result = hex_to_bin(*(itr + 2)) << 4 | hex_to_bin(*(itr + 3));
  198. itr += 3;
  199. }
  200. else
  201. result = '\0';
  202. }
  203. inline void cleanup_escapes(std::string& s)
  204. {
  205. std::string::iterator itr1 = s.begin();
  206. std::string::iterator itr2 = s.begin();
  207. std::string::iterator end = s.end ();
  208. std::size_t removal_count = 0;
  209. while (end != itr1)
  210. {
  211. if ('\\' == (*itr1))
  212. {
  213. ++removal_count;
  214. if (end == ++itr1)
  215. break;
  216. else if ('\\' != (*itr1))
  217. {
  218. switch (*itr1)
  219. {
  220. case 'n' : (*itr1) = '\n'; break;
  221. case 'r' : (*itr1) = '\r'; break;
  222. case 't' : (*itr1) = '\t'; break;
  223. case '0' : parse_hex(itr1,end,(*itr1));
  224. removal_count += 3;
  225. break;
  226. }
  227. continue;
  228. }
  229. }
  230. if (itr1 != itr2)
  231. {
  232. (*itr2) = (*itr1);
  233. }
  234. ++itr1;
  235. ++itr2;
  236. }
  237. s.resize(s.size() - removal_count);
  238. }
  239. class build_string
  240. {
  241. public:
  242. build_string(const std::size_t& initial_size = 64)
  243. {
  244. data_.reserve(initial_size);
  245. }
  246. inline build_string& operator << (const std::string& s)
  247. {
  248. data_ += s;
  249. return (*this);
  250. }
  251. inline build_string& operator << (const char* s)
  252. {
  253. data_ += std::string(s);
  254. return (*this);
  255. }
  256. inline operator std::string () const
  257. {
  258. return data_;
  259. }
  260. inline std::string as_string() const
  261. {
  262. return data_;
  263. }
  264. private:
  265. std::string data_;
  266. };
  267. struct ilesscompare
  268. {
  269. inline bool operator()(const std::string& s1, const std::string& s2) const
  270. {
  271. const std::size_t length = std::min(s1.size(),s2.size());
  272. for (std::size_t i = 0; i < length; ++i)
  273. {
  274. const char c1 = static_cast<char>(std::tolower(s1[i]));
  275. const char c2 = static_cast<char>(std::tolower(s2[i]));
  276. if (c1 > c2)
  277. return false;
  278. else if (c1 < c2)
  279. return true;
  280. }
  281. return s1.size() < s2.size();
  282. }
  283. };
  284. static const std::string reserved_words[] =
  285. {
  286. "break", "case", "continue", "default", "false", "for",
  287. "if", "else", "ilike", "in", "like", "and", "nand", "nor",
  288. "not", "null", "or", "repeat", "shl", "shr", "swap",
  289. "switch", "true", "until", "var", "while", "xnor", "xor",
  290. "&", "|"
  291. };
  292. static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
  293. static const std::string reserved_symbols[] =
  294. {
  295. "abs", "acos", "acosh", "and", "asin", "asinh", "atan",
  296. "atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
  297. "continue", "cos", "cosh", "cot", "csc", "default",
  298. "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp",
  299. "expm1", "false", "floor", "for", "frac", "grad2deg",
  300. "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
  301. "like", "log", "log10", "log2", "logn", "log1p", "mand",
  302. "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
  303. "not", "not_equal", "null", "or", "pow", "rad2deg",
  304. "repeat", "root", "round", "roundn", "sec", "sgn", "shl",
  305. "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
  306. "switch", "tan", "tanh", "true", "trunc", "until", "var",
  307. "while", "xnor", "xor", "&", "|"
  308. };
  309. static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
  310. inline bool is_reserved_word(const std::string& symbol)
  311. {
  312. for (std::size_t i = 0; i < reserved_words_size; ++i)
  313. {
  314. if (imatch(symbol,reserved_words[i]))
  315. {
  316. return true;
  317. }
  318. }
  319. return false;
  320. }
  321. inline bool is_reserved_symbol(const std::string& symbol)
  322. {
  323. for (std::size_t i = 0; i < reserved_symbols_size; ++i)
  324. {
  325. if (imatch(symbol,reserved_symbols[i]))
  326. {
  327. return true;
  328. }
  329. }
  330. return false;
  331. }
  332. struct cs_match
  333. {
  334. static inline bool cmp(const char c0, const char c1)
  335. {
  336. return (c0 == c1);
  337. }
  338. };
  339. struct cis_match
  340. {
  341. static inline bool cmp(const char c0, const char c1)
  342. {
  343. return (std::tolower(c0) == std::tolower(c1));
  344. }
  345. };
  346. template <typename Iterator, typename Compare>
  347. inline bool match_impl(const Iterator pattern_begin,
  348. const Iterator pattern_end,
  349. const Iterator data_begin,
  350. const Iterator data_end,
  351. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  352. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  353. {
  354. if (0 == std::distance(data_begin,data_end))
  355. {
  356. return false;
  357. }
  358. Iterator d_itr = data_begin;
  359. Iterator p_itr = pattern_begin;
  360. Iterator c_itr = data_begin;
  361. Iterator m_itr = data_begin;
  362. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  363. {
  364. if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr)))
  365. {
  366. return false;
  367. }
  368. ++p_itr;
  369. ++d_itr;
  370. }
  371. while (data_end != d_itr)
  372. {
  373. if (zero_or_more == (*p_itr))
  374. {
  375. if (pattern_end == (++p_itr))
  376. {
  377. return true;
  378. }
  379. m_itr = p_itr;
  380. c_itr = d_itr;
  381. ++c_itr;
  382. }
  383. else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr)))
  384. {
  385. ++p_itr;
  386. ++d_itr;
  387. }
  388. else
  389. {
  390. p_itr = m_itr;
  391. d_itr = c_itr++;
  392. }
  393. }
  394. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) { ++p_itr; }
  395. return (p_itr == pattern_end);
  396. }
  397. inline bool wc_match(const std::string& wild_card,
  398. const std::string& str)
  399. {
  400. return match_impl<const char*,cs_match>(wild_card.data(),
  401. wild_card.data() + wild_card.size(),
  402. str.data(),
  403. str.data() + str.size(),
  404. '*',
  405. '?');
  406. }
  407. inline bool wc_imatch(const std::string& wild_card,
  408. const std::string& str)
  409. {
  410. return match_impl<const char*,cis_match>(wild_card.data(),
  411. wild_card.data() + wild_card.size(),
  412. str.data(),
  413. str.data() + str.size(),
  414. '*',
  415. '?');
  416. }
  417. inline bool sequence_match(const std::string& pattern,
  418. const std::string& str,
  419. std::size_t& diff_index,
  420. char& diff_value)
  421. {
  422. if (str.empty() || pattern.empty())
  423. return false;
  424. else if ('*' == pattern[0])
  425. return false;
  426. typedef std::string::const_iterator itr_t;
  427. itr_t p_itr = pattern.begin();
  428. itr_t s_itr = str .begin();
  429. itr_t p_end = pattern.end();
  430. itr_t s_end = str .end();
  431. while ((s_end != s_itr) && (p_end != p_itr))
  432. {
  433. if ('*' == (*p_itr))
  434. {
  435. const char target = std::toupper(*(p_itr - 1));
  436. if ('*' == target)
  437. {
  438. diff_index = std::distance(str.begin(),s_itr);
  439. diff_value = std::toupper(*p_itr);
  440. return false;
  441. }
  442. else
  443. ++p_itr;
  444. while (s_itr != s_end)
  445. {
  446. if (target != std::toupper(*s_itr))
  447. break;
  448. else
  449. ++s_itr;
  450. }
  451. continue;
  452. }
  453. else if (
  454. ('?' != *p_itr) &&
  455. std::toupper(*p_itr) != std::toupper(*s_itr)
  456. )
  457. {
  458. diff_index = std::distance(str.begin(),s_itr);
  459. diff_value = std::toupper(*p_itr);
  460. return false;
  461. }
  462. ++p_itr;
  463. ++s_itr;
  464. }
  465. return (
  466. (s_end == s_itr) &&
  467. (
  468. (p_end == p_itr) ||
  469. ('*' == *p_itr)
  470. )
  471. );
  472. }
  473. static const double pow10[] = {
  474. 1.0,
  475. 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
  476. 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
  477. 1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
  478. 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
  479. };
  480. static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
  481. namespace numeric
  482. {
  483. namespace constant
  484. {
  485. static const double e = 2.718281828459045235360;
  486. static const double pi = 3.141592653589793238462;
  487. static const double pi_2 = 1.570796326794896619231;
  488. static const double pi_4 = 0.785398163397448309616;
  489. static const double pi_180 = 0.017453292519943295769;
  490. static const double _1_pi = 0.318309886183790671538;
  491. static const double _2_pi = 0.636619772367581343076;
  492. static const double _180_pi = 57.295779513082320876798;
  493. static const double log2 = 0.693147180559945309417;
  494. static const double sqrt2 = 1.414213562373095048801;
  495. }
  496. namespace details
  497. {
  498. struct unknown_type_tag {};
  499. struct real_type_tag {};
  500. struct int_type_tag {};
  501. template <typename T>
  502. struct number_type { typedef unknown_type_tag type; };
  503. #define exprtk_register_real_type_tag(T) \
  504. template<> struct number_type<T> { typedef real_type_tag type; }; \
  505. #define exprtk_register_int_type_tag(T) \
  506. template<> struct number_type<T> { typedef int_type_tag type; }; \
  507. exprtk_register_real_type_tag(double )
  508. exprtk_register_real_type_tag(long double)
  509. exprtk_register_real_type_tag(float )
  510. exprtk_register_int_type_tag(short )
  511. exprtk_register_int_type_tag(int )
  512. exprtk_register_int_type_tag(long long int )
  513. exprtk_register_int_type_tag(unsigned short )
  514. exprtk_register_int_type_tag(unsigned int )
  515. exprtk_register_int_type_tag(unsigned long long int)
  516. #undef exprtk_register_real_type_tag
  517. #undef exprtk_register_int_type_tag
  518. template <typename T>
  519. struct epsilon_type
  520. {
  521. static inline T value()
  522. {
  523. const T epsilon = T(0.0000000001);
  524. return epsilon;
  525. }
  526. };
  527. template <>
  528. struct epsilon_type <float>
  529. {
  530. static inline float value()
  531. {
  532. const float epsilon = float(0.000001f);
  533. return epsilon;
  534. }
  535. };
  536. template <>
  537. struct epsilon_type <long double>
  538. {
  539. static inline long double value()
  540. {
  541. const long double epsilon = (long double)(0.000000000001);
  542. return epsilon;
  543. }
  544. };
  545. template <typename T>
  546. inline bool is_nan_impl(const T v, real_type_tag)
  547. {
  548. return std::not_equal_to<T>()(v,v);
  549. }
  550. template <typename T>
  551. inline int to_int32_impl(const T v, real_type_tag)
  552. {
  553. return static_cast<int>(v);
  554. }
  555. template <typename T>
  556. inline long long int to_int64_impl(const T v, real_type_tag)
  557. {
  558. return static_cast<long long int>(v);
  559. }
  560. template <typename T>
  561. inline bool is_true_impl(const T v)
  562. {
  563. return std::not_equal_to<T>()(T(0),v);
  564. }
  565. template <typename T>
  566. inline bool is_false_impl(const T v)
  567. {
  568. return std::equal_to<T>()(T(0),v);
  569. }
  570. template <typename T>
  571. inline T abs_impl(const T v, real_type_tag)
  572. {
  573. return ((v >= T(0)) ? v : -v);
  574. }
  575. template <typename T>
  576. inline T min_impl(const T v0, const T v1, real_type_tag)
  577. {
  578. return std::min<T>(v0,v1);
  579. }
  580. template <typename T>
  581. inline T max_impl(const T v0, const T v1, real_type_tag)
  582. {
  583. return std::max<T>(v0,v1);
  584. }
  585. template <typename T>
  586. inline T equal_impl(const T v0, const T v1, real_type_tag)
  587. {
  588. const T epsilon = epsilon_type<T>::value();
  589. 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);
  590. }
  591. inline float equal_impl(const float v0, const float v1, real_type_tag)
  592. {
  593. const float epsilon = epsilon_type<float>::value();
  594. 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;
  595. }
  596. template <typename T>
  597. inline T equal_impl(const T v0, const T v1, int_type_tag)
  598. {
  599. return (v0 == v1) ? 1 : 0;
  600. }
  601. template <typename T>
  602. inline T expm1_impl(const T v, real_type_tag)
  603. {
  604. // return std::expm1<T>(v);
  605. if (abs_impl(v,real_type_tag()) < T(0.00001))
  606. return v + (T(0.5) * v * v);
  607. else
  608. return std::exp(v) - T(1);
  609. }
  610. template <typename T>
  611. inline T expm1_impl(const T v, int_type_tag)
  612. {
  613. return T(std::exp<double>(v)) - T(1);
  614. }
  615. template <typename T>
  616. inline T nequal_impl(const T v0, const T v1, real_type_tag)
  617. {
  618. const T epsilon = epsilon_type<T>::value();
  619. 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);
  620. }
  621. inline float nequal_impl(const float v0, const float v1, real_type_tag)
  622. {
  623. const float epsilon = epsilon_type<float>::value();
  624. 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;
  625. }
  626. template <typename T>
  627. inline T nequal_impl(const T v0, const T v1, int_type_tag)
  628. {
  629. return (v0 != v1) ? 1 : 0;
  630. }
  631. template <typename T>
  632. inline T modulus_impl(const T v0, const T v1, real_type_tag)
  633. {
  634. return std::fmod(v0,v1);
  635. }
  636. template <typename T>
  637. inline T modulus_impl(const T v0, const T v1, int_type_tag)
  638. {
  639. return v0 % v1;
  640. }
  641. template <typename T>
  642. inline T pow_impl(const T v0, const T v1, real_type_tag)
  643. {
  644. return std::pow(v0,v1);
  645. }
  646. template <typename T>
  647. inline T pow_impl(const T v0, const T v1, int_type_tag)
  648. {
  649. return std::pow(static_cast<double>(v0),static_cast<double>(v1));
  650. }
  651. template <typename T>
  652. inline T logn_impl(const T v0, const T v1, real_type_tag)
  653. {
  654. return std::log(v0) / std::log(v1);
  655. }
  656. template <typename T>
  657. inline T logn_impl(const T v0, const T v1, int_type_tag)
  658. {
  659. return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
  660. }
  661. template <typename T>
  662. inline T log1p_impl(const T v, real_type_tag)
  663. {
  664. if (v > T(-1))
  665. {
  666. if (abs_impl(v,real_type_tag()) > T(0.0001))
  667. {
  668. return std::log(T(1) + v);
  669. }
  670. else
  671. return (T(-0.5) * v + T(1)) * v;
  672. }
  673. else
  674. return std::numeric_limits<T>::quiet_NaN();
  675. }
  676. template <typename T>
  677. inline T log1p_impl(const T v, int_type_tag)
  678. {
  679. if (v > T(-1))
  680. {
  681. return std::log(T(1) + v);
  682. }
  683. else
  684. return std::numeric_limits<T>::quiet_NaN();
  685. }
  686. template <typename T>
  687. inline T root_impl(const T v0, const T v1, real_type_tag)
  688. {
  689. return std::pow(v0,T(1) / v1);
  690. }
  691. template <typename T>
  692. inline T root_impl(const T v0, const T v1, int_type_tag)
  693. {
  694. return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
  695. }
  696. template <typename T>
  697. inline T round_impl(const T v, real_type_tag)
  698. {
  699. return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
  700. }
  701. template <typename T>
  702. inline T roundn_impl(const T v0, const T v1, real_type_tag)
  703. {
  704. const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1)));
  705. const T p10 = T(pow10[index]);
  706. if (v0 < T(0))
  707. return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
  708. else
  709. return T(std::floor((v0 * p10) + T(0.5)) / p10);
  710. }
  711. template <typename T>
  712. inline T roundn_impl(const T v0, const T, int_type_tag)
  713. {
  714. return v0;
  715. }
  716. template <typename T>
  717. inline T hypot_impl(const T v0, const T v1, real_type_tag)
  718. {
  719. return std::sqrt((v0 * v0) + (v1 * v1));
  720. }
  721. template <typename T>
  722. inline T hypot_impl(const T v0, const T v1, int_type_tag)
  723. {
  724. return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
  725. }
  726. template <typename T>
  727. inline T atan2_impl(const T v0, const T v1, real_type_tag)
  728. {
  729. return std::atan2(v0,v1);
  730. }
  731. template <typename T>
  732. inline T atan2_impl(const T, const T, int_type_tag)
  733. {
  734. return 0;
  735. }
  736. template <typename T>
  737. inline T shr_impl(const T v0, const T v1, real_type_tag)
  738. {
  739. return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
  740. }
  741. template <typename T>
  742. inline T shr_impl(const T v0, const T v1, int_type_tag)
  743. {
  744. return v0 >> v1;
  745. }
  746. template <typename T>
  747. inline T shl_impl(const T v0, const T v1, real_type_tag)
  748. {
  749. return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
  750. }
  751. template <typename T>
  752. inline T shl_impl(const T v0, const T v1, int_type_tag)
  753. {
  754. return v0 << v1;
  755. }
  756. template <typename T>
  757. inline T sgn_impl(const T v, real_type_tag)
  758. {
  759. if (v > T(0)) return T(+1);
  760. else if (v < T(0)) return T(-1);
  761. else return T( 0);
  762. }
  763. template <typename T>
  764. inline T sgn_impl(const T v, int_type_tag)
  765. {
  766. if (v > T(0)) return T(+1);
  767. else if (v < T(0)) return T(-1);
  768. else return T( 0);
  769. }
  770. template <typename T>
  771. inline T and_impl(const T v0, const T v1, real_type_tag)
  772. {
  773. return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
  774. }
  775. template <typename T>
  776. inline T and_impl(const T v0, const T v1, int_type_tag)
  777. {
  778. return v0 && v1;
  779. }
  780. template <typename T>
  781. inline T nand_impl(const T v0, const T v1, real_type_tag)
  782. {
  783. return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
  784. }
  785. template <typename T>
  786. inline T nand_impl(const T v0, const T v1, int_type_tag)
  787. {
  788. return !(v0 && v1);
  789. }
  790. template <typename T>
  791. inline T or_impl(const T v0, const T v1, real_type_tag)
  792. {
  793. return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
  794. }
  795. template <typename T>
  796. inline T or_impl(const T v0, const T v1, int_type_tag)
  797. {
  798. return (v0 || v1);
  799. }
  800. template <typename T>
  801. inline T nor_impl(const T v0, const T v1, real_type_tag)
  802. {
  803. return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
  804. }
  805. template <typename T>
  806. inline T nor_impl(const T v0, const T v1, int_type_tag)
  807. {
  808. return !(v0 || v1);
  809. }
  810. template <typename T>
  811. inline T xor_impl(const T v0, const T v1, real_type_tag)
  812. {
  813. return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
  814. }
  815. template <typename T>
  816. inline T xor_impl(const T v0, const T v1, int_type_tag)
  817. {
  818. return v0 ^ v1;
  819. }
  820. template <typename T>
  821. inline T xnor_impl(const T v0, const T v1, real_type_tag)
  822. {
  823. const bool v0_true = is_true_impl(v0);
  824. const bool v1_true = is_true_impl(v1);
  825. if ((v0_true && v1_true) || (!v0_true && !v1_true))
  826. return T(1);
  827. else
  828. return T(0);
  829. }
  830. template <typename T>
  831. inline T xnor_impl(const T v0, const T v1, int_type_tag)
  832. {
  833. const bool v0_true = is_true_impl(v0);
  834. const bool v1_true = is_true_impl(v1);
  835. if ((v0_true && v1_true) || (!v0_true && !v1_true))
  836. return T(1);
  837. else
  838. return T(0);
  839. }
  840. template <typename T>
  841. inline T erf_impl(T v, real_type_tag)
  842. {
  843. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  844. // Credits: Abramowitz & Stegun Equations 7.1.25-28
  845. const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
  846. static const T c[] = {
  847. T( 1.26551223), T(1.00002368),
  848. T( 0.37409196), T(0.09678418),
  849. T(-0.18628806), T(0.27886807),
  850. T(-1.13520398), T(1.48851587),
  851. T(-0.82215223), T(0.17087277)
  852. };
  853. T result = T(1) - t * std::exp((-v * v) -
  854. c[0] + t * (c[1] + t *
  855. (c[2] + t * (c[3] + t *
  856. (c[4] + t * (c[5] + t *
  857. (c[6] + t * (c[7] + t *
  858. (c[8] + t * (c[9]))))))))));
  859. return (v >= T(0)) ? result : -result;
  860. #else
  861. return ::erf(v);
  862. #endif
  863. }
  864. template <typename T>
  865. inline T erf_impl(T v, int_type_tag)
  866. {
  867. return erf_impl(static_cast<double>(v),real_type_tag());
  868. }
  869. template <typename T>
  870. inline T erfc_impl(T v, real_type_tag)
  871. {
  872. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  873. return T(1) - erf_impl(v,real_type_tag());
  874. #else
  875. return ::erfc(v);
  876. #endif
  877. }
  878. template <typename T>
  879. inline T erfc_impl(T v, int_type_tag)
  880. {
  881. return erfc_impl(static_cast<double>(v),real_type_tag());
  882. }
  883. template <typename T>
  884. inline T ncdf_impl(T v, real_type_tag)
  885. {
  886. T cnd = T(0.5) * (T(1) + erf_impl(
  887. abs_impl(v,real_type_tag()) /
  888. T(numeric::constant::sqrt2),real_type_tag()));
  889. return (v < T(0)) ? (T(1) - cnd) : cnd;
  890. }
  891. template <typename T>
  892. inline T ncdf_impl(T v, int_type_tag)
  893. {
  894. return ncdf_impl(static_cast<double>(v),real_type_tag());
  895. }
  896. template <typename T>
  897. inline T sinc_impl(T v, real_type_tag)
  898. {
  899. if (std::abs(v) >= std::numeric_limits<T>::epsilon())
  900. return(std::sin(v) / v);
  901. else
  902. return T(1);
  903. }
  904. template <typename T>
  905. inline T sinc_impl(T v, int_type_tag)
  906. {
  907. return sinc_impl(static_cast<double>(v),real_type_tag());
  908. }
  909. template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
  910. template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
  911. template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
  912. template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
  913. template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
  914. template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - log(T(1) - v)) / T(2); }
  915. template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
  916. template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
  917. template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
  918. template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
  919. template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
  920. template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
  921. template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
  922. template <typename T> inline T log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
  923. template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
  924. template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
  925. template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
  926. template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
  927. template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
  928. template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
  929. template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
  930. template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
  931. template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
  932. template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
  933. template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
  934. template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
  935. template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); }
  936. template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); }
  937. 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)); }
  938. template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
  939. template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
  940. template <typename T> inline T abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
  941. template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
  942. template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
  943. template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
  944. template <typename T> inline T log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
  945. template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
  946. template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
  947. template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
  948. template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
  949. template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
  950. template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
  951. template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
  952. template <typename T> inline T frac_impl(const T , int_type_tag) { return T(0); }
  953. template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
  954. template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  955. template <typename T> inline T acosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  956. template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  957. template <typename T> inline T asinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  958. template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  959. template <typename T> inline T atanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  960. template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  961. template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  962. template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  963. template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  964. template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  965. template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  966. template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  967. template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  968. template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  969. template <typename T>
  970. inline bool is_integer_impl(const T& v, real_type_tag)
  971. {
  972. return std::equal_to<T>()(T(0),std::fmod(v,T(1)));
  973. }
  974. template <typename T>
  975. inline bool is_integer_impl(const T&, int_type_tag)
  976. {
  977. return true;
  978. }
  979. }
  980. template <typename Type>
  981. struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
  982. template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
  983. template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
  984. template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
  985. template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
  986. template <typename T>
  987. inline int to_int32(const T v)
  988. {
  989. typename details::number_type<T>::type num_type;
  990. return to_int32_impl(v,num_type);
  991. }
  992. template <typename T>
  993. inline long long int to_int64(const T v)
  994. {
  995. typename details::number_type<T>::type num_type;
  996. return to_int64_impl(v,num_type);
  997. }
  998. template <typename T>
  999. inline bool is_nan(const T v)
  1000. {
  1001. typename details::number_type<T>::type num_type;
  1002. return is_nan_impl(v,num_type);
  1003. }
  1004. template <typename T>
  1005. inline T min(const T v0, const T v1)
  1006. {
  1007. typename details::number_type<T>::type num_type;
  1008. return min_impl(v0,v1,num_type);
  1009. }
  1010. template <typename T>
  1011. inline T max(const T v0, const T v1)
  1012. {
  1013. typename details::number_type<T>::type num_type;
  1014. return max_impl(v0,v1,num_type);
  1015. }
  1016. template <typename T>
  1017. inline T equal(const T v0, const T v1)
  1018. {
  1019. typename details::number_type<T>::type num_type;
  1020. return equal_impl(v0,v1,num_type);
  1021. }
  1022. template <typename T>
  1023. inline T nequal(const T v0, const T v1)
  1024. {
  1025. typename details::number_type<T>::type num_type;
  1026. return nequal_impl(v0,v1,num_type);
  1027. }
  1028. template <typename T>
  1029. inline T modulus(const T v0, const T v1)
  1030. {
  1031. typename details::number_type<T>::type num_type;
  1032. return modulus_impl(v0,v1,num_type);
  1033. }
  1034. template <typename T>
  1035. inline T pow(const T v0, const T v1)
  1036. {
  1037. typename details::number_type<T>::type num_type;
  1038. return pow_impl(v0,v1,num_type);
  1039. }
  1040. template <typename T>
  1041. inline T logn(const T v0, const T v1)
  1042. {
  1043. typename details::number_type<T>::type num_type;
  1044. return logn_impl(v0,v1,num_type);
  1045. }
  1046. template <typename T>
  1047. inline T root(const T v0, const T v1)
  1048. {
  1049. typename details::number_type<T>::type num_type;
  1050. return root_impl(v0,v1,num_type);
  1051. }
  1052. template <typename T>
  1053. inline T roundn(const T v0, const T v1)
  1054. {
  1055. typename details::number_type<T>::type num_type;
  1056. return roundn_impl(v0,v1,num_type);
  1057. }
  1058. template <typename T>
  1059. inline T hypot(const T v0, const T v1)
  1060. {
  1061. typename details::number_type<T>::type num_type;
  1062. return hypot_impl(v0,v1,num_type);
  1063. }
  1064. template <typename T>
  1065. inline T atan2(const T v0, const T v1)
  1066. {
  1067. typename details::number_type<T>::type num_type;
  1068. return atan2_impl(v0,v1,num_type);
  1069. }
  1070. template <typename T>
  1071. inline T shr(const T v0, const T v1)
  1072. {
  1073. typename details::number_type<T>::type num_type;
  1074. return shr_impl(v0,v1,num_type);
  1075. }
  1076. template <typename T>
  1077. inline T shl(const T v0, const T v1)
  1078. {
  1079. typename details::number_type<T>::type num_type;
  1080. return shl_impl(v0,v1,num_type);
  1081. }
  1082. template <typename T>
  1083. inline T and_opr(const T v0, const T v1)
  1084. {
  1085. typename details::number_type<T>::type num_type;
  1086. return and_impl(v0,v1,num_type);
  1087. }
  1088. template <typename T>
  1089. inline T nand_opr(const T v0, const T v1)
  1090. {
  1091. typename details::number_type<T>::type num_type;
  1092. return nand_impl(v0,v1,num_type);
  1093. }
  1094. template <typename T>
  1095. inline T or_opr(const T v0, const T v1)
  1096. {
  1097. typename details::number_type<T>::type num_type;
  1098. return or_impl(v0,v1,num_type);
  1099. }
  1100. template <typename T>
  1101. inline T nor_opr(const T v0, const T v1)
  1102. {
  1103. typename details::number_type<T>::type num_type;
  1104. return nor_impl(v0,v1,num_type);
  1105. }
  1106. template <typename T>
  1107. inline T xor_opr(const T v0, const T v1)
  1108. {
  1109. typename details::number_type<T>::type num_type;
  1110. return xor_impl(v0,v1,num_type);
  1111. }
  1112. template <typename T>
  1113. inline T xnor_opr(const T v0, const T v1)
  1114. {
  1115. typename details::number_type<T>::type num_type;
  1116. return xnor_impl(v0,v1,num_type);
  1117. }
  1118. template <typename T>
  1119. inline bool is_integer(const T v)
  1120. {
  1121. typename details::number_type<T>::type num_type;
  1122. return is_integer_impl(v,num_type);
  1123. }
  1124. template <typename T, unsigned int N>
  1125. struct fast_exp
  1126. {
  1127. static inline T result(T v)
  1128. {
  1129. unsigned int k = N;
  1130. T l = T(1);
  1131. while (k)
  1132. {
  1133. if (k & 1)
  1134. {
  1135. l *= v;
  1136. --k;
  1137. }
  1138. v *= v;
  1139. k >>= 1;
  1140. }
  1141. return l;
  1142. }
  1143. };
  1144. template <typename T> struct fast_exp<T,10> { static inline T result(T v) { T v_5 = fast_exp<T,5>::result(v); return v_5 * v_5; } };
  1145. template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
  1146. template <typename T> struct fast_exp<T, 8> { static inline T result(T v) { T v_4 = fast_exp<T,4>::result(v); return v_4 * v_4; } };
  1147. template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
  1148. template <typename T> struct fast_exp<T, 6> { static inline T result(T v) { T v_3 = fast_exp<T,3>::result(v); return v_3 * v_3; } };
  1149. template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
  1150. template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
  1151. template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
  1152. template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v; } };
  1153. template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } };
  1154. template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } };
  1155. #define exprtk_define_unary_function(FunctionName) \
  1156. template <typename T> \
  1157. inline T FunctionName (const T v) \
  1158. { \
  1159. typename details::number_type<T>::type num_type; \
  1160. return FunctionName##_impl(v,num_type); \
  1161. } \
  1162. exprtk_define_unary_function(abs )
  1163. exprtk_define_unary_function(acos )
  1164. exprtk_define_unary_function(acosh)
  1165. exprtk_define_unary_function(asin )
  1166. exprtk_define_unary_function(asinh)
  1167. exprtk_define_unary_function(atan )
  1168. exprtk_define_unary_function(atanh)
  1169. exprtk_define_unary_function(ceil )
  1170. exprtk_define_unary_function(cos )
  1171. exprtk_define_unary_function(cosh )
  1172. exprtk_define_unary_function(exp )
  1173. exprtk_define_unary_function(expm1)
  1174. exprtk_define_unary_function(floor)
  1175. exprtk_define_unary_function(log )
  1176. exprtk_define_unary_function(log10)
  1177. exprtk_define_unary_function(log2 )
  1178. exprtk_define_unary_function(log1p)
  1179. exprtk_define_unary_function(neg )
  1180. exprtk_define_unary_function(pos )
  1181. exprtk_define_unary_function(round)
  1182. exprtk_define_unary_function(sin )
  1183. exprtk_define_unary_function(sinc )
  1184. exprtk_define_unary_function(sinh )
  1185. exprtk_define_unary_function(sqrt )
  1186. exprtk_define_unary_function(tan )
  1187. exprtk_define_unary_function(tanh )
  1188. exprtk_define_unary_function(cot )
  1189. exprtk_define_unary_function(sec )
  1190. exprtk_define_unary_function(csc )
  1191. exprtk_define_unary_function(r2d )
  1192. exprtk_define_unary_function(d2r )
  1193. exprtk_define_unary_function(d2g )
  1194. exprtk_define_unary_function(g2d )
  1195. exprtk_define_unary_function(notl )
  1196. exprtk_define_unary_function(sgn )
  1197. exprtk_define_unary_function(erf )
  1198. exprtk_define_unary_function(erfc )
  1199. exprtk_define_unary_function(ncdf )
  1200. exprtk_define_unary_function(frac )
  1201. exprtk_define_unary_function(trunc)
  1202. #undef exprtk_define_unary_function
  1203. }
  1204. template <typename T>
  1205. inline T compute_pow10(T d, const int exponent)
  1206. {
  1207. static const double fract10[] =
  1208. {
  1209. 0.0,
  1210. 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,
  1211. 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,
  1212. 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,
  1213. 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,
  1214. 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,
  1215. 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,
  1216. 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,
  1217. 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,
  1218. 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,
  1219. 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,
  1220. 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,
  1221. 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,
  1222. 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,
  1223. 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,
  1224. 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,
  1225. 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,
  1226. 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,
  1227. 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,
  1228. 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,
  1229. 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,
  1230. 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,
  1231. 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,
  1232. 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,
  1233. 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,
  1234. 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,
  1235. 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,
  1236. 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,
  1237. 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,
  1238. 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,
  1239. 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,
  1240. 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
  1241. };
  1242. static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
  1243. const int e = std::abs(exponent);
  1244. if (exponent >= std::numeric_limits<T>::min_exponent10)
  1245. {
  1246. if (e < fract10_size)
  1247. {
  1248. if (exponent > 0)
  1249. return T(d * fract10[e]);
  1250. else
  1251. return T(d / fract10[e]);
  1252. }
  1253. else
  1254. return T(d * std::pow(10.0, 10.0 * exponent));
  1255. }
  1256. else
  1257. {
  1258. d /= T(fract10[ -std::numeric_limits<T>::min_exponent10]);
  1259. return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
  1260. }
  1261. }
  1262. template <typename Iterator, typename T>
  1263. inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result)
  1264. {
  1265. if (itr == end)
  1266. return false;
  1267. bool negative = ('-' == (*itr));
  1268. if (negative || ('+' == (*itr)))
  1269. {
  1270. if (end == ++itr)
  1271. return false;
  1272. }
  1273. while ((end != itr) && ('0' == (*itr))) ++itr;
  1274. bool return_result = true;
  1275. unsigned int digit = 0;
  1276. const std::size_t length = std::distance(itr,end);
  1277. if (length <= 4)
  1278. {
  1279. switch (length)
  1280. {
  1281. #ifdef exprtk_use_lut
  1282. #define exprtk_process_digit \
  1283. if ((digit = details::digit_table[(int)*itr++]) < 10) result = result * 10 + (digit); else { return_result = false; break; }
  1284. #else
  1285. #define exprtk_process_digit \
  1286. if ((digit = (*itr++ - '0')) < 10) result = result * 10 + (digit); else { return_result = false; break; }
  1287. #endif
  1288. case 4 : exprtk_process_digit
  1289. case 3 : exprtk_process_digit
  1290. case 2 : exprtk_process_digit
  1291. case 1 : if ((digit = (*itr - '0'))>= 10) { digit = 0; return_result = false; }
  1292. #undef exprtk_process_digit
  1293. }
  1294. }
  1295. else
  1296. return_result = false;
  1297. if (length && return_result)
  1298. {
  1299. result = result * 10 + static_cast<T>(digit);
  1300. ++itr;
  1301. }
  1302. result = negative ? -result : result;
  1303. return return_result;
  1304. }
  1305. template <typename Iterator, typename T>
  1306. static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
  1307. {
  1308. typedef typename std::iterator_traits<Iterator>::value_type type;
  1309. static const std::size_t nan_length = 3;
  1310. if (std::distance(itr,end) != static_cast<int>(nan_length))
  1311. return false;
  1312. if (static_cast<type>('n') == (*itr))
  1313. {
  1314. if (
  1315. (static_cast<type>('a') != *(itr + 1)) ||
  1316. (static_cast<type>('n') != *(itr + 2))
  1317. )
  1318. {
  1319. return false;
  1320. }
  1321. }
  1322. else if (
  1323. (static_cast<type>('A') != *(itr + 1)) ||
  1324. (static_cast<type>('N') != *(itr + 2))
  1325. )
  1326. {
  1327. return false;
  1328. }
  1329. t = std::numeric_limits<T>::quiet_NaN();
  1330. return true;
  1331. }
  1332. template <typename Iterator, typename T>
  1333. static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
  1334. {
  1335. static const char inf_uc[] = "INFINITY";
  1336. static const char inf_lc[] = "infinity";
  1337. static const std::size_t inf_length = 8;
  1338. const std::size_t length = std::distance(itr,end);
  1339. if ((3 != length) && (inf_length != length))
  1340. return false;
  1341. const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
  1342. while (end != itr)
  1343. {
  1344. if (*inf_itr == static_cast<char>(*itr))
  1345. {
  1346. ++itr;
  1347. ++inf_itr;
  1348. continue;
  1349. }
  1350. else
  1351. return false;
  1352. }
  1353. if (negative)
  1354. t = -std::numeric_limits<T>::infinity();
  1355. else
  1356. t = std::numeric_limits<T>::infinity();
  1357. return true;
  1358. }
  1359. template <typename Iterator, typename T>
  1360. inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t, numeric::details::real_type_tag)
  1361. {
  1362. if (end == itr_external) return false;
  1363. Iterator itr = itr_external;
  1364. T d = T(0);
  1365. bool negative = ('-' == (*itr));
  1366. if (negative || '+' == (*itr))
  1367. {
  1368. if (end == ++itr)
  1369. return false;
  1370. }
  1371. bool instate = false;
  1372. #define parse_digit_1(d) \
  1373. if ((digit = (*itr - '0')) < 10) { d = d * T(10) + digit; } else break; if (end == ++itr) break; \
  1374. #define parse_digit_2(d) \
  1375. if ((digit = (*itr - '0')) < 10) { d = d * T(10) + digit; } else break; ++itr; \
  1376. if ('.' != (*itr))
  1377. {
  1378. const Iterator curr = itr;
  1379. while ((end != itr) && ('0' == (*itr))) ++itr;
  1380. unsigned int digit;
  1381. while (end != itr)
  1382. {
  1383. // Note: For 'physical' superscalar architectures it
  1384. // is advised that the following loop be: 4xPD1 and 1xPD2
  1385. #ifdef exprtk_enable_superscalar
  1386. parse_digit_1(d)
  1387. parse_digit_1(d)
  1388. #endif
  1389. parse_digit_1(d)
  1390. parse_digit_1(d)
  1391. parse_digit_2(d)
  1392. }
  1393. if (curr != itr) instate = true;
  1394. }
  1395. int exponent = 0;
  1396. if (end != itr)
  1397. {
  1398. if ('.' == (*itr))
  1399. {
  1400. const Iterator curr = ++itr;
  1401. unsigned int digit;
  1402. T tmp_d = T(0);
  1403. while (end != itr)
  1404. {
  1405. #ifdef exprtk_enable_superscalar
  1406. parse_digit_1(tmp_d)
  1407. parse_digit_1(tmp_d)
  1408. parse_digit_1(tmp_d)
  1409. #endif
  1410. parse_digit_1(tmp_d)
  1411. parse_digit_1(tmp_d)
  1412. parse_digit_2(tmp_d)
  1413. }
  1414. if (curr != itr)
  1415. {
  1416. instate = true;
  1417. d += compute_pow10(tmp_d,-std::distance(curr,itr));
  1418. }
  1419. #undef parse_digit_1
  1420. #undef parse_digit_2
  1421. }
  1422. if (end != itr)
  1423. {
  1424. typename std::iterator_traits<Iterator>::value_type c = (*itr);
  1425. if (('e' == c) || ('E' == c))
  1426. {
  1427. int exp = 0;
  1428. if (!details::string_to_type_converter_impl_ref(++itr,end,exp))
  1429. {
  1430. if (end == itr)
  1431. return false;
  1432. else
  1433. c = (*itr);
  1434. }
  1435. exponent += exp;
  1436. }
  1437. if (end != itr)
  1438. {
  1439. if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
  1440. ++itr;
  1441. else if ('#' == c)
  1442. {
  1443. if (end == ++itr)
  1444. return false;
  1445. else if (('I' <= (*itr)) && ((*itr) <= 'n'))
  1446. {
  1447. if (('i' == (*itr)) || ('I' == (*itr)))
  1448. {
  1449. return parse_inf(itr,end,t,negative);
  1450. }
  1451. else if (('n' == (*itr)) || ('N' == (*itr)))
  1452. {
  1453. return parse_nan(itr,end,t);
  1454. }
  1455. else
  1456. return false;
  1457. }
  1458. else
  1459. return false;
  1460. }
  1461. else if (('I' <= (*itr)) && ((*itr) <= 'n'))
  1462. {
  1463. if (('i' == (*itr)) || ('I' == (*itr)))
  1464. {
  1465. return parse_inf(itr,end,t,negative);
  1466. }
  1467. else if (('n' == (*itr)) || ('N' == (*itr)))
  1468. {
  1469. return parse_nan(itr,end,t);
  1470. }
  1471. else
  1472. return false;
  1473. }
  1474. else
  1475. return false;
  1476. }
  1477. }
  1478. }
  1479. if ((end != itr) || (!instate))
  1480. return false;
  1481. else if (exponent)
  1482. d = compute_pow10(d,exponent);
  1483. t = static_cast<T>((negative) ? -d : d);
  1484. return true;
  1485. }
  1486. template <typename T>
  1487. inline bool string_to_real(const std::string& s, T& t)
  1488. {
  1489. const char* begin = s.data();
  1490. const char* end = s.data() + s.size();
  1491. typename numeric::details::number_type<T>::type num_type;
  1492. return string_to_real(begin,end,t,num_type);
  1493. }
  1494. template <typename T>
  1495. struct functor_t
  1496. {
  1497. /*
  1498. Note: The following definitions for Type, may require tweaking
  1499. based on the compiler and target architecture. The benchmark
  1500. should provide enough information to make the right choice.
  1501. */
  1502. //typedef T Type;
  1503. //typedef const T Type;
  1504. typedef const T& Type;
  1505. typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3);
  1506. typedef T (*tfunc_t)(Type t0, Type t1, Type t2);
  1507. typedef T (*bfunc_t)(Type t0, Type t1);
  1508. typedef T (*ufunc_t)(Type t0);
  1509. };
  1510. } // namespace details
  1511. namespace lexer
  1512. {
  1513. struct token
  1514. {
  1515. enum token_type
  1516. {
  1517. e_none = 0, e_error = 1, e_err_symbol = 2,
  1518. e_err_number = 3, e_err_string = 4, e_err_sfunc = 5,
  1519. e_eof = 6, e_number = 7, e_symbol = 8,
  1520. e_string = 9, e_assign = 10, e_addass = 11,
  1521. e_subass = 12, e_mulass = 13, e_divass = 14,
  1522. e_modass = 15, e_shr = 16, e_shl = 17,
  1523. e_lte = 18, e_ne = 19, e_gte = 20,
  1524. e_swap = 21, e_lt = '<', e_gt = '>',
  1525. e_eq = '=', e_rbracket = ')', e_lbracket = '(',
  1526. e_rsqrbracket = ']', e_lsqrbracket = '[', e_rcrlbracket = '}',
  1527. e_lcrlbracket = '{', e_comma = ',', e_add = '+',
  1528. e_sub = '-', e_div = '/', e_mul = '*',
  1529. e_mod = '%', e_pow = '^', e_colon = ':',
  1530. e_ternary = '?'
  1531. };
  1532. token()
  1533. : type(e_none),
  1534. value(""),
  1535. position(std::numeric_limits<std::size_t>::max())
  1536. {}
  1537. void clear()
  1538. {
  1539. type = e_none;
  1540. value = "";
  1541. position = std::numeric_limits<std::size_t>::max();
  1542. }
  1543. template <typename Iterator>
  1544. inline token& set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1545. {
  1546. type = tt;
  1547. value.assign(begin,end);
  1548. if (base_begin)
  1549. position = std::distance(base_begin,begin);
  1550. return *this;
  1551. }
  1552. template <typename Iterator>
  1553. inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1554. {
  1555. type = e_symbol;
  1556. value.assign(begin,end);
  1557. if (base_begin)
  1558. position = std::distance(base_begin,begin);
  1559. return *this;
  1560. }
  1561. template <typename Iterator>
  1562. inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1563. {
  1564. type = e_number;
  1565. value.assign(begin,end);
  1566. if (base_begin)
  1567. position = std::distance(base_begin,begin);
  1568. return *this;
  1569. }
  1570. template <typename Iterator>
  1571. inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1572. {
  1573. type = e_string;
  1574. value.assign(begin,end);
  1575. if (base_begin)
  1576. position = std::distance(base_begin,begin);
  1577. return *this;
  1578. }
  1579. inline token& set_string(const std::string& s, const std::size_t p)
  1580. {
  1581. type = e_string;
  1582. value = s;
  1583. position = p;
  1584. return *this;
  1585. }
  1586. template <typename Iterator>
  1587. inline token& set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1588. {
  1589. if (
  1590. (e_error == et) ||
  1591. (e_err_symbol == et) ||
  1592. (e_err_number == et) ||
  1593. (e_err_string == et) ||
  1594. (e_err_sfunc == et)
  1595. )
  1596. {
  1597. type = et;
  1598. }
  1599. else
  1600. type = e_error;
  1601. value.assign(begin,end);
  1602. if (base_begin)
  1603. position = std::distance(base_begin,begin);
  1604. return *this;
  1605. }
  1606. static inline std::string to_str(token_type t)
  1607. {
  1608. switch (t)
  1609. {
  1610. case e_none : return "NONE";
  1611. case e_error : return "ERROR";
  1612. case e_err_symbol : return "ERROR_SYMBOL";
  1613. case e_err_number : return "ERROR_NUMBER";
  1614. case e_err_string : return "ERROR_STRING";
  1615. case e_eof : return "EOF";
  1616. case e_number : return "NUMBER";
  1617. case e_symbol : return "SYMBOL";
  1618. case e_string : return "STRING";
  1619. case e_assign : return ":=";
  1620. case e_addass : return "+=";
  1621. case e_subass : return "-=";
  1622. case e_mulass : return "*=";
  1623. case e_divass : return "/=";
  1624. case e_modass : return "%=";
  1625. case e_shr : return ">>";
  1626. case e_shl : return "<<";
  1627. case e_lte : return "<=";
  1628. case e_ne : return "!=";
  1629. case e_gte : return ">=";
  1630. case e_lt : return "<";
  1631. case e_gt : return ">";
  1632. case e_eq : return "=";
  1633. case e_rbracket : return ")";
  1634. case e_lbracket : return "(";
  1635. case e_rsqrbracket : return "]";
  1636. case e_lsqrbracket : return "[";
  1637. case e_rcrlbracket : return "}";
  1638. case e_lcrlbracket : return "{";
  1639. case e_comma : return ",";
  1640. case e_add : return "+";
  1641. case e_sub : return "-";
  1642. case e_div : return "/";
  1643. case e_mul : return "*";
  1644. case e_mod : return "%";
  1645. case e_pow : return "^";
  1646. case e_colon : return ":";
  1647. case e_ternary : return "?";
  1648. case e_swap : return "<=>";
  1649. default : return "UNKNOWN";
  1650. }
  1651. }
  1652. inline bool is_error() const
  1653. {
  1654. return (
  1655. (e_error == type) ||
  1656. (e_err_symbol == type) ||
  1657. (e_err_number == type) ||
  1658. (e_err_string == type) ||
  1659. (e_err_sfunc == type)
  1660. );
  1661. }
  1662. token_type type;
  1663. std::string value;
  1664. std::size_t position;
  1665. };
  1666. class generator
  1667. {
  1668. public:
  1669. typedef token token_t;
  1670. typedef std::vector<token_t> token_list_t;
  1671. typedef std::vector<token_t>::iterator token_list_itr_t;
  1672. generator()
  1673. : base_itr_(0),
  1674. s_itr_ (0),
  1675. s_end_ (0)
  1676. {
  1677. clear();
  1678. }
  1679. inline void clear()
  1680. {
  1681. base_itr_ = 0;
  1682. s_itr_ = 0;
  1683. s_end_ = 0;
  1684. token_list_.clear();
  1685. token_itr_ = token_list_.end();
  1686. store_token_itr_ = token_list_.end();
  1687. }
  1688. inline bool process(const std::string& str)
  1689. {
  1690. base_itr_ = str.data();
  1691. s_itr_ = str.data();
  1692. s_end_ = str.data() + str.size();
  1693. eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
  1694. token_list_.clear();
  1695. while (!is_end(s_itr_))
  1696. {
  1697. scan_token();
  1698. if (token_list_.empty())
  1699. return true;
  1700. else if (token_list_.back().is_error())
  1701. {
  1702. return false;
  1703. }
  1704. }
  1705. return true;
  1706. }
  1707. inline bool empty() const
  1708. {
  1709. return token_list_.empty();
  1710. }
  1711. inline std::size_t size() const
  1712. {
  1713. return token_list_.size();
  1714. }
  1715. inline void begin()
  1716. {
  1717. token_itr_ = token_list_.begin();
  1718. store_token_itr_ = token_list_.begin();
  1719. }
  1720. inline void store()
  1721. {
  1722. store_token_itr_ = token_itr_;
  1723. }
  1724. inline void restore()
  1725. {
  1726. token_itr_ = store_token_itr_;
  1727. }
  1728. inline token_t& next_token()
  1729. {
  1730. if (token_list_.end() != token_itr_)
  1731. {
  1732. return *token_itr_++;
  1733. }
  1734. else
  1735. return eof_token_;
  1736. }
  1737. inline token_t& peek_next_token()
  1738. {
  1739. if (token_list_.end() != token_itr_)
  1740. {
  1741. return *token_itr_;
  1742. }
  1743. else
  1744. return eof_token_;
  1745. }
  1746. inline token_t& operator[](const std::size_t& index)
  1747. {
  1748. if (index < token_list_.size())
  1749. return token_list_[index];
  1750. else
  1751. return eof_token_;
  1752. }
  1753. inline token_t operator[](const std::size_t& index) const
  1754. {
  1755. if (index < token_list_.size())
  1756. return token_list_[index];
  1757. else
  1758. return eof_token_;
  1759. }
  1760. inline bool finished() const
  1761. {
  1762. return (token_list_.end() == token_itr_);
  1763. }
  1764. inline void insert_front(token_t::token_type tk_type)
  1765. {
  1766. if (
  1767. !token_list_.empty() &&
  1768. (token_list_.end() != token_itr_)
  1769. )
  1770. {
  1771. token_t t = *token_itr_;
  1772. t.type = tk_type;
  1773. token_itr_ = token_list_.insert(token_itr_,t);
  1774. }
  1775. }
  1776. private:
  1777. inline bool is_end(const char* itr)
  1778. {
  1779. return (s_end_ == itr);
  1780. }
  1781. inline void skip_whitespace()
  1782. {
  1783. while (!is_end(s_itr_) && details::is_whitespace(*s_itr_))
  1784. {
  1785. ++s_itr_;
  1786. }
  1787. }
  1788. inline void skip_comments()
  1789. {
  1790. #ifndef exprtk_disable_comments
  1791. // The following comment styles are supported:
  1792. // 1. // .... \n
  1793. // 2. # .... \n
  1794. // 3. /* .... */
  1795. struct test
  1796. {
  1797. static inline bool comment_start(const char c0, const char c1, int& mode, int& incr)
  1798. {
  1799. mode = 0;
  1800. if ('#' == c0) { mode = 1; incr = 1; }
  1801. else if ('/' == c0)
  1802. {
  1803. if ('/' == c1) { mode = 1; incr = 2; }
  1804. else if ('*' == c1) { mode = 2; incr = 2; }
  1805. }
  1806. return (0 != mode);
  1807. }
  1808. static inline bool comment_end(const char c0, const char c1, const int mode)
  1809. {
  1810. return (
  1811. ((1 == mode) && ('\n' == c0)) ||
  1812. ((2 == mode) && ( '*' == c0) && ('/' == c1))
  1813. );
  1814. }
  1815. };
  1816. int mode = 0;
  1817. int increment = 0;
  1818. if (is_end(s_itr_) || is_end((s_itr_ + 1)))
  1819. return;
  1820. else if (!test::comment_start(*s_itr_,*(s_itr_ + 1),mode,increment))
  1821. return;
  1822. s_itr_ += increment;
  1823. while (!is_end(s_itr_) && !test::comment_end(*s_itr_,*(s_itr_ + 1),mode))
  1824. {
  1825. ++s_itr_;
  1826. }
  1827. if (!is_end(s_itr_))
  1828. {
  1829. s_itr_ += mode;
  1830. skip_whitespace();
  1831. skip_comments();
  1832. }
  1833. #endif
  1834. }
  1835. inline void scan_token()
  1836. {
  1837. skip_whitespace();
  1838. skip_comments();
  1839. if (is_end(s_itr_))
  1840. {
  1841. return;
  1842. }
  1843. else if (details::is_operator_char(*s_itr_))
  1844. {
  1845. scan_operator();
  1846. return;
  1847. }
  1848. else if (details::is_letter(*s_itr_))
  1849. {
  1850. scan_symbol();
  1851. return;
  1852. }
  1853. else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_)))
  1854. {
  1855. scan_number();
  1856. return;
  1857. }
  1858. else if ('$' == (*s_itr_))
  1859. {
  1860. scan_special_function();
  1861. return;
  1862. }
  1863. #ifndef exprtk_disable_string_capabilities
  1864. else if ('\'' == (*s_itr_))
  1865. {
  1866. scan_string();
  1867. return;
  1868. }
  1869. #endif
  1870. else if ('~' == (*s_itr_))
  1871. {
  1872. token_t t;
  1873. t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
  1874. token_list_.push_back(t);
  1875. ++s_itr_;
  1876. return;
  1877. }
  1878. else
  1879. {
  1880. token_t t;
  1881. t.set_error(token::e_error,s_itr_,s_itr_ + 2,base_itr_);
  1882. token_list_.push_back(t);
  1883. ++s_itr_;
  1884. }
  1885. }
  1886. inline void scan_operator()
  1887. {
  1888. token_t t;
  1889. const char c0 = s_itr_[0];
  1890. if (!is_end(s_itr_ + 1))
  1891. {
  1892. const char c1 = s_itr_[1];
  1893. if (!is_end(s_itr_ + 2))
  1894. {
  1895. const char c2 = s_itr_[2];
  1896. if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
  1897. {
  1898. t.set_operator(token_t::e_swap,s_itr_,s_itr_ + 3,base_itr_);
  1899. token_list_.push_back(t);
  1900. s_itr_ += 3;
  1901. return;
  1902. }
  1903. }
  1904. token_t::token_type ttype = token_t::e_none;
  1905. if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
  1906. else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
  1907. else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
  1908. else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
  1909. else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
  1910. else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
  1911. else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
  1912. else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
  1913. else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass;
  1914. else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass;
  1915. else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass;
  1916. else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass;
  1917. else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass;
  1918. if (token_t::e_none != ttype)
  1919. {
  1920. t.set_operator(ttype,s_itr_,s_itr_ + 2,base_itr_);
  1921. token_list_.push_back(t);
  1922. s_itr_ += 2;
  1923. return;
  1924. }
  1925. }
  1926. if ('<' == c0)
  1927. t.set_operator(token_t::e_lt ,s_itr_,s_itr_ + 1,base_itr_);
  1928. else if ('>' == c0)
  1929. t.set_operator(token_t::e_gt ,s_itr_,s_itr_ + 1,base_itr_);
  1930. else if (';' == c0)
  1931. t.set_operator(token_t::e_eof,s_itr_,s_itr_ + 1,base_itr_);
  1932. else if ('&' == c0)
  1933. t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
  1934. else if ('|' == c0)
  1935. t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
  1936. else
  1937. t.set_operator(token_t::token_type(c0),s_itr_,s_itr_ + 1,base_itr_);
  1938. token_list_.push_back(t);
  1939. ++s_itr_;
  1940. }
  1941. inline void scan_symbol()
  1942. {
  1943. const char* initial_itr = s_itr_;
  1944. while (
  1945. (!is_end(s_itr_)) &&
  1946. (details::is_letter_or_digit(*s_itr_) || ((*s_itr_) == '_'))
  1947. )
  1948. {
  1949. ++s_itr_;
  1950. }
  1951. token_t t;
  1952. t.set_symbol(initial_itr,s_itr_,base_itr_);
  1953. token_list_.push_back(t);
  1954. }
  1955. inline void scan_number()
  1956. {
  1957. /*
  1958. Attempt to match a valid numeric value in one of the following formats:
  1959. 1. 123456
  1960. 2. 123.456
  1961. 3. 123.456e3
  1962. 4. 123.456E3
  1963. 5. 123.456e+3
  1964. 6. 123.456E+3
  1965. 7. 123.456e-3
  1966. 8. 123.456E-3
  1967. */
  1968. const char* initial_itr = s_itr_;
  1969. bool dot_found = false;
  1970. bool e_found = false;
  1971. bool post_e_sign_found = false;
  1972. token_t t;
  1973. while (!is_end(s_itr_))
  1974. {
  1975. if ('.' == (*s_itr_))
  1976. {
  1977. if (dot_found)
  1978. {
  1979. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  1980. token_list_.push_back(t);
  1981. return;
  1982. }
  1983. dot_found = true;
  1984. ++s_itr_;
  1985. continue;
  1986. }
  1987. else if (details::imatch('e',(*s_itr_)))
  1988. {
  1989. const char& c = *(s_itr_ + 1);
  1990. if (is_end(s_itr_ + 1))
  1991. {
  1992. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  1993. token_list_.push_back(t);
  1994. return;
  1995. }
  1996. else if (
  1997. ('+' != c) &&
  1998. ('-' != c) &&
  1999. !details::is_digit(c)
  2000. )
  2001. {
  2002. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  2003. token_list_.push_back(t);
  2004. return;
  2005. }
  2006. e_found = true;
  2007. ++s_itr_;
  2008. continue;
  2009. }
  2010. else if (e_found && details::is_sign(*s_itr_))
  2011. {
  2012. if (post_e_sign_found)
  2013. {
  2014. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  2015. token_list_.push_back(t);
  2016. return;
  2017. }
  2018. post_e_sign_found = true;
  2019. ++s_itr_;
  2020. continue;
  2021. }
  2022. else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
  2023. break;
  2024. else
  2025. ++s_itr_;
  2026. }
  2027. t.set_numeric(initial_itr,s_itr_,base_itr_);
  2028. token_list_.push_back(t);
  2029. return;
  2030. }
  2031. inline void scan_special_function()
  2032. {
  2033. const char* initial_itr = s_itr_;
  2034. token_t t;
  2035. // $fdd(x,x,x) = at least 11 chars
  2036. if (std::distance(s_itr_,s_end_) < 11)
  2037. {
  2038. t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_);
  2039. token_list_.push_back(t);
  2040. return;
  2041. }
  2042. if (
  2043. !(('$' == *s_itr_) &&
  2044. (details::imatch ('f',*(s_itr_ + 1))) &&
  2045. (details::is_digit(*(s_itr_ + 2))) &&
  2046. (details::is_digit(*(s_itr_ + 3))))
  2047. )
  2048. {
  2049. t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_);
  2050. token_list_.push_back(t);
  2051. return;
  2052. }
  2053. s_itr_ += 4; // $fdd = 4chars
  2054. t.set_symbol(initial_itr,s_itr_,base_itr_);
  2055. token_list_.push_back(t);
  2056. return;
  2057. }
  2058. #ifndef exprtk_disable_string_capabilities
  2059. inline void scan_string()
  2060. {
  2061. const char* initial_itr = s_itr_ + 1;
  2062. token_t t;
  2063. if (std::distance(s_itr_,s_end_) < 2)
  2064. {
  2065. t.set_error(token::e_err_string,s_itr_,s_end_,base_itr_);
  2066. token_list_.push_back(t);
  2067. return;
  2068. }
  2069. ++s_itr_;
  2070. bool escaped_found = false;
  2071. bool escaped = false;
  2072. while (!is_end(s_itr_))
  2073. {
  2074. if ('\\' == *s_itr_)
  2075. {
  2076. escaped_found = true;
  2077. escaped = true;
  2078. ++s_itr_;
  2079. continue;
  2080. }
  2081. else if (!escaped)
  2082. {
  2083. if ('\'' == *s_itr_)
  2084. break;
  2085. }
  2086. else if (escaped)
  2087. {
  2088. if (!is_end(s_itr_) && ('0' == *(s_itr_)))
  2089. {
  2090. if (
  2091. is_end(s_itr_ + 1) ||
  2092. is_end(s_itr_ + 2) ||
  2093. is_end(s_itr_ + 3) ||
  2094. (
  2095. ('x' != *(s_itr_ + 1)) &&
  2096. ('X' != *(s_itr_ + 1))
  2097. ) ||
  2098. (!details::is_hex_digit(*(s_itr_ + 2))) ||
  2099. (!details::is_hex_digit(*(s_itr_ + 3)))
  2100. )
  2101. {
  2102. t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_);
  2103. token_list_.push_back(t);
  2104. return;
  2105. }
  2106. else
  2107. s_itr_ += 3;
  2108. }
  2109. escaped = false;
  2110. }
  2111. ++s_itr_;
  2112. }
  2113. if (is_end(s_itr_))
  2114. {
  2115. t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_);
  2116. token_list_.push_back(t);
  2117. return;
  2118. }
  2119. if (!escaped_found)
  2120. t.set_string(initial_itr,s_itr_,base_itr_);
  2121. else
  2122. {
  2123. std::string parsed_string(initial_itr,s_itr_);
  2124. details::cleanup_escapes(parsed_string);
  2125. t.set_string(parsed_string, std::distance(base_itr_,initial_itr));
  2126. }
  2127. token_list_.push_back(t);
  2128. ++s_itr_;
  2129. return;
  2130. }
  2131. #endif
  2132. private:
  2133. token_list_t token_list_;
  2134. token_list_itr_t token_itr_;
  2135. token_list_itr_t store_token_itr_;
  2136. token_t eof_token_;
  2137. const char* base_itr_;
  2138. const char* s_itr_;
  2139. const char* s_end_;
  2140. friend class token_scanner;
  2141. friend class token_modifier;
  2142. friend class token_inserter;
  2143. friend class token_joiner;
  2144. };
  2145. class helper_interface
  2146. {
  2147. public:
  2148. virtual void init() { }
  2149. virtual void reset() { }
  2150. virtual bool result() { return true; }
  2151. virtual std::size_t process(generator&) { return 0; }
  2152. virtual ~helper_interface() { }
  2153. };
  2154. class token_scanner : public helper_interface
  2155. {
  2156. public:
  2157. virtual ~token_scanner()
  2158. {}
  2159. explicit token_scanner(const std::size_t& stride)
  2160. : stride_(stride)
  2161. {
  2162. if (stride > 4)
  2163. {
  2164. throw std::invalid_argument("token_scanner() - Invalid stride value");
  2165. }
  2166. }
  2167. inline std::size_t process(generator& g)
  2168. {
  2169. if (g.token_list_.size() >= stride_)
  2170. {
  2171. for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
  2172. {
  2173. token t;
  2174. switch (stride_)
  2175. {
  2176. case 1 :
  2177. {
  2178. const token& t0 = g.token_list_[i];
  2179. if (!operator()(t0))
  2180. {
  2181. return i;
  2182. }
  2183. }
  2184. break;
  2185. case 2 :
  2186. {
  2187. const token& t0 = g.token_list_[i ];
  2188. const token& t1 = g.token_list_[i + 1];
  2189. if (!operator()(t0,t1))
  2190. {
  2191. return i;
  2192. }
  2193. }
  2194. break;
  2195. case 3 :
  2196. {
  2197. const token& t0 = g.token_list_[i ];
  2198. const token& t1 = g.token_list_[i + 1];
  2199. const token& t2 = g.token_list_[i + 2];
  2200. if (!operator()(t0,t1,t2))
  2201. {
  2202. return i;
  2203. }
  2204. }
  2205. break;
  2206. case 4 :
  2207. {
  2208. const token& t0 = g.token_list_[i ];
  2209. const token& t1 = g.token_list_[i + 1];
  2210. const token& t2 = g.token_list_[i + 2];
  2211. const token& t3 = g.token_list_[i + 3];
  2212. if (!operator()(t0,t1,t2,t3))
  2213. {
  2214. return i;
  2215. }
  2216. }
  2217. break;
  2218. }
  2219. }
  2220. }
  2221. return (g.token_list_.size() - stride_ + 1);
  2222. }
  2223. virtual bool operator()(const token&)
  2224. {
  2225. return false;
  2226. }
  2227. virtual bool operator()(const token&, const token&)
  2228. {
  2229. return false;
  2230. }
  2231. virtual bool operator()(const token&, const token&, const token&)
  2232. {
  2233. return false;
  2234. }
  2235. virtual bool operator()(const token&, const token&, const token&, const token&)
  2236. {
  2237. return false;
  2238. }
  2239. private:
  2240. std::size_t stride_;
  2241. };
  2242. class token_modifier : public helper_interface
  2243. {
  2244. public:
  2245. inline std::size_t process(generator& g)
  2246. {
  2247. std::size_t changes = 0;
  2248. for (std::size_t i = 0; i < g.token_list_.size(); ++i)
  2249. {
  2250. if (modify(g.token_list_[i])) changes++;
  2251. }
  2252. return changes;
  2253. }
  2254. virtual bool modify(token& t) = 0;
  2255. };
  2256. class token_inserter : public helper_interface
  2257. {
  2258. public:
  2259. explicit token_inserter(const std::size_t& stride)
  2260. : stride_(stride)
  2261. {
  2262. if (stride > 5)
  2263. {
  2264. throw std::invalid_argument("token_inserter() - Invalid stride value");
  2265. }
  2266. }
  2267. inline std::size_t process(generator& g)
  2268. {
  2269. if (g.token_list_.empty())
  2270. return 0;
  2271. else if (g.token_list_.size() < stride_)
  2272. return 0;
  2273. std::size_t changes = 0;
  2274. for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
  2275. {
  2276. int insert_index = -1;
  2277. token t;
  2278. switch (stride_)
  2279. {
  2280. case 1 : insert_index = insert(g.token_list_[i],t);
  2281. break;
  2282. case 2 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],t);
  2283. break;
  2284. case 3 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t);
  2285. break;
  2286. 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);
  2287. break;
  2288. 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);
  2289. break;
  2290. }
  2291. if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
  2292. {
  2293. g.token_list_.insert(g.token_list_.begin() + (i + insert_index),t);
  2294. changes++;
  2295. }
  2296. }
  2297. return changes;
  2298. }
  2299. inline virtual int insert(const token&, token& )
  2300. {
  2301. return -1;
  2302. }
  2303. inline virtual int insert(const token&, const token&, token&)
  2304. {
  2305. return -1;
  2306. }
  2307. inline virtual int insert(const token&, const token&, const token&, token&)
  2308. {
  2309. return -1;
  2310. }
  2311. inline virtual int insert(const token&, const token&, const token&, const token&, token&)
  2312. {
  2313. return -1;
  2314. }
  2315. inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
  2316. {
  2317. return -1;
  2318. }
  2319. private:
  2320. std::size_t stride_;
  2321. };
  2322. class token_joiner : public helper_interface
  2323. {
  2324. public:
  2325. token_joiner(const std::size_t& stride)
  2326. : stride_(stride)
  2327. {}
  2328. inline std::size_t process(generator& g)
  2329. {
  2330. if (g.token_list_.empty())
  2331. return 0;
  2332. switch (stride_)
  2333. {
  2334. case 2 : return process_stride_2(g);
  2335. case 3 : return process_stride_3(g);
  2336. default : return 0;
  2337. }
  2338. }
  2339. virtual bool join(const token&, const token&, token&) { return false; }
  2340. virtual bool join(const token&, const token&, const token&, token&) { return false; }
  2341. private:
  2342. inline std::size_t process_stride_2(generator& g)
  2343. {
  2344. if (g.token_list_.size() < 2)
  2345. return 0;
  2346. std::size_t changes = 0;
  2347. for (std::size_t i = 0; i < g.token_list_.size() - 1; ++i)
  2348. {
  2349. token t;
  2350. while (join(g.token_list_[i],g.token_list_[i + 1],t))
  2351. {
  2352. g.token_list_[i] = t;
  2353. g.token_list_.erase(g.token_list_.begin() + (i + 1));
  2354. ++changes;
  2355. }
  2356. }
  2357. return changes;
  2358. }
  2359. inline std::size_t process_stride_3(generator& g)
  2360. {
  2361. if (g.token_list_.size() < 3)
  2362. return 0;
  2363. std::size_t changes = 0;
  2364. for (std::size_t i = 0; i < g.token_list_.size() - 2; ++i)
  2365. {
  2366. token t;
  2367. while (join(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t))
  2368. {
  2369. g.token_list_[i] = t;
  2370. g.token_list_.erase(g.token_list_.begin() + (i + 1),
  2371. g.token_list_.begin() + (i + 3));
  2372. ++changes;
  2373. }
  2374. }
  2375. return changes;
  2376. }
  2377. std::size_t stride_;
  2378. };
  2379. namespace helper
  2380. {
  2381. inline void dump(lexer::generator& generator)
  2382. {
  2383. for (std::size_t i = 0; i < generator.size(); ++i)
  2384. {
  2385. lexer::token t = generator[i];
  2386. printf("Token[%02d] @ %03d %6s --> '%s'\n",
  2387. static_cast<int>(i),
  2388. static_cast<int>(t.position),
  2389. t.to_str(t.type).c_str(),
  2390. t.value.c_str());
  2391. }
  2392. }
  2393. class commutative_inserter : public lexer::token_inserter
  2394. {
  2395. public:
  2396. commutative_inserter()
  2397. : lexer::token_inserter(2)
  2398. {}
  2399. inline void ignore_symbol(const std::string& symbol)
  2400. {
  2401. ignore_set_.insert(symbol);
  2402. }
  2403. inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token)
  2404. {
  2405. bool match = false;
  2406. new_token.type = lexer::token::e_mul;
  2407. new_token.value = "*";
  2408. new_token.position = t1.position;
  2409. if (t0.type == lexer::token::e_symbol)
  2410. {
  2411. if (ignore_set_.end() != ignore_set_.find(t0.value))
  2412. {
  2413. return -1;
  2414. }
  2415. else if (!t0.value.empty() && ('$' == t0.value[0]))
  2416. {
  2417. return -1;
  2418. }
  2419. }
  2420. if (t1.type == lexer::token::e_symbol)
  2421. {
  2422. if (ignore_set_.end() != ignore_set_.find(t1.value))
  2423. {
  2424. return -1;
  2425. }
  2426. }
  2427. if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
  2428. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
  2429. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
  2430. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
  2431. else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
  2432. else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
  2433. else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
  2434. else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
  2435. else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
  2436. else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
  2437. else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
  2438. return (match) ? 1 : -1;
  2439. }
  2440. private:
  2441. std::set<std::string,details::ilesscompare> ignore_set_;
  2442. };
  2443. class operator_joiner : public token_joiner
  2444. {
  2445. public:
  2446. operator_joiner(const std::size_t& stride)
  2447. : token_joiner(stride)
  2448. {}
  2449. inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t)
  2450. {
  2451. // ': =' --> ':='
  2452. if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
  2453. {
  2454. t.type = lexer::token::e_assign;
  2455. t.value = ":=";
  2456. t.position = t0.position;
  2457. return true;
  2458. }
  2459. // '+ =' --> '+='
  2460. else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq))
  2461. {
  2462. t.type = lexer::token::e_addass;
  2463. t.value = "+=";
  2464. t.position = t0.position;
  2465. return true;
  2466. }
  2467. // '- =' --> '-='
  2468. else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq))
  2469. {
  2470. t.type = lexer::token::e_subass;
  2471. t.value = "-=";
  2472. t.position = t0.position;
  2473. return true;
  2474. }
  2475. // '* =' --> '*='
  2476. else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq))
  2477. {
  2478. t.type = lexer::token::e_mulass;
  2479. t.value = "*=";
  2480. t.position = t0.position;
  2481. return true;
  2482. }
  2483. // '/ =' --> '/='
  2484. else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq))
  2485. {
  2486. t.type = lexer::token::e_divass;
  2487. t.value = "/=";
  2488. t.position = t0.position;
  2489. return true;
  2490. }
  2491. // '% =' --> '%='
  2492. else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq))
  2493. {
  2494. t.type = lexer::token::e_modass;
  2495. t.value = "%=";
  2496. t.position = t0.position;
  2497. return true;
  2498. }
  2499. // '> =' --> '>='
  2500. else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
  2501. {
  2502. t.type = lexer::token::e_gte;
  2503. t.value = ">=";
  2504. t.position = t0.position;
  2505. return true;
  2506. }
  2507. // '< =' --> '<='
  2508. else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
  2509. {
  2510. t.type = lexer::token::e_lte;
  2511. t.value = "<=";
  2512. t.position = t0.position;
  2513. return true;
  2514. }
  2515. // '= =' --> '=='
  2516. else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
  2517. {
  2518. t.type = lexer::token::e_eq;
  2519. t.value = "==";
  2520. t.position = t0.position;
  2521. return true;
  2522. }
  2523. // '! =' --> '!='
  2524. else if ((static_cast<char>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
  2525. {
  2526. t.type = lexer::token::e_ne;
  2527. t.value = "!=";
  2528. t.position = t0.position;
  2529. return true;
  2530. }
  2531. // '< >' --> '<>'
  2532. else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
  2533. {
  2534. t.type = lexer::token::e_ne;
  2535. t.value = "<>";
  2536. t.position = t0.position;
  2537. return true;
  2538. }
  2539. // '<= >' --> '<=>'
  2540. else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt))
  2541. {
  2542. t.type = lexer::token::e_swap;
  2543. t.value = "<=>";
  2544. t.position = t0.position;
  2545. return true;
  2546. }
  2547. else
  2548. return false;
  2549. }
  2550. inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, lexer::token& t)
  2551. {
  2552. // '[ * ]' --> '[*]'
  2553. if (
  2554. (t0.type == lexer::token::e_lsqrbracket) &&
  2555. (t1.type == lexer::token::e_mul ) &&
  2556. (t2.type == lexer::token::e_rsqrbracket)
  2557. )
  2558. {
  2559. t.type = lexer::token::e_symbol;
  2560. t.value = "[*]";
  2561. t.position = t0.position;
  2562. return true;
  2563. }
  2564. else
  2565. return false;
  2566. }
  2567. };
  2568. class bracket_checker : public lexer::token_scanner
  2569. {
  2570. public:
  2571. bracket_checker()
  2572. : token_scanner(1),
  2573. state_(true)
  2574. {}
  2575. bool result()
  2576. {
  2577. if (!stack_.empty())
  2578. {
  2579. lexer::token t;
  2580. t.value = stack_.top().first;
  2581. t.position = stack_.top().second;
  2582. error_token_ = t;
  2583. state_ = false;
  2584. return false;
  2585. }
  2586. else
  2587. return state_;
  2588. }
  2589. lexer::token error_token()
  2590. {
  2591. return error_token_;
  2592. }
  2593. void reset()
  2594. {
  2595. // Why? because msvc doesn't support swap properly.
  2596. stack_ = std::stack<std::pair<char,std::size_t> >();
  2597. state_ = true;
  2598. error_token_.clear();
  2599. }
  2600. bool operator()(const lexer::token& t)
  2601. {
  2602. if (
  2603. !t.value.empty() &&
  2604. (lexer::token::e_string != t.type) &&
  2605. (lexer::token::e_symbol != t.type) &&
  2606. exprtk::details::is_bracket(t.value[0])
  2607. )
  2608. {
  2609. char c = t.value[0];
  2610. if (t.type == lexer::token::e_lbracket) stack_.push(std::make_pair(')',t.position));
  2611. else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
  2612. else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
  2613. else if (exprtk::details::is_right_bracket(c))
  2614. {
  2615. if (stack_.empty())
  2616. {
  2617. state_ = false;
  2618. error_token_ = t;
  2619. return false;
  2620. }
  2621. else if (c != stack_.top().first)
  2622. {
  2623. state_ = false;
  2624. error_token_ = t;
  2625. return false;
  2626. }
  2627. else
  2628. stack_.pop();
  2629. }
  2630. }
  2631. return true;
  2632. }
  2633. private:
  2634. bool state_;
  2635. std::stack<std::pair<char,std::size_t> > stack_;
  2636. lexer::token error_token_;
  2637. };
  2638. class numeric_checker : public lexer::token_scanner
  2639. {
  2640. public:
  2641. numeric_checker()
  2642. : token_scanner (1),
  2643. current_index_(0)
  2644. {}
  2645. bool result()
  2646. {
  2647. return error_list_.empty();
  2648. }
  2649. void reset()
  2650. {
  2651. error_list_.clear();
  2652. current_index_ = 0;
  2653. }
  2654. bool operator()(const lexer::token& t)
  2655. {
  2656. if (token::e_number == t.type)
  2657. {
  2658. double v;
  2659. if (!exprtk::details::string_to_real(t.value,v))
  2660. {
  2661. error_list_.push_back(current_index_);
  2662. }
  2663. }
  2664. ++current_index_;
  2665. return true;
  2666. }
  2667. std::size_t error_count() const
  2668. {
  2669. return error_list_.size();
  2670. }
  2671. std::size_t error_index(const std::size_t& i)
  2672. {
  2673. if (i < error_list_.size())
  2674. return error_list_[i];
  2675. else
  2676. return std::numeric_limits<std::size_t>::max();
  2677. }
  2678. void clear_errors()
  2679. {
  2680. error_list_.clear();
  2681. }
  2682. private:
  2683. std::size_t current_index_;
  2684. std::vector<std::size_t> error_list_;
  2685. };
  2686. class symbol_replacer : public lexer::token_modifier
  2687. {
  2688. private:
  2689. typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
  2690. public:
  2691. bool remove(const std::string& target_symbol)
  2692. {
  2693. replace_map_t::iterator itr = replace_map_.find(target_symbol);
  2694. if (replace_map_.end() == itr)
  2695. return false;
  2696. replace_map_.erase(itr);
  2697. return true;
  2698. }
  2699. bool add_replace(const std::string& target_symbol,
  2700. const std::string& replace_symbol,
  2701. const lexer::token::token_type token_type = lexer::token::e_symbol)
  2702. {
  2703. replace_map_t::iterator itr = replace_map_.find(target_symbol);
  2704. if (replace_map_.end() != itr)
  2705. {
  2706. return false;
  2707. }
  2708. replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
  2709. return true;
  2710. }
  2711. void clear()
  2712. {
  2713. replace_map_.clear();
  2714. }
  2715. private:
  2716. bool modify(lexer::token& t)
  2717. {
  2718. if (lexer::token::e_symbol == t.type)
  2719. {
  2720. if (replace_map_.empty())
  2721. return false;
  2722. replace_map_t::iterator itr = replace_map_.find(t.value);
  2723. if (replace_map_.end() != itr)
  2724. {
  2725. t.value = itr->second.first;
  2726. t.type = itr->second.second;
  2727. return true;
  2728. }
  2729. }
  2730. return false;
  2731. }
  2732. replace_map_t replace_map_;
  2733. };
  2734. class sequence_validator : public lexer::token_scanner
  2735. {
  2736. private:
  2737. typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
  2738. typedef std::set<token_pair_t> set_t;
  2739. public:
  2740. sequence_validator()
  2741. : lexer::token_scanner(2)
  2742. {
  2743. add_invalid(lexer::token::e_number ,lexer::token::e_number );
  2744. add_invalid(lexer::token::e_string ,lexer::token::e_string );
  2745. add_invalid(lexer::token::e_number ,lexer::token::e_string );
  2746. add_invalid(lexer::token::e_string ,lexer::token::e_number );
  2747. add_invalid(lexer::token::e_string ,lexer::token::e_colon );
  2748. add_invalid(lexer::token::e_string ,lexer::token::e_ternary);
  2749. add_invalid(lexer::token::e_colon ,lexer::token::e_string );
  2750. add_invalid(lexer::token::e_ternary,lexer::token::e_string );
  2751. add_invalid_set1(lexer::token::e_assign );
  2752. add_invalid_set1(lexer::token::e_shr );
  2753. add_invalid_set1(lexer::token::e_shl );
  2754. add_invalid_set1(lexer::token::e_lte );
  2755. add_invalid_set1(lexer::token::e_ne );
  2756. add_invalid_set1(lexer::token::e_gte );
  2757. add_invalid_set1(lexer::token::e_lt );
  2758. add_invalid_set1(lexer::token::e_gt );
  2759. add_invalid_set1(lexer::token::e_eq );
  2760. add_invalid_set1(lexer::token::e_comma );
  2761. add_invalid_set1(lexer::token::e_add );
  2762. add_invalid_set1(lexer::token::e_sub );
  2763. add_invalid_set1(lexer::token::e_div );
  2764. add_invalid_set1(lexer::token::e_mul );
  2765. add_invalid_set1(lexer::token::e_mod );
  2766. add_invalid_set1(lexer::token::e_pow );
  2767. add_invalid_set1(lexer::token::e_colon );
  2768. add_invalid_set1(lexer::token::e_ternary);
  2769. }
  2770. bool result()
  2771. {
  2772. return error_list_.empty();
  2773. }
  2774. bool operator()(const lexer::token& t0, const lexer::token& t1)
  2775. {
  2776. set_t::value_type p = std::make_pair(t0.type,t1.type);
  2777. if (invalid_bracket_check(t0.type,t1.type))
  2778. {
  2779. error_list_.push_back(std::make_pair(t0,t1));
  2780. }
  2781. else if (invalid_comb_.find(p) != invalid_comb_.end())
  2782. {
  2783. error_list_.push_back(std::make_pair(t0,t1));
  2784. }
  2785. return true;
  2786. }
  2787. std::size_t error_count()
  2788. {
  2789. return error_list_.size();
  2790. }
  2791. std::pair<lexer::token,lexer::token> error(const std::size_t index)
  2792. {
  2793. if (index < error_list_.size())
  2794. {
  2795. return error_list_[index];
  2796. }
  2797. else
  2798. {
  2799. static const lexer::token error_token;
  2800. return std::make_pair(error_token,error_token);
  2801. }
  2802. }
  2803. void clear_errors()
  2804. {
  2805. error_list_.clear();
  2806. }
  2807. private:
  2808. void add_invalid(lexer::token::token_type base, lexer::token::token_type t)
  2809. {
  2810. invalid_comb_.insert(std::make_pair(base,t));
  2811. }
  2812. void add_invalid_set1(lexer::token::token_type t)
  2813. {
  2814. add_invalid(t,lexer::token::e_assign);
  2815. add_invalid(t,lexer::token::e_shr );
  2816. add_invalid(t,lexer::token::e_shl );
  2817. add_invalid(t,lexer::token::e_lte );
  2818. add_invalid(t,lexer::token::e_ne );
  2819. add_invalid(t,lexer::token::e_gte );
  2820. add_invalid(t,lexer::token::e_lt );
  2821. add_invalid(t,lexer::token::e_gt );
  2822. add_invalid(t,lexer::token::e_eq );
  2823. add_invalid(t,lexer::token::e_comma );
  2824. add_invalid(t,lexer::token::e_div );
  2825. add_invalid(t,lexer::token::e_mul );
  2826. add_invalid(t,lexer::token::e_mod );
  2827. add_invalid(t,lexer::token::e_pow );
  2828. add_invalid(t,lexer::token::e_colon );
  2829. }
  2830. bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
  2831. {
  2832. if (details::is_right_bracket(static_cast<char>(base)))
  2833. {
  2834. switch (t)
  2835. {
  2836. case lexer::token::e_assign : return (']' != base);
  2837. case lexer::token::e_string : return true;
  2838. default : return false;
  2839. }
  2840. }
  2841. else if (details::is_left_bracket(static_cast<char>(base)))
  2842. {
  2843. if (details::is_right_bracket(static_cast<char>(t)))
  2844. return false;
  2845. else if (details::is_left_bracket(static_cast<char>(t)))
  2846. return false;
  2847. else
  2848. {
  2849. switch (t)
  2850. {
  2851. case lexer::token::e_number : return false;
  2852. case lexer::token::e_symbol : return false;
  2853. case lexer::token::e_string : return false;
  2854. case lexer::token::e_add : return false;
  2855. case lexer::token::e_sub : return false;
  2856. case lexer::token::e_colon : return false;
  2857. case lexer::token::e_ternary : return false;
  2858. default : return true;
  2859. }
  2860. }
  2861. }
  2862. else if (details::is_right_bracket(static_cast<char>(t)))
  2863. {
  2864. switch (base)
  2865. {
  2866. case lexer::token::e_number : return false;
  2867. case lexer::token::e_symbol : return false;
  2868. case lexer::token::e_string : return false;
  2869. case lexer::token::e_eof : return false;
  2870. case lexer::token::e_colon : return false;
  2871. case lexer::token::e_ternary : return false;
  2872. default : return true;
  2873. }
  2874. }
  2875. else if (details::is_left_bracket(static_cast<char>(t)))
  2876. {
  2877. switch (base)
  2878. {
  2879. case lexer::token::e_rbracket : return true;
  2880. case lexer::token::e_rsqrbracket : return true;
  2881. case lexer::token::e_rcrlbracket : return true;
  2882. default : return false;
  2883. }
  2884. }
  2885. return false;
  2886. }
  2887. set_t invalid_comb_;
  2888. std::vector<std::pair<lexer::token,lexer::token> > error_list_;
  2889. };
  2890. struct helper_assembly
  2891. {
  2892. inline bool register_scanner(lexer::token_scanner* scanner)
  2893. {
  2894. if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
  2895. token_scanner_list.end(),
  2896. scanner))
  2897. {
  2898. return false;
  2899. }
  2900. token_scanner_list.push_back(scanner);
  2901. return true;
  2902. }
  2903. inline bool register_modifier(lexer::token_modifier* modifier)
  2904. {
  2905. if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
  2906. token_modifier_list.end(),
  2907. modifier))
  2908. {
  2909. return false;
  2910. }
  2911. token_modifier_list.push_back(modifier);
  2912. return true;
  2913. }
  2914. inline bool register_joiner(lexer::token_joiner* joiner)
  2915. {
  2916. if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
  2917. token_joiner_list.end(),
  2918. joiner))
  2919. {
  2920. return false;
  2921. }
  2922. token_joiner_list.push_back(joiner);
  2923. return true;
  2924. }
  2925. inline bool register_inserter(lexer::token_inserter* inserter)
  2926. {
  2927. if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
  2928. token_inserter_list.end(),
  2929. inserter))
  2930. {
  2931. return false;
  2932. }
  2933. token_inserter_list.push_back(inserter);
  2934. return true;
  2935. }
  2936. inline bool run_modifiers(lexer::generator& g)
  2937. {
  2938. error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
  2939. bool result = true;
  2940. for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
  2941. {
  2942. lexer::token_modifier& modifier = (*token_modifier_list[i]);
  2943. modifier.reset();
  2944. modifier.process(g);
  2945. if (!modifier.result())
  2946. {
  2947. error_token_modifier = token_modifier_list[i];
  2948. return false;
  2949. }
  2950. }
  2951. return result;
  2952. }
  2953. inline bool run_joiners(lexer::generator& g)
  2954. {
  2955. error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
  2956. bool result = true;
  2957. for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
  2958. {
  2959. lexer::token_joiner& joiner = (*token_joiner_list[i]);
  2960. joiner.reset();
  2961. joiner.process(g);
  2962. if (!joiner.result())
  2963. {
  2964. error_token_joiner = token_joiner_list[i];
  2965. return false;
  2966. }
  2967. }
  2968. return result;
  2969. }
  2970. inline bool run_inserters(lexer::generator& g)
  2971. {
  2972. error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
  2973. bool result = true;
  2974. for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
  2975. {
  2976. lexer::token_inserter& inserter = (*token_inserter_list[i]);
  2977. inserter.reset();
  2978. inserter.process(g);
  2979. if (!inserter.result())
  2980. {
  2981. error_token_inserter = token_inserter_list[i];
  2982. return false;
  2983. }
  2984. }
  2985. return result;
  2986. }
  2987. inline bool run_scanners(lexer::generator& g)
  2988. {
  2989. error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
  2990. bool result = true;
  2991. for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
  2992. {
  2993. lexer::token_scanner& scanner = (*token_scanner_list[i]);
  2994. scanner.reset();
  2995. scanner.process(g);
  2996. if (!scanner.result())
  2997. {
  2998. error_token_scanner = token_scanner_list[i];
  2999. return false;
  3000. }
  3001. }
  3002. return result;
  3003. }
  3004. std::vector<lexer::token_scanner*> token_scanner_list;
  3005. std::vector<lexer::token_modifier*> token_modifier_list;
  3006. std::vector<lexer::token_joiner*> token_joiner_list;
  3007. std::vector<lexer::token_inserter*> token_inserter_list;
  3008. lexer::token_scanner* error_token_scanner;
  3009. lexer::token_modifier* error_token_modifier;
  3010. lexer::token_joiner* error_token_joiner;
  3011. lexer::token_inserter* error_token_inserter;
  3012. };
  3013. }
  3014. }
  3015. template <typename T>
  3016. struct type_store
  3017. {
  3018. enum store_type
  3019. {
  3020. e_unknown,
  3021. e_scalar,
  3022. e_vector,
  3023. e_string
  3024. };
  3025. type_store()
  3026. : size(0),
  3027. data(0),
  3028. type(e_unknown)
  3029. {}
  3030. std::size_t size;
  3031. void* data;
  3032. store_type type;
  3033. class parameter_list
  3034. {
  3035. public:
  3036. parameter_list(std::vector<type_store>& pl)
  3037. : parameter_list_(pl)
  3038. {}
  3039. inline bool empty() const
  3040. {
  3041. return parameter_list_.empty();
  3042. }
  3043. inline std::size_t size() const
  3044. {
  3045. return parameter_list_.size();
  3046. }
  3047. inline type_store& operator[](const std::size_t& index)
  3048. {
  3049. return parameter_list_[index];
  3050. }
  3051. inline const type_store& operator[](const std::size_t& index) const
  3052. {
  3053. return parameter_list_[index];
  3054. }
  3055. inline type_store& front()
  3056. {
  3057. return parameter_list_[0];
  3058. }
  3059. inline const type_store& front() const
  3060. {
  3061. return parameter_list_[0];
  3062. }
  3063. inline type_store& back()
  3064. {
  3065. return parameter_list_[size() - 1];
  3066. }
  3067. inline const type_store& back() const
  3068. {
  3069. return parameter_list_[size() - 1];
  3070. }
  3071. private:
  3072. std::vector<type_store>& parameter_list_;
  3073. };
  3074. template <typename ViewType>
  3075. struct type_view
  3076. {
  3077. typedef type_store<T> type_store_t;
  3078. typedef ViewType value_t;
  3079. type_view(type_store_t& ts)
  3080. : ts_(ts),
  3081. data_(reinterpret_cast<value_t*>(ts_.data))
  3082. {}
  3083. inline std::size_t size() const
  3084. {
  3085. return ts_.size;
  3086. }
  3087. inline value_t& operator[](const std::size_t& i)
  3088. {
  3089. return data_[i];
  3090. }
  3091. inline const value_t& operator[](const std::size_t& i) const
  3092. {
  3093. return data_[i];
  3094. }
  3095. inline const value_t* begin() const { return data_; }
  3096. inline value_t* begin() { return data_; }
  3097. inline const value_t* end() const { return data_ + ts_.size; }
  3098. inline value_t* end() { return data_ + ts_.size; }
  3099. type_store_t& ts_;
  3100. value_t* data_;
  3101. };
  3102. typedef type_view<T> vector_view;
  3103. typedef type_view<char> string_view;
  3104. struct scalar_view
  3105. {
  3106. typedef type_store<T> type_store_t;
  3107. typedef T value_t;
  3108. scalar_view(type_store_t& ts)
  3109. : v_(*reinterpret_cast<value_t*>(ts.data))
  3110. {}
  3111. value_t& operator()()
  3112. {
  3113. return v_;
  3114. }
  3115. const value_t& operator()() const
  3116. {
  3117. return v_;
  3118. }
  3119. T& v_;
  3120. };
  3121. };
  3122. template <typename StringView>
  3123. inline std::string to_str(const StringView& view)
  3124. {
  3125. return std::string(view.begin(),view.size());
  3126. }
  3127. namespace details
  3128. {
  3129. enum operator_type
  3130. {
  3131. e_default , e_null , e_add , e_sub ,
  3132. e_mul , e_div , e_mod , e_pow ,
  3133. e_atan2 , e_min , e_max , e_avg ,
  3134. e_sum , e_prod , e_lt , e_lte ,
  3135. e_eq , e_equal , e_ne , e_nequal ,
  3136. e_gte , e_gt , e_and , e_nand ,
  3137. e_or , e_nor , e_xor , e_xnor ,
  3138. e_mand , e_mor , e_scand , e_scor ,
  3139. e_shr , e_shl , e_abs , e_acos ,
  3140. e_acosh , e_asin , e_asinh , e_atan ,
  3141. e_atanh , e_ceil , e_cos , e_cosh ,
  3142. e_exp , e_expm1 , e_floor , e_log ,
  3143. e_log10 , e_log2 , e_log1p , e_logn ,
  3144. e_neg , e_pos , e_round , e_roundn ,
  3145. e_root , e_sqrt , e_sin , e_sinc ,
  3146. e_sinh , e_sec , e_csc , e_tan ,
  3147. e_tanh , e_cot , e_clamp , e_iclamp ,
  3148. e_inrange , e_sgn , e_r2d , e_d2r ,
  3149. e_d2g , e_g2d , e_hypot , e_notl ,
  3150. e_erf , e_erfc , e_ncdf , e_frac ,
  3151. e_trunc , e_assign , e_addass , e_subass ,
  3152. e_mulass , e_divass , e_modass , e_in ,
  3153. e_like , e_ilike , e_multi , e_swap ,
  3154. // Do not add new functions/operators after this point.
  3155. e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
  3156. e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
  3157. e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
  3158. e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
  3159. e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
  3160. e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
  3161. e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
  3162. e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
  3163. e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
  3164. e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
  3165. e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
  3166. e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
  3167. e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
  3168. e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
  3169. e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
  3170. e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
  3171. e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
  3172. e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
  3173. e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
  3174. e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
  3175. e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083,
  3176. e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087,
  3177. e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091,
  3178. e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095,
  3179. e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099,
  3180. e_sffinal = 1100,
  3181. e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003,
  3182. e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007,
  3183. e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011,
  3184. e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015,
  3185. e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019,
  3186. e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023,
  3187. e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027,
  3188. e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031,
  3189. e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035,
  3190. e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
  3191. e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043,
  3192. e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
  3193. e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
  3194. e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
  3195. e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059
  3196. };
  3197. struct base_operation_t
  3198. {
  3199. base_operation_t(const operator_type t, const unsigned int& np)
  3200. : type(t),
  3201. num_params(np)
  3202. {}
  3203. operator_type type;
  3204. unsigned int num_params;
  3205. };
  3206. namespace numeric
  3207. {
  3208. namespace details
  3209. {
  3210. template <typename T>
  3211. inline T process_impl(const operator_type operation, const T arg)
  3212. {
  3213. switch (operation)
  3214. {
  3215. case e_abs : return numeric::abs (arg);
  3216. case e_acos : return numeric::acos (arg);
  3217. case e_acosh : return numeric::acosh(arg);
  3218. case e_asin : return numeric::asin (arg);
  3219. case e_asinh : return numeric::asinh(arg);
  3220. case e_atan : return numeric::atan (arg);
  3221. case e_atanh : return numeric::atanh(arg);
  3222. case e_ceil : return numeric::ceil (arg);
  3223. case e_cos : return numeric::cos (arg);
  3224. case e_cosh : return numeric::cosh (arg);
  3225. case e_exp : return numeric::exp (arg);
  3226. case e_expm1 : return numeric::expm1(arg);
  3227. case e_floor : return numeric::floor(arg);
  3228. case e_log : return numeric::log (arg);
  3229. case e_log10 : return numeric::log10(arg);
  3230. case e_log2 : return numeric::log2 (arg);
  3231. case e_log1p : return numeric::log1p(arg);
  3232. case e_neg : return numeric::neg (arg);
  3233. case e_pos : return numeric::pos (arg);
  3234. case e_round : return numeric::round(arg);
  3235. case e_sin : return numeric::sin (arg);
  3236. case e_sinc : return numeric::sinc (arg);
  3237. case e_sinh : return numeric::sinh (arg);
  3238. case e_sqrt : return numeric::sqrt (arg);
  3239. case e_tan : return numeric::tan (arg);
  3240. case e_tanh : return numeric::tanh (arg);
  3241. case e_cot : return numeric::cot (arg);
  3242. case e_sec : return numeric::sec (arg);
  3243. case e_csc : return numeric::csc (arg);
  3244. case e_r2d : return numeric::r2d (arg);
  3245. case e_d2r : return numeric::d2r (arg);
  3246. case e_d2g : return numeric::d2g (arg);
  3247. case e_g2d : return numeric::g2d (arg);
  3248. case e_notl : return numeric::notl (arg);
  3249. case e_sgn : return numeric::sgn (arg);
  3250. case e_erf : return numeric::erf (arg);
  3251. case e_erfc : return numeric::erfc (arg);
  3252. case e_ncdf : return numeric::ncdf (arg);
  3253. case e_frac : return numeric::frac (arg);
  3254. case e_trunc : return numeric::trunc(arg);
  3255. default : return std::numeric_limits<T>::quiet_NaN();
  3256. }
  3257. }
  3258. template <typename T>
  3259. inline T process_impl(const operator_type operation, const T arg0, const T arg1)
  3260. {
  3261. switch (operation)
  3262. {
  3263. case e_add : return (arg0 + arg1);
  3264. case e_sub : return (arg0 - arg1);
  3265. case e_mul : return (arg0 * arg1);
  3266. case e_div : return (arg0 / arg1);
  3267. case e_mod : return modulus<T>(arg0,arg1);
  3268. case e_pow : return pow<T>(arg0,arg1);
  3269. case e_atan2 : return atan2<T>(arg0,arg1);
  3270. case e_min : return std::min<T>(arg0,arg1);
  3271. case e_max : return std::max<T>(arg0,arg1);
  3272. case e_logn : return logn<T>(arg0,arg1);
  3273. case e_lt : return (arg0 < arg1) ? T(1) : T(0);
  3274. case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
  3275. case e_eq : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0);
  3276. case e_ne : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0);
  3277. case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
  3278. case e_gt : return (arg0 > arg1) ? T(1) : T(0);
  3279. case e_and : return and_opr<T> (arg0,arg1);
  3280. case e_nand : return nand_opr<T>(arg0,arg1);
  3281. case e_or : return or_opr<T> (arg0,arg1);
  3282. case e_nor : return nor_opr<T> (arg0,arg1);
  3283. case e_xor : return xor_opr<T> (arg0,arg1);
  3284. case e_xnor : return xnor_opr<T>(arg0,arg1);
  3285. case e_root : return root<T> (arg0,arg1);
  3286. case e_roundn : return roundn<T> (arg0,arg1);
  3287. case e_equal : return equal<T> (arg0,arg1);
  3288. case e_nequal : return nequal<T> (arg0,arg1);
  3289. case e_hypot : return hypot<T> (arg0,arg1);
  3290. case e_shr : return shr<T> (arg0,arg1);
  3291. case e_shl : return shl<T> (arg0,arg1);
  3292. default : return std::numeric_limits<T>::quiet_NaN();
  3293. }
  3294. }
  3295. template <typename T>
  3296. inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
  3297. {
  3298. switch (operation)
  3299. {
  3300. case e_add : return (arg0 + arg1);
  3301. case e_sub : return (arg0 - arg1);
  3302. case e_mul : return (arg0 * arg1);
  3303. case e_div : return (arg0 / arg1);
  3304. case e_mod : return arg0 % arg1;
  3305. case e_pow : return pow<T>(arg0,arg1);
  3306. case e_min : return std::min<T>(arg0,arg1);
  3307. case e_max : return std::max<T>(arg0,arg1);
  3308. case e_logn : return logn<T>(arg0,arg1);
  3309. case e_lt : return (arg0 < arg1) ? T(1) : T(0);
  3310. case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
  3311. case e_eq : return (arg0 == arg1) ? T(1) : T(0);
  3312. case e_ne : return (arg0 != arg1) ? T(1) : T(0);
  3313. case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
  3314. case e_gt : return (arg0 > arg1) ? T(1) : T(0);
  3315. case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
  3316. case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
  3317. case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
  3318. case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
  3319. case e_xor : return arg0 ^ arg1;
  3320. case e_xnor : return !(arg0 ^ arg1);
  3321. case e_root : return root<T>(arg0,arg1);
  3322. case e_equal : return arg0 == arg1;
  3323. case e_nequal : return arg0 != arg1;
  3324. case e_hypot : return hypot<T>(arg0,arg1);
  3325. case e_shr : return arg0 >> arg1;
  3326. case e_shl : return arg0 << arg1;
  3327. default : return std::numeric_limits<T>::quiet_NaN();
  3328. }
  3329. }
  3330. }
  3331. template <typename T>
  3332. inline T process(const operator_type operation, const T arg)
  3333. {
  3334. return exprtk::details::numeric::details::process_impl(operation,arg);
  3335. }
  3336. template <typename T>
  3337. inline T process(const operator_type operation, const T arg0, const T arg1)
  3338. {
  3339. return exprtk::details::numeric::details::process_impl(operation,arg0,arg1);
  3340. }
  3341. }
  3342. template <typename T>
  3343. class expression_node
  3344. {
  3345. public:
  3346. enum node_type
  3347. {
  3348. e_none , e_null , e_constant , e_unary ,
  3349. e_binary , e_binary_ext , e_trinary , e_quaternary ,
  3350. e_quinary , e_senary , e_vararg , e_conditional ,
  3351. e_while , e_repeat , e_for , e_switch ,
  3352. e_mswitch , e_variable , e_stringvar , e_stringconst ,
  3353. e_stringvarrng , e_cstringvarrng, e_strgenrange , e_strconcat ,
  3354. e_stringvarsize, e_strswap , e_stringsize , e_function ,
  3355. e_vafunction , e_genfunction , e_strfunction , e_add ,
  3356. e_sub , e_mul , e_div , e_mod ,
  3357. e_pow , e_lt , e_lte , e_gt ,
  3358. e_gte , e_eq , e_ne , e_and ,
  3359. e_nand , e_or , e_nor , e_xor ,
  3360. e_xnor , e_in , e_like , e_ilike ,
  3361. e_inranges , e_ipow , e_ipowinv , e_abs ,
  3362. e_acos , e_acosh , e_asin , e_asinh ,
  3363. e_atan , e_atanh , e_ceil , e_cos ,
  3364. e_cosh , e_exp , e_expm1 , e_floor ,
  3365. e_log , e_log10 , e_log2 , e_log1p ,
  3366. e_neg , e_pos , e_round , e_sin ,
  3367. e_sinc , e_sinh , e_sqrt , e_tan ,
  3368. e_tanh , e_cot , e_sec , e_csc ,
  3369. e_r2d , e_d2r , e_d2g , e_g2d ,
  3370. e_notl , e_sgn , e_erf , e_erfc ,
  3371. e_ncdf , e_frac , e_trunc , e_uvouv ,
  3372. e_vov , e_cov , e_voc , e_vob ,
  3373. e_bov , e_cob , e_boc , e_vovov ,
  3374. e_vovoc , e_vocov , e_covov , e_covoc ,
  3375. e_vovovov , e_vovovoc , e_vovocov , e_vocovov ,
  3376. e_covovov , e_covocov , e_vocovoc , e_covovoc ,
  3377. e_vococov , e_sf3ext , e_sf4ext , e_nulleq ,
  3378. e_strass , e_vector , e_vecelem , e_vecdefass ,
  3379. e_vecvalass , e_vecvecass , e_vecopvalass , e_vecopvecass ,
  3380. e_vecfunc , e_vecvecswap , e_vecvecineq , e_vecvalineq ,
  3381. e_valvecineq , e_vecvecarith , e_vecvalarith , e_valvecarith ,
  3382. e_vecunaryop , e_break , e_continue , e_swap
  3383. };
  3384. typedef T value_type;
  3385. typedef expression_node<T>* expression_ptr;
  3386. virtual ~expression_node()
  3387. {}
  3388. inline virtual T value() const
  3389. {
  3390. return std::numeric_limits<T>::quiet_NaN();
  3391. }
  3392. inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
  3393. {
  3394. return reinterpret_cast<expression_ptr>(index * 0);
  3395. }
  3396. inline virtual node_type type() const
  3397. {
  3398. return e_none;
  3399. }
  3400. };
  3401. template <typename T>
  3402. inline bool is_generally_string_node(const expression_node<T>* node);
  3403. inline bool is_true(const double v)
  3404. {
  3405. return std::not_equal_to<double>()(0.0,v);
  3406. }
  3407. inline bool is_true(const long double v)
  3408. {
  3409. return std::not_equal_to<long double>()(0.0L,v);
  3410. }
  3411. inline bool is_true(const float v)
  3412. {
  3413. return std::not_equal_to<float>()(0.0f,v);
  3414. }
  3415. template <typename T>
  3416. inline bool is_true(const expression_node<T>* node)
  3417. {
  3418. return std::not_equal_to<T>()(T(0),node->value());
  3419. }
  3420. template <typename T>
  3421. inline bool is_false(const expression_node<T>* node)
  3422. {
  3423. return std::equal_to<T>()(T(0),node->value());
  3424. }
  3425. template <typename T>
  3426. inline bool is_unary_node(const expression_node<T>* node)
  3427. {
  3428. return node && (details::expression_node<T>::e_unary == node->type());
  3429. }
  3430. template <typename T>
  3431. inline bool is_neg_unary_node(const expression_node<T>* node)
  3432. {
  3433. return node && (details::expression_node<T>::e_neg == node->type());
  3434. }
  3435. template <typename T>
  3436. inline bool is_binary_node(const expression_node<T>* node)
  3437. {
  3438. return node && (details::expression_node<T>::e_binary == node->type());
  3439. }
  3440. template <typename T>
  3441. inline bool is_variable_node(const expression_node<T>* node)
  3442. {
  3443. return node && (details::expression_node<T>::e_variable == node->type());
  3444. }
  3445. template <typename T>
  3446. inline bool is_ivariable_node(const expression_node<T>* node)
  3447. {
  3448. return node &&
  3449. (
  3450. details::expression_node<T>::e_variable == node->type() ||
  3451. details::expression_node<T>::e_vecelem == node->type()
  3452. );
  3453. }
  3454. template <typename T>
  3455. inline bool is_vector_elem_node(const expression_node<T>* node)
  3456. {
  3457. return node && (details::expression_node<T>::e_vecelem == node->type());
  3458. }
  3459. template <typename T>
  3460. inline bool is_vector_node(const expression_node<T>* node)
  3461. {
  3462. return node && (details::expression_node<T>::e_vector == node->type());
  3463. }
  3464. template <typename T>
  3465. inline bool is_ivector_node(const expression_node<T>* node)
  3466. {
  3467. if (node)
  3468. {
  3469. switch (node->type())
  3470. {
  3471. case details::expression_node<T>::e_vector :
  3472. case details::expression_node<T>::e_vecvalass :
  3473. case details::expression_node<T>::e_vecvecass :
  3474. case details::expression_node<T>::e_vecopvalass :
  3475. case details::expression_node<T>::e_vecopvecass :
  3476. case details::expression_node<T>::e_vecvecswap :
  3477. case details::expression_node<T>::e_vecvecarith :
  3478. case details::expression_node<T>::e_vecvalarith :
  3479. case details::expression_node<T>::e_valvecarith :
  3480. case details::expression_node<T>::e_vecunaryop : return true;
  3481. default : return false;
  3482. }
  3483. }
  3484. else
  3485. return false;
  3486. }
  3487. template <typename T>
  3488. inline bool is_constant_node(const expression_node<T>* node)
  3489. {
  3490. return node && (details::expression_node<T>::e_constant == node->type());
  3491. }
  3492. template <typename T>
  3493. inline bool is_null_node(const expression_node<T>* node)
  3494. {
  3495. return node && (details::expression_node<T>::e_null == node->type());
  3496. }
  3497. template <typename T>
  3498. inline bool is_break_node(const expression_node<T>* node)
  3499. {
  3500. return node && (details::expression_node<T>::e_break == node->type());
  3501. }
  3502. template <typename T>
  3503. inline bool is_continue_node(const expression_node<T>* node)
  3504. {
  3505. return node && (details::expression_node<T>::e_continue == node->type());
  3506. }
  3507. template <typename T>
  3508. inline bool is_swap_node(const expression_node<T>* node)
  3509. {
  3510. return node && (details::expression_node<T>::e_swap == node->type());
  3511. }
  3512. template <typename T>
  3513. inline bool is_function(const expression_node<T>* node)
  3514. {
  3515. return node && (details::expression_node<T>::e_function == node->type());
  3516. }
  3517. template <typename T> class unary_node;
  3518. template <typename T>
  3519. inline bool is_negate_node(const expression_node<T>* node)
  3520. {
  3521. if (node && is_unary_node(node))
  3522. {
  3523. return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
  3524. }
  3525. else
  3526. return false;
  3527. }
  3528. template <typename T>
  3529. inline bool branch_deletable(expression_node<T>* node)
  3530. {
  3531. return !is_variable_node(node) &&
  3532. !is_string_node (node) ;
  3533. }
  3534. template <std::size_t N, typename T>
  3535. inline bool all_nodes_valid(expression_node<T>* (&b)[N])
  3536. {
  3537. for (std::size_t i = 0; i < N; ++i)
  3538. {
  3539. if (0 == b[i]) return false;
  3540. }
  3541. return true;
  3542. }
  3543. template <typename T,
  3544. typename Allocator,
  3545. template <typename,typename> class Sequence>
  3546. inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b)
  3547. {
  3548. for (std::size_t i = 0; i < b.size(); ++i)
  3549. {
  3550. if (0 == b[i]) return false;
  3551. }
  3552. return true;
  3553. }
  3554. template <std::size_t N, typename T>
  3555. inline bool all_nodes_variables(expression_node<T>* (&b)[N])
  3556. {
  3557. for (std::size_t i = 0; i < N; ++i)
  3558. {
  3559. if (0 == b[i])
  3560. return false;
  3561. else if (!is_variable_node(b[i]))
  3562. return false;
  3563. }
  3564. return true;
  3565. }
  3566. template <typename T,
  3567. typename Allocator,
  3568. template <typename,typename> class Sequence>
  3569. inline bool all_nodes_variables(Sequence<expression_node<T>*,Allocator>& b)
  3570. {
  3571. for (std::size_t i = 0; i < b.size(); ++i)
  3572. {
  3573. if (0 == b[i])
  3574. return false;
  3575. else if (!is_variable_node(b[i]))
  3576. return false;
  3577. }
  3578. return true;
  3579. }
  3580. template <typename NodeAllocator, typename T, std::size_t N>
  3581. inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N])
  3582. {
  3583. for (std::size_t i = 0; i < N; ++i)
  3584. {
  3585. free_node(node_allocator,b[i]);
  3586. }
  3587. }
  3588. template <typename NodeAllocator,
  3589. typename T,
  3590. typename Allocator,
  3591. template <typename,typename> class Sequence>
  3592. inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b)
  3593. {
  3594. for (std::size_t i = 0; i < b.size(); ++i)
  3595. {
  3596. free_node(node_allocator,b[i]);
  3597. }
  3598. b.clear();
  3599. }
  3600. template <typename NodeAllocator, typename T>
  3601. inline void free_node(NodeAllocator& node_allocator, expression_node<T>*& node, const bool force_delete = false)
  3602. {
  3603. if (0 != node)
  3604. {
  3605. if (
  3606. (is_variable_node(node) || is_string_node(node)) ||
  3607. force_delete
  3608. )
  3609. return;
  3610. node_allocator.free(node);
  3611. node = 0;
  3612. }
  3613. }
  3614. template <typename Type>
  3615. class vector_holder
  3616. {
  3617. private:
  3618. typedef Type value_type;
  3619. typedef value_type* value_ptr;
  3620. typedef const value_ptr const_value_ptr;
  3621. class vector_holder_base
  3622. {
  3623. public:
  3624. virtual ~vector_holder_base(){}
  3625. inline value_ptr operator[](const std::size_t& index) const
  3626. {
  3627. return value_at(index);
  3628. }
  3629. inline std::size_t size() const
  3630. {
  3631. return vector_size();
  3632. }
  3633. protected:
  3634. virtual value_ptr value_at(const std::size_t&) const = 0;
  3635. virtual std::size_t vector_size() const = 0;
  3636. };
  3637. class array_vector_impl : public vector_holder_base
  3638. {
  3639. public:
  3640. array_vector_impl(const Type* vec, const std::size_t& vec_size)
  3641. : vec_(vec),
  3642. size_(vec_size)
  3643. {}
  3644. protected:
  3645. value_ptr value_at(const std::size_t& index) const
  3646. {
  3647. if (index < size_)
  3648. return const_cast<const_value_ptr>(vec_ + index);
  3649. else
  3650. return const_value_ptr(0);
  3651. }
  3652. std::size_t vector_size() const
  3653. {
  3654. return size_;
  3655. }
  3656. private:
  3657. array_vector_impl operator=(const array_vector_impl&);
  3658. const Type* vec_;
  3659. const std::size_t size_;
  3660. };
  3661. template <typename Allocator,
  3662. template <typename,typename> class Sequence>
  3663. class sequence_vector_impl : public vector_holder_base
  3664. {
  3665. public:
  3666. typedef Sequence<Type,Allocator> sequence_t;
  3667. sequence_vector_impl(sequence_t& seq)
  3668. : sequence_(seq)
  3669. {}
  3670. protected:
  3671. value_ptr value_at(const std::size_t& index) const
  3672. {
  3673. return (index < sequence_.size()) ? (&sequence_[index]) : const_value_ptr(0);
  3674. }
  3675. std::size_t vector_size() const
  3676. {
  3677. return sequence_.size();
  3678. }
  3679. private:
  3680. sequence_vector_impl operator=(const sequence_vector_impl&);
  3681. sequence_t& sequence_;
  3682. };
  3683. public:
  3684. vector_holder(Type* vec, const std::size_t& vec_size)
  3685. : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
  3686. {}
  3687. template <typename Allocator>
  3688. vector_holder(std::vector<Type,Allocator>& vec)
  3689. : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
  3690. {}
  3691. template <typename Allocator>
  3692. vector_holder(std::deque<Type,Allocator>& deq)
  3693. : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::deque>(deq))
  3694. {}
  3695. inline value_ptr operator[](const std::size_t& index) const
  3696. {
  3697. return (*vector_holder_base_)[index];
  3698. }
  3699. inline std::size_t size() const
  3700. {
  3701. return vector_holder_base_->size();
  3702. }
  3703. private:
  3704. mutable vector_holder_base* vector_holder_base_;
  3705. unsigned char buffer[64];
  3706. };
  3707. template <typename T>
  3708. class null_node : public expression_node<T>
  3709. {
  3710. public:
  3711. inline T value() const
  3712. {
  3713. return std::numeric_limits<T>::quiet_NaN();
  3714. }
  3715. inline typename expression_node<T>::node_type type() const
  3716. {
  3717. return expression_node<T>::e_null;
  3718. }
  3719. };
  3720. template <typename T>
  3721. class null_eq_node : public expression_node<T>
  3722. {
  3723. public:
  3724. typedef expression_node<T>* expression_ptr;
  3725. null_eq_node(expression_ptr brnch, const bool equality = true)
  3726. : branch_(brnch),
  3727. branch_deletable_(branch_deletable(branch_)),
  3728. equality_(equality)
  3729. {}
  3730. ~null_eq_node()
  3731. {
  3732. if (branch_ && branch_deletable_)
  3733. {
  3734. delete branch_;
  3735. branch_ = 0;
  3736. }
  3737. }
  3738. inline T value() const
  3739. {
  3740. const T v = branch_->value();
  3741. const bool result = details::numeric::is_nan(v);
  3742. if (result)
  3743. return (equality_) ? T(1) : T(0);
  3744. else
  3745. return (equality_) ? T(0) : T(1);
  3746. }
  3747. inline typename expression_node<T>::node_type type() const
  3748. {
  3749. return expression_node<T>::e_nulleq;
  3750. }
  3751. inline operator_type operation() const
  3752. {
  3753. return details::e_eq;
  3754. }
  3755. inline expression_node<T>* branch(const std::size_t&) const
  3756. {
  3757. return branch_;
  3758. }
  3759. private:
  3760. expression_ptr branch_;
  3761. bool branch_deletable_;
  3762. bool equality_;
  3763. };
  3764. template <typename T>
  3765. class literal_node : public expression_node<T>
  3766. {
  3767. public:
  3768. explicit literal_node(const T& v)
  3769. : value_(v)
  3770. {}
  3771. inline T value() const
  3772. {
  3773. return value_;
  3774. }
  3775. inline typename expression_node<T>::node_type type() const
  3776. {
  3777. return expression_node<T>::e_constant;
  3778. }
  3779. inline expression_node<T>* branch(const std::size_t&) const
  3780. {
  3781. return reinterpret_cast<expression_node<T>*>(0);
  3782. }
  3783. private:
  3784. literal_node(literal_node<T>&) {}
  3785. literal_node<T>& operator=(literal_node<T>&) { return *this; }
  3786. const T value_;
  3787. };
  3788. template <typename T>
  3789. struct range_pack;
  3790. template <typename T>
  3791. struct range_data_type;
  3792. template <typename T>
  3793. class range_interface
  3794. {
  3795. public:
  3796. typedef range_pack<T> range_t;
  3797. virtual range_t& range_ref() = 0;
  3798. virtual const range_t& range_ref() const = 0;
  3799. };
  3800. template <typename T>
  3801. class string_base_node
  3802. {
  3803. public:
  3804. typedef range_data_type<T> range_data_type_t;
  3805. virtual std::string str () const = 0;
  3806. virtual const char* base() const = 0;
  3807. virtual std::size_t size() const = 0;
  3808. };
  3809. template <typename T>
  3810. class string_literal_node : public expression_node <T>,
  3811. public string_base_node<T>,
  3812. public range_interface <T>
  3813. {
  3814. public:
  3815. typedef range_pack<T> range_t;
  3816. explicit string_literal_node(const std::string& v)
  3817. : value_(v)
  3818. {
  3819. rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  3820. rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
  3821. rp_.cache.first = rp_.n0_c.second;
  3822. rp_.cache.second = rp_.n1_c.second;
  3823. }
  3824. inline T value() const
  3825. {
  3826. return std::numeric_limits<T>::quiet_NaN();
  3827. }
  3828. inline typename expression_node<T>::node_type type() const
  3829. {
  3830. return expression_node<T>::e_stringconst;
  3831. }
  3832. inline expression_node<T>* branch(const std::size_t&) const
  3833. {
  3834. return reinterpret_cast<expression_node<T>*>(0);
  3835. }
  3836. std::string str() const
  3837. {
  3838. return value_;
  3839. }
  3840. const char* base() const
  3841. {
  3842. return value_.data();
  3843. }
  3844. std::size_t size() const
  3845. {
  3846. return value_.size();
  3847. }
  3848. range_t& range_ref()
  3849. {
  3850. return rp_;
  3851. }
  3852. const range_t& range_ref() const
  3853. {
  3854. return rp_;
  3855. }
  3856. private:
  3857. string_literal_node(const string_literal_node<T>&);
  3858. string_literal_node<T>& operator=(const string_literal_node<T>&);
  3859. const std::string value_;
  3860. range_t rp_;
  3861. };
  3862. template <typename T>
  3863. class unary_node : public expression_node<T>
  3864. {
  3865. public:
  3866. typedef expression_node<T>* expression_ptr;
  3867. unary_node(const operator_type& opr,
  3868. expression_ptr brnch)
  3869. : operation_(opr),
  3870. branch_(brnch),
  3871. branch_deletable_(branch_deletable(branch_))
  3872. {}
  3873. ~unary_node()
  3874. {
  3875. if (branch_ && branch_deletable_)
  3876. {
  3877. delete branch_;
  3878. branch_ = 0;
  3879. }
  3880. }
  3881. inline T value() const
  3882. {
  3883. const T arg = branch_->value();
  3884. return numeric::process<T>(operation_,arg);
  3885. }
  3886. inline typename expression_node<T>::node_type type() const
  3887. {
  3888. return expression_node<T>::e_unary;
  3889. }
  3890. inline operator_type operation() const
  3891. {
  3892. return operation_;
  3893. }
  3894. inline expression_node<T>* branch(const std::size_t&) const
  3895. {
  3896. return branch_;
  3897. }
  3898. inline void release()
  3899. {
  3900. branch_deletable_ = false;
  3901. }
  3902. protected:
  3903. operator_type operation_;
  3904. expression_ptr branch_;
  3905. bool branch_deletable_;
  3906. };
  3907. template <typename T, std::size_t D, bool B>
  3908. struct construct_branch_pair
  3909. {
  3910. template <std::size_t N>
  3911. static inline void process(std::pair<expression_node<T>*,bool> (&)[N], expression_node<T>*)
  3912. {}
  3913. };
  3914. template <typename T, std::size_t D>
  3915. struct construct_branch_pair<T,D,true>
  3916. {
  3917. template <std::size_t N>
  3918. static inline void process(std::pair<expression_node<T>*,bool> (&branch)[N], expression_node<T>* b)
  3919. {
  3920. if (b)
  3921. {
  3922. branch[D] = std::make_pair(b,branch_deletable(b));
  3923. }
  3924. }
  3925. };
  3926. template <std::size_t N, typename T>
  3927. inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
  3928. expression_node<T>* b0,
  3929. expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
  3930. expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
  3931. expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
  3932. expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
  3933. expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
  3934. expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
  3935. expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
  3936. expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
  3937. expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
  3938. {
  3939. construct_branch_pair<T,0,(N > 0)>::process(branch,b0);
  3940. construct_branch_pair<T,1,(N > 1)>::process(branch,b1);
  3941. construct_branch_pair<T,2,(N > 2)>::process(branch,b2);
  3942. construct_branch_pair<T,3,(N > 3)>::process(branch,b3);
  3943. construct_branch_pair<T,4,(N > 4)>::process(branch,b4);
  3944. construct_branch_pair<T,5,(N > 5)>::process(branch,b5);
  3945. construct_branch_pair<T,6,(N > 6)>::process(branch,b6);
  3946. construct_branch_pair<T,7,(N > 7)>::process(branch,b7);
  3947. construct_branch_pair<T,8,(N > 8)>::process(branch,b8);
  3948. construct_branch_pair<T,9,(N > 9)>::process(branch,b9);
  3949. }
  3950. struct cleanup_branches
  3951. {
  3952. template <typename T, std::size_t N>
  3953. static inline void execute(std::pair<expression_node<T>*,bool> (&branch)[N])
  3954. {
  3955. for (std::size_t i = 0; i < N; ++i)
  3956. {
  3957. if (branch[i].first && branch[i].second)
  3958. {
  3959. delete branch[i].first;
  3960. branch[i].first = 0;
  3961. }
  3962. }
  3963. }
  3964. template <typename T,
  3965. typename Allocator,
  3966. template <typename,typename> class Sequence>
  3967. static inline void execute(Sequence<std::pair<expression_node<T>*,bool>,Allocator>& branch)
  3968. {
  3969. for (std::size_t i = 0; i < branch.size(); ++i)
  3970. {
  3971. if (branch[i].first && branch[i].second)
  3972. {
  3973. delete branch[i].first;
  3974. branch[i].first = 0;
  3975. }
  3976. }
  3977. }
  3978. };
  3979. template <typename T>
  3980. class binary_node : public expression_node<T>
  3981. {
  3982. public:
  3983. typedef expression_node<T>* expression_ptr;
  3984. typedef std::pair<expression_ptr,bool> branch_t;
  3985. binary_node(const operator_type& opr,
  3986. expression_ptr branch0,
  3987. expression_ptr branch1)
  3988. : operation_(opr)
  3989. {
  3990. init_branches<2>(branch_,branch0,branch1);
  3991. }
  3992. ~binary_node()
  3993. {
  3994. cleanup_branches::execute<T,2>(branch_);
  3995. }
  3996. inline T value() const
  3997. {
  3998. const T arg0 = branch_[0].first->value();
  3999. const T arg1 = branch_[1].first->value();
  4000. return numeric::process<T>(operation_,arg0,arg1);
  4001. }
  4002. inline typename expression_node<T>::node_type type() const
  4003. {
  4004. return expression_node<T>::e_binary;
  4005. }
  4006. inline operator_type operation()
  4007. {
  4008. return operation_;
  4009. }
  4010. inline expression_node<T>* branch(const std::size_t& index = 0) const
  4011. {
  4012. if (0 == index)
  4013. return branch_[0].first;
  4014. else if (1 == index)
  4015. return branch_[1].first;
  4016. else
  4017. return reinterpret_cast<expression_ptr>(0);
  4018. }
  4019. protected:
  4020. operator_type operation_;
  4021. branch_t branch_[2];
  4022. };
  4023. template <typename T, typename Operation>
  4024. class binary_ext_node : public expression_node<T>
  4025. {
  4026. public:
  4027. typedef expression_node<T>* expression_ptr;
  4028. typedef std::pair<expression_ptr,bool> branch_t;
  4029. binary_ext_node(expression_ptr branch0, expression_ptr branch1)
  4030. {
  4031. init_branches<2>(branch_,branch0,branch1);
  4032. }
  4033. ~binary_ext_node()
  4034. {
  4035. cleanup_branches::execute<T,2>(branch_);
  4036. }
  4037. inline T value() const
  4038. {
  4039. const T arg0 = branch_[0].first->value();
  4040. const T arg1 = branch_[1].first->value();
  4041. return Operation::process(arg0,arg1);
  4042. }
  4043. inline typename expression_node<T>::node_type type() const
  4044. {
  4045. return expression_node<T>::e_binary_ext;
  4046. }
  4047. inline operator_type operation()
  4048. {
  4049. return Operation::operation();
  4050. }
  4051. inline expression_node<T>* branch(const std::size_t& index = 0) const
  4052. {
  4053. if (0 == index)
  4054. return branch_[0].first;
  4055. else if (1 == index)
  4056. return branch_[1].first;
  4057. else
  4058. return reinterpret_cast<expression_ptr>(0);
  4059. }
  4060. protected:
  4061. branch_t branch_[2];
  4062. };
  4063. template <typename T>
  4064. class trinary_node : public expression_node<T>
  4065. {
  4066. public:
  4067. typedef expression_node<T>* expression_ptr;
  4068. typedef std::pair<expression_ptr,bool> branch_t;
  4069. trinary_node(const operator_type& opr,
  4070. expression_ptr branch0,
  4071. expression_ptr branch1,
  4072. expression_ptr branch2)
  4073. : operation_(opr)
  4074. {
  4075. init_branches<3>(branch_,branch0,branch1,branch2);
  4076. }
  4077. ~trinary_node()
  4078. {
  4079. cleanup_branches::execute<T,3>(branch_);
  4080. }
  4081. inline T value() const
  4082. {
  4083. const T arg0 = branch_[0].first->value();
  4084. const T arg1 = branch_[1].first->value();
  4085. const T arg2 = branch_[2].first->value();
  4086. switch (operation_)
  4087. {
  4088. case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
  4089. case e_min : return std::min<T>(std::min<T>(arg0,arg1),arg2);
  4090. case e_max : return std::max<T>(std::max<T>(arg0,arg1),arg2);
  4091. case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
  4092. case e_iclamp : if ((arg1 <= arg0) || (arg1 >= arg2))
  4093. return arg1;
  4094. else
  4095. return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2);
  4096. default : return std::numeric_limits<T>::quiet_NaN();
  4097. }
  4098. }
  4099. inline typename expression_node<T>::node_type type() const
  4100. {
  4101. return expression_node<T>::e_trinary;
  4102. }
  4103. protected:
  4104. operator_type operation_;
  4105. branch_t branch_[3];
  4106. };
  4107. template <typename T>
  4108. class quaternary_node : public expression_node<T>
  4109. {
  4110. public:
  4111. typedef expression_node<T>* expression_ptr;
  4112. typedef std::pair<expression_ptr,bool> branch_t;
  4113. quaternary_node(const operator_type& opr,
  4114. expression_ptr branch0,
  4115. expression_ptr branch1,
  4116. expression_ptr branch2,
  4117. expression_ptr branch3)
  4118. : operation_(opr)
  4119. {
  4120. init_branches<4>(branch_,branch0,branch1,branch2,branch3);
  4121. }
  4122. ~quaternary_node()
  4123. {
  4124. cleanup_branches::execute<T,4>(branch_);
  4125. }
  4126. inline T value() const
  4127. {
  4128. const T arg0 = branch_[0].first->value();
  4129. const T arg1 = branch_[1].first->value();
  4130. const T arg2 = branch_[2].first->value();
  4131. const T arg3 = branch_[3].first->value();
  4132. switch (operation_)
  4133. {
  4134. case e_min : return std::min<T>(std::min<T>(arg0,arg1),std::min<T>(arg2,arg3));
  4135. case e_max : return std::max<T>(std::max<T>(arg0,arg1),std::max<T>(arg2,arg3));
  4136. default : return std::numeric_limits<T>::quiet_NaN();
  4137. }
  4138. }
  4139. inline typename expression_node<T>::node_type type() const
  4140. {
  4141. return expression_node<T>::e_quaternary;
  4142. }
  4143. protected:
  4144. operator_type operation_;
  4145. branch_t branch_[4];
  4146. };
  4147. template <typename T>
  4148. class quinary_node : public expression_node<T>
  4149. {
  4150. public:
  4151. typedef expression_node<T>* expression_ptr;
  4152. typedef std::pair<expression_ptr,bool> branch_t;
  4153. quinary_node(const operator_type& opr,
  4154. expression_ptr branch0,
  4155. expression_ptr branch1,
  4156. expression_ptr branch2,
  4157. expression_ptr branch3,
  4158. expression_ptr branch4)
  4159. : operation_(opr)
  4160. {
  4161. init_branches<5>(branch_,branch0,branch1,branch2,branch3,branch4);
  4162. }
  4163. ~quinary_node()
  4164. {
  4165. cleanup_branches::execute<T,5>(branch_);
  4166. }
  4167. inline T value() const
  4168. {
  4169. const T arg0 = branch_[0].first->value();
  4170. const T arg1 = branch_[1].first->value();
  4171. const T arg2 = branch_[2].first->value();
  4172. const T arg3 = branch_[3].first->value();
  4173. const T arg4 = branch_[4].first->value();
  4174. switch (operation_)
  4175. {
  4176. case e_min : return std::min<T>(std::min<T>(std::min<T>(arg0,arg1),std::min<T>(arg2,arg3)),arg4);
  4177. case e_max : return std::max<T>(std::max<T>(std::max<T>(arg0,arg1),std::max<T>(arg2,arg3)),arg4);
  4178. default : return std::numeric_limits<T>::quiet_NaN();
  4179. }
  4180. }
  4181. inline typename expression_node<T>::node_type type() const
  4182. {
  4183. return expression_node<T>::e_quinary;
  4184. }
  4185. private:
  4186. operator_type operation_;
  4187. branch_t branch_[5];
  4188. };
  4189. template <typename T>
  4190. class senary_node : public expression_node<T>
  4191. {
  4192. public:
  4193. typedef expression_node<T>* expression_ptr;
  4194. typedef std::pair<expression_ptr,bool> branch_t;
  4195. senary_node(const operator_type& opr,
  4196. expression_ptr branch0,
  4197. expression_ptr branch1,
  4198. expression_ptr branch2,
  4199. expression_ptr branch3,
  4200. expression_ptr branch4,
  4201. expression_ptr branch5)
  4202. : operation_(opr)
  4203. {
  4204. init_branches<6>(branch_,branch0,branch1,branch2,branch3,branch4,branch5);
  4205. }
  4206. ~senary_node()
  4207. {
  4208. cleanup_branches::execute<T,6>(branch_);
  4209. }
  4210. inline T value() const
  4211. {
  4212. const T arg0 = branch_[0].first->value();
  4213. const T arg1 = branch_[1].first->value();
  4214. const T arg2 = branch_[2].first->value();
  4215. const T arg3 = branch_[3].first->value();
  4216. const T arg4 = branch_[4].first->value();
  4217. const T arg5 = branch_[5].first->value();
  4218. switch (operation_)
  4219. {
  4220. case e_min : return std::min<T>(std::min<T>(std::min<T>(arg0,arg1),std::min<T>(arg2,arg3)),std::min<T>(arg4,arg5));
  4221. case e_max : return std::max<T>(std::max<T>(std::max<T>(arg0,arg1),std::max<T>(arg2,arg3)),std::max<T>(arg4,arg5));
  4222. case e_default :
  4223. default : return std::numeric_limits<T>::quiet_NaN();
  4224. }
  4225. }
  4226. inline typename expression_node<T>::node_type type() const
  4227. {
  4228. return expression_node<T>::e_senary;
  4229. }
  4230. private:
  4231. operator_type operation_;
  4232. branch_t branch_[6];
  4233. };
  4234. template <typename T>
  4235. class conditional_node : public expression_node<T>
  4236. {
  4237. public:
  4238. typedef expression_node<T>* expression_ptr;
  4239. conditional_node(expression_ptr test,
  4240. expression_ptr consequent,
  4241. expression_ptr alternative)
  4242. : test_(test),
  4243. consequent_(consequent),
  4244. alternative_(alternative),
  4245. test_deletable_(branch_deletable(test_)),
  4246. consequent_deletable_(branch_deletable(consequent_)),
  4247. alternative_deletable_(branch_deletable(alternative_))
  4248. {}
  4249. ~conditional_node()
  4250. {
  4251. if (test_ && test_deletable_ ) delete test_;
  4252. if (consequent_ && consequent_deletable_ ) delete consequent_;
  4253. if (alternative_ && alternative_deletable_) delete alternative_;
  4254. }
  4255. inline T value() const
  4256. {
  4257. if (is_true(test_))
  4258. return consequent_->value();
  4259. else
  4260. return alternative_->value();
  4261. }
  4262. inline typename expression_node<T>::node_type type() const
  4263. {
  4264. return expression_node<T>::e_conditional;
  4265. }
  4266. private:
  4267. expression_ptr test_;
  4268. expression_ptr consequent_;
  4269. expression_ptr alternative_;
  4270. bool test_deletable_;
  4271. bool consequent_deletable_;
  4272. bool alternative_deletable_;
  4273. };
  4274. template <typename T>
  4275. class cons_conditional_node : public expression_node<T>
  4276. {
  4277. public:
  4278. // Consequent only conditional statement node
  4279. typedef expression_node<T>* expression_ptr;
  4280. cons_conditional_node(expression_ptr test,
  4281. expression_ptr consequent)
  4282. : test_(test),
  4283. consequent_(consequent),
  4284. test_deletable_(branch_deletable(test_)),
  4285. consequent_deletable_(branch_deletable(consequent_))
  4286. {}
  4287. ~cons_conditional_node()
  4288. {
  4289. if (test_ && test_deletable_ ) delete test_;
  4290. if (consequent_ && consequent_deletable_) delete consequent_;
  4291. }
  4292. inline T value() const
  4293. {
  4294. if (is_true(test_))
  4295. return consequent_->value();
  4296. else
  4297. return std::numeric_limits<T>::quiet_NaN();
  4298. }
  4299. inline typename expression_node<T>::node_type type() const
  4300. {
  4301. return expression_node<T>::e_conditional;
  4302. }
  4303. private:
  4304. expression_ptr test_;
  4305. expression_ptr consequent_;
  4306. bool test_deletable_;
  4307. bool consequent_deletable_;
  4308. };
  4309. #ifndef exprtk_disable_break_continue
  4310. template <typename T>
  4311. class break_exception : public std::exception
  4312. {
  4313. public:
  4314. break_exception(const T& v)
  4315. : value(v)
  4316. {}
  4317. T value;
  4318. };
  4319. class continue_exception : public std::exception
  4320. {};
  4321. template <typename T>
  4322. class break_node : public expression_node<T>
  4323. {
  4324. public:
  4325. typedef expression_node<T>* expression_ptr;
  4326. break_node(expression_ptr ret = expression_ptr(0))
  4327. : return_(ret),
  4328. return_deletable_(branch_deletable(return_))
  4329. {}
  4330. ~break_node()
  4331. {
  4332. if (return_deletable_)
  4333. {
  4334. delete return_;
  4335. }
  4336. }
  4337. inline T value() const
  4338. {
  4339. throw break_exception<T>(return_ ? return_->value() : std::numeric_limits<T>::quiet_NaN());
  4340. #ifndef _MSC_VER
  4341. return std::numeric_limits<T>::quiet_NaN();
  4342. #endif
  4343. }
  4344. inline typename expression_node<T>::node_type type() const
  4345. {
  4346. return expression_node<T>::e_break;
  4347. }
  4348. private:
  4349. expression_ptr return_;
  4350. bool return_deletable_;
  4351. };
  4352. template <typename T>
  4353. class continue_node : public expression_node<T>
  4354. {
  4355. public:
  4356. inline T value() const
  4357. {
  4358. throw continue_exception();
  4359. #ifndef _MSC_VER
  4360. return std::numeric_limits<T>::quiet_NaN();
  4361. #endif
  4362. }
  4363. inline typename expression_node<T>::node_type type() const
  4364. {
  4365. return expression_node<T>::e_break;
  4366. }
  4367. };
  4368. #endif
  4369. template <typename T>
  4370. class while_loop_node : public expression_node<T>
  4371. {
  4372. public:
  4373. typedef expression_node<T>* expression_ptr;
  4374. while_loop_node(expression_ptr condition, expression_ptr loop_body)
  4375. : condition_(condition),
  4376. loop_body_(loop_body),
  4377. condition_deletable_(branch_deletable(condition_)),
  4378. loop_body_deletable_(branch_deletable(loop_body_))
  4379. {}
  4380. ~while_loop_node()
  4381. {
  4382. if (condition_ && condition_deletable_)
  4383. {
  4384. delete condition_;
  4385. }
  4386. if (loop_body_ && loop_body_deletable_)
  4387. {
  4388. delete loop_body_;
  4389. }
  4390. }
  4391. inline T value() const
  4392. {
  4393. T result = T(0);
  4394. while (is_true(condition_))
  4395. {
  4396. result = loop_body_->value();
  4397. }
  4398. return result;
  4399. }
  4400. inline typename expression_node<T>::node_type type() const
  4401. {
  4402. return expression_node<T>::e_while;
  4403. }
  4404. private:
  4405. expression_ptr condition_;
  4406. expression_ptr loop_body_;
  4407. bool condition_deletable_;
  4408. bool loop_body_deletable_;
  4409. };
  4410. template <typename T>
  4411. class repeat_until_loop_node : public expression_node<T>
  4412. {
  4413. public:
  4414. typedef expression_node<T>* expression_ptr;
  4415. repeat_until_loop_node(expression_ptr condition, expression_ptr loop_body)
  4416. : condition_(condition),
  4417. loop_body_(loop_body),
  4418. condition_deletable_(branch_deletable(condition_)),
  4419. loop_body_deletable_(branch_deletable(loop_body_))
  4420. {}
  4421. ~repeat_until_loop_node()
  4422. {
  4423. if (condition_ && condition_deletable_)
  4424. {
  4425. delete condition_;
  4426. }
  4427. if (loop_body_ && loop_body_deletable_)
  4428. {
  4429. delete loop_body_;
  4430. }
  4431. }
  4432. inline T value() const
  4433. {
  4434. T result = T(0);
  4435. do
  4436. {
  4437. result = loop_body_->value();
  4438. }
  4439. while (is_false(condition_));
  4440. return result;
  4441. }
  4442. inline typename expression_node<T>::node_type type() const
  4443. {
  4444. return expression_node<T>::e_repeat;
  4445. }
  4446. private:
  4447. expression_ptr condition_;
  4448. expression_ptr loop_body_;
  4449. bool condition_deletable_;
  4450. bool loop_body_deletable_;
  4451. };
  4452. template <typename T>
  4453. class for_loop_node : public expression_node<T>
  4454. {
  4455. public:
  4456. typedef expression_node<T>* expression_ptr;
  4457. for_loop_node(expression_ptr initialiser,
  4458. expression_ptr condition,
  4459. expression_ptr incrementor,
  4460. expression_ptr loop_body)
  4461. : initialiser_(initialiser),
  4462. condition_ (condition),
  4463. incrementor_(incrementor),
  4464. loop_body_ (loop_body),
  4465. initialiser_deletable_(branch_deletable(initialiser_)),
  4466. condition_deletable_ (branch_deletable(condition_ )),
  4467. incrementor_deletable_(branch_deletable(incrementor_)),
  4468. loop_body_deletable_ (branch_deletable(loop_body_ ))
  4469. {}
  4470. ~for_loop_node()
  4471. {
  4472. if (initialiser_ && initialiser_deletable_)
  4473. {
  4474. delete initialiser_;
  4475. }
  4476. if (condition_ && condition_deletable_)
  4477. {
  4478. delete condition_;
  4479. }
  4480. if (incrementor_ && incrementor_deletable_)
  4481. {
  4482. delete incrementor_;
  4483. }
  4484. if (loop_body_ && loop_body_deletable_)
  4485. {
  4486. delete loop_body_;
  4487. }
  4488. }
  4489. inline T value() const
  4490. {
  4491. T result = T(0);
  4492. if (initialiser_)
  4493. initialiser_->value();
  4494. if (incrementor_)
  4495. {
  4496. while (is_true(condition_))
  4497. {
  4498. result = loop_body_->value();
  4499. incrementor_->value();
  4500. }
  4501. }
  4502. else
  4503. {
  4504. while (is_true(condition_))
  4505. {
  4506. result = loop_body_->value();
  4507. }
  4508. }
  4509. return result;
  4510. }
  4511. inline typename expression_node<T>::node_type type() const
  4512. {
  4513. return expression_node<T>::e_for;
  4514. }
  4515. private:
  4516. expression_ptr initialiser_;
  4517. expression_ptr condition_ ;
  4518. expression_ptr incrementor_;
  4519. expression_ptr loop_body_ ;
  4520. bool initialiser_deletable_;
  4521. bool condition_deletable_ ;
  4522. bool incrementor_deletable_;
  4523. bool loop_body_deletable_ ;
  4524. };
  4525. #ifndef exprtk_disable_break_continue
  4526. template <typename T>
  4527. class while_loop_bc_node : public expression_node<T>
  4528. {
  4529. public:
  4530. typedef expression_node<T>* expression_ptr;
  4531. while_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
  4532. : condition_(condition),
  4533. loop_body_(loop_body),
  4534. condition_deletable_(branch_deletable(condition_)),
  4535. loop_body_deletable_(branch_deletable(loop_body_))
  4536. {}
  4537. ~while_loop_bc_node()
  4538. {
  4539. if (condition_ && condition_deletable_)
  4540. {
  4541. delete condition_;
  4542. }
  4543. if (loop_body_ && loop_body_deletable_)
  4544. {
  4545. delete loop_body_;
  4546. }
  4547. }
  4548. inline T value() const
  4549. {
  4550. T result = T(0);
  4551. while (is_true(condition_))
  4552. {
  4553. try
  4554. {
  4555. result = loop_body_->value();
  4556. }
  4557. catch(const break_exception<T>& e)
  4558. {
  4559. return e.value;
  4560. }
  4561. catch(const continue_exception&)
  4562. {}
  4563. }
  4564. return result;
  4565. }
  4566. inline typename expression_node<T>::node_type type() const
  4567. {
  4568. return expression_node<T>::e_while;
  4569. }
  4570. private:
  4571. expression_ptr condition_;
  4572. expression_ptr loop_body_;
  4573. bool condition_deletable_;
  4574. bool loop_body_deletable_;
  4575. };
  4576. template <typename T>
  4577. class repeat_until_loop_bc_node : public expression_node<T>
  4578. {
  4579. public:
  4580. typedef expression_node<T>* expression_ptr;
  4581. repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
  4582. : condition_(condition),
  4583. loop_body_(loop_body),
  4584. condition_deletable_(branch_deletable(condition_)),
  4585. loop_body_deletable_(branch_deletable(loop_body_))
  4586. {}
  4587. ~repeat_until_loop_bc_node()
  4588. {
  4589. if (condition_ && condition_deletable_)
  4590. {
  4591. delete condition_;
  4592. }
  4593. if (loop_body_ && loop_body_deletable_)
  4594. {
  4595. delete loop_body_;
  4596. }
  4597. }
  4598. inline T value() const
  4599. {
  4600. T result = T(0);
  4601. do
  4602. {
  4603. try
  4604. {
  4605. result = loop_body_->value();
  4606. }
  4607. catch(const break_exception<T>& e)
  4608. {
  4609. return e.value;
  4610. }
  4611. catch(const continue_exception&)
  4612. {}
  4613. }
  4614. while (is_false(condition_));
  4615. return result;
  4616. }
  4617. inline typename expression_node<T>::node_type type() const
  4618. {
  4619. return expression_node<T>::e_repeat;
  4620. }
  4621. private:
  4622. expression_ptr condition_;
  4623. expression_ptr loop_body_;
  4624. bool condition_deletable_;
  4625. bool loop_body_deletable_;
  4626. };
  4627. template <typename T>
  4628. class for_loop_bc_node : public expression_node<T>
  4629. {
  4630. public:
  4631. typedef expression_node<T>* expression_ptr;
  4632. for_loop_bc_node(expression_ptr initialiser,
  4633. expression_ptr condition,
  4634. expression_ptr incrementor,
  4635. expression_ptr loop_body)
  4636. : initialiser_(initialiser),
  4637. condition_ (condition ),
  4638. incrementor_(incrementor),
  4639. loop_body_ (loop_body ),
  4640. initialiser_deletable_(branch_deletable(initialiser_)),
  4641. condition_deletable_ (branch_deletable(condition_ )),
  4642. incrementor_deletable_(branch_deletable(incrementor_)),
  4643. loop_body_deletable_ (branch_deletable(loop_body_ ))
  4644. {}
  4645. ~for_loop_bc_node()
  4646. {
  4647. if (initialiser_ && initialiser_deletable_)
  4648. {
  4649. delete initialiser_;
  4650. }
  4651. if (condition_ && condition_deletable_)
  4652. {
  4653. delete condition_;
  4654. }
  4655. if (incrementor_ && incrementor_deletable_)
  4656. {
  4657. delete incrementor_;
  4658. }
  4659. if (loop_body_ && loop_body_deletable_)
  4660. {
  4661. delete loop_body_;
  4662. }
  4663. }
  4664. inline T value() const
  4665. {
  4666. T result = T(0);
  4667. if (initialiser_)
  4668. initialiser_->value();
  4669. if (incrementor_)
  4670. {
  4671. while (is_true(condition_))
  4672. {
  4673. try
  4674. {
  4675. result = loop_body_->value();
  4676. }
  4677. catch(const break_exception<T>& e)
  4678. {
  4679. return e.value;
  4680. }
  4681. catch(const continue_exception&)
  4682. {}
  4683. incrementor_->value();
  4684. }
  4685. }
  4686. else
  4687. {
  4688. while (is_true(condition_))
  4689. {
  4690. try
  4691. {
  4692. result = loop_body_->value();
  4693. }
  4694. catch(const break_exception<T>& e)
  4695. {
  4696. return e.value;
  4697. }
  4698. catch(const continue_exception&)
  4699. {}
  4700. }
  4701. }
  4702. return result;
  4703. }
  4704. inline typename expression_node<T>::node_type type() const
  4705. {
  4706. return expression_node<T>::e_for;
  4707. }
  4708. private:
  4709. expression_ptr initialiser_;
  4710. expression_ptr condition_ ;
  4711. expression_ptr incrementor_;
  4712. expression_ptr loop_body_ ;
  4713. bool initialiser_deletable_;
  4714. bool condition_deletable_ ;
  4715. bool incrementor_deletable_;
  4716. bool loop_body_deletable_ ;
  4717. };
  4718. #endif
  4719. template <typename T>
  4720. class switch_node : public expression_node<T>
  4721. {
  4722. public:
  4723. typedef expression_node<T>* expression_ptr;
  4724. template <typename Allocator,
  4725. template <typename,typename> class Sequence>
  4726. switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
  4727. {
  4728. if (1 != (arg_list.size() & 1))
  4729. return;
  4730. arg_list_.resize(arg_list.size());
  4731. delete_branch_.resize(arg_list.size());
  4732. for (std::size_t i = 0; i < arg_list.size(); ++i)
  4733. {
  4734. if (arg_list[i])
  4735. {
  4736. arg_list_[i] = arg_list[i];
  4737. delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
  4738. }
  4739. else
  4740. {
  4741. arg_list_.clear();
  4742. delete_branch_.clear();
  4743. return;
  4744. }
  4745. }
  4746. }
  4747. ~switch_node()
  4748. {
  4749. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  4750. {
  4751. if (arg_list_[i] && delete_branch_[i])
  4752. {
  4753. delete arg_list_[i];
  4754. arg_list_[i] = 0;
  4755. }
  4756. }
  4757. }
  4758. inline T value() const
  4759. {
  4760. if (!arg_list_.empty())
  4761. {
  4762. const std::size_t upper_bound = (arg_list_.size() - 1);
  4763. for (std::size_t i = 0; i < upper_bound; i += 2)
  4764. {
  4765. expression_ptr condition = arg_list_[i ];
  4766. expression_ptr consequent = arg_list_[i + 1];
  4767. if (is_true(condition))
  4768. {
  4769. return consequent->value();
  4770. }
  4771. }
  4772. return arg_list_[upper_bound]->value();
  4773. }
  4774. else
  4775. return std::numeric_limits<T>::quiet_NaN();
  4776. }
  4777. inline typename expression_node<T>::node_type type() const
  4778. {
  4779. return expression_node<T>::e_switch;
  4780. }
  4781. private:
  4782. std::vector<expression_ptr> arg_list_;
  4783. std::vector<unsigned char> delete_branch_;
  4784. };
  4785. template <typename T>
  4786. class multi_switch_node : public expression_node<T>
  4787. {
  4788. public:
  4789. typedef expression_node<T>* expression_ptr;
  4790. template <typename Allocator,
  4791. template <typename,typename> class Sequence>
  4792. multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
  4793. {
  4794. if (0 != (arg_list.size() & 1))
  4795. return;
  4796. arg_list_.resize(arg_list.size());
  4797. delete_branch_.resize(arg_list.size());
  4798. for (std::size_t i = 0; i < arg_list.size(); ++i)
  4799. {
  4800. if (arg_list[i])
  4801. {
  4802. arg_list_[i] = arg_list[i];
  4803. delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
  4804. }
  4805. else
  4806. {
  4807. arg_list_.clear();
  4808. delete_branch_.clear();
  4809. return;
  4810. }
  4811. }
  4812. }
  4813. ~multi_switch_node()
  4814. {
  4815. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  4816. {
  4817. if (arg_list_[i] && delete_branch_[i])
  4818. {
  4819. delete arg_list_[i];
  4820. arg_list_[i] = 0;
  4821. }
  4822. }
  4823. }
  4824. inline T value() const
  4825. {
  4826. T result = T(0);
  4827. if (arg_list_.empty())
  4828. {
  4829. return std::numeric_limits<T>::quiet_NaN();
  4830. }
  4831. const std::size_t upper_bound = (arg_list_.size() - 1);
  4832. for (std::size_t i = 0; i < upper_bound; i += 2)
  4833. {
  4834. expression_ptr condition = arg_list_[i ];
  4835. expression_ptr consequent = arg_list_[i + 1];
  4836. if (is_true(condition))
  4837. {
  4838. result = consequent->value();
  4839. }
  4840. }
  4841. return result;
  4842. }
  4843. inline typename expression_node<T>::node_type type() const
  4844. {
  4845. return expression_node<T>::e_mswitch;
  4846. }
  4847. private:
  4848. std::vector<expression_ptr> arg_list_;
  4849. std::vector<unsigned char> delete_branch_;
  4850. };
  4851. template <typename T>
  4852. class ivariable
  4853. {
  4854. public:
  4855. virtual T& ref() = 0;
  4856. virtual const T& ref() const = 0;
  4857. };
  4858. template <typename T>
  4859. class variable_node : public expression_node<T>,
  4860. public ivariable<T>
  4861. {
  4862. public:
  4863. static T null_value;
  4864. explicit variable_node()
  4865. : value_(&null_value),
  4866. delete_value_(false)
  4867. {}
  4868. variable_node(T& v)
  4869. : value_(&v),
  4870. delete_value_(false)
  4871. {}
  4872. ~variable_node()
  4873. {
  4874. if (delete_value_)
  4875. {
  4876. delete value_;
  4877. }
  4878. }
  4879. inline bool operator <(const variable_node<T>& v) const
  4880. {
  4881. return this < (&v);
  4882. }
  4883. inline T value() const
  4884. {
  4885. return (*value_);
  4886. }
  4887. inline T& ref()
  4888. {
  4889. return (*value_);
  4890. }
  4891. inline const T& ref() const
  4892. {
  4893. return (*value_);
  4894. }
  4895. inline typename expression_node<T>::node_type type() const
  4896. {
  4897. return expression_node<T>::e_variable;
  4898. }
  4899. inline bool& delete_value()
  4900. {
  4901. return delete_value_;
  4902. }
  4903. private:
  4904. T* value_;
  4905. bool delete_value_;
  4906. };
  4907. template <typename T>
  4908. T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
  4909. template <typename T>
  4910. struct range_pack
  4911. {
  4912. typedef expression_node<T>* expression_node_ptr;
  4913. typedef std::pair<std::size_t,std::size_t> cached_range_t;
  4914. range_pack()
  4915. : n0_e (std::make_pair(false,expression_node_ptr(0))),
  4916. n1_e (std::make_pair(false,expression_node_ptr(0))),
  4917. n0_c (std::make_pair(false,0)),
  4918. n1_c (std::make_pair(false,0)),
  4919. cache(std::make_pair(0,0))
  4920. {}
  4921. void clear()
  4922. {
  4923. n0_e = std::make_pair(false,expression_node_ptr(0));
  4924. n1_e = std::make_pair(false,expression_node_ptr(0));
  4925. n0_c = std::make_pair(false,0);
  4926. n1_c = std::make_pair(false,0);
  4927. cache = std::make_pair(0,0);
  4928. }
  4929. void free()
  4930. {
  4931. if (n0_e.first && n0_e.second)
  4932. {
  4933. n0_e.first = false;
  4934. if (
  4935. !is_variable_node(n0_e.second) &&
  4936. !is_string_node (n0_e.second)
  4937. )
  4938. {
  4939. delete n0_e.second;
  4940. n0_e.second = expression_node_ptr(0);
  4941. }
  4942. }
  4943. if (n1_e.first && n1_e.second)
  4944. {
  4945. n1_e.first = false;
  4946. if (
  4947. !is_variable_node(n1_e.second) &&
  4948. !is_string_node (n1_e.second)
  4949. )
  4950. {
  4951. delete n1_e.second;
  4952. n1_e.second = expression_node_ptr(0);
  4953. }
  4954. }
  4955. }
  4956. bool const_range()
  4957. {
  4958. return ( n0_c.first && n1_c.first) &&
  4959. (!n0_e.first && !n1_e.first);
  4960. }
  4961. bool var_range()
  4962. {
  4963. return ( n0_e.first && n1_e.first) &&
  4964. (!n0_c.first && !n1_c.first);
  4965. }
  4966. bool operator()(std::size_t& r0, std::size_t& r1, const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
  4967. {
  4968. if (n0_c.first)
  4969. r0 = n0_c.second;
  4970. else if (n0_e.first)
  4971. {
  4972. T r0_value = n0_e.second->value();
  4973. if (r0_value < 0)
  4974. return false;
  4975. else
  4976. r0 = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
  4977. }
  4978. else
  4979. return false;
  4980. if (n1_c.first)
  4981. r1 = n1_c.second;
  4982. else if (n1_e.first)
  4983. {
  4984. T r1_value = n1_e.second->value();
  4985. if (r1_value < 0)
  4986. return false;
  4987. else
  4988. r1 = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
  4989. }
  4990. else
  4991. return false;
  4992. if (
  4993. (std::numeric_limits<std::size_t>::max() != size) &&
  4994. (std::numeric_limits<std::size_t>::max() == r1 )
  4995. )
  4996. {
  4997. r1 = size - 1;
  4998. }
  4999. cache.first = r0;
  5000. cache.second = r1;
  5001. return (r0 <= r1);
  5002. }
  5003. inline std::size_t const_size() const
  5004. {
  5005. return (n1_c.second - n0_c.second + 1);
  5006. }
  5007. inline std::size_t cache_size() const
  5008. {
  5009. return (cache.second - cache.first + 1);
  5010. }
  5011. std::pair<bool,expression_node_ptr> n0_e;
  5012. std::pair<bool,expression_node_ptr> n1_e;
  5013. std::pair<bool,std::size_t > n0_c;
  5014. std::pair<bool,std::size_t > n1_c;
  5015. mutable cached_range_t cache;
  5016. };
  5017. template <typename T>
  5018. class string_base_node;
  5019. template <typename T>
  5020. struct range_data_type
  5021. {
  5022. typedef range_pack<T> range_t;
  5023. typedef string_base_node<T>* strbase_ptr_t;
  5024. range_data_type()
  5025. : range(0),
  5026. data (0),
  5027. size (0),
  5028. type_size(0),
  5029. str_node (0)
  5030. {}
  5031. range_t* range;
  5032. void* data;
  5033. std::size_t size;
  5034. std::size_t type_size;
  5035. strbase_ptr_t str_node;
  5036. };
  5037. template <typename T> class vector_node;
  5038. template <typename T>
  5039. class vector_interface
  5040. {
  5041. public:
  5042. typedef vector_node<T>* vector_node_ptr;
  5043. virtual ~vector_interface()
  5044. {}
  5045. virtual vector_node_ptr vec() const = 0;
  5046. virtual vector_node_ptr vec() = 0;
  5047. virtual std::size_t size() const = 0;
  5048. };
  5049. template <typename T>
  5050. class vector_node : public expression_node<T>,
  5051. public vector_interface<T>
  5052. {
  5053. public:
  5054. typedef expression_node<T>* expression_ptr;
  5055. typedef vector_holder<T> vector_holder_t;
  5056. typedef vector_node<T>* vector_node_ptr;
  5057. vector_node(vector_holder_t* vh)
  5058. : vector_holder_(vh)
  5059. {}
  5060. inline T value() const
  5061. {
  5062. return *(ref()[0]);
  5063. }
  5064. inline const vector_holder_t& ref() const
  5065. {
  5066. return (*vector_holder_);
  5067. }
  5068. inline vector_holder_t& ref()
  5069. {
  5070. return (*vector_holder_);
  5071. }
  5072. vector_node_ptr vec() const
  5073. {
  5074. return const_cast<vector_node_ptr>(this);
  5075. }
  5076. vector_node_ptr vec()
  5077. {
  5078. return this;
  5079. }
  5080. inline typename expression_node<T>::node_type type() const
  5081. {
  5082. return expression_node<T>::e_vector;
  5083. }
  5084. std::size_t size() const
  5085. {
  5086. return ref().size();
  5087. }
  5088. private:
  5089. vector_holder_t* vector_holder_;
  5090. };
  5091. template <typename T>
  5092. class vector_elem_node : public expression_node<T>,
  5093. public ivariable<T>
  5094. {
  5095. public:
  5096. typedef expression_node<T>* expression_ptr;
  5097. vector_elem_node(expression_ptr index, T* vector_base)
  5098. : index_(index),
  5099. vector_base_(vector_base),
  5100. index_deletable_(branch_deletable(index_))
  5101. {}
  5102. ~vector_elem_node()
  5103. {
  5104. if (index_ && index_deletable_)
  5105. {
  5106. delete index_;
  5107. }
  5108. }
  5109. inline T value() const
  5110. {
  5111. return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
  5112. }
  5113. inline T& ref()
  5114. {
  5115. return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
  5116. }
  5117. inline const T& ref() const
  5118. {
  5119. return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
  5120. }
  5121. inline typename expression_node<T>::node_type type() const
  5122. {
  5123. return expression_node<T>::e_vecelem;
  5124. }
  5125. private:
  5126. expression_ptr index_;
  5127. T* vector_base_;
  5128. bool index_deletable_;
  5129. };
  5130. template <typename T>
  5131. class vector_assignment_node : public expression_node<T>
  5132. {
  5133. public:
  5134. typedef expression_node<T>* expression_ptr;
  5135. vector_assignment_node(T* vector_base,
  5136. const std::size_t& size,
  5137. const std::vector<expression_ptr>& initialiser_list,
  5138. const bool single_value_initialse)
  5139. : vector_base_(vector_base),
  5140. initialiser_list_(initialiser_list),
  5141. size_(size),
  5142. single_value_initialse_(single_value_initialse)
  5143. {}
  5144. ~vector_assignment_node()
  5145. {
  5146. for (std::size_t i = 0; i < initialiser_list_.size(); ++i)
  5147. {
  5148. if (branch_deletable(initialiser_list_[i]))
  5149. {
  5150. delete initialiser_list_[i];
  5151. }
  5152. }
  5153. }
  5154. inline T value() const
  5155. {
  5156. if (single_value_initialse_)
  5157. {
  5158. for (std::size_t i = 0; i < size_; ++i)
  5159. {
  5160. *(vector_base_ + i) = initialiser_list_[0]->value();
  5161. }
  5162. }
  5163. else
  5164. {
  5165. std::size_t il_size = initialiser_list_.size();
  5166. for (std::size_t i = 0; i < il_size; ++i)
  5167. {
  5168. *(vector_base_ + i) = initialiser_list_[i]->value();
  5169. }
  5170. if (il_size < size_)
  5171. {
  5172. for (std::size_t i = il_size; i < size_; ++i)
  5173. {
  5174. *(vector_base_ + i) = T(0);
  5175. }
  5176. }
  5177. }
  5178. return *(vector_base_);
  5179. }
  5180. inline typename expression_node<T>::node_type type() const
  5181. {
  5182. return expression_node<T>::e_vecdefass;
  5183. }
  5184. private:
  5185. vector_assignment_node<T>& operator=(const vector_assignment_node<T>&);
  5186. mutable T* vector_base_;
  5187. std::vector<expression_ptr> initialiser_list_;
  5188. const std::size_t size_;
  5189. const bool single_value_initialse_;
  5190. };
  5191. template <typename T>
  5192. class swap_node : public expression_node<T>
  5193. {
  5194. public:
  5195. typedef expression_node<T>* expression_ptr;
  5196. typedef variable_node<T>* variable_node_ptr;
  5197. swap_node(variable_node_ptr var0, variable_node_ptr var1)
  5198. : var0_(var0),
  5199. var1_(var1)
  5200. {}
  5201. inline T value() const
  5202. {
  5203. std::swap(var0_->ref(),var1_->ref());
  5204. return var1_->ref();
  5205. }
  5206. inline typename expression_node<T>::node_type type() const
  5207. {
  5208. return expression_node<T>::e_swap;
  5209. }
  5210. private:
  5211. variable_node_ptr var0_;
  5212. variable_node_ptr var1_;
  5213. };
  5214. template <typename T>
  5215. class swap_generic_node : public binary_node<T>
  5216. {
  5217. public:
  5218. typedef expression_node<T>* expression_ptr;
  5219. typedef ivariable<T>* ivariable_ptr;
  5220. swap_generic_node(expression_ptr var0, expression_ptr var1)
  5221. : binary_node<T>(details::e_swap,var0,var1),
  5222. var0_(dynamic_cast<ivariable_ptr>(var0)),
  5223. var1_(dynamic_cast<ivariable_ptr>(var1))
  5224. {}
  5225. inline T value() const
  5226. {
  5227. std::swap(var0_->ref(),var1_->ref());
  5228. return var1_->ref();
  5229. }
  5230. inline typename expression_node<T>::node_type type() const
  5231. {
  5232. return expression_node<T>::e_swap;
  5233. }
  5234. private:
  5235. ivariable_ptr var0_;
  5236. ivariable_ptr var1_;
  5237. };
  5238. template <typename T>
  5239. class swap_vecvec_node : public binary_node<T>,
  5240. public vector_interface<T>
  5241. {
  5242. public:
  5243. typedef expression_node<T>* expression_ptr;
  5244. typedef vector_node<T>* vector_node_ptr;
  5245. swap_vecvec_node(expression_ptr branch0,
  5246. expression_ptr branch1)
  5247. : binary_node<T>(details::e_swap,branch0,branch1),
  5248. vec0_node_ptr_(0),
  5249. vec1_node_ptr_(0),
  5250. vec_size_ (0)
  5251. {
  5252. if (is_ivector_node(binary_node<T>::branch_[0].first))
  5253. {
  5254. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  5255. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  5256. {
  5257. vec0_node_ptr_ = vi->vec();
  5258. }
  5259. }
  5260. if (is_ivector_node(binary_node<T>::branch_[1].first))
  5261. {
  5262. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  5263. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  5264. {
  5265. vec1_node_ptr_ = vi->vec();
  5266. }
  5267. }
  5268. if (vec0_node_ptr_ && vec1_node_ptr_)
  5269. {
  5270. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  5271. vec1_node_ptr_->ref().size());
  5272. }
  5273. }
  5274. inline T value() const
  5275. {
  5276. if (vec0_node_ptr_ && vec1_node_ptr_)
  5277. {
  5278. binary_node<T>::branch_[0].first->value();
  5279. binary_node<T>::branch_[1].first->value();
  5280. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  5281. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  5282. for (std::size_t i = 0; i < vec_size_; ++i)
  5283. {
  5284. std::swap((*vec0[i]),(*vec1[i]));
  5285. }
  5286. return vec1_node_ptr_->value();
  5287. }
  5288. else
  5289. return std::numeric_limits<T>::quiet_NaN();
  5290. }
  5291. vector_node_ptr vec() const
  5292. {
  5293. return vec0_node_ptr_;
  5294. }
  5295. vector_node_ptr vec()
  5296. {
  5297. return vec0_node_ptr_;
  5298. }
  5299. inline typename expression_node<T>::node_type type() const
  5300. {
  5301. return expression_node<T>::e_vecvecswap;
  5302. }
  5303. std::size_t size() const
  5304. {
  5305. return vec_size_;
  5306. }
  5307. private:
  5308. vector_node<T>* vec0_node_ptr_;
  5309. vector_node<T>* vec1_node_ptr_;
  5310. std::size_t vec_size_;
  5311. };
  5312. #ifndef exprtk_disable_string_capabilities
  5313. template <typename T>
  5314. class stringvar_node : public expression_node <T>,
  5315. public string_base_node<T>,
  5316. public range_interface <T>
  5317. {
  5318. public:
  5319. typedef range_pack<T> range_t;
  5320. static std::string null_value;
  5321. explicit stringvar_node()
  5322. : value_(&null_value)
  5323. {}
  5324. explicit stringvar_node(std::string& v)
  5325. : value_(&v)
  5326. {
  5327. rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  5328. rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
  5329. rp_.cache.first = rp_.n0_c.second;
  5330. rp_.cache.second = rp_.n1_c.second;
  5331. }
  5332. inline bool operator <(const stringvar_node<T>& v) const
  5333. {
  5334. return this < (&v);
  5335. }
  5336. inline T value() const
  5337. {
  5338. rp_.n1_c.second = (*value_).size() - 1;
  5339. rp_.cache.second = rp_.n1_c.second;
  5340. return std::numeric_limits<T>::quiet_NaN();
  5341. }
  5342. std::string str() const
  5343. {
  5344. return ref();
  5345. }
  5346. const char* base() const
  5347. {
  5348. return (*value_).data();
  5349. }
  5350. std::size_t size() const
  5351. {
  5352. return ref().size();
  5353. }
  5354. std::string& ref()
  5355. {
  5356. return (*value_);
  5357. }
  5358. const std::string& ref() const
  5359. {
  5360. return (*value_);
  5361. }
  5362. range_t& range_ref()
  5363. {
  5364. return rp_;
  5365. }
  5366. const range_t& range_ref() const
  5367. {
  5368. return rp_;
  5369. }
  5370. inline typename expression_node<T>::node_type type() const
  5371. {
  5372. return expression_node<T>::e_stringvar;
  5373. }
  5374. private:
  5375. std::string* value_;
  5376. mutable range_t rp_;
  5377. };
  5378. template <typename T>
  5379. std::string stringvar_node<T>::null_value = std::string("");
  5380. template <typename T>
  5381. class string_range_node : public expression_node <T>,
  5382. public string_base_node<T>,
  5383. public range_interface <T>
  5384. {
  5385. public:
  5386. typedef range_pack<T> range_t;
  5387. static std::string null_value;
  5388. explicit string_range_node(std::string& v, range_t rp)
  5389. : value_(&v),
  5390. rp_(rp)
  5391. {}
  5392. ~string_range_node()
  5393. {
  5394. rp_.free();
  5395. }
  5396. inline bool operator <(const string_range_node<T>& v) const
  5397. {
  5398. return this < (&v);
  5399. }
  5400. inline T value() const
  5401. {
  5402. return std::numeric_limits<T>::quiet_NaN();
  5403. }
  5404. inline std::string str() const
  5405. {
  5406. return (*value_);
  5407. }
  5408. const char* base() const
  5409. {
  5410. return (*value_).data();
  5411. }
  5412. std::size_t size() const
  5413. {
  5414. return ref().size();
  5415. }
  5416. inline range_t range() const
  5417. {
  5418. return rp_;
  5419. }
  5420. inline virtual std::string& ref()
  5421. {
  5422. return (*value_);
  5423. }
  5424. inline virtual const std::string& ref() const
  5425. {
  5426. return (*value_);
  5427. }
  5428. inline range_t& range_ref()
  5429. {
  5430. return rp_;
  5431. }
  5432. inline const range_t& range_ref() const
  5433. {
  5434. return rp_;
  5435. }
  5436. inline typename expression_node<T>::node_type type() const
  5437. {
  5438. return expression_node<T>::e_stringvarrng;
  5439. }
  5440. private:
  5441. std::string* value_;
  5442. range_t rp_;
  5443. };
  5444. template <typename T>
  5445. std::string string_range_node<T>::null_value = std::string("");
  5446. template <typename T>
  5447. class const_string_range_node : public expression_node <T>,
  5448. public string_base_node<T>,
  5449. public range_interface <T>
  5450. {
  5451. public:
  5452. typedef range_pack<T> range_t;
  5453. explicit const_string_range_node(const std::string& v, range_t rp)
  5454. : value_(v),
  5455. rp_(rp)
  5456. {}
  5457. ~const_string_range_node()
  5458. {
  5459. rp_.free();
  5460. }
  5461. inline T value() const
  5462. {
  5463. return std::numeric_limits<T>::quiet_NaN();
  5464. }
  5465. std::string str() const
  5466. {
  5467. return value_;
  5468. }
  5469. const char* base() const
  5470. {
  5471. return value_.data();
  5472. }
  5473. std::size_t size() const
  5474. {
  5475. return value_.size();
  5476. }
  5477. range_t range() const
  5478. {
  5479. return rp_;
  5480. }
  5481. range_t& range_ref()
  5482. {
  5483. return rp_;
  5484. }
  5485. const range_t& range_ref() const
  5486. {
  5487. return rp_;
  5488. }
  5489. inline typename expression_node<T>::node_type type() const
  5490. {
  5491. return expression_node<T>::e_cstringvarrng;
  5492. }
  5493. private:
  5494. const_string_range_node<T>& operator=(const const_string_range_node<T>&);
  5495. const std::string value_;
  5496. range_t rp_;
  5497. };
  5498. template <typename T>
  5499. class generic_string_range_node : public expression_node <T>,
  5500. public string_base_node<T>,
  5501. public range_interface <T>
  5502. {
  5503. public:
  5504. typedef expression_node <T>* expression_ptr;
  5505. typedef stringvar_node <T>* strvar_node_ptr;
  5506. typedef string_base_node<T>* str_base_ptr;
  5507. typedef range_pack <T> range_t;
  5508. typedef range_t* range_ptr;
  5509. typedef range_interface<T> irange_t;
  5510. typedef irange_t* irange_ptr;
  5511. typedef typename range_t::cached_range_t cached_range_t;
  5512. generic_string_range_node(expression_ptr str_branch, range_t brange)
  5513. : initialised_(false),
  5514. branch_(str_branch),
  5515. branch_deletable_(branch_deletable(branch_)),
  5516. str_base_ptr_ (0),
  5517. str_range_ptr_(0),
  5518. base_range_(brange)
  5519. {
  5520. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  5521. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  5522. range_.cache.first = range_.n0_c.second;
  5523. range_.cache.second = range_.n1_c.second;
  5524. if (is_generally_string_node(branch_))
  5525. {
  5526. str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
  5527. if (0 == str_base_ptr_)
  5528. return;
  5529. str_range_ptr_ = dynamic_cast<irange_ptr>(branch_);
  5530. if (0 == str_range_ptr_)
  5531. return;
  5532. }
  5533. initialised_ = (str_base_ptr_ && str_range_ptr_);
  5534. }
  5535. ~generic_string_range_node()
  5536. {
  5537. base_range_.free();
  5538. if (branch_ && branch_deletable_)
  5539. {
  5540. delete branch_;
  5541. branch_ = 0;
  5542. }
  5543. }
  5544. inline T value() const
  5545. {
  5546. if (initialised_)
  5547. {
  5548. branch_->value();
  5549. std::size_t str_r0 = 0;
  5550. std::size_t str_r1 = 0;
  5551. std::size_t r0 = 0;
  5552. std::size_t r1 = 0;
  5553. range_t& range = str_range_ptr_->range_ref();
  5554. const std::size_t base_str_size = str_base_ptr_->size();
  5555. if (
  5556. range (str_r0,str_r1,base_str_size) &&
  5557. base_range_( r0, r1,base_str_size)
  5558. )
  5559. {
  5560. const std::size_t size = (r1 - r0) + 1;
  5561. range_.n1_c.second = size - 1;
  5562. range_.cache.second = range_.n1_c.second;
  5563. value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
  5564. }
  5565. }
  5566. return std::numeric_limits<T>::quiet_NaN();
  5567. }
  5568. std::string str() const
  5569. {
  5570. return value_;
  5571. }
  5572. const char* base() const
  5573. {
  5574. return value_.data();
  5575. }
  5576. std::size_t size() const
  5577. {
  5578. return value_.size();
  5579. }
  5580. range_t& range_ref()
  5581. {
  5582. return range_;
  5583. }
  5584. const range_t& range_ref() const
  5585. {
  5586. return range_;
  5587. }
  5588. inline typename expression_node<T>::node_type type() const
  5589. {
  5590. return expression_node<T>::e_strgenrange;
  5591. }
  5592. private:
  5593. bool initialised_;
  5594. expression_ptr branch_;
  5595. bool branch_deletable_;
  5596. str_base_ptr str_base_ptr_;
  5597. irange_ptr str_range_ptr_;
  5598. mutable range_t base_range_;
  5599. mutable range_t range_;
  5600. mutable std::string value_;
  5601. };
  5602. template <typename T>
  5603. class string_concat_node : public binary_node <T>,
  5604. public string_base_node<T>,
  5605. public range_interface <T>
  5606. {
  5607. public:
  5608. typedef expression_node <T>* expression_ptr;
  5609. typedef stringvar_node <T>* strvar_node_ptr;
  5610. typedef string_base_node<T>* str_base_ptr;
  5611. typedef range_pack <T> range_t;
  5612. typedef range_t* range_ptr;
  5613. typedef range_interface<T> irange_t;
  5614. typedef irange_t* irange_ptr;
  5615. typedef typename range_t::cached_range_t cached_range_t;
  5616. string_concat_node(const operator_type& opr,
  5617. expression_ptr branch0,
  5618. expression_ptr branch1)
  5619. : binary_node<T>(opr,branch0,branch1),
  5620. initialised_(false),
  5621. str0_base_ptr_ (0),
  5622. str1_base_ptr_ (0),
  5623. str0_range_ptr_(0),
  5624. str1_range_ptr_(0)
  5625. {
  5626. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  5627. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  5628. range_.cache.first = range_.n0_c.second;
  5629. range_.cache.second = range_.n1_c.second;
  5630. if (is_generally_string_node(binary_node<T>::branch_[0].first))
  5631. {
  5632. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  5633. if (0 == str0_base_ptr_)
  5634. return;
  5635. str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  5636. if (0 == str0_range_ptr_)
  5637. return;
  5638. }
  5639. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  5640. {
  5641. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  5642. if (0 == str1_base_ptr_)
  5643. return;
  5644. str1_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  5645. if (0 == str1_range_ptr_)
  5646. return;
  5647. }
  5648. initialised_ = str0_base_ptr_ &&
  5649. str1_base_ptr_ &&
  5650. str0_range_ptr_ &&
  5651. str1_range_ptr_ ;
  5652. }
  5653. inline T value() const
  5654. {
  5655. if (initialised_)
  5656. {
  5657. binary_node<T>::branch_[0].first->value();
  5658. binary_node<T>::branch_[1].first->value();
  5659. std::size_t str0_r0 = 0;
  5660. std::size_t str0_r1 = 0;
  5661. std::size_t str1_r0 = 0;
  5662. std::size_t str1_r1 = 0;
  5663. range_t& range0 = str0_range_ptr_->range_ref();
  5664. range_t& range1 = str1_range_ptr_->range_ref();
  5665. if (
  5666. range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
  5667. range1(str1_r0,str1_r1,str1_base_ptr_->size())
  5668. )
  5669. {
  5670. const std::size_t size0 = (str0_r1 - str0_r0) + 1;
  5671. const std::size_t size1 = (str1_r1 - str1_r0) + 1;
  5672. value_.assign(str0_base_ptr_->base() + str0_r0, size0);
  5673. value_.append(str1_base_ptr_->base() + str1_r0, size1);
  5674. range_.n1_c.second = value_.size() - 1;
  5675. range_.cache.second = range_.n1_c.second;
  5676. }
  5677. }
  5678. return std::numeric_limits<T>::quiet_NaN();
  5679. }
  5680. std::string str() const
  5681. {
  5682. return value_;
  5683. }
  5684. const char* base() const
  5685. {
  5686. return value_.data();
  5687. }
  5688. std::size_t size() const
  5689. {
  5690. return value_.size();
  5691. }
  5692. range_t& range_ref()
  5693. {
  5694. return range_;
  5695. }
  5696. const range_t& range_ref() const
  5697. {
  5698. return range_;
  5699. }
  5700. inline typename expression_node<T>::node_type type() const
  5701. {
  5702. return expression_node<T>::e_strconcat;
  5703. }
  5704. private:
  5705. bool initialised_;
  5706. str_base_ptr str0_base_ptr_;
  5707. str_base_ptr str1_base_ptr_;
  5708. irange_ptr str0_range_ptr_;
  5709. irange_ptr str1_range_ptr_;
  5710. mutable range_t range_;
  5711. mutable std::string value_;
  5712. };
  5713. template <typename T>
  5714. class swap_string_node : public binary_node <T>,
  5715. public string_base_node<T>,
  5716. public range_interface <T>
  5717. {
  5718. public:
  5719. typedef expression_node <T>* expression_ptr;
  5720. typedef stringvar_node <T>* strvar_node_ptr;
  5721. typedef string_base_node<T>* str_base_ptr;
  5722. typedef range_pack <T> range_t;
  5723. typedef range_t* range_ptr;
  5724. typedef range_interface<T> irange_t;
  5725. typedef irange_t* irange_ptr;
  5726. typedef typename range_t::cached_range_t cached_range_t;
  5727. swap_string_node(expression_ptr branch0, expression_ptr branch1)
  5728. : binary_node<T>(details::e_swap,branch0,branch1),
  5729. initialised_(false),
  5730. str0_node_ptr_(0),
  5731. str1_node_ptr_(0)
  5732. {
  5733. if (is_string_node(binary_node<T>::branch_[0].first))
  5734. {
  5735. str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
  5736. }
  5737. if (is_string_node(binary_node<T>::branch_[1].first))
  5738. {
  5739. str1_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[1].first);
  5740. }
  5741. initialised_ = (str0_node_ptr_ && str1_node_ptr_);
  5742. }
  5743. inline T value() const
  5744. {
  5745. if (initialised_)
  5746. {
  5747. binary_node<T>::branch_[0].first->value();
  5748. binary_node<T>::branch_[1].first->value();
  5749. std::swap(str0_node_ptr_->ref(),str1_node_ptr_->ref());
  5750. }
  5751. return std::numeric_limits<T>::quiet_NaN();
  5752. }
  5753. std::string str() const
  5754. {
  5755. return str0_node_ptr_->str();
  5756. }
  5757. const char* base() const
  5758. {
  5759. return str0_node_ptr_->base();
  5760. }
  5761. std::size_t size() const
  5762. {
  5763. return str0_node_ptr_->size();
  5764. }
  5765. range_t& range_ref()
  5766. {
  5767. return str0_node_ptr_->range_ref();
  5768. }
  5769. const range_t& range_ref() const
  5770. {
  5771. return str0_node_ptr_->range_ref();
  5772. }
  5773. inline typename expression_node<T>::node_type type() const
  5774. {
  5775. return expression_node<T>::e_strswap;
  5776. }
  5777. private:
  5778. bool initialised_;
  5779. strvar_node_ptr str0_node_ptr_;
  5780. strvar_node_ptr str1_node_ptr_;
  5781. };
  5782. template <typename T>
  5783. class stringvar_size_node : public expression_node<T>
  5784. {
  5785. public:
  5786. static std::string null_value;
  5787. explicit stringvar_size_node()
  5788. : value_(&null_value)
  5789. {}
  5790. explicit stringvar_size_node(std::string& v)
  5791. : value_(&v)
  5792. {}
  5793. inline T value() const
  5794. {
  5795. return T((*value_).size());
  5796. }
  5797. inline typename expression_node<T>::node_type type() const
  5798. {
  5799. return expression_node<T>::e_stringvarsize;
  5800. }
  5801. private:
  5802. std::string* value_;
  5803. };
  5804. template <typename T>
  5805. std::string stringvar_size_node<T>::null_value = std::string("");
  5806. template <typename T>
  5807. class string_size_node : public expression_node<T>
  5808. {
  5809. public:
  5810. typedef expression_node <T>* expression_ptr;
  5811. typedef string_base_node<T>* str_base_ptr;
  5812. string_size_node(expression_ptr brnch)
  5813. : branch_(brnch),
  5814. branch_deletable_(branch_deletable(branch_)),
  5815. str_base_ptr_(0)
  5816. {
  5817. if (is_generally_string_node(branch_))
  5818. {
  5819. str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
  5820. if (0 == str_base_ptr_)
  5821. return;
  5822. }
  5823. }
  5824. ~string_size_node()
  5825. {
  5826. if (branch_ && branch_deletable_)
  5827. {
  5828. delete branch_;
  5829. branch_ = 0;
  5830. }
  5831. }
  5832. inline T value() const
  5833. {
  5834. T result = std::numeric_limits<T>::quiet_NaN();
  5835. if (str_base_ptr_)
  5836. {
  5837. branch_->value();
  5838. result = T(str_base_ptr_->size());
  5839. }
  5840. return result;
  5841. }
  5842. inline typename expression_node<T>::node_type type() const
  5843. {
  5844. return expression_node<T>::e_stringsize;
  5845. }
  5846. private:
  5847. expression_ptr branch_;
  5848. bool branch_deletable_;
  5849. str_base_ptr str_base_ptr_;
  5850. };
  5851. struct asn_assignment
  5852. {
  5853. static inline void execute(std::string& s, const char* data, const std::size_t size)
  5854. { s.assign(data,size); }
  5855. };
  5856. struct asn_addassignment
  5857. {
  5858. static inline void execute(std::string& s, const char* data, const std::size_t size)
  5859. { s.append(data,size); }
  5860. };
  5861. template <typename T, typename AssignmentProcess = asn_assignment>
  5862. class assignment_string_node : public binary_node <T>,
  5863. public string_base_node<T>,
  5864. public range_interface <T>
  5865. {
  5866. public:
  5867. typedef expression_node <T>* expression_ptr;
  5868. typedef stringvar_node <T>* strvar_node_ptr;
  5869. typedef string_base_node<T>* str_base_ptr;
  5870. typedef range_pack <T> range_t;
  5871. typedef range_t* range_ptr;
  5872. typedef range_interface<T> irange_t;
  5873. typedef irange_t* irange_ptr;
  5874. typedef typename range_t::cached_range_t cached_range_t;
  5875. assignment_string_node(const operator_type& opr,
  5876. expression_ptr branch0,
  5877. expression_ptr branch1)
  5878. : binary_node<T>(opr,branch0,branch1),
  5879. initialised_(false),
  5880. str0_base_ptr_ (0),
  5881. str1_base_ptr_ (0),
  5882. str0_node_ptr_ (0),
  5883. str1_range_ptr_(0)
  5884. {
  5885. if (is_string_node(binary_node<T>::branch_[0].first))
  5886. {
  5887. str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
  5888. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  5889. }
  5890. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  5891. {
  5892. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  5893. if (0 == str1_base_ptr_)
  5894. return;
  5895. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  5896. if (0 == range_ptr)
  5897. return;
  5898. str1_range_ptr_ = &(range_ptr->range_ref());
  5899. }
  5900. initialised_ = str0_base_ptr_ &&
  5901. str1_base_ptr_ &&
  5902. str0_node_ptr_ &&
  5903. str1_range_ptr_ ;
  5904. }
  5905. inline T value() const
  5906. {
  5907. if (initialised_)
  5908. {
  5909. binary_node<T>::branch_[1].first->value();
  5910. std::size_t r0 = 0;
  5911. std::size_t r1 = 0;
  5912. range_t& range = (*str1_range_ptr_);
  5913. if (range(r0,r1,str1_base_ptr_->size()))
  5914. {
  5915. AssignmentProcess::execute(str0_node_ptr_->ref(),
  5916. str1_base_ptr_->base() + r0,
  5917. (r1 - r0) + 1);
  5918. binary_node<T>::branch_[0].first->value();
  5919. }
  5920. }
  5921. return std::numeric_limits<T>::quiet_NaN();
  5922. }
  5923. std::string str() const
  5924. {
  5925. return str0_node_ptr_->str();
  5926. }
  5927. const char* base() const
  5928. {
  5929. return str0_node_ptr_->base();
  5930. }
  5931. std::size_t size() const
  5932. {
  5933. return str0_node_ptr_->size();
  5934. }
  5935. range_t& range_ref()
  5936. {
  5937. return str0_node_ptr_->range_ref();
  5938. }
  5939. const range_t& range_ref() const
  5940. {
  5941. return str0_node_ptr_->range_ref();
  5942. }
  5943. inline typename expression_node<T>::node_type type() const
  5944. {
  5945. return expression_node<T>::e_strass;
  5946. }
  5947. private:
  5948. bool initialised_;
  5949. str_base_ptr str0_base_ptr_;
  5950. str_base_ptr str1_base_ptr_;
  5951. strvar_node_ptr str0_node_ptr_;
  5952. range_ptr str1_range_ptr_;
  5953. };
  5954. template <typename T, typename AssignmentProcess = asn_assignment>
  5955. class assignment_string_range_node : public binary_node <T>,
  5956. public string_base_node<T>,
  5957. public range_interface <T>
  5958. {
  5959. public:
  5960. typedef expression_node <T>* expression_ptr;
  5961. typedef stringvar_node <T>* strvar_node_ptr;
  5962. typedef string_base_node<T>* str_base_ptr;
  5963. typedef range_pack <T> range_t;
  5964. typedef range_t* range_ptr;
  5965. typedef range_interface<T> irange_t;
  5966. typedef irange_t* irange_ptr;
  5967. typedef typename range_t::cached_range_t cached_range_t;
  5968. assignment_string_range_node(const operator_type& opr,
  5969. expression_ptr branch0,
  5970. expression_ptr branch1)
  5971. : binary_node<T>(opr,branch0,branch1),
  5972. initialised_(false),
  5973. str0_base_ptr_ (0),
  5974. str1_base_ptr_ (0),
  5975. str0_node_ptr_ (0),
  5976. str0_range_ptr_(0),
  5977. str1_range_ptr_(0)
  5978. {
  5979. if (is_string_range_node(binary_node<T>::branch_[0].first))
  5980. {
  5981. str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
  5982. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  5983. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  5984. if (0 == range_ptr)
  5985. return;
  5986. str0_range_ptr_ = &(range_ptr->range_ref());
  5987. }
  5988. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  5989. {
  5990. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  5991. if (0 == str1_base_ptr_)
  5992. return;
  5993. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  5994. if (0 == range_ptr)
  5995. return;
  5996. str1_range_ptr_ = &(range_ptr->range_ref());
  5997. }
  5998. initialised_ = str0_base_ptr_ &&
  5999. str1_base_ptr_ &&
  6000. str0_node_ptr_ &&
  6001. str0_range_ptr_ &&
  6002. str1_range_ptr_ ;
  6003. }
  6004. inline T value() const
  6005. {
  6006. if (initialised_)
  6007. {
  6008. binary_node<T>::branch_[0].first->value();
  6009. binary_node<T>::branch_[1].first->value();
  6010. std::size_t s0_r0 = 0;
  6011. std::size_t s0_r1 = 0;
  6012. std::size_t s1_r0 = 0;
  6013. std::size_t s1_r1 = 0;
  6014. range_t& range0 = (*str0_range_ptr_);
  6015. range_t& range1 = (*str1_range_ptr_);
  6016. if (
  6017. range0(s0_r0,s0_r1,str0_base_ptr_->size()) &&
  6018. range1(s1_r0,s1_r1,str1_base_ptr_->size())
  6019. )
  6020. {
  6021. std::size_t size = std::min((s0_r1 - s0_r0),(s1_r1 - s1_r0)) + 1;
  6022. std::copy(str1_base_ptr_->base() + s1_r0,
  6023. str1_base_ptr_->base() + s1_r0 + size,
  6024. const_cast<char*>(base() + s0_r0));
  6025. }
  6026. }
  6027. return std::numeric_limits<T>::quiet_NaN();
  6028. }
  6029. std::string str() const
  6030. {
  6031. return str0_node_ptr_->str();
  6032. }
  6033. const char* base() const
  6034. {
  6035. return str0_node_ptr_->base();
  6036. }
  6037. std::size_t size() const
  6038. {
  6039. return str0_node_ptr_->size();
  6040. }
  6041. range_t& range_ref()
  6042. {
  6043. return str0_node_ptr_->range_ref();
  6044. }
  6045. const range_t& range_ref() const
  6046. {
  6047. return str0_node_ptr_->range_ref();
  6048. }
  6049. inline typename expression_node<T>::node_type type() const
  6050. {
  6051. return expression_node<T>::e_strass;
  6052. }
  6053. private:
  6054. bool initialised_;
  6055. str_base_ptr str0_base_ptr_;
  6056. str_base_ptr str1_base_ptr_;
  6057. strvar_node_ptr str0_node_ptr_;
  6058. range_ptr str0_range_ptr_;
  6059. range_ptr str1_range_ptr_;
  6060. };
  6061. #endif
  6062. template <typename T, std::size_t N>
  6063. inline T axn(T a, T x)
  6064. {
  6065. // a*x^n
  6066. return a * exprtk::details::numeric::fast_exp<T,N>::result(x);
  6067. }
  6068. template <typename T, std::size_t N>
  6069. inline T axnb(T a, T x, T b)
  6070. {
  6071. // a*x^n+b
  6072. return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b;
  6073. }
  6074. template <typename T>
  6075. struct sf_base
  6076. {
  6077. typedef typename details::functor_t<T>::Type Type;
  6078. typedef typename details::functor_t<T> functor_t;
  6079. typedef typename functor_t::qfunc_t quaternary_functor_t;
  6080. typedef typename functor_t::tfunc_t trinary_functor_t;
  6081. typedef typename functor_t::bfunc_t binary_functor_t;
  6082. typedef typename functor_t::ufunc_t unary_functor_t;
  6083. };
  6084. #define define_sfop3(NN,OP0,OP1) \
  6085. template <typename T> \
  6086. struct sf##NN##_op : public sf_base<T> \
  6087. { \
  6088. typedef typename sf_base<T>::Type Type; \
  6089. static inline T process(Type x, Type y, Type z) \
  6090. { \
  6091. return (OP0); \
  6092. } \
  6093. static inline std::string id() \
  6094. { \
  6095. return OP1; \
  6096. } \
  6097. }; \
  6098. define_sfop3(00,(x + y) / z ,"(t+t)/t")
  6099. define_sfop3(01,(x + y) * z ,"(t+t)*t")
  6100. define_sfop3(02,(x + y) - z ,"(t+t)-t")
  6101. define_sfop3(03,(x + y) + z ,"(t+t)+t")
  6102. define_sfop3(04,(x - y) + z ,"(t-t)+t")
  6103. define_sfop3(05,(x - y) / z ,"(t-t)/t")
  6104. define_sfop3(06,(x - y) * z ,"(t-t)*t")
  6105. define_sfop3(07,(x * y) + z ,"(t*t)+t")
  6106. define_sfop3(08,(x * y) - z ,"(t*t)-t")
  6107. define_sfop3(09,(x * y) / z ,"(t*t)/t")
  6108. define_sfop3(10,(x * y) * z ,"(t*t)*t")
  6109. define_sfop3(11,(x / y) + z ,"(t/t)+t")
  6110. define_sfop3(12,(x / y) - z ,"(t/t)-t")
  6111. define_sfop3(13,(x / y) / z ,"(t/t)/t")
  6112. define_sfop3(14,(x / y) * z ,"(t/t)*t")
  6113. define_sfop3(15,x / (y + z) ,"t/(t+t)")
  6114. define_sfop3(16,x / (y - z) ,"t/(t-t)")
  6115. define_sfop3(17,x / (y * z) ,"t/(t*t)")
  6116. define_sfop3(18,x / (y / z) ,"t/(t/t)")
  6117. define_sfop3(19,x * (y + z) ,"t*(t+t)")
  6118. define_sfop3(20,x * (y - z) ,"t*(t-t)")
  6119. define_sfop3(21,x * (y * z) ,"t*(t*t)")
  6120. define_sfop3(22,x * (y / z) ,"t*(t/t)")
  6121. define_sfop3(23,x - (y + z) ,"t-(t+t)")
  6122. define_sfop3(24,x - (y - z) ,"t-(t-t)")
  6123. define_sfop3(25,x - (y / z) ,"t-(t/t)")
  6124. define_sfop3(26,x - (y * z) ,"t-(t*t)")
  6125. define_sfop3(27,x + (y * z) ,"t+(t*t)")
  6126. define_sfop3(28,x + (y / z) ,"t+(t/t)")
  6127. define_sfop3(29,x + (y + z) ,"t+(t+t)")
  6128. define_sfop3(30,x + (y - z) ,"t+(t-t)")
  6129. define_sfop3(31,(axnb<T,2>(x,y,z))," ")
  6130. define_sfop3(32,(axnb<T,3>(x,y,z))," ")
  6131. define_sfop3(33,(axnb<T,4>(x,y,z))," ")
  6132. define_sfop3(34,(axnb<T,5>(x,y,z))," ")
  6133. define_sfop3(35,(axnb<T,6>(x,y,z))," ")
  6134. define_sfop3(36,(axnb<T,7>(x,y,z))," ")
  6135. define_sfop3(37,(axnb<T,8>(x,y,z))," ")
  6136. define_sfop3(38,(axnb<T,9>(x,y,z))," ")
  6137. define_sfop3(39,x * numeric::log(y) + z,"")
  6138. define_sfop3(40,x * numeric::log(y) - z,"")
  6139. define_sfop3(41,x * numeric::log10(y) + z,"")
  6140. define_sfop3(42,x * numeric::log10(y) - z,"")
  6141. define_sfop3(43,x * numeric::sin(y) + z ,"")
  6142. define_sfop3(44,x * numeric::sin(y) - z ,"")
  6143. define_sfop3(45,x * numeric::cos(y) + z ,"")
  6144. define_sfop3(46,x * numeric::cos(y) - z ,"")
  6145. define_sfop3(47,details::is_true(x) ? y : z,"")
  6146. #define define_sfop4(NN,OP0,OP1) \
  6147. template <typename T> \
  6148. struct sf##NN##_op : public sf_base<T> \
  6149. { \
  6150. typedef typename sf_base<T>::Type Type; \
  6151. static inline T process(Type x, Type y, Type z, Type w) \
  6152. { \
  6153. return (OP0); \
  6154. } \
  6155. static inline std::string id() { return OP1; } \
  6156. }; \
  6157. define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
  6158. define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)")
  6159. define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)")
  6160. define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)")
  6161. define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)")
  6162. define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)")
  6163. define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)")
  6164. define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)")
  6165. define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)")
  6166. define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)")
  6167. define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)")
  6168. define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)")
  6169. define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)")
  6170. define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)")
  6171. define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)")
  6172. define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)")
  6173. define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)")
  6174. define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t")
  6175. define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t")
  6176. define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t")
  6177. define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t")
  6178. define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t")
  6179. define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t")
  6180. define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t")
  6181. define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t")
  6182. define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)")
  6183. define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)")
  6184. define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)")
  6185. define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)")
  6186. define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)")
  6187. define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)")
  6188. define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)")
  6189. define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))")
  6190. define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))")
  6191. define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))")
  6192. define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))")
  6193. define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"")
  6194. define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"")
  6195. define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"")
  6196. define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"")
  6197. define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"")
  6198. define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"")
  6199. define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"")
  6200. define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"")
  6201. define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"")
  6202. define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"")
  6203. define_sfop4(94,((x < y) ? z : w),"")
  6204. define_sfop4(95,((x <= y) ? z : w),"")
  6205. define_sfop4(96,((x > y) ? z : w),"")
  6206. define_sfop4(97,((x >= y) ? z : w),"")
  6207. define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"")
  6208. define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"")
  6209. define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)")
  6210. define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)")
  6211. define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)")
  6212. define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)")
  6213. define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)")
  6214. define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)")
  6215. define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)")
  6216. define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)")
  6217. define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)")
  6218. define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)")
  6219. define_sfop4(ext10,((x + y) * (z - w)),"(t+t)*(t-t)")
  6220. define_sfop4(ext11,((x + y) / (z - w)),"(t+t)/(t-t)")
  6221. define_sfop4(ext12,((x - y) - (z + w)),"(t-t)-(t+t)")
  6222. define_sfop4(ext13,((x - y) + (z + w)),"(t-t)+(t+t)")
  6223. define_sfop4(ext14,((x - y) * (z + w)),"(t-t)*(t+t)")
  6224. define_sfop4(ext15,((x - y) / (z + w)),"(t-t)/(t+t)")
  6225. define_sfop4(ext16,((x * y) - (z + w)),"(t*t)-(t+t)")
  6226. define_sfop4(ext17,((x / y) - (z + w)),"(t/t)-(t+t)")
  6227. define_sfop4(ext18,((x * y) + (z + w)),"(t*t)+(t+t)")
  6228. define_sfop4(ext19,((x / y) + (z + w)),"(t/t)+(t+t)")
  6229. define_sfop4(ext20,((x * y) + (z - w)),"(t*t)+(t-t)")
  6230. define_sfop4(ext21,((x / y) + (z - w)),"(t/t)+(t-t)")
  6231. define_sfop4(ext22,((x * y) - (z - w)),"(t*t)-(t-t)")
  6232. define_sfop4(ext23,((x / y) - (z - w)),"(t/t)-(t-t)")
  6233. define_sfop4(ext24,((x + y) * (z * w)),"(t+t)*(t*t)")
  6234. define_sfop4(ext25,((x + y) * (z / w)),"(t+t)*(t/t)")
  6235. define_sfop4(ext26,((x + y) / (z * w)),"(t+t)/(t*t)")
  6236. define_sfop4(ext27,((x + y) / (z / w)),"(t+t)/(t/t)")
  6237. define_sfop4(ext28,((x - y) / (z * w)),"(t-t)/(t*t)")
  6238. define_sfop4(ext29,((x - y) / (z / w)),"(t-t)/(t/t)")
  6239. define_sfop4(ext30,((x - y) * (z * w)),"(t-t)*(t*t)")
  6240. define_sfop4(ext31,((x - y) * (z / w)),"(t-t)*(t/t)")
  6241. define_sfop4(ext32,((x * y) * (z + w)),"(t*t)*(t+t)")
  6242. define_sfop4(ext33,((x / y) * (z + w)),"(t/t)*(t+t)")
  6243. define_sfop4(ext34,((x * y) / (z + w)),"(t*t)/(t+t)")
  6244. define_sfop4(ext35,((x / y) / (z + w)),"(t/t)/(t+t)")
  6245. define_sfop4(ext36,((x * y) / (z - w)),"(t*t)/(t-t)")
  6246. define_sfop4(ext37,((x / y) / (z - w)),"(t/t)/(t-t)")
  6247. define_sfop4(ext38,((x * y) * (z - w)),"(t*t)*(t-t)")
  6248. define_sfop4(ext39,((x * y) / (z * w)),"(t*t)/(t*t)")
  6249. define_sfop4(ext40,((x / y) * (z / w)),"(t/t)*(t/t)")
  6250. define_sfop4(ext41,((x / y) * (z - w)),"(t/t)*(t-t)")
  6251. define_sfop4(ext42,((x * y) * (z * w)),"(t*t)*(t*t)")
  6252. define_sfop4(ext43,(x + (y * (z / w))),"t+(t*(t/t))")
  6253. define_sfop4(ext44,(x - (y * (z / w))),"t-(t*(t/t))")
  6254. define_sfop4(ext45,(x + (y / (z * w))),"t+(t/(t*t))")
  6255. define_sfop4(ext46,(x - (y / (z * w))),"t-(t/(t*t))")
  6256. define_sfop4(ext47,(((x - y) - z) * w),"((t-t)-t)*t")
  6257. define_sfop4(ext48,(((x - y) - z) / w),"((t-t)-t)/t")
  6258. define_sfop4(ext49,(((x - y) + z) * w),"((t-t)+t)*t")
  6259. define_sfop4(ext50,(((x - y) + z) / w),"((t-t)+t)/t")
  6260. define_sfop4(ext51,((x + (y - z)) * w),"(t+(t-t))*t")
  6261. define_sfop4(ext52,((x + (y - z)) / w),"(t+(t-t))/t")
  6262. define_sfop4(ext53,((x + y) / (z + w)),"(t+t)/(t+t)")
  6263. define_sfop4(ext54,((x - y) / (z - w)),"(t-t)/(t-t)")
  6264. define_sfop4(ext55,((x + y) * (z + w)),"(t+t)*(t+t)")
  6265. define_sfop4(ext56,((x - y) * (z - w)),"(t-t)*(t-t)")
  6266. define_sfop4(ext57,((x - y) + (z - w)),"(t-t)+(t-t)")
  6267. define_sfop4(ext58,((x - y) - (z - w)),"(t-t)-(t-t)")
  6268. define_sfop4(ext59,((x / y) + (z * w)),"(t/t)+(t*t)")
  6269. #undef define_sfop3
  6270. #undef define_sfop4
  6271. template <typename T, typename SpecialFunction>
  6272. class sf3_node : public trinary_node<T>
  6273. {
  6274. public:
  6275. typedef expression_node<T>* expression_ptr;
  6276. sf3_node(const operator_type& opr,
  6277. expression_ptr branch0,
  6278. expression_ptr branch1,
  6279. expression_ptr branch2)
  6280. : trinary_node<T>(opr,branch0,branch1,branch2)
  6281. {}
  6282. inline T value() const
  6283. {
  6284. const T x = trinary_node<T>::branch_[0].first->value();
  6285. const T y = trinary_node<T>::branch_[1].first->value();
  6286. const T z = trinary_node<T>::branch_[2].first->value();
  6287. return SpecialFunction::process(x,y,z);
  6288. }
  6289. };
  6290. template <typename T, typename SpecialFunction>
  6291. class sf4_node : public quaternary_node<T>
  6292. {
  6293. public:
  6294. typedef expression_node<T>* expression_ptr;
  6295. sf4_node(const operator_type& opr,
  6296. expression_ptr branch0,
  6297. expression_ptr branch1,
  6298. expression_ptr branch2,
  6299. expression_ptr branch3)
  6300. : quaternary_node<T>(opr,branch0,branch1,branch2,branch3)
  6301. {}
  6302. inline T value() const
  6303. {
  6304. const T x = quaternary_node<T>::branch_[0].first->value();
  6305. const T y = quaternary_node<T>::branch_[1].first->value();
  6306. const T z = quaternary_node<T>::branch_[2].first->value();
  6307. const T w = quaternary_node<T>::branch_[3].first->value();
  6308. return SpecialFunction::process(x,y,z,w);
  6309. }
  6310. };
  6311. template <typename T, typename SpecialFunction>
  6312. class sf3_var_node : public expression_node<T>
  6313. {
  6314. public:
  6315. typedef expression_node<T>* expression_ptr;
  6316. sf3_var_node(const T& v0, const T& v1, const T& v2)
  6317. : v0_(v0),
  6318. v1_(v1),
  6319. v2_(v2)
  6320. {}
  6321. inline T value() const
  6322. {
  6323. return SpecialFunction::process(v0_,v1_,v2_);
  6324. }
  6325. inline typename expression_node<T>::node_type type() const
  6326. {
  6327. return expression_node<T>::e_trinary;
  6328. }
  6329. private:
  6330. sf3_var_node(sf3_var_node<T,SpecialFunction>&);
  6331. sf3_var_node<T,SpecialFunction>& operator=(sf3_var_node<T,SpecialFunction>&);
  6332. const T& v0_;
  6333. const T& v1_;
  6334. const T& v2_;
  6335. };
  6336. template <typename T, typename SpecialFunction>
  6337. class sf4_var_node : public expression_node<T>
  6338. {
  6339. public:
  6340. typedef expression_node<T>* expression_ptr;
  6341. sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
  6342. : v0_(v0),
  6343. v1_(v1),
  6344. v2_(v2),
  6345. v3_(v3)
  6346. {}
  6347. inline T value() const
  6348. {
  6349. return SpecialFunction::process(v0_,v1_,v2_,v3_);
  6350. }
  6351. inline typename expression_node<T>::node_type type() const
  6352. {
  6353. return expression_node<T>::e_trinary;
  6354. }
  6355. private:
  6356. sf4_var_node(sf4_var_node<T,SpecialFunction>&);
  6357. sf4_var_node<T,SpecialFunction>& operator=(sf4_var_node<T,SpecialFunction>&);
  6358. const T& v0_;
  6359. const T& v1_;
  6360. const T& v2_;
  6361. const T& v3_;
  6362. };
  6363. template <typename T, typename VarArgFunction>
  6364. class vararg_node : public expression_node<T>
  6365. {
  6366. public:
  6367. typedef expression_node<T>* expression_ptr;
  6368. template <typename Allocator,
  6369. template <typename,typename> class Sequence>
  6370. vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
  6371. {
  6372. arg_list_.resize(arg_list.size());
  6373. delete_branch_.resize(arg_list.size());
  6374. for (std::size_t i = 0; i < arg_list.size(); ++i)
  6375. {
  6376. if (arg_list[i])
  6377. {
  6378. arg_list_[i] = arg_list[i];
  6379. delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
  6380. }
  6381. else
  6382. {
  6383. arg_list_.clear();
  6384. delete_branch_.clear();
  6385. return;
  6386. }
  6387. }
  6388. }
  6389. ~vararg_node()
  6390. {
  6391. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  6392. {
  6393. if (arg_list_[i] && delete_branch_[i])
  6394. {
  6395. delete arg_list_[i];
  6396. arg_list_[i] = 0;
  6397. }
  6398. }
  6399. }
  6400. inline T value() const
  6401. {
  6402. if (!arg_list_.empty())
  6403. return VarArgFunction::process(arg_list_);
  6404. else
  6405. return std::numeric_limits<T>::quiet_NaN();
  6406. }
  6407. inline typename expression_node<T>::node_type type() const
  6408. {
  6409. return expression_node<T>::e_vararg;
  6410. }
  6411. private:
  6412. std::vector<expression_ptr> arg_list_;
  6413. std::vector<unsigned char> delete_branch_;
  6414. };
  6415. template <typename T, typename VarArgFunction>
  6416. class vararg_varnode : public expression_node<T>
  6417. {
  6418. public:
  6419. typedef expression_node<T>* expression_ptr;
  6420. template <typename Allocator,
  6421. template <typename,typename> class Sequence>
  6422. vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
  6423. {
  6424. arg_list_.resize(arg_list.size());
  6425. for (std::size_t i = 0; i < arg_list.size(); ++i)
  6426. {
  6427. if (arg_list[i] && is_variable_node(arg_list[i]))
  6428. {
  6429. variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]);
  6430. arg_list_[i] = (&var_node_ptr->ref());
  6431. }
  6432. else
  6433. {
  6434. arg_list_.clear();
  6435. return;
  6436. }
  6437. }
  6438. }
  6439. inline T value() const
  6440. {
  6441. if (!arg_list_.empty())
  6442. return VarArgFunction::process(arg_list_);
  6443. else
  6444. return std::numeric_limits<T>::quiet_NaN();
  6445. }
  6446. inline typename expression_node<T>::node_type type() const
  6447. {
  6448. return expression_node<T>::e_vararg;
  6449. }
  6450. private:
  6451. std::vector<const T*> arg_list_;
  6452. };
  6453. template <typename T, typename VecFunction>
  6454. class vectorize_node : public expression_node<T>
  6455. {
  6456. public:
  6457. typedef expression_node<T>* expression_ptr;
  6458. vectorize_node(const expression_ptr v)
  6459. : ivec_ptr_(0),
  6460. v_(v),
  6461. v_deletable_(branch_deletable(v_))
  6462. {
  6463. if (is_ivector_node(v))
  6464. {
  6465. ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v);
  6466. }
  6467. else
  6468. ivec_ptr_ = 0;
  6469. }
  6470. ~vectorize_node()
  6471. {
  6472. if (v_ && v_deletable_)
  6473. {
  6474. delete v_;
  6475. }
  6476. }
  6477. inline T value() const
  6478. {
  6479. if (ivec_ptr_)
  6480. {
  6481. v_->value();
  6482. return VecFunction::process(ivec_ptr_);
  6483. }
  6484. else
  6485. return std::numeric_limits<T>::quiet_NaN();
  6486. }
  6487. inline typename expression_node<T>::node_type type() const
  6488. {
  6489. return expression_node<T>::e_vecfunc;
  6490. }
  6491. private:
  6492. vector_interface<T>* ivec_ptr_;
  6493. expression_ptr v_;
  6494. bool v_deletable_;
  6495. };
  6496. template <typename T>
  6497. class assignment_node : public binary_node<T>
  6498. {
  6499. public:
  6500. typedef expression_node<T>* expression_ptr;
  6501. assignment_node(const operator_type& opr,
  6502. expression_ptr branch0,
  6503. expression_ptr branch1)
  6504. : binary_node<T>(opr,branch0,branch1),
  6505. var_node_ptr_(0)
  6506. {
  6507. if (is_variable_node(binary_node<T>::branch_[0].first))
  6508. {
  6509. var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
  6510. }
  6511. }
  6512. inline T value() const
  6513. {
  6514. if (var_node_ptr_)
  6515. {
  6516. T& result = var_node_ptr_->ref();
  6517. result = binary_node<T>::branch_[1].first->value();
  6518. return result;
  6519. }
  6520. else
  6521. return std::numeric_limits<T>::quiet_NaN();
  6522. }
  6523. private:
  6524. variable_node<T>* var_node_ptr_;
  6525. };
  6526. template <typename T>
  6527. class assignment_vec_elem_node : public binary_node<T>
  6528. {
  6529. public:
  6530. typedef expression_node<T>* expression_ptr;
  6531. assignment_vec_elem_node(const operator_type& opr,
  6532. expression_ptr branch0,
  6533. expression_ptr branch1)
  6534. : binary_node<T>(opr,branch0,branch1),
  6535. vec_node_ptr_(0)
  6536. {
  6537. if (is_vector_elem_node(binary_node<T>::branch_[0].first))
  6538. {
  6539. vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
  6540. }
  6541. }
  6542. inline T value() const
  6543. {
  6544. if (vec_node_ptr_)
  6545. {
  6546. T& result = vec_node_ptr_->ref();
  6547. result = binary_node<T>::branch_[1].first->value();
  6548. return result;
  6549. }
  6550. else
  6551. return std::numeric_limits<T>::quiet_NaN();
  6552. }
  6553. private:
  6554. vector_elem_node<T>* vec_node_ptr_;
  6555. };
  6556. template <typename T>
  6557. class assignment_vec_node : public binary_node<T>,
  6558. public vector_interface<T>
  6559. {
  6560. public:
  6561. typedef expression_node<T>* expression_ptr;
  6562. typedef vector_node<T>* vector_node_ptr;
  6563. assignment_vec_node(const operator_type& opr,
  6564. expression_ptr branch0,
  6565. expression_ptr branch1)
  6566. : binary_node<T>(opr,branch0,branch1),
  6567. vec_node_ptr_(0),
  6568. vec_size_ (0)
  6569. {
  6570. if (is_vector_node(binary_node<T>::branch_[0].first))
  6571. {
  6572. vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  6573. vec_size_ = vec_node_ptr_->ref().size();
  6574. }
  6575. }
  6576. inline T value() const
  6577. {
  6578. if (vec_node_ptr_)
  6579. {
  6580. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  6581. const T v = binary_node<T>::branch_[1].first->value();
  6582. for (std::size_t i = 0; i < vec_size_; ++i)
  6583. {
  6584. (*vec_hldr[i]) = v;
  6585. }
  6586. return vec_node_ptr_->value();
  6587. }
  6588. else
  6589. return std::numeric_limits<T>::quiet_NaN();
  6590. }
  6591. vector_node_ptr vec() const
  6592. {
  6593. return vec_node_ptr_;
  6594. }
  6595. vector_node_ptr vec()
  6596. {
  6597. return vec_node_ptr_;
  6598. }
  6599. inline typename expression_node<T>::node_type type() const
  6600. {
  6601. return expression_node<T>::e_vecvalass;
  6602. }
  6603. std::size_t size() const
  6604. {
  6605. return vec_size_;
  6606. }
  6607. private:
  6608. vector_node<T>* vec_node_ptr_;
  6609. std::size_t vec_size_;
  6610. };
  6611. template <typename T>
  6612. class assignment_vecvec_node : public binary_node<T>,
  6613. public vector_interface<T>
  6614. {
  6615. public:
  6616. typedef expression_node<T>* expression_ptr;
  6617. typedef vector_node<T>* vector_node_ptr;
  6618. assignment_vecvec_node(const operator_type& opr,
  6619. expression_ptr branch0,
  6620. expression_ptr branch1)
  6621. : binary_node<T>(opr,branch0,branch1),
  6622. vec0_node_ptr_(0),
  6623. vec1_node_ptr_(0),
  6624. vec_size_ (0)
  6625. {
  6626. if (is_vector_node(binary_node<T>::branch_[0].first))
  6627. {
  6628. vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  6629. }
  6630. if (is_vector_node(binary_node<T>::branch_[1].first))
  6631. {
  6632. vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
  6633. }
  6634. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  6635. {
  6636. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  6637. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  6638. {
  6639. vec1_node_ptr_ = vi->vec();
  6640. }
  6641. }
  6642. if (vec0_node_ptr_ && vec1_node_ptr_)
  6643. {
  6644. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  6645. vec1_node_ptr_->ref().size());
  6646. }
  6647. }
  6648. inline T value() const
  6649. {
  6650. binary_node<T>::branch_[1].first->value();
  6651. if (vec0_node_ptr_ && vec1_node_ptr_)
  6652. {
  6653. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  6654. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  6655. for (std::size_t i = 0; i < vec_size_; ++i)
  6656. {
  6657. (*vec0[i]) = (*vec1[i]);
  6658. }
  6659. return vec0_node_ptr_->value();
  6660. }
  6661. else
  6662. return std::numeric_limits<T>::quiet_NaN();
  6663. }
  6664. vector_node_ptr vec() const
  6665. {
  6666. return vec0_node_ptr_;
  6667. }
  6668. vector_node_ptr vec()
  6669. {
  6670. return vec0_node_ptr_;
  6671. }
  6672. inline typename expression_node<T>::node_type type() const
  6673. {
  6674. return expression_node<T>::e_vecvecass;
  6675. }
  6676. std::size_t size() const
  6677. {
  6678. return vec_size_;
  6679. }
  6680. private:
  6681. vector_node<T>* vec0_node_ptr_;
  6682. vector_node<T>* vec1_node_ptr_;
  6683. std::size_t vec_size_;
  6684. };
  6685. template <typename T, typename Operation>
  6686. class assignment_op_node : public binary_node<T>
  6687. {
  6688. public:
  6689. typedef expression_node<T>* expression_ptr;
  6690. assignment_op_node(const operator_type& opr,
  6691. expression_ptr branch0,
  6692. expression_ptr branch1)
  6693. : binary_node<T>(opr,branch0,branch1),
  6694. var_node_ptr_(0)
  6695. {
  6696. if (is_variable_node(binary_node<T>::branch_[0].first))
  6697. {
  6698. var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
  6699. }
  6700. }
  6701. inline T value() const
  6702. {
  6703. if (var_node_ptr_)
  6704. {
  6705. T& v = var_node_ptr_->ref();
  6706. v = Operation::process(v,binary_node<T>::branch_[1].first->value());
  6707. return v;
  6708. }
  6709. else
  6710. return std::numeric_limits<T>::quiet_NaN();
  6711. }
  6712. private:
  6713. variable_node<T>* var_node_ptr_;
  6714. };
  6715. template <typename T, typename Operation>
  6716. class assignment_vec_elem_op_node : public binary_node<T>
  6717. {
  6718. public:
  6719. typedef expression_node<T>* expression_ptr;
  6720. assignment_vec_elem_op_node(const operator_type& opr,
  6721. expression_ptr branch0,
  6722. expression_ptr branch1)
  6723. : binary_node<T>(opr,branch0,branch1),
  6724. vec_node_ptr_(0)
  6725. {
  6726. if (is_vector_elem_node(binary_node<T>::branch_[0].first))
  6727. {
  6728. vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
  6729. }
  6730. }
  6731. inline T value() const
  6732. {
  6733. if (vec_node_ptr_)
  6734. {
  6735. T& v = vec_node_ptr_->ref();
  6736. v = Operation::process(v,binary_node<T>::branch_[1].first->value());
  6737. return v;
  6738. }
  6739. else
  6740. return std::numeric_limits<T>::quiet_NaN();
  6741. }
  6742. private:
  6743. vector_elem_node<T>* vec_node_ptr_;
  6744. };
  6745. template <typename T, typename Operation>
  6746. class assignment_vec_op_node : public binary_node<T>,
  6747. public vector_interface<T>
  6748. {
  6749. public:
  6750. typedef expression_node<T>* expression_ptr;
  6751. typedef vector_node<T>* vector_node_ptr;
  6752. assignment_vec_op_node(const operator_type& opr,
  6753. expression_ptr branch0,
  6754. expression_ptr branch1)
  6755. : binary_node<T>(opr,branch0,branch1),
  6756. vec_node_ptr_(0),
  6757. vec_size_ (0)
  6758. {
  6759. if (is_vector_node(binary_node<T>::branch_[0].first))
  6760. {
  6761. vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  6762. vec_size_ = vec_node_ptr_->ref().size();
  6763. }
  6764. }
  6765. inline T value() const
  6766. {
  6767. if (vec_node_ptr_)
  6768. {
  6769. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  6770. const T v = binary_node<T>::branch_[1].first->value();
  6771. for (std::size_t i = 0; i < vec_size_; ++i)
  6772. {
  6773. T& vec_i = *vec_hldr[i];
  6774. vec_i = Operation::process(vec_i,v);
  6775. }
  6776. return vec_node_ptr_->value();
  6777. }
  6778. else
  6779. return std::numeric_limits<T>::quiet_NaN();
  6780. }
  6781. vector_node_ptr vec() const
  6782. {
  6783. return vec_node_ptr_;
  6784. }
  6785. vector_node_ptr vec()
  6786. {
  6787. return vec_node_ptr_;
  6788. }
  6789. inline typename expression_node<T>::node_type type() const
  6790. {
  6791. return expression_node<T>::e_vecopvalass;
  6792. }
  6793. std::size_t size() const
  6794. {
  6795. return vec_size_;
  6796. }
  6797. private:
  6798. vector_node<T>* vec_node_ptr_;
  6799. std::size_t vec_size_;
  6800. };
  6801. template <typename T, typename Operation>
  6802. class assignment_vecvec_op_node : public binary_node<T>,
  6803. public vector_interface<T>
  6804. {
  6805. public:
  6806. typedef expression_node<T>* expression_ptr;
  6807. typedef vector_node<T>* vector_node_ptr;
  6808. assignment_vecvec_op_node(const operator_type& opr,
  6809. expression_ptr branch0,
  6810. expression_ptr branch1)
  6811. : binary_node<T>(opr,branch0,branch1),
  6812. vec0_node_ptr_(0),
  6813. vec1_node_ptr_(0),
  6814. vec_size_ (0)
  6815. {
  6816. if (is_vector_node(binary_node<T>::branch_[0].first))
  6817. {
  6818. vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  6819. }
  6820. if (is_vector_node(binary_node<T>::branch_[1].first))
  6821. {
  6822. vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
  6823. }
  6824. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  6825. {
  6826. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  6827. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  6828. {
  6829. vec1_node_ptr_ = vi->vec();
  6830. }
  6831. }
  6832. if (vec0_node_ptr_ && vec1_node_ptr_)
  6833. {
  6834. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  6835. vec1_node_ptr_->ref().size());
  6836. }
  6837. }
  6838. inline T value() const
  6839. {
  6840. if (vec0_node_ptr_ && vec1_node_ptr_)
  6841. {
  6842. binary_node<T>::branch_[0].first->value();
  6843. binary_node<T>::branch_[1].first->value();
  6844. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  6845. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  6846. for (std::size_t i = 0; i < vec_size_; ++i)
  6847. {
  6848. T& vec0_i = *vec0[i];
  6849. T& vec1_i = *vec1[i];
  6850. vec0_i = Operation::process(vec0_i,vec1_i);
  6851. }
  6852. return vec0_node_ptr_->value();
  6853. }
  6854. else
  6855. return std::numeric_limits<T>::quiet_NaN();
  6856. }
  6857. vector_node_ptr vec() const
  6858. {
  6859. return vec0_node_ptr_;
  6860. }
  6861. vector_node_ptr vec()
  6862. {
  6863. return vec0_node_ptr_;
  6864. }
  6865. inline typename expression_node<T>::node_type type() const
  6866. {
  6867. return expression_node<T>::e_vecopvecass;
  6868. }
  6869. std::size_t size() const
  6870. {
  6871. return vec_size_;
  6872. }
  6873. private:
  6874. vector_node<T>* vec0_node_ptr_;
  6875. vector_node<T>* vec1_node_ptr_;
  6876. std::size_t vec_size_;
  6877. };
  6878. template <typename T, typename Operation>
  6879. class eqineq_vecvec_node : public binary_node<T>,
  6880. public vector_interface<T>
  6881. {
  6882. public:
  6883. typedef expression_node<T>* expression_ptr;
  6884. typedef vector_node<T>* vector_node_ptr;
  6885. eqineq_vecvec_node(const operator_type& opr,
  6886. expression_ptr branch0,
  6887. expression_ptr branch1)
  6888. : binary_node<T>(opr,branch0,branch1),
  6889. vec0_node_ptr_(0),
  6890. vec1_node_ptr_(0),
  6891. vec_size_ (0)
  6892. {
  6893. if (is_vector_node(binary_node<T>::branch_[0].first))
  6894. {
  6895. vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  6896. }
  6897. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  6898. {
  6899. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  6900. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  6901. {
  6902. vec0_node_ptr_ = vi->vec();
  6903. }
  6904. }
  6905. if (is_vector_node(binary_node<T>::branch_[1].first))
  6906. {
  6907. vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
  6908. }
  6909. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  6910. {
  6911. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  6912. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  6913. {
  6914. vec1_node_ptr_ = vi->vec();
  6915. }
  6916. }
  6917. if (vec0_node_ptr_ && vec1_node_ptr_)
  6918. {
  6919. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  6920. vec1_node_ptr_->ref().size());
  6921. }
  6922. }
  6923. inline T value() const
  6924. {
  6925. if (vec0_node_ptr_ && vec1_node_ptr_)
  6926. {
  6927. binary_node<T>::branch_[0].first->value();
  6928. binary_node<T>::branch_[1].first->value();
  6929. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  6930. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  6931. for (std::size_t i = 0; i < vec_size_; ++i)
  6932. {
  6933. if (std::equal_to<T>()(T(0),Operation::process(*vec0[i],*vec1[i])))
  6934. {
  6935. return T(0);
  6936. }
  6937. }
  6938. return T(1);
  6939. }
  6940. else
  6941. return std::numeric_limits<T>::quiet_NaN();
  6942. }
  6943. vector_node_ptr vec() const
  6944. {
  6945. return vec0_node_ptr_;
  6946. }
  6947. vector_node_ptr vec()
  6948. {
  6949. return vec0_node_ptr_;
  6950. }
  6951. inline typename expression_node<T>::node_type type() const
  6952. {
  6953. return expression_node<T>::e_vecvecineq;
  6954. }
  6955. std::size_t size() const
  6956. {
  6957. return vec_size_;
  6958. }
  6959. private:
  6960. vector_node<T>* vec0_node_ptr_;
  6961. vector_node<T>* vec1_node_ptr_;
  6962. std::size_t vec_size_;
  6963. };
  6964. template <typename T, typename Operation>
  6965. class eqineq_vecval_node : public binary_node<T>,
  6966. public vector_interface<T>
  6967. {
  6968. public:
  6969. typedef expression_node<T>* expression_ptr;
  6970. typedef vector_node<T>* vector_node_ptr;
  6971. eqineq_vecval_node(const operator_type& opr,
  6972. expression_ptr branch0,
  6973. expression_ptr branch1)
  6974. : binary_node<T>(opr,branch0,branch1),
  6975. vec_node_ptr_(0),
  6976. vec_size_ (0)
  6977. {
  6978. if (is_vector_node(binary_node<T>::branch_[0].first))
  6979. {
  6980. vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
  6981. }
  6982. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  6983. {
  6984. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  6985. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  6986. {
  6987. vec_node_ptr_ = vi->vec();
  6988. }
  6989. }
  6990. if (vec_node_ptr_)
  6991. {
  6992. vec_size_ = vec_node_ptr_->ref().size();
  6993. }
  6994. }
  6995. inline T value() const
  6996. {
  6997. if (vec_node_ptr_)
  6998. {
  6999. binary_node<T>::branch_[0].first->value();
  7000. T v = binary_node<T>::branch_[1].first->value();
  7001. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  7002. for (std::size_t i = 0; i < vec_size_; ++i)
  7003. {
  7004. if (std::equal_to<T>()(T(0),Operation::process(*vec_hldr[i],v)))
  7005. {
  7006. return T(0);
  7007. }
  7008. }
  7009. return T(1);
  7010. }
  7011. else
  7012. return std::numeric_limits<T>::quiet_NaN();
  7013. }
  7014. vector_node_ptr vec() const
  7015. {
  7016. return vec_node_ptr_;
  7017. }
  7018. vector_node_ptr vec()
  7019. {
  7020. return vec_node_ptr_;
  7021. }
  7022. inline typename expression_node<T>::node_type type() const
  7023. {
  7024. return expression_node<T>::e_vecvalineq;
  7025. }
  7026. std::size_t size() const
  7027. {
  7028. return vec_size_;
  7029. }
  7030. private:
  7031. vector_node<T>* vec_node_ptr_;
  7032. std::size_t vec_size_;
  7033. };
  7034. template <typename T, typename Operation>
  7035. class eqineq_valvec_node : public binary_node<T>,
  7036. public vector_interface<T>
  7037. {
  7038. public:
  7039. typedef expression_node<T>* expression_ptr;
  7040. typedef vector_node<T>* vector_node_ptr;
  7041. eqineq_valvec_node(const operator_type& opr,
  7042. expression_ptr branch0,
  7043. expression_ptr branch1)
  7044. : binary_node<T>(opr,branch0,branch1),
  7045. vec_node_ptr_(0),
  7046. vec_size_ (0)
  7047. {
  7048. if (is_vector_node(binary_node<T>::branch_[1].first))
  7049. {
  7050. vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
  7051. }
  7052. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7053. {
  7054. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7055. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7056. {
  7057. vec_node_ptr_ = vi->vec();
  7058. }
  7059. }
  7060. if (vec_node_ptr_)
  7061. {
  7062. vec_size_ = vec_node_ptr_->ref().size();
  7063. }
  7064. }
  7065. inline T value() const
  7066. {
  7067. if (vec_node_ptr_)
  7068. {
  7069. T v = binary_node<T>::branch_[0].first->value();
  7070. binary_node<T>::branch_[1].first->value();
  7071. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  7072. for (std::size_t i = 0; i < vec_size_; ++i)
  7073. {
  7074. if (std::equal_to<T>()(T(0),Operation::process(v,*vec_hldr[i])))
  7075. {
  7076. return T(0);
  7077. }
  7078. }
  7079. return T(1);
  7080. }
  7081. else
  7082. return std::numeric_limits<T>::quiet_NaN();
  7083. }
  7084. vector_node_ptr vec() const
  7085. {
  7086. return vec_node_ptr_;
  7087. }
  7088. vector_node_ptr vec()
  7089. {
  7090. return vec_node_ptr_;
  7091. }
  7092. inline typename expression_node<T>::node_type type() const
  7093. {
  7094. return expression_node<T>::e_valvecineq;
  7095. }
  7096. std::size_t size() const
  7097. {
  7098. return vec_size_;
  7099. }
  7100. private:
  7101. vector_node<T>* vec_node_ptr_;
  7102. std::size_t vec_size_;
  7103. };
  7104. template <typename T, typename Operation>
  7105. class vecarith_vecvec_node : public binary_node<T>,
  7106. public vector_interface<T>
  7107. {
  7108. public:
  7109. typedef expression_node<T>* expression_ptr;
  7110. typedef vector_node<T>* vector_node_ptr;
  7111. typedef vector_holder<T>* vector_holder_ptr;
  7112. vecarith_vecvec_node(const operator_type& opr,
  7113. expression_ptr branch0,
  7114. expression_ptr branch1)
  7115. : binary_node<T>(opr,branch0,branch1),
  7116. vec0_node_ptr_(0),
  7117. vec1_node_ptr_(0),
  7118. vec_size_ (0),
  7119. data_ (0),
  7120. temp_ (0),
  7121. temp_vec_node_(0)
  7122. {
  7123. if (is_vector_node(binary_node<T>::branch_[0].first))
  7124. {
  7125. vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
  7126. }
  7127. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  7128. {
  7129. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7130. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  7131. {
  7132. vec0_node_ptr_ = vi->vec();
  7133. }
  7134. }
  7135. if (is_vector_node(binary_node<T>::branch_[1].first))
  7136. {
  7137. vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
  7138. }
  7139. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7140. {
  7141. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7142. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7143. {
  7144. vec1_node_ptr_ = vi->vec();
  7145. }
  7146. }
  7147. if (vec0_node_ptr_ && vec1_node_ptr_)
  7148. {
  7149. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7150. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7151. vec_size_ = std::min(vec0.size(),vec1.size());
  7152. data_ = new T[vec_size_];
  7153. temp_ = new vector_holder<T>(data_,vec_size_);
  7154. temp_vec_node_ = new vector_node<T> (temp_);
  7155. }
  7156. }
  7157. ~vecarith_vecvec_node()
  7158. {
  7159. delete[] data_;
  7160. delete temp_;
  7161. delete temp_vec_node_;
  7162. }
  7163. inline T value() const
  7164. {
  7165. if (vec0_node_ptr_ && vec1_node_ptr_)
  7166. {
  7167. binary_node<T>::branch_[0].first->value();
  7168. binary_node<T>::branch_[1].first->value();
  7169. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7170. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7171. vector_holder<T>& vec2 = *temp_;
  7172. for (std::size_t i = 0; i < vec_size_; ++i)
  7173. {
  7174. T& vec0_i = *vec0[i];
  7175. T& vec1_i = *vec1[i];
  7176. T& vec2_i = *vec2[i];
  7177. vec2_i = Operation::process(vec0_i,vec1_i);
  7178. }
  7179. return *vec2[0];
  7180. }
  7181. else
  7182. return std::numeric_limits<T>::quiet_NaN();
  7183. }
  7184. vector_node_ptr vec() const
  7185. {
  7186. return temp_vec_node_;
  7187. }
  7188. vector_node_ptr vec()
  7189. {
  7190. return temp_vec_node_;
  7191. }
  7192. inline typename expression_node<T>::node_type type() const
  7193. {
  7194. return expression_node<T>::e_vecvecarith;
  7195. }
  7196. std::size_t size() const
  7197. {
  7198. return vec_size_;
  7199. }
  7200. private:
  7201. vector_node_ptr vec0_node_ptr_;
  7202. vector_node_ptr vec1_node_ptr_;
  7203. std::size_t vec_size_;
  7204. T* data_;
  7205. vector_holder_ptr temp_;
  7206. vector_node_ptr temp_vec_node_;
  7207. };
  7208. template <typename T, typename Operation>
  7209. class vecarith_vecval_node : public binary_node<T>,
  7210. public vector_interface<T>
  7211. {
  7212. public:
  7213. typedef expression_node<T>* expression_ptr;
  7214. typedef vector_node<T>* vector_node_ptr;
  7215. typedef vector_holder<T>* vector_holder_ptr;
  7216. vecarith_vecval_node(const operator_type& opr,
  7217. expression_ptr branch0,
  7218. expression_ptr branch1)
  7219. : binary_node<T>(opr,branch0,branch1),
  7220. vec0_node_ptr_(0),
  7221. vec_size_ (0),
  7222. data_ (0),
  7223. temp_ (0),
  7224. temp_vec_node_(0)
  7225. {
  7226. if (is_vector_node(binary_node<T>::branch_[0].first))
  7227. {
  7228. vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
  7229. }
  7230. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  7231. {
  7232. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7233. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  7234. {
  7235. vec0_node_ptr_ = vi->vec();
  7236. }
  7237. }
  7238. if (vec0_node_ptr_)
  7239. {
  7240. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7241. vec_size_ = vec0.size();
  7242. data_ = new T[vec_size_];
  7243. temp_ = new vector_holder<T>(data_,vec_size_);
  7244. temp_vec_node_ = new vector_node<T> (temp_);
  7245. }
  7246. }
  7247. ~vecarith_vecval_node()
  7248. {
  7249. delete[] data_;
  7250. delete temp_;
  7251. delete temp_vec_node_;
  7252. }
  7253. inline T value() const
  7254. {
  7255. if (vec0_node_ptr_)
  7256. {
  7257. binary_node<T>::branch_[0].first->value();
  7258. const T v = binary_node<T>::branch_[1].first->value();
  7259. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7260. vector_holder<T>& vec1 = *temp_;
  7261. for (std::size_t i = 0; i < vec_size_; ++i)
  7262. {
  7263. T& vec0_i = *vec0[i];
  7264. T& vec1_i = *vec1[i];
  7265. vec1_i = Operation::process(vec0_i,v);
  7266. }
  7267. return *vec1[0];
  7268. }
  7269. else
  7270. return std::numeric_limits<T>::quiet_NaN();
  7271. }
  7272. vector_node_ptr vec() const
  7273. {
  7274. return temp_vec_node_;
  7275. }
  7276. vector_node_ptr vec()
  7277. {
  7278. return temp_vec_node_;
  7279. }
  7280. inline typename expression_node<T>::node_type type() const
  7281. {
  7282. return expression_node<T>::e_vecvalarith;
  7283. }
  7284. std::size_t size() const
  7285. {
  7286. return vec_size_;
  7287. }
  7288. private:
  7289. vector_node_ptr vec0_node_ptr_;
  7290. std::size_t vec_size_;
  7291. T* data_;
  7292. vector_holder_ptr temp_;
  7293. vector_node_ptr temp_vec_node_;
  7294. };
  7295. template <typename T, typename Operation>
  7296. class vecarith_valvec_node : public binary_node<T>,
  7297. public vector_interface<T>
  7298. {
  7299. public:
  7300. typedef expression_node<T>* expression_ptr;
  7301. typedef vector_node<T>* vector_node_ptr;
  7302. typedef vector_holder<T>* vector_holder_ptr;
  7303. vecarith_valvec_node(const operator_type& opr,
  7304. expression_ptr branch0,
  7305. expression_ptr branch1)
  7306. : binary_node<T>(opr,branch0,branch1),
  7307. vec1_node_ptr_(0),
  7308. vec_size_ (0),
  7309. data_ (0),
  7310. temp_ (0),
  7311. temp_vec_node_(0)
  7312. {
  7313. if (is_vector_node(binary_node<T>::branch_[1].first))
  7314. {
  7315. vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
  7316. }
  7317. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7318. {
  7319. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7320. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7321. {
  7322. vec1_node_ptr_ = vi->vec();
  7323. }
  7324. }
  7325. if (vec1_node_ptr_)
  7326. {
  7327. vector_holder<T>& vec0 = vec1_node_ptr_->ref();
  7328. vec_size_ = vec0.size();
  7329. data_ = new T[vec_size_];
  7330. temp_ = new vector_holder<T>(data_,vec_size_);
  7331. temp_vec_node_ = new vector_node<T> (temp_);
  7332. }
  7333. }
  7334. ~vecarith_valvec_node()
  7335. {
  7336. delete[] data_;
  7337. delete temp_;
  7338. delete temp_vec_node_;
  7339. }
  7340. inline T value() const
  7341. {
  7342. if (vec1_node_ptr_)
  7343. {
  7344. const T v = binary_node<T>::branch_[0].first->value();
  7345. binary_node<T>::branch_[1].first->value();
  7346. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7347. vector_holder<T>& vec2 = *temp_;
  7348. for (std::size_t i = 0; i < vec_size_; ++i)
  7349. {
  7350. T& vec1_i = *vec1[i];
  7351. T& vec2_i = *vec2[i];
  7352. vec2_i = Operation::process(v,vec1_i);
  7353. }
  7354. return *vec2[0];
  7355. }
  7356. else
  7357. return std::numeric_limits<T>::quiet_NaN();
  7358. }
  7359. vector_node_ptr vec() const
  7360. {
  7361. return temp_vec_node_;
  7362. }
  7363. vector_node_ptr vec()
  7364. {
  7365. return temp_vec_node_;
  7366. }
  7367. inline typename expression_node<T>::node_type type() const
  7368. {
  7369. return expression_node<T>::e_vecvalarith;
  7370. }
  7371. std::size_t size() const
  7372. {
  7373. return vec_size_;
  7374. }
  7375. private:
  7376. vector_node_ptr vec1_node_ptr_;
  7377. std::size_t vec_size_;
  7378. T* data_;
  7379. vector_holder_ptr temp_;
  7380. vector_node_ptr temp_vec_node_;
  7381. };
  7382. template <typename T, typename Operation>
  7383. class unary_vector_node : public unary_node<T>,
  7384. public vector_interface<T>
  7385. {
  7386. public:
  7387. typedef expression_node<T>* expression_ptr;
  7388. typedef vector_node<T>* vector_node_ptr;
  7389. typedef vector_holder<T>* vector_holder_ptr;
  7390. unary_vector_node(const operator_type& opr, expression_ptr branch0)
  7391. : unary_node<T>(opr,branch0),
  7392. vec0_node_ptr_(0),
  7393. vec_size_ (0),
  7394. data_ (0),
  7395. temp_ (0),
  7396. temp_vec_node_(0)
  7397. {
  7398. if (is_vector_node(unary_node<T>::branch_))
  7399. {
  7400. vec0_node_ptr_ = static_cast<vector_node_ptr>(unary_node<T>::branch_);
  7401. }
  7402. else if (is_ivector_node(unary_node<T>::branch_))
  7403. {
  7404. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7405. if ((vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_)))
  7406. {
  7407. vec0_node_ptr_ = vi->vec();
  7408. }
  7409. }
  7410. if (vec0_node_ptr_)
  7411. {
  7412. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7413. vec_size_ = vec0.size();
  7414. data_ = new T[vec_size_];
  7415. temp_ = new vector_holder<T>(data_,vec_size_);
  7416. temp_vec_node_ = new vector_node<T> (temp_);
  7417. }
  7418. }
  7419. ~unary_vector_node()
  7420. {
  7421. delete[] data_;
  7422. delete temp_;
  7423. delete temp_vec_node_;
  7424. }
  7425. inline T value() const
  7426. {
  7427. unary_node<T>::branch_->value();
  7428. if (vec0_node_ptr_)
  7429. {
  7430. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7431. vector_holder<T>& vec1 = *temp_;
  7432. for (std::size_t i = 0; i < vec_size_; ++i)
  7433. {
  7434. T& vec0_i = *vec0[i];
  7435. T& vec1_i = *vec1[i];
  7436. vec1_i = Operation::process(vec0_i);
  7437. }
  7438. return *vec1[0];
  7439. }
  7440. else
  7441. return std::numeric_limits<T>::quiet_NaN();
  7442. }
  7443. vector_node_ptr vec() const
  7444. {
  7445. return temp_vec_node_;
  7446. }
  7447. vector_node_ptr vec()
  7448. {
  7449. return temp_vec_node_;
  7450. }
  7451. inline typename expression_node<T>::node_type type() const
  7452. {
  7453. return expression_node<T>::e_vecunaryop;
  7454. }
  7455. std::size_t size() const
  7456. {
  7457. return vec_size_;
  7458. }
  7459. private:
  7460. vector_node_ptr vec0_node_ptr_;
  7461. std::size_t vec_size_;
  7462. T* data_;
  7463. vector_holder_ptr temp_;
  7464. vector_node_ptr temp_vec_node_;
  7465. };
  7466. template <typename T>
  7467. class scand_node : public binary_node<T>
  7468. {
  7469. public:
  7470. typedef expression_node<T>* expression_ptr;
  7471. scand_node(const operator_type& opr,
  7472. expression_ptr branch0,
  7473. expression_ptr branch1)
  7474. : binary_node<T>(opr,branch0,branch1)
  7475. {}
  7476. inline T value() const
  7477. {
  7478. return (
  7479. std::not_equal_to<T>()
  7480. (T(0),binary_node<T>::branch_[0].first->value()) &&
  7481. std::not_equal_to<T>()
  7482. (T(0),binary_node<T>::branch_[1].first->value())
  7483. ) ? T(1) : T(0);
  7484. }
  7485. };
  7486. template <typename T>
  7487. class scor_node : public binary_node<T>
  7488. {
  7489. public:
  7490. typedef expression_node<T>* expression_ptr;
  7491. scor_node(const operator_type& opr,
  7492. expression_ptr branch0,
  7493. expression_ptr branch1)
  7494. : binary_node<T>(opr,branch0,branch1)
  7495. {}
  7496. inline T value() const
  7497. {
  7498. return (
  7499. std::not_equal_to<T>()
  7500. (T(0),binary_node<T>::branch_[0].first->value()) ||
  7501. std::not_equal_to<T>()
  7502. (T(0),binary_node<T>::branch_[1].first->value())
  7503. ) ? T(1) : T(0);
  7504. }
  7505. };
  7506. template <typename T, typename IFunction, std::size_t N>
  7507. class function_N_node : public expression_node<T>
  7508. {
  7509. public:
  7510. // Function of N paramters.
  7511. typedef expression_node<T>* expression_ptr;
  7512. typedef std::pair<expression_ptr,bool> branch_t;
  7513. typedef IFunction ifunction;
  7514. function_N_node(ifunction* func)
  7515. : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
  7516. parameter_count_(func->param_count)
  7517. {}
  7518. ~function_N_node()
  7519. {
  7520. cleanup_branches::execute<T,N>(branch_);
  7521. }
  7522. template <std::size_t NumBranches>
  7523. bool init_branches(expression_ptr (&b)[NumBranches])
  7524. {
  7525. // Needed for incompetent and broken msvc compiler versions
  7526. #ifdef _MSC_VER
  7527. #pragma warning(push)
  7528. #pragma warning(disable: 4127)
  7529. #endif
  7530. if (N != NumBranches)
  7531. return false;
  7532. else
  7533. {
  7534. for (std::size_t i = 0; i < NumBranches; ++i)
  7535. {
  7536. if (b[i])
  7537. branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
  7538. else
  7539. return false;
  7540. }
  7541. return true;
  7542. }
  7543. #ifdef _MSC_VER
  7544. #pragma warning(pop)
  7545. #endif
  7546. }
  7547. inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
  7548. {
  7549. return this < (&fn);
  7550. }
  7551. inline T value() const
  7552. {
  7553. // Needed for incompetent and broken msvc compiler versions
  7554. #ifdef _MSC_VER
  7555. #pragma warning(push)
  7556. #pragma warning(disable: 4127)
  7557. #endif
  7558. if ((0 == function_) || (0 == N))
  7559. return std::numeric_limits<T>::quiet_NaN();
  7560. else
  7561. {
  7562. T v[N];
  7563. evaluate_branches<T,N>::execute(v,branch_);
  7564. return invoke<T,N>::execute(*function_,v);
  7565. }
  7566. #ifdef _MSC_VER
  7567. #pragma warning(pop)
  7568. #endif
  7569. }
  7570. template <typename T_, std::size_t BranchCount>
  7571. struct evaluate_branches
  7572. {
  7573. static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
  7574. {
  7575. for (std::size_t i = 0; i < BranchCount; ++i)
  7576. {
  7577. v[i] = b[i].first->value();
  7578. }
  7579. }
  7580. };
  7581. template <typename T_>
  7582. struct evaluate_branches <T_,5>
  7583. {
  7584. static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
  7585. {
  7586. v[0] = b[0].first->value();
  7587. v[1] = b[1].first->value();
  7588. v[2] = b[2].first->value();
  7589. v[3] = b[3].first->value();
  7590. v[4] = b[4].first->value();
  7591. }
  7592. };
  7593. template <typename T_>
  7594. struct evaluate_branches <T_,4>
  7595. {
  7596. static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
  7597. {
  7598. v[0] = b[0].first->value();
  7599. v[1] = b[1].first->value();
  7600. v[2] = b[2].first->value();
  7601. v[3] = b[3].first->value();
  7602. }
  7603. };
  7604. template <typename T_>
  7605. struct evaluate_branches <T_,3>
  7606. {
  7607. static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
  7608. {
  7609. v[0] = b[0].first->value();
  7610. v[1] = b[1].first->value();
  7611. v[2] = b[2].first->value();
  7612. }
  7613. };
  7614. template <typename T_>
  7615. struct evaluate_branches <T_,2>
  7616. {
  7617. static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
  7618. {
  7619. v[0] = b[0].first->value();
  7620. v[1] = b[1].first->value();
  7621. }
  7622. };
  7623. template <typename T_>
  7624. struct evaluate_branches <T_,1>
  7625. {
  7626. static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
  7627. {
  7628. v[0] = b[0].first->value();
  7629. }
  7630. };
  7631. template <typename T_, std::size_t ParamCount>
  7632. struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
  7633. template <typename T_>
  7634. struct invoke<T_,20>
  7635. {
  7636. static inline T_ execute(ifunction& f, T_ (&v)[20])
  7637. { 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]); }
  7638. };
  7639. template <typename T_>
  7640. struct invoke<T_,19>
  7641. {
  7642. static inline T_ execute(ifunction& f, T_ (&v)[19])
  7643. { 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]); }
  7644. };
  7645. template <typename T_>
  7646. struct invoke<T_,18>
  7647. {
  7648. static inline T_ execute(ifunction& f, T_ (&v)[18])
  7649. { 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]); }
  7650. };
  7651. template <typename T_>
  7652. struct invoke<T_,17>
  7653. {
  7654. static inline T_ execute(ifunction& f, T_ (&v)[17])
  7655. { 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]); }
  7656. };
  7657. template <typename T_>
  7658. struct invoke<T_,16>
  7659. {
  7660. static inline T_ execute(ifunction& f, T_ (&v)[16])
  7661. { 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]); }
  7662. };
  7663. template <typename T_>
  7664. struct invoke<T_,15>
  7665. {
  7666. static inline T_ execute(ifunction& f, T_ (&v)[15])
  7667. { 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]); }
  7668. };
  7669. template <typename T_>
  7670. struct invoke<T_,14>
  7671. {
  7672. static inline T_ execute(ifunction& f, T_ (&v)[14])
  7673. { 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]); }
  7674. };
  7675. template <typename T_>
  7676. struct invoke<T_,13>
  7677. {
  7678. static inline T_ execute(ifunction& f, T_ (&v)[13])
  7679. { 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]); }
  7680. };
  7681. template <typename T_>
  7682. struct invoke<T_,12>
  7683. {
  7684. static inline T_ execute(ifunction& f, T_ (&v)[12])
  7685. { 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]); }
  7686. };
  7687. template <typename T_>
  7688. struct invoke<T_,11>
  7689. {
  7690. static inline T_ execute(ifunction& f, T_ (&v)[11])
  7691. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10]); }
  7692. };
  7693. template <typename T_>
  7694. struct invoke<T_,10>
  7695. {
  7696. static inline T_ execute(ifunction& f, T_ (&v)[10])
  7697. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); }
  7698. };
  7699. template <typename T_>
  7700. struct invoke<T_,9>
  7701. {
  7702. static inline T_ execute(ifunction& f, T_ (&v)[9])
  7703. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); }
  7704. };
  7705. template <typename T_>
  7706. struct invoke<T_,8>
  7707. {
  7708. static inline T_ execute(ifunction& f, T_ (&v)[8])
  7709. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); }
  7710. };
  7711. template <typename T_>
  7712. struct invoke<T_,7>
  7713. {
  7714. static inline T_ execute(ifunction& f, T_ (&v)[7])
  7715. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); }
  7716. };
  7717. template <typename T_>
  7718. struct invoke<T_,6>
  7719. {
  7720. static inline T_ execute(ifunction& f, T_ (&v)[6])
  7721. { return f(v[0],v[1],v[2],v[3],v[4],v[5]); }
  7722. };
  7723. template <typename T_>
  7724. struct invoke<T_,5>
  7725. {
  7726. static inline T_ execute(ifunction& f, T_ (&v)[5])
  7727. { return f(v[0],v[1],v[2],v[3],v[4]); }
  7728. };
  7729. template <typename T_>
  7730. struct invoke<T_,4>
  7731. {
  7732. static inline T_ execute(ifunction& f, T_ (&v)[4])
  7733. { return f(v[0],v[1],v[2],v[3]); }
  7734. };
  7735. template <typename T_>
  7736. struct invoke<T_,3>
  7737. {
  7738. static inline T_ execute(ifunction& f, T_ (&v)[3])
  7739. { return f(v[0],v[1],v[2]); }
  7740. };
  7741. template <typename T_>
  7742. struct invoke<T_,2>
  7743. {
  7744. static inline T_ execute(ifunction& f, T_ (&v)[2])
  7745. { return f(v[0],v[1]); }
  7746. };
  7747. template <typename T_>
  7748. struct invoke<T_,1>
  7749. {
  7750. static inline T_ execute(ifunction& f, T_ (&v)[1])
  7751. { return f(v[0]); }
  7752. };
  7753. inline typename expression_node<T>::node_type type() const
  7754. {
  7755. return expression_node<T>::e_function;
  7756. }
  7757. private:
  7758. ifunction* function_;
  7759. std::size_t parameter_count_;
  7760. branch_t branch_[N];
  7761. };
  7762. template <typename T, typename IFunction>
  7763. class function_N_node<T,IFunction,0> : public expression_node<T>
  7764. {
  7765. public:
  7766. typedef expression_node<T>* expression_ptr;
  7767. typedef IFunction ifunction;
  7768. function_N_node(ifunction* func)
  7769. : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
  7770. {}
  7771. inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
  7772. {
  7773. return this < (&fn);
  7774. }
  7775. inline T value() const
  7776. {
  7777. if (function_)
  7778. return (*function_)();
  7779. else
  7780. return std::numeric_limits<T>::quiet_NaN();
  7781. }
  7782. inline typename expression_node<T>::node_type type() const
  7783. {
  7784. return expression_node<T>::e_function;
  7785. }
  7786. private:
  7787. ifunction* function_;
  7788. };
  7789. template <typename T, typename VarArgFunction>
  7790. class vararg_function_node : public expression_node<T>
  7791. {
  7792. public:
  7793. typedef expression_node<T>* expression_ptr;
  7794. vararg_function_node(VarArgFunction* func,
  7795. const std::vector<expression_ptr>& arg_list)
  7796. : function_(func),
  7797. arg_list_(arg_list)
  7798. {
  7799. value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
  7800. }
  7801. ~vararg_function_node()
  7802. {
  7803. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  7804. {
  7805. if (arg_list_[i] && !details::is_variable_node(arg_list_[i]))
  7806. {
  7807. delete arg_list_[i];
  7808. arg_list_[i] = 0;
  7809. }
  7810. }
  7811. }
  7812. inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
  7813. {
  7814. return this < (&fn);
  7815. }
  7816. inline T value() const
  7817. {
  7818. if (function_)
  7819. {
  7820. populate_value_list();
  7821. return (*function_)(value_list_);
  7822. }
  7823. else
  7824. return std::numeric_limits<T>::quiet_NaN();
  7825. }
  7826. inline typename expression_node<T>::node_type type() const
  7827. {
  7828. return expression_node<T>::e_vafunction;
  7829. }
  7830. private:
  7831. inline void populate_value_list() const
  7832. {
  7833. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  7834. {
  7835. value_list_[i] = arg_list_[i]->value();
  7836. }
  7837. }
  7838. VarArgFunction* function_;
  7839. std::vector<expression_ptr> arg_list_;
  7840. mutable std::vector<T> value_list_;
  7841. };
  7842. template <typename T, typename GenericFunction>
  7843. class generic_function_node : public expression_node<T>
  7844. {
  7845. public:
  7846. typedef type_store<T> type_store_t;
  7847. typedef expression_node<T>* expression_ptr;
  7848. typedef variable_node<T> variable_node_t;
  7849. typedef vector_elem_node<T> vector_elem_node_t;
  7850. typedef vector_node<T> vector_node_t;
  7851. typedef variable_node_t* variable_node_ptr_t;
  7852. typedef vector_elem_node_t* vector_elem_node_ptr_t;
  7853. typedef vector_node_t* vector_node_ptr_t;
  7854. typedef range_interface<T> range_interface_t;
  7855. typedef range_data_type<T> range_data_type_t;
  7856. typedef range_pack<T> range_t;
  7857. typedef std::pair<expression_ptr,bool> branch_t;
  7858. typedef std::pair<void*,std::size_t> void_t;
  7859. typedef std::vector<T> tmp_vs_t;
  7860. typedef std::vector<type_store_t> typestore_list_t;
  7861. typedef std::vector<range_data_type_t> range_list_t;
  7862. generic_function_node(GenericFunction* func,
  7863. const std::vector<expression_ptr>& arg_list)
  7864. : function_(func),
  7865. arg_list_(arg_list)
  7866. {}
  7867. ~generic_function_node()
  7868. {
  7869. cleanup_branches::execute(branch_);
  7870. }
  7871. virtual bool init_branches()
  7872. {
  7873. expr_as_vec1_store_.resize(arg_list_.size(),T(0) );
  7874. typestore_list_ .resize(arg_list_.size(),type_store_t() );
  7875. range_list_ .resize(arg_list_.size(),range_data_type_t());
  7876. branch_ .resize(arg_list_.size(),branch_t((expression_ptr)0,false));
  7877. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  7878. {
  7879. type_store_t& ts = typestore_list_[i];
  7880. if (0 == arg_list_[i])
  7881. return false;
  7882. else if (is_ivector_node(arg_list_[i]))
  7883. {
  7884. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7885. if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i])))
  7886. return false;
  7887. ts.size = vi->size();
  7888. ts.data = vi->vec()->ref()[0];
  7889. ts.type = type_store_t::e_vector;
  7890. }
  7891. else if (is_generally_string_node(arg_list_[i]))
  7892. {
  7893. string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0);
  7894. if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i])))
  7895. return false;
  7896. ts.size = sbn->size();
  7897. ts.data = reinterpret_cast<void*>(const_cast<char*>(sbn->base()));
  7898. ts.type = type_store_t::e_string;
  7899. range_list_[i].data = ts.data;
  7900. range_list_[i].size = ts.size;
  7901. range_list_[i].type_size = sizeof(char);
  7902. range_list_[i].str_node = sbn;
  7903. if (is_generally_string_node(arg_list_[i]))
  7904. {
  7905. range_interface_t* ri = reinterpret_cast<range_interface_t*>(0);
  7906. if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i])))
  7907. return false;
  7908. range_t& rp = ri->range_ref();
  7909. if (
  7910. rp.const_range() &&
  7911. is_const_string_range_node(arg_list_[i])
  7912. )
  7913. {
  7914. ts.size = rp.const_size();
  7915. ts.data = static_cast<char*>(ts.data) + rp.n0_c.second;
  7916. range_list_[i].range = reinterpret_cast<range_t*>(0);
  7917. }
  7918. else
  7919. range_list_[i].range = &(ri->range_ref());
  7920. }
  7921. }
  7922. else if (is_variable_node(arg_list_[i]))
  7923. {
  7924. variable_node_ptr_t var = variable_node_ptr_t(0);
  7925. if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i])))
  7926. return false;
  7927. ts.size = 1;
  7928. ts.data = &var->ref();
  7929. ts.type = type_store_t::e_scalar;
  7930. }
  7931. else if (is_vector_elem_node(arg_list_[i]))
  7932. {
  7933. vector_elem_node_ptr_t var = vector_elem_node_ptr_t(0);
  7934. if (0 == (var = dynamic_cast<vector_elem_node_ptr_t>(arg_list_[i])))
  7935. return false;
  7936. ts.size = 1;
  7937. ts.data = reinterpret_cast<void*>(&var->ref());
  7938. ts.type = type_store_t::e_scalar;
  7939. }
  7940. else
  7941. {
  7942. ts.size = 1;
  7943. ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]);
  7944. ts.type = type_store_t::e_scalar;
  7945. }
  7946. branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]));
  7947. }
  7948. return true;
  7949. }
  7950. inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const
  7951. {
  7952. return this < (&fn);
  7953. }
  7954. inline T value() const
  7955. {
  7956. if (function_)
  7957. {
  7958. if (populate_value_list())
  7959. {
  7960. typedef typename GenericFunction::parameter_list_t parameter_list_t;
  7961. return (*function_)(parameter_list_t(typestore_list_));
  7962. }
  7963. }
  7964. return std::numeric_limits<T>::quiet_NaN();
  7965. }
  7966. inline typename expression_node<T>::node_type type() const
  7967. {
  7968. return expression_node<T>::e_genfunction;
  7969. }
  7970. protected:
  7971. inline virtual bool populate_value_list() const
  7972. {
  7973. for (std::size_t i = 0; i < branch_.size(); ++i)
  7974. {
  7975. expr_as_vec1_store_[i] = branch_[i].first->value();
  7976. }
  7977. for (std::size_t i = 0; i < branch_.size(); ++i)
  7978. {
  7979. range_data_type_t& rdt = range_list_[i];
  7980. if (rdt.range)
  7981. {
  7982. range_t& rp = (*rdt.range);
  7983. std::size_t r0 = 0;
  7984. std::size_t r1 = 0;
  7985. if (rp(r0,r1,rdt.size))
  7986. {
  7987. type_store_t& ts = typestore_list_[i];
  7988. ts.size = rp.cache_size();
  7989. if (ts.type == type_store_t::e_string)
  7990. ts.data = const_cast<char*>(rdt.str_node->base()) + rp.cache.first;
  7991. else
  7992. ts.data = static_cast<char*>(rdt.data) + (rp.cache.first * rdt.type_size);
  7993. }
  7994. else
  7995. return false;
  7996. }
  7997. }
  7998. return true;
  7999. }
  8000. GenericFunction* function_;
  8001. mutable typestore_list_t typestore_list_;
  8002. private:
  8003. std::vector<expression_ptr> arg_list_;
  8004. std::vector<branch_t> branch_;
  8005. mutable tmp_vs_t expr_as_vec1_store_;
  8006. mutable range_list_t range_list_;
  8007. };
  8008. template <typename T, typename StringFunction>
  8009. class string_function_node : public generic_function_node<T,StringFunction>,
  8010. public string_base_node<T>,
  8011. public range_interface <T>
  8012. {
  8013. public:
  8014. typedef generic_function_node<T, StringFunction> gen_function_t;
  8015. typedef range_pack<T> range_t;
  8016. string_function_node(StringFunction* func,
  8017. const std::vector<typename gen_function_t::expression_ptr>& arg_list)
  8018. : gen_function_t(func,arg_list)
  8019. {
  8020. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  8021. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  8022. range_.cache.first = range_.n0_c.second;
  8023. range_.cache.second = range_.n1_c.second;
  8024. }
  8025. inline bool operator <(const string_function_node<T,StringFunction>& fn) const
  8026. {
  8027. return this < (&fn);
  8028. }
  8029. inline T value() const
  8030. {
  8031. T result = std::numeric_limits<T>::quiet_NaN();
  8032. if (gen_function_t::function_)
  8033. {
  8034. if (gen_function_t::populate_value_list())
  8035. {
  8036. typedef typename StringFunction::parameter_list_t parameter_list_t;
  8037. result = (*gen_function_t::function_)(ret_string_,
  8038. parameter_list_t(gen_function_t::typestore_list_));
  8039. range_.n1_c.second = ret_string_.size() - 1;
  8040. range_.cache.second = range_.n1_c.second;
  8041. return result;
  8042. }
  8043. }
  8044. return result;
  8045. }
  8046. inline typename expression_node<T>::node_type type() const
  8047. {
  8048. return expression_node<T>::e_strfunction;
  8049. }
  8050. std::string str() const
  8051. {
  8052. return ret_string_;
  8053. }
  8054. const char* base() const
  8055. {
  8056. return ret_string_.data();
  8057. }
  8058. std::size_t size() const
  8059. {
  8060. return ret_string_.size();
  8061. }
  8062. range_t& range_ref()
  8063. {
  8064. return range_;
  8065. }
  8066. const range_t& range_ref() const
  8067. {
  8068. return range_;
  8069. }
  8070. protected:
  8071. mutable range_t range_;
  8072. mutable std::string ret_string_;
  8073. };
  8074. template <typename T, typename GenericFunction>
  8075. class multimode_genfunction_node : public generic_function_node<T,GenericFunction>
  8076. {
  8077. public:
  8078. typedef generic_function_node<T, GenericFunction> gen_function_t;
  8079. typedef range_pack<T> range_t;
  8080. multimode_genfunction_node(GenericFunction* func,
  8081. const std::size_t& param_seq_index,
  8082. const std::vector<typename gen_function_t::expression_ptr>& arg_list)
  8083. : gen_function_t(func,arg_list),
  8084. param_seq_index_(param_seq_index)
  8085. {}
  8086. inline T value() const
  8087. {
  8088. T result = std::numeric_limits<T>::quiet_NaN();
  8089. if (gen_function_t::function_)
  8090. {
  8091. if (gen_function_t::populate_value_list())
  8092. {
  8093. typedef typename GenericFunction::parameter_list_t parameter_list_t;
  8094. return (*gen_function_t::function_)(param_seq_index_,
  8095. parameter_list_t(gen_function_t::typestore_list_));
  8096. }
  8097. }
  8098. return result;
  8099. }
  8100. inline typename expression_node<T>::node_type type() const
  8101. {
  8102. return expression_node<T>::e_genfunction;
  8103. }
  8104. private:
  8105. std::size_t param_seq_index_;
  8106. };
  8107. template <typename T, typename StringFunction>
  8108. class multimode_strfunction_node : public string_function_node<T,StringFunction>
  8109. {
  8110. public:
  8111. typedef string_function_node<T, StringFunction> str_function_t;
  8112. typedef range_pack<T> range_t;
  8113. multimode_strfunction_node(StringFunction* func,
  8114. const std::size_t& param_seq_index,
  8115. const std::vector<typename str_function_t::expression_ptr>& arg_list)
  8116. : str_function_t(func,arg_list),
  8117. param_seq_index_(param_seq_index)
  8118. {}
  8119. inline T value() const
  8120. {
  8121. T result = std::numeric_limits<T>::quiet_NaN();
  8122. if (str_function_t::function_)
  8123. {
  8124. if (str_function_t::populate_value_list())
  8125. {
  8126. typedef typename StringFunction::parameter_list_t parameter_list_t;
  8127. result = (*str_function_t::function_)(param_seq_index_,
  8128. str_function_t::ret_string_,
  8129. parameter_list_t(str_function_t::typestore_list_));
  8130. str_function_t::range_.n1_c.second = str_function_t::ret_string_.size() - 1;
  8131. str_function_t::range_.cache.second = str_function_t::range_.n1_c.second;
  8132. return result;
  8133. }
  8134. }
  8135. return result;
  8136. }
  8137. inline typename expression_node<T>::node_type type() const
  8138. {
  8139. return expression_node<T>::e_strfunction;
  8140. }
  8141. private:
  8142. std::size_t param_seq_index_;
  8143. };
  8144. #define exprtk_define_unary_op(OpName) \
  8145. template <typename T> \
  8146. struct OpName##_op \
  8147. { \
  8148. typedef typename functor_t<T>::Type Type; \
  8149. \
  8150. static inline T process(Type v) \
  8151. { \
  8152. return numeric:: OpName (v); \
  8153. } \
  8154. \
  8155. static inline typename expression_node<T>::node_type type() \
  8156. { \
  8157. return expression_node<T>::e_##OpName; \
  8158. } \
  8159. \
  8160. static inline details::operator_type operation() \
  8161. { \
  8162. return details::e_##OpName; \
  8163. } \
  8164. }; \
  8165. exprtk_define_unary_op(abs )
  8166. exprtk_define_unary_op(acos )
  8167. exprtk_define_unary_op(acosh)
  8168. exprtk_define_unary_op(asin )
  8169. exprtk_define_unary_op(asinh)
  8170. exprtk_define_unary_op(atan )
  8171. exprtk_define_unary_op(atanh)
  8172. exprtk_define_unary_op(ceil )
  8173. exprtk_define_unary_op(cos )
  8174. exprtk_define_unary_op(cosh )
  8175. exprtk_define_unary_op(cot )
  8176. exprtk_define_unary_op(csc )
  8177. exprtk_define_unary_op(d2g )
  8178. exprtk_define_unary_op(d2r )
  8179. exprtk_define_unary_op(erf )
  8180. exprtk_define_unary_op(erfc )
  8181. exprtk_define_unary_op(exp )
  8182. exprtk_define_unary_op(expm1)
  8183. exprtk_define_unary_op(floor)
  8184. exprtk_define_unary_op(frac )
  8185. exprtk_define_unary_op(g2d )
  8186. exprtk_define_unary_op(log )
  8187. exprtk_define_unary_op(log10)
  8188. exprtk_define_unary_op(log2 )
  8189. exprtk_define_unary_op(log1p)
  8190. exprtk_define_unary_op(ncdf )
  8191. exprtk_define_unary_op(neg )
  8192. exprtk_define_unary_op(notl )
  8193. exprtk_define_unary_op(pos )
  8194. exprtk_define_unary_op(r2d )
  8195. exprtk_define_unary_op(round)
  8196. exprtk_define_unary_op(sec )
  8197. exprtk_define_unary_op(sgn )
  8198. exprtk_define_unary_op(sin )
  8199. exprtk_define_unary_op(sinc )
  8200. exprtk_define_unary_op(sinh )
  8201. exprtk_define_unary_op(sqrt )
  8202. exprtk_define_unary_op(tan )
  8203. exprtk_define_unary_op(tanh )
  8204. exprtk_define_unary_op(trunc)
  8205. #undef exprtk_define_unary_op
  8206. template <typename T>
  8207. struct opr_base
  8208. {
  8209. typedef typename details::functor_t<T>::Type Type;
  8210. typedef typename details::functor_t<T> functor_t;
  8211. typedef typename functor_t::qfunc_t quaternary_functor_t;
  8212. typedef typename functor_t::tfunc_t trinary_functor_t;
  8213. typedef typename functor_t::bfunc_t binary_functor_t;
  8214. typedef typename functor_t::ufunc_t unary_functor_t;
  8215. };
  8216. template <typename T>
  8217. struct add_op : public opr_base<T>
  8218. {
  8219. typedef typename opr_base<T>::Type Type;
  8220. static inline T process(Type t1, Type t2) { return t1 + t2; }
  8221. static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
  8222. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; }
  8223. static inline details::operator_type operation() { return details::e_add; }
  8224. };
  8225. template <typename T>
  8226. struct mul_op : public opr_base<T>
  8227. {
  8228. typedef typename opr_base<T>::Type Type;
  8229. static inline T process(Type t1, Type t2) { return t1 * t2; }
  8230. static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
  8231. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; }
  8232. static inline details::operator_type operation() { return details::e_mul; }
  8233. };
  8234. template <typename T>
  8235. struct sub_op : public opr_base<T>
  8236. {
  8237. typedef typename opr_base<T>::Type Type;
  8238. static inline T process(Type t1, Type t2) { return t1 - t2; }
  8239. static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
  8240. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; }
  8241. static inline details::operator_type operation() { return details::e_sub; }
  8242. };
  8243. template <typename T>
  8244. struct div_op : public opr_base<T>
  8245. {
  8246. typedef typename opr_base<T>::Type Type;
  8247. static inline T process(Type t1, Type t2) { return t1 / t2; }
  8248. static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
  8249. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; }
  8250. static inline details::operator_type operation() { return details::e_div; }
  8251. };
  8252. template <typename T>
  8253. struct mod_op : public opr_base<T>
  8254. {
  8255. typedef typename opr_base<T>::Type Type;
  8256. static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
  8257. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
  8258. static inline details::operator_type operation() { return details::e_mod; }
  8259. };
  8260. template <typename T>
  8261. struct pow_op : public opr_base<T>
  8262. {
  8263. typedef typename opr_base<T>::Type Type;
  8264. static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
  8265. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
  8266. static inline details::operator_type operation() { return details::e_pow; }
  8267. };
  8268. template <typename T>
  8269. struct lt_op : public opr_base<T>
  8270. {
  8271. typedef typename opr_base<T>::Type Type;
  8272. static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
  8273. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
  8274. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
  8275. static inline details::operator_type operation() { return details::e_lt; }
  8276. };
  8277. template <typename T>
  8278. struct lte_op : public opr_base<T>
  8279. {
  8280. typedef typename opr_base<T>::Type Type;
  8281. static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
  8282. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
  8283. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
  8284. static inline details::operator_type operation() { return details::e_lte; }
  8285. };
  8286. template <typename T>
  8287. struct gt_op : public opr_base<T>
  8288. {
  8289. typedef typename opr_base<T>::Type Type;
  8290. static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
  8291. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
  8292. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
  8293. static inline details::operator_type operation() { return details::e_gt; }
  8294. };
  8295. template <typename T>
  8296. struct gte_op : public opr_base<T>
  8297. {
  8298. typedef typename opr_base<T>::Type Type;
  8299. static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
  8300. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
  8301. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
  8302. static inline details::operator_type operation() { return details::e_gte; }
  8303. };
  8304. template <typename T>
  8305. struct eq_op : public opr_base<T>
  8306. {
  8307. typedef typename opr_base<T>::Type Type;
  8308. static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); }
  8309. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
  8310. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
  8311. static inline details::operator_type operation() { return details::e_eq; }
  8312. };
  8313. template <typename T>
  8314. struct ne_op : public opr_base<T>
  8315. {
  8316. typedef typename opr_base<T>::Type Type;
  8317. static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
  8318. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
  8319. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
  8320. static inline details::operator_type operation() { return details::e_ne; }
  8321. };
  8322. template <typename T>
  8323. struct and_op : public opr_base<T>
  8324. {
  8325. typedef typename opr_base<T>::Type Type;
  8326. static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
  8327. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
  8328. static inline details::operator_type operation() { return details::e_and; }
  8329. };
  8330. template <typename T>
  8331. struct nand_op : public opr_base<T>
  8332. {
  8333. typedef typename opr_base<T>::Type Type;
  8334. static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
  8335. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; }
  8336. static inline details::operator_type operation() { return details::e_nand; }
  8337. };
  8338. template <typename T>
  8339. struct or_op : public opr_base<T>
  8340. {
  8341. typedef typename opr_base<T>::Type Type;
  8342. static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
  8343. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
  8344. static inline details::operator_type operation() { return details::e_or; }
  8345. };
  8346. template <typename T>
  8347. struct nor_op : public opr_base<T>
  8348. {
  8349. typedef typename opr_base<T>::Type Type;
  8350. static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
  8351. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  8352. static inline details::operator_type operation() { return details::e_nor; }
  8353. };
  8354. template <typename T>
  8355. struct xor_op : public opr_base<T>
  8356. {
  8357. typedef typename opr_base<T>::Type Type;
  8358. static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
  8359. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  8360. static inline details::operator_type operation() { return details::e_xor; }
  8361. };
  8362. template <typename T>
  8363. struct xnor_op : public opr_base<T>
  8364. {
  8365. typedef typename opr_base<T>::Type Type;
  8366. static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
  8367. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  8368. static inline details::operator_type operation() { return details::e_xnor; }
  8369. };
  8370. template <typename T>
  8371. struct in_op : public opr_base<T>
  8372. {
  8373. typedef typename opr_base<T>::Type Type;
  8374. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  8375. static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
  8376. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
  8377. static inline details::operator_type operation() { return details::e_in; }
  8378. };
  8379. template <typename T>
  8380. struct like_op : public opr_base<T>
  8381. {
  8382. typedef typename opr_base<T>::Type Type;
  8383. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  8384. static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
  8385. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; }
  8386. static inline details::operator_type operation() { return details::e_like; }
  8387. };
  8388. template <typename T>
  8389. struct ilike_op : public opr_base<T>
  8390. {
  8391. typedef typename opr_base<T>::Type Type;
  8392. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  8393. static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
  8394. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; }
  8395. static inline details::operator_type operation() { return details::e_ilike; }
  8396. };
  8397. template <typename T>
  8398. struct inrange_op : public opr_base<T>
  8399. {
  8400. typedef typename opr_base<T>::Type Type;
  8401. static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
  8402. static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
  8403. {
  8404. return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
  8405. }
  8406. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_inranges; }
  8407. static inline details::operator_type operation() { return details::e_inrange; }
  8408. };
  8409. template <typename T>
  8410. inline T value(details::expression_node<T>* n)
  8411. {
  8412. return n->value();
  8413. }
  8414. template <typename T>
  8415. inline T value(T* t)
  8416. {
  8417. return (*t);
  8418. }
  8419. template <typename T>
  8420. struct vararg_add_op : public opr_base<T>
  8421. {
  8422. typedef typename opr_base<T>::Type Type;
  8423. template <typename Type,
  8424. typename Allocator,
  8425. template <typename,typename> class Sequence>
  8426. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8427. {
  8428. switch (arg_list.size())
  8429. {
  8430. case 0 : return T(0);
  8431. case 1 : return process_1(arg_list);
  8432. case 2 : return process_2(arg_list);
  8433. case 3 : return process_3(arg_list);
  8434. case 4 : return process_4(arg_list);
  8435. case 5 : return process_5(arg_list);
  8436. default :
  8437. {
  8438. T result = T(0);
  8439. for (std::size_t i = 0; i < arg_list.size(); ++i)
  8440. {
  8441. result += value(arg_list[i]);
  8442. }
  8443. return result;
  8444. }
  8445. }
  8446. }
  8447. template <typename Sequence>
  8448. static inline T process_1(const Sequence& arg_list)
  8449. {
  8450. return value(arg_list[0]);
  8451. }
  8452. template <typename Sequence>
  8453. static inline T process_2(const Sequence& arg_list)
  8454. {
  8455. return value(arg_list[0]) + value(arg_list[1]);
  8456. }
  8457. template <typename Sequence>
  8458. static inline T process_3(const Sequence& arg_list)
  8459. {
  8460. return value(arg_list[0]) + value(arg_list[1]) +
  8461. value(arg_list[2]);
  8462. }
  8463. template <typename Sequence>
  8464. static inline T process_4(const Sequence& arg_list)
  8465. {
  8466. return value(arg_list[0]) + value(arg_list[1]) +
  8467. value(arg_list[2]) + value(arg_list[3]);
  8468. }
  8469. template <typename Sequence>
  8470. static inline T process_5(const Sequence& arg_list)
  8471. {
  8472. return value(arg_list[0]) + value(arg_list[1]) +
  8473. value(arg_list[2]) + value(arg_list[3]) +
  8474. value(arg_list[4]);
  8475. }
  8476. };
  8477. template <typename T>
  8478. struct vararg_mul_op : public opr_base<T>
  8479. {
  8480. typedef typename opr_base<T>::Type Type;
  8481. template <typename Type,
  8482. typename Allocator,
  8483. template <typename,typename> class Sequence>
  8484. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8485. {
  8486. switch (arg_list.size())
  8487. {
  8488. case 0 : return T(0);
  8489. case 1 : return process_1(arg_list);
  8490. case 2 : return process_2(arg_list);
  8491. case 3 : return process_3(arg_list);
  8492. case 4 : return process_4(arg_list);
  8493. case 5 : return process_5(arg_list);
  8494. default :
  8495. {
  8496. T result = T(value(arg_list[0]));
  8497. for (std::size_t i = 1; i < arg_list.size(); ++i)
  8498. {
  8499. result *= value(arg_list[i]);
  8500. }
  8501. return result;
  8502. }
  8503. }
  8504. }
  8505. template <typename Sequence>
  8506. static inline T process_1(const Sequence& arg_list)
  8507. {
  8508. return value(arg_list[0]);
  8509. }
  8510. template <typename Sequence>
  8511. static inline T process_2(const Sequence& arg_list)
  8512. {
  8513. return value(arg_list[0]) * value(arg_list[1]);
  8514. }
  8515. template <typename Sequence>
  8516. static inline T process_3(const Sequence& arg_list)
  8517. {
  8518. return value(arg_list[0]) * value(arg_list[1]) *
  8519. value(arg_list[2]);
  8520. }
  8521. template <typename Sequence>
  8522. static inline T process_4(const Sequence& arg_list)
  8523. {
  8524. return value(arg_list[0]) * value(arg_list[1]) *
  8525. value(arg_list[2]) * value(arg_list[3]);
  8526. }
  8527. template <typename Sequence>
  8528. static inline T process_5(const Sequence& arg_list)
  8529. {
  8530. return value(arg_list[0]) * value(arg_list[1]) *
  8531. value(arg_list[2]) * value(arg_list[3]) *
  8532. value(arg_list[4]);
  8533. }
  8534. };
  8535. template <typename T>
  8536. struct vararg_avg_op : public opr_base<T>
  8537. {
  8538. typedef typename opr_base<T>::Type Type;
  8539. template <typename Type,
  8540. typename Allocator,
  8541. template <typename,typename> class Sequence>
  8542. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8543. {
  8544. switch (arg_list.size())
  8545. {
  8546. case 0 : return T(0);
  8547. case 1 : return process_1(arg_list);
  8548. case 2 : return process_2(arg_list);
  8549. case 3 : return process_3(arg_list);
  8550. case 4 : return process_4(arg_list);
  8551. case 5 : return process_5(arg_list);
  8552. default : return vararg_add_op<T>::process(arg_list) / arg_list.size();
  8553. }
  8554. }
  8555. template <typename Sequence>
  8556. static inline T process_1(const Sequence& arg_list)
  8557. {
  8558. return value(arg_list[0]);
  8559. }
  8560. template <typename Sequence>
  8561. static inline T process_2(const Sequence& arg_list)
  8562. {
  8563. return (value(arg_list[0]) + value(arg_list[1])) / T(2);
  8564. }
  8565. template <typename Sequence>
  8566. static inline T process_3(const Sequence& arg_list)
  8567. {
  8568. return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3);
  8569. }
  8570. template <typename Sequence>
  8571. static inline T process_4(const Sequence& arg_list)
  8572. {
  8573. return (value(arg_list[0]) + value(arg_list[1]) +
  8574. value(arg_list[2]) + value(arg_list[3])) / T(4);
  8575. }
  8576. template <typename Sequence>
  8577. static inline T process_5(const Sequence& arg_list)
  8578. {
  8579. return (value(arg_list[0]) + value(arg_list[1]) +
  8580. value(arg_list[2]) + value(arg_list[3]) +
  8581. value(arg_list[4])) / T(5);
  8582. }
  8583. };
  8584. template <typename T>
  8585. struct vararg_min_op : public opr_base<T>
  8586. {
  8587. typedef typename opr_base<T>::Type Type;
  8588. template <typename Type,
  8589. typename Allocator,
  8590. template <typename,typename> class Sequence>
  8591. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8592. {
  8593. switch (arg_list.size())
  8594. {
  8595. case 0 : return T(0);
  8596. case 1 : return process_1(arg_list);
  8597. case 2 : return process_2(arg_list);
  8598. case 3 : return process_3(arg_list);
  8599. case 4 : return process_4(arg_list);
  8600. case 5 : return process_5(arg_list);
  8601. default :
  8602. {
  8603. T result = T(value(arg_list[0]));
  8604. for (std::size_t i = 1; i < arg_list.size(); ++i)
  8605. {
  8606. const T v = value(arg_list[i]);
  8607. if (v < result)
  8608. result = v;
  8609. }
  8610. return result;
  8611. }
  8612. }
  8613. }
  8614. template <typename Sequence>
  8615. static inline T process_1(const Sequence& arg_list)
  8616. {
  8617. return value(arg_list[0]);
  8618. }
  8619. template <typename Sequence>
  8620. static inline T process_2(const Sequence& arg_list)
  8621. {
  8622. return std::min<T>(value(arg_list[0]),value(arg_list[1]));
  8623. }
  8624. template <typename Sequence>
  8625. static inline T process_3(const Sequence& arg_list)
  8626. {
  8627. return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
  8628. }
  8629. template <typename Sequence>
  8630. static inline T process_4(const Sequence& arg_list)
  8631. {
  8632. return std::min<T>(
  8633. std::min<T>(value(arg_list[0]),value(arg_list[1])),
  8634. std::min<T>(value(arg_list[2]),value(arg_list[3])));
  8635. }
  8636. template <typename Sequence>
  8637. static inline T process_5(const Sequence& arg_list)
  8638. {
  8639. return std::min<T>(
  8640. std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),
  8641. std::min<T>(value(arg_list[2]),value(arg_list[3]))),
  8642. value(arg_list[4]));
  8643. }
  8644. };
  8645. template <typename T>
  8646. struct vararg_max_op : public opr_base<T>
  8647. {
  8648. typedef typename opr_base<T>::Type Type;
  8649. template <typename Type,
  8650. typename Allocator,
  8651. template <typename,typename> class Sequence>
  8652. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8653. {
  8654. switch (arg_list.size())
  8655. {
  8656. case 0 : return T(0);
  8657. case 1 : return process_1(arg_list);
  8658. case 2 : return process_2(arg_list);
  8659. case 3 : return process_3(arg_list);
  8660. case 4 : return process_4(arg_list);
  8661. case 5 : return process_5(arg_list);
  8662. default :
  8663. {
  8664. T result = T(value(arg_list[0]));
  8665. for (std::size_t i = 1; i < arg_list.size(); ++i)
  8666. {
  8667. const T v = value(arg_list[i]);
  8668. if (v > result)
  8669. result = v;
  8670. }
  8671. return result;
  8672. }
  8673. }
  8674. }
  8675. template <typename Sequence>
  8676. static inline T process_1(const Sequence& arg_list)
  8677. {
  8678. return value(arg_list[0]);
  8679. }
  8680. template <typename Sequence>
  8681. static inline T process_2(const Sequence& arg_list)
  8682. {
  8683. return std::max<T>(value(arg_list[0]),value(arg_list[1]));
  8684. }
  8685. template <typename Sequence>
  8686. static inline T process_3(const Sequence& arg_list)
  8687. {
  8688. return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
  8689. }
  8690. template <typename Sequence>
  8691. static inline T process_4(const Sequence& arg_list)
  8692. {
  8693. return std::max<T>(
  8694. std::max<T>(value(arg_list[0]),value(arg_list[1])),
  8695. std::max<T>(value(arg_list[2]),value(arg_list[3])));
  8696. }
  8697. template <typename Sequence>
  8698. static inline T process_5(const Sequence& arg_list)
  8699. {
  8700. return std::max<T>(
  8701. std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),
  8702. std::max<T>(value(arg_list[2]),value(arg_list[3]))),
  8703. value(arg_list[4]));
  8704. }
  8705. };
  8706. template <typename T>
  8707. struct vararg_mand_op : public opr_base<T>
  8708. {
  8709. typedef typename opr_base<T>::Type Type;
  8710. template <typename Type,
  8711. typename Allocator,
  8712. template <typename,typename> class Sequence>
  8713. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8714. {
  8715. switch (arg_list.size())
  8716. {
  8717. case 1 : return process_1(arg_list);
  8718. case 2 : return process_2(arg_list);
  8719. case 3 : return process_3(arg_list);
  8720. case 4 : return process_4(arg_list);
  8721. case 5 : return process_5(arg_list);
  8722. default :
  8723. {
  8724. for (std::size_t i = 0; i < arg_list.size(); ++i)
  8725. {
  8726. if (std::equal_to<T>()(T(0),value(arg_list[i])))
  8727. return T(0);
  8728. }
  8729. return T(1);
  8730. }
  8731. }
  8732. }
  8733. template <typename Sequence>
  8734. static inline T process_1(const Sequence& arg_list)
  8735. {
  8736. return std::not_equal_to<T>()
  8737. (T(0),value(arg_list[0])) ? T(1) : T(0);
  8738. }
  8739. template <typename Sequence>
  8740. static inline T process_2(const Sequence& arg_list)
  8741. {
  8742. return (
  8743. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  8744. std::not_equal_to<T>()(T(0),value(arg_list[1]))
  8745. ) ? T(1) : T(0);
  8746. }
  8747. template <typename Sequence>
  8748. static inline T process_3(const Sequence& arg_list)
  8749. {
  8750. return (
  8751. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  8752. std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
  8753. std::not_equal_to<T>()(T(0),value(arg_list[2]))
  8754. ) ? T(1) : T(0);
  8755. }
  8756. template <typename Sequence>
  8757. static inline T process_4(const Sequence& arg_list)
  8758. {
  8759. return (
  8760. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  8761. std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
  8762. std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
  8763. std::not_equal_to<T>()(T(0),value(arg_list[3]))
  8764. ) ? T(1) : T(0);
  8765. }
  8766. template <typename Sequence>
  8767. static inline T process_5(const Sequence& arg_list)
  8768. {
  8769. return (
  8770. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  8771. std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
  8772. std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
  8773. std::not_equal_to<T>()(T(0),value(arg_list[3])) &&
  8774. std::not_equal_to<T>()(T(0),value(arg_list[4]))
  8775. ) ? T(1) : T(0);
  8776. }
  8777. };
  8778. template <typename T>
  8779. struct vararg_mor_op : public opr_base<T>
  8780. {
  8781. typedef typename opr_base<T>::Type Type;
  8782. template <typename Type,
  8783. typename Allocator,
  8784. template <typename,typename> class Sequence>
  8785. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8786. {
  8787. switch (arg_list.size())
  8788. {
  8789. case 1 : return process_1(arg_list);
  8790. case 2 : return process_2(arg_list);
  8791. case 3 : return process_3(arg_list);
  8792. case 4 : return process_4(arg_list);
  8793. case 5 : return process_5(arg_list);
  8794. default :
  8795. {
  8796. for (std::size_t i = 0; i < arg_list.size(); ++i)
  8797. {
  8798. if (std::not_equal_to<T>()(T(0),value(arg_list[i])))
  8799. return T(1);
  8800. }
  8801. return T(0);
  8802. }
  8803. }
  8804. }
  8805. template <typename Sequence>
  8806. static inline T process_1(const Sequence& arg_list)
  8807. {
  8808. return std::not_equal_to<T>()
  8809. (T(0),value(arg_list[0])) ? T(1) : T(0);
  8810. }
  8811. template <typename Sequence>
  8812. static inline T process_2(const Sequence& arg_list)
  8813. {
  8814. return (
  8815. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  8816. std::not_equal_to<T>()(T(0),value(arg_list[1]))
  8817. ) ? T(1) : T(0);
  8818. }
  8819. template <typename Sequence>
  8820. static inline T process_3(const Sequence& arg_list)
  8821. {
  8822. return (
  8823. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  8824. std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
  8825. std::not_equal_to<T>()(T(0),value(arg_list[2]))
  8826. ) ? T(1) : T(0);
  8827. }
  8828. template <typename Sequence>
  8829. static inline T process_4(const Sequence& arg_list)
  8830. {
  8831. return (
  8832. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  8833. std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
  8834. std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
  8835. std::not_equal_to<T>()(T(0),value(arg_list[3]))
  8836. ) ? T(1) : T(0);
  8837. }
  8838. template <typename Sequence>
  8839. static inline T process_5(const Sequence& arg_list)
  8840. {
  8841. return (
  8842. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  8843. std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
  8844. std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
  8845. std::not_equal_to<T>()(T(0),value(arg_list[3])) ||
  8846. std::not_equal_to<T>()(T(0),value(arg_list[4]))
  8847. ) ? T(1) : T(0);
  8848. }
  8849. };
  8850. template <typename T>
  8851. struct vararg_multi_op : public opr_base<T>
  8852. {
  8853. typedef typename opr_base<T>::Type Type;
  8854. template <typename Type,
  8855. typename Allocator,
  8856. template <typename,typename> class Sequence>
  8857. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8858. {
  8859. switch (arg_list.size())
  8860. {
  8861. case 0 : return std::numeric_limits<T>::quiet_NaN();
  8862. case 1 : return process_1(arg_list);
  8863. case 2 : return process_2(arg_list);
  8864. case 3 : return process_3(arg_list);
  8865. case 4 : return process_4(arg_list);
  8866. case 5 : return process_5(arg_list);
  8867. case 6 : return process_6(arg_list);
  8868. case 7 : return process_7(arg_list);
  8869. case 8 : return process_8(arg_list);
  8870. default :
  8871. {
  8872. for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
  8873. {
  8874. value(arg_list[i]);
  8875. }
  8876. return value(arg_list.back());
  8877. }
  8878. }
  8879. }
  8880. template <typename Sequence>
  8881. static inline T process_1(const Sequence& arg_list)
  8882. {
  8883. return value(arg_list[0]);
  8884. }
  8885. template <typename Sequence>
  8886. static inline T process_2(const Sequence& arg_list)
  8887. {
  8888. value(arg_list[0]);
  8889. return value(arg_list[1]);
  8890. }
  8891. template <typename Sequence>
  8892. static inline T process_3(const Sequence& arg_list)
  8893. {
  8894. value(arg_list[0]);
  8895. value(arg_list[1]);
  8896. return value(arg_list[2]);
  8897. }
  8898. template <typename Sequence>
  8899. static inline T process_4(const Sequence& arg_list)
  8900. {
  8901. value(arg_list[0]);
  8902. value(arg_list[1]);
  8903. value(arg_list[2]);
  8904. return value(arg_list[3]);
  8905. }
  8906. template <typename Sequence>
  8907. static inline T process_5(const Sequence& arg_list)
  8908. {
  8909. value(arg_list[0]);
  8910. value(arg_list[1]);
  8911. value(arg_list[2]);
  8912. value(arg_list[3]);
  8913. return value(arg_list[4]);
  8914. }
  8915. template <typename Sequence>
  8916. static inline T process_6(const Sequence& arg_list)
  8917. {
  8918. value(arg_list[0]);
  8919. value(arg_list[1]);
  8920. value(arg_list[2]);
  8921. value(arg_list[3]);
  8922. value(arg_list[4]);
  8923. return value(arg_list[5]);
  8924. }
  8925. template <typename Sequence>
  8926. static inline T process_7(const Sequence& arg_list)
  8927. {
  8928. value(arg_list[0]);
  8929. value(arg_list[1]);
  8930. value(arg_list[2]);
  8931. value(arg_list[3]);
  8932. value(arg_list[4]);
  8933. value(arg_list[5]);
  8934. return value(arg_list[6]);
  8935. }
  8936. template <typename Sequence>
  8937. static inline T process_8(const Sequence& arg_list)
  8938. {
  8939. value(arg_list[0]);
  8940. value(arg_list[1]);
  8941. value(arg_list[2]);
  8942. value(arg_list[3]);
  8943. value(arg_list[4]);
  8944. value(arg_list[5]);
  8945. value(arg_list[6]);
  8946. return value(arg_list[7]);
  8947. }
  8948. };
  8949. template <typename T>
  8950. struct vec_add_op
  8951. {
  8952. typedef vector_interface<T>* ivector_ptr;
  8953. static inline T process(const ivector_ptr v)
  8954. {
  8955. vector_holder<T>& vec = v->vec()->ref();
  8956. T result = T(0);
  8957. for (std::size_t i = 0; i < vec.size(); ++i)
  8958. {
  8959. result += (*vec[i]);
  8960. }
  8961. return result;
  8962. }
  8963. };
  8964. template <typename T>
  8965. struct vec_mul_op
  8966. {
  8967. typedef vector_interface<T>* ivector_ptr;
  8968. static inline T process(const ivector_ptr v)
  8969. {
  8970. vector_holder<T>& vec = v->vec()->ref();
  8971. T result = (*vec[0]);
  8972. for (std::size_t i = 1; i < vec.size(); ++i)
  8973. {
  8974. result *= (*vec[i]);
  8975. }
  8976. return result;
  8977. }
  8978. };
  8979. template <typename T>
  8980. struct vec_avg_op
  8981. {
  8982. typedef vector_interface<T>* ivector_ptr;
  8983. static inline T process(const ivector_ptr v)
  8984. {
  8985. vector_holder<T>& vec = v->vec()->ref();
  8986. T result = T(0);
  8987. for (std::size_t i = 0; i < vec.size(); ++i)
  8988. {
  8989. result += (*vec[i]);
  8990. }
  8991. return result / vec.size();
  8992. }
  8993. };
  8994. template <typename T>
  8995. struct vec_min_op
  8996. {
  8997. typedef vector_interface<T>* ivector_ptr;
  8998. static inline T process(const ivector_ptr v)
  8999. {
  9000. vector_holder<T>& vec = v->vec()->ref();
  9001. T result = (*vec[0]);
  9002. for (std::size_t i = 1; i < vec.size(); ++i)
  9003. {
  9004. T v_i = (*vec[i]);
  9005. if (v_i < result)
  9006. result = v_i;
  9007. }
  9008. return result;
  9009. }
  9010. };
  9011. template <typename T>
  9012. struct vec_max_op
  9013. {
  9014. typedef vector_interface<T>* ivector_ptr;
  9015. static inline T process(const ivector_ptr v)
  9016. {
  9017. vector_holder<T>& vec = v->vec()->ref();
  9018. T result = (*vec[0]);
  9019. for (std::size_t i = 1; i < vec.size(); ++i)
  9020. {
  9021. T v_i = (*vec[i]);
  9022. if (v_i > result)
  9023. result = v_i;
  9024. }
  9025. return result;
  9026. }
  9027. };
  9028. template <typename T>
  9029. class vov_base_node : public expression_node<T>
  9030. {
  9031. public:
  9032. inline virtual operator_type operation() const
  9033. {
  9034. return details::e_default;
  9035. }
  9036. virtual const T& v0() const = 0;
  9037. virtual const T& v1() const = 0;
  9038. };
  9039. template <typename T>
  9040. class cov_base_node : public expression_node<T>
  9041. {
  9042. public:
  9043. inline virtual operator_type operation() const
  9044. {
  9045. return details::e_default;
  9046. }
  9047. virtual const T c() const = 0;
  9048. virtual const T& v() const = 0;
  9049. };
  9050. template <typename T>
  9051. class voc_base_node : public expression_node<T>
  9052. {
  9053. public:
  9054. inline virtual operator_type operation() const
  9055. {
  9056. return details::e_default;
  9057. }
  9058. virtual const T c() const = 0;
  9059. virtual const T& v() const = 0;
  9060. };
  9061. template <typename T>
  9062. class vob_base_node : public expression_node<T>
  9063. {
  9064. public:
  9065. virtual const T& v() const = 0;
  9066. };
  9067. template <typename T>
  9068. class bov_base_node : public expression_node<T>
  9069. {
  9070. public:
  9071. virtual const T& v() const = 0;
  9072. };
  9073. template <typename T>
  9074. class cob_base_node : public expression_node<T>
  9075. {
  9076. public:
  9077. inline virtual operator_type operation() const
  9078. {
  9079. return details::e_default;
  9080. }
  9081. virtual const T c() const = 0;
  9082. virtual void set_c(const T) = 0;
  9083. virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
  9084. };
  9085. template <typename T>
  9086. class boc_base_node : public expression_node<T>
  9087. {
  9088. public:
  9089. inline virtual operator_type operation() const
  9090. {
  9091. return details::e_default;
  9092. }
  9093. virtual const T c() const = 0;
  9094. virtual void set_c(const T) = 0;
  9095. virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
  9096. };
  9097. template <typename T>
  9098. class uv_base_node : public expression_node<T>
  9099. {
  9100. public:
  9101. inline virtual operator_type operation() const
  9102. {
  9103. return details::e_default;
  9104. }
  9105. virtual const T& v() const = 0;
  9106. };
  9107. template <typename T>
  9108. class sos_base_node : public expression_node<T>
  9109. {
  9110. public:
  9111. inline virtual operator_type operation() const
  9112. {
  9113. return details::e_default;
  9114. }
  9115. };
  9116. template <typename T>
  9117. class sosos_base_node : public expression_node<T>
  9118. {
  9119. public:
  9120. inline virtual operator_type operation() const
  9121. {
  9122. return details::e_default;
  9123. }
  9124. };
  9125. template <typename T>
  9126. class T0oT1oT2_base_node : public expression_node<T>
  9127. {
  9128. public:
  9129. virtual std::string type_id() const = 0;
  9130. };
  9131. template <typename T>
  9132. class T0oT1oT2oT3_base_node : public expression_node<T>
  9133. {
  9134. public:
  9135. virtual std::string type_id() const = 0;
  9136. };
  9137. template <typename T, typename Operation>
  9138. class unary_variable_node : public uv_base_node<T>
  9139. {
  9140. public:
  9141. typedef expression_node<T>* expression_ptr;
  9142. typedef Operation operation_t;
  9143. explicit unary_variable_node(const T& var)
  9144. : v_(var)
  9145. {}
  9146. inline T value() const
  9147. {
  9148. return Operation::process(v_);
  9149. }
  9150. inline typename expression_node<T>::node_type type() const
  9151. {
  9152. return Operation::type();
  9153. }
  9154. inline operator_type operation() const
  9155. {
  9156. return Operation::operation();
  9157. }
  9158. inline const T& v() const
  9159. {
  9160. return v_;
  9161. }
  9162. private:
  9163. unary_variable_node(unary_variable_node<T,Operation>&);
  9164. unary_variable_node<T,Operation>& operator=(unary_variable_node<T,Operation>&);
  9165. const T& v_;
  9166. };
  9167. template <typename T>
  9168. class uvouv_node : public expression_node<T>
  9169. {
  9170. public:
  9171. // UOpr1(v0) Op UOpr2(v1)
  9172. typedef expression_node<T>* expression_ptr;
  9173. typedef typename details::functor_t<T> functor_t;
  9174. typedef typename functor_t::bfunc_t bfunc_t;
  9175. typedef typename functor_t::ufunc_t ufunc_t;
  9176. explicit uvouv_node(const T& var0,const T& var1,
  9177. ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
  9178. : v0_(var0),
  9179. v1_(var1),
  9180. u0_(uf0),
  9181. u1_(uf1),
  9182. f_ (bf)
  9183. {}
  9184. inline T value() const
  9185. {
  9186. return f_(u0_(v0_),u1_(v1_));
  9187. }
  9188. inline typename expression_node<T>::node_type type() const
  9189. {
  9190. return expression_node<T>::e_uvouv;
  9191. }
  9192. inline operator_type operation() const
  9193. {
  9194. return details::e_default;
  9195. }
  9196. inline const T& v0()
  9197. {
  9198. return v0_;
  9199. }
  9200. inline const T& v1()
  9201. {
  9202. return v1_;
  9203. }
  9204. inline ufunc_t u0()
  9205. {
  9206. return u0_;
  9207. }
  9208. inline ufunc_t u1()
  9209. {
  9210. return u1_;
  9211. }
  9212. inline ufunc_t f()
  9213. {
  9214. return f_;
  9215. }
  9216. private:
  9217. uvouv_node(uvouv_node<T>&);
  9218. uvouv_node<T>& operator=(uvouv_node<T>&);
  9219. const T& v0_;
  9220. const T& v1_;
  9221. const ufunc_t u0_;
  9222. const ufunc_t u1_;
  9223. const bfunc_t f_;
  9224. };
  9225. template <typename T, typename Operation>
  9226. class unary_branch_node : public expression_node<T>
  9227. {
  9228. public:
  9229. typedef expression_node<T>* expression_ptr;
  9230. typedef Operation operation_t;
  9231. explicit unary_branch_node(expression_ptr brnch)
  9232. : branch_(brnch),
  9233. branch_deletable_(branch_deletable(branch_))
  9234. {}
  9235. ~unary_branch_node()
  9236. {
  9237. if (branch_ && branch_deletable_)
  9238. {
  9239. delete branch_;
  9240. branch_ = 0;
  9241. }
  9242. }
  9243. inline T value() const
  9244. {
  9245. return Operation::process(branch_->value());
  9246. }
  9247. inline typename expression_node<T>::node_type type() const
  9248. {
  9249. return Operation::type();
  9250. }
  9251. inline operator_type operation() const
  9252. {
  9253. return Operation::operation();
  9254. }
  9255. inline expression_node<T>* branch(const std::size_t&) const
  9256. {
  9257. return branch_;
  9258. }
  9259. inline void release()
  9260. {
  9261. branch_deletable_ = false;
  9262. }
  9263. private:
  9264. unary_branch_node(unary_branch_node<T,Operation>&);
  9265. unary_branch_node<T,Operation>& operator=(unary_branch_node<T,Operation>&);
  9266. expression_ptr branch_;
  9267. bool branch_deletable_;
  9268. };
  9269. template <typename T> struct is_const { enum {result = 0}; };
  9270. template <typename T> struct is_const <const T> { enum {result = 1}; };
  9271. template <typename T> struct is_const_ref { enum {result = 0}; };
  9272. template <typename T> struct is_const_ref <const T&> { enum {result = 1}; };
  9273. template <typename T> struct is_ref { enum {result = 0}; };
  9274. template <typename T> struct is_ref<T&> { enum {result = 1}; };
  9275. template <typename T> struct is_ref<const T&> { enum {result = 0}; };
  9276. template <std::size_t State>
  9277. struct param_to_str { static std::string result() { static const std::string r("v"); return r; } };
  9278. template <>
  9279. struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } };
  9280. #define exprtk_crtype(Type) \
  9281. param_to_str<is_const_ref< Type >::result>::result() \
  9282. template <typename T>
  9283. struct T0oT1oT2process
  9284. {
  9285. typedef typename details::functor_t<T> functor_t;
  9286. typedef typename functor_t::bfunc_t bfunc_t;
  9287. struct mode0
  9288. {
  9289. static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
  9290. {
  9291. // (T0 o0 T1) o1 T2
  9292. return bf1(bf0(t0,t1),t2);
  9293. }
  9294. template <typename T0, typename T1, typename T2>
  9295. static inline std::string id()
  9296. {
  9297. static const std::string result = "(" + exprtk_crtype(T0) + "o" +
  9298. exprtk_crtype(T1) + ")o(" +
  9299. exprtk_crtype(T2) + ")" ;
  9300. return result;
  9301. }
  9302. };
  9303. struct mode1
  9304. {
  9305. static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
  9306. {
  9307. // T0 o0 (T1 o1 T2)
  9308. return bf0(t0,bf1(t1,t2));
  9309. }
  9310. template <typename T0, typename T1, typename T2>
  9311. static inline std::string id()
  9312. {
  9313. static const std::string result = "(" + exprtk_crtype(T0) + ")o(" +
  9314. exprtk_crtype(T1) + "o" +
  9315. exprtk_crtype(T2) + ")" ;
  9316. return result;
  9317. }
  9318. };
  9319. };
  9320. template <typename T>
  9321. struct T0oT1oT20T3process
  9322. {
  9323. typedef typename details::functor_t<T> functor_t;
  9324. typedef typename functor_t::bfunc_t bfunc_t;
  9325. struct mode0
  9326. {
  9327. static inline T process(const T& t0, const T& t1,
  9328. const T& t2, const T& t3,
  9329. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9330. {
  9331. // (T0 o0 T1) o1 (T2 o2 T3)
  9332. return bf1(bf0(t0,t1),bf2(t2,t3));
  9333. }
  9334. template <typename T0, typename T1, typename T2, typename T3>
  9335. static inline std::string id()
  9336. {
  9337. static const std::string result = "(" + exprtk_crtype(T0) + "o" +
  9338. exprtk_crtype(T1) + ")o" +
  9339. "(" + exprtk_crtype(T2) + "o" +
  9340. exprtk_crtype(T3) + ")" ;
  9341. return result;
  9342. }
  9343. };
  9344. struct mode1
  9345. {
  9346. static inline T process(const T& t0, const T& t1,
  9347. const T& t2, const T& t3,
  9348. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9349. {
  9350. // (T0 o0 (T1 o1 (T2 o2 T3))
  9351. return bf0(t0,bf1(t1,bf2(t2,t3)));
  9352. }
  9353. template <typename T0, typename T1, typename T2, typename T3>
  9354. static inline std::string id()
  9355. {
  9356. static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
  9357. exprtk_crtype(T1) + ")o(" +
  9358. exprtk_crtype(T2) + "o" +
  9359. exprtk_crtype(T3) + "))" ;
  9360. return result;
  9361. }
  9362. };
  9363. struct mode2
  9364. {
  9365. static inline T process(const T& t0, const T& t1,
  9366. const T& t2, const T& t3,
  9367. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9368. {
  9369. // (T0 o0 ((T1 o1 T2) o2 T3)
  9370. return bf0(t0,bf2(bf1(t1,t2),t3));
  9371. }
  9372. template <typename T0, typename T1, typename T2, typename T3>
  9373. static inline std::string id()
  9374. {
  9375. static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
  9376. exprtk_crtype(T1) + "o" +
  9377. exprtk_crtype(T2) + ")o(" +
  9378. exprtk_crtype(T3) + "))" ;
  9379. return result;
  9380. }
  9381. };
  9382. struct mode3
  9383. {
  9384. static inline T process(const T& t0, const T& t1,
  9385. const T& t2, const T& t3,
  9386. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9387. {
  9388. // (((T0 o0 T1) o1 T2) o2 T3)
  9389. return bf2(bf1(bf0(t0,t1),t2),t3);
  9390. }
  9391. template <typename T0, typename T1, typename T2, typename T3>
  9392. static inline std::string id()
  9393. {
  9394. static const std::string result = "((" + exprtk_crtype(T0) + "o" +
  9395. exprtk_crtype(T1) + ")o(" +
  9396. exprtk_crtype(T2) + "))o(" +
  9397. exprtk_crtype(T3) + ")";
  9398. return result;
  9399. }
  9400. };
  9401. struct mode4
  9402. {
  9403. static inline T process(const T& t0, const T& t1,
  9404. const T& t2, const T& t3,
  9405. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9406. {
  9407. // ((T0 o0 (T1 o1 T2)) o2 T3
  9408. return bf2(bf0(t0,bf1(t1,t2)),t3);
  9409. }
  9410. template <typename T0, typename T1, typename T2, typename T3>
  9411. static inline std::string id()
  9412. {
  9413. static const std::string result = "((" + exprtk_crtype(T0) + ")o(" +
  9414. exprtk_crtype(T1) + "o" +
  9415. exprtk_crtype(T2) + "))o(" +
  9416. exprtk_crtype(T3) + ")" ;
  9417. return result;
  9418. }
  9419. };
  9420. };
  9421. #undef exprtk_crtype
  9422. template <typename T, typename T0, typename T1>
  9423. struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; };
  9424. template <typename T, typename T0, typename T1>
  9425. const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none;
  9426. #define synthesis_node_type_define(T0_,T1_,v_) \
  9427. template <typename T, typename T0, typename T1> \
  9428. struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
  9429. template <typename T, typename T0, typename T1> \
  9430. const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
  9431. synthesis_node_type_define(const T0&,const T1&, e_vov)
  9432. synthesis_node_type_define(const T0&,const T1 , e_voc)
  9433. synthesis_node_type_define(const T0 ,const T1&, e_cov)
  9434. synthesis_node_type_define( T0&, T1&,e_none)
  9435. synthesis_node_type_define(const T0 ,const T1 ,e_none)
  9436. synthesis_node_type_define( T0&,const T1 ,e_none)
  9437. synthesis_node_type_define(const T0 , T1&,e_none)
  9438. synthesis_node_type_define(const T0&, T1&,e_none)
  9439. synthesis_node_type_define( T0&,const T1&,e_none)
  9440. #undef synthesis_node_type_define
  9441. template <typename T, typename T0, typename T1, typename T2>
  9442. struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
  9443. template <typename T, typename T0, typename T1, typename T2>
  9444. const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none;
  9445. #define synthesis_node_type_define(T0_,T1_,T2_,v_) \
  9446. template <typename T, typename T0, typename T1, typename T2> \
  9447. struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
  9448. template <typename T, typename T0, typename T1, typename T2> \
  9449. const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
  9450. synthesis_node_type_define(const T0&,const T1&,const T2&, e_vovov)
  9451. synthesis_node_type_define(const T0&,const T1&,const T2 , e_vovoc)
  9452. synthesis_node_type_define(const T0&,const T1 ,const T2&, e_vocov)
  9453. synthesis_node_type_define(const T0 ,const T1&,const T2&, e_covov)
  9454. synthesis_node_type_define(const T0 ,const T1&,const T2 , e_covoc)
  9455. synthesis_node_type_define(const T0 ,const T1 ,const T2 , e_none )
  9456. synthesis_node_type_define(const T0 ,const T1 ,const T2&, e_none )
  9457. synthesis_node_type_define(const T0&,const T1 ,const T2 , e_none )
  9458. synthesis_node_type_define( T0&, T1&, T2&, e_none )
  9459. #undef synthesis_node_type_define
  9460. template <typename T, typename T0, typename T1, typename T2, typename T3>
  9461. struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; };
  9462. template <typename T, typename T0, typename T1, typename T2, typename T3>
  9463. const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none;
  9464. #define synthesis_node_type_define(T0_,T1_,T2_,T3_,v_) \
  9465. template <typename T, typename T0, typename T1, typename T2, typename T3> \
  9466. struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
  9467. template <typename T, typename T0, typename T1, typename T2, typename T3> \
  9468. const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
  9469. synthesis_node_type_define(const T0&,const T1&,const T2&, const T3&,e_vovovov)
  9470. synthesis_node_type_define(const T0&,const T1&,const T2&, const T3 ,e_vovovoc)
  9471. synthesis_node_type_define(const T0&,const T1&,const T2 , const T3&,e_vovocov)
  9472. synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3&,e_vocovov)
  9473. synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3&,e_covovov)
  9474. synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3&,e_covocov)
  9475. synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc)
  9476. synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3 ,e_covovoc)
  9477. synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3&,e_vococov)
  9478. synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3 ,e_none )
  9479. synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3&,e_none )
  9480. synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3 ,e_none )
  9481. synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3 ,e_none )
  9482. synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3 ,e_none )
  9483. synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3&,e_none )
  9484. synthesis_node_type_define(const T0&,const T1&,const T2 , const T3 ,e_none )
  9485. #undef synthesis_node_type_define
  9486. template <typename T, typename T0, typename T1>
  9487. class T0oT1 : public expression_node<T>
  9488. {
  9489. public:
  9490. typedef typename details::functor_t<T> functor_t;
  9491. typedef typename functor_t::bfunc_t bfunc_t;
  9492. typedef T value_type;
  9493. typedef T0oT1<T,T0,T1> node_type;
  9494. T0oT1(T0 p0, T1 p1, const bfunc_t p2)
  9495. : t0_(p0),
  9496. t1_(p1),
  9497. f_ (p2)
  9498. {}
  9499. inline typename expression_node<T>::node_type type() const
  9500. {
  9501. static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result;
  9502. return result;
  9503. }
  9504. inline operator_type operation() const
  9505. {
  9506. return e_default;
  9507. }
  9508. inline T value() const
  9509. {
  9510. return f_(t0_,t1_);
  9511. }
  9512. inline T0 t0() const
  9513. {
  9514. return t0_;
  9515. }
  9516. inline T1 t1() const
  9517. {
  9518. return t1_;
  9519. }
  9520. inline bfunc_t f() const
  9521. {
  9522. return f_;
  9523. }
  9524. template <typename Allocator>
  9525. static inline expression_node<T>* allocate(Allocator& allocator,
  9526. T0 p0, T1 p1,
  9527. bfunc_t p2)
  9528. {
  9529. return allocator.template allocate_type<node_type,T0,T1,bfunc_t&>(p0,p1,p2);
  9530. }
  9531. private:
  9532. T0oT1(T0oT1<T,T0,T1>&) {}
  9533. T0oT1<T,T0,T1>& operator=(T0oT1<T,T0,T1>&) { return *this; }
  9534. T0 t0_;
  9535. T1 t1_;
  9536. const bfunc_t f_;
  9537. };
  9538. template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
  9539. class T0oT1oT2 : public T0oT1oT2_base_node<T>
  9540. {
  9541. public:
  9542. typedef typename details::functor_t<T> functor_t;
  9543. typedef typename functor_t::bfunc_t bfunc_t;
  9544. typedef T value_type;
  9545. typedef T0oT1oT2<T,T0,T1,T2,ProcessMode> node_type;
  9546. typedef ProcessMode process_mode_t;
  9547. T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
  9548. : t0_(p0),
  9549. t1_(p1),
  9550. t2_(p2),
  9551. f0_(p3),
  9552. f1_(p4)
  9553. {}
  9554. inline typename expression_node<T>::node_type type() const
  9555. {
  9556. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
  9557. return result;
  9558. }
  9559. inline operator_type operation() const
  9560. {
  9561. return e_default;
  9562. }
  9563. inline T value() const
  9564. {
  9565. return ProcessMode::process(t0_,t1_,t2_,f0_,f1_);
  9566. }
  9567. inline T0 t0() const
  9568. {
  9569. return t0_;
  9570. }
  9571. inline T1 t1() const
  9572. {
  9573. return t1_;
  9574. }
  9575. inline T2 t2() const
  9576. {
  9577. return t2_;
  9578. }
  9579. bfunc_t f0() const
  9580. {
  9581. return f0_;
  9582. }
  9583. bfunc_t f1() const
  9584. {
  9585. return f1_;
  9586. }
  9587. std::string type_id() const
  9588. {
  9589. return id();
  9590. }
  9591. static inline std::string id()
  9592. {
  9593. return process_mode_t::template id<T0,T1,T2>();
  9594. }
  9595. template <typename Allocator>
  9596. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
  9597. {
  9598. return allocator.template allocate_type<node_type,T0,T1,T2,bfunc_t,bfunc_t>(p0,p1,p2,p3,p4);
  9599. }
  9600. private:
  9601. T0oT1oT2(node_type&) {}
  9602. node_type& operator=(node_type&) { return *this; }
  9603. T0 t0_;
  9604. T1 t1_;
  9605. T2 t2_;
  9606. const bfunc_t f0_;
  9607. const bfunc_t f1_;
  9608. };
  9609. template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode>
  9610. class T0oT1oT2oT3 : public T0oT1oT2oT3_base_node<T>
  9611. {
  9612. public:
  9613. typedef typename details::functor_t<T> functor_t;
  9614. typedef typename functor_t::bfunc_t bfunc_t;
  9615. typedef T value_type;
  9616. typedef T0_ T0;
  9617. typedef T1_ T1;
  9618. typedef T2_ T2;
  9619. typedef T3_ T3;
  9620. typedef T0oT1oT2oT3<T,T0,T1,T2,T3,ProcessMode> node_type;
  9621. typedef ProcessMode process_mode_t;
  9622. T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
  9623. : t0_(p0),
  9624. t1_(p1),
  9625. t2_(p2),
  9626. t3_(p3),
  9627. f0_(p4),
  9628. f1_(p5),
  9629. f2_(p6)
  9630. {}
  9631. inline T value() const
  9632. {
  9633. return ProcessMode::process(t0_,t1_,t2_,t3_,f0_,f1_,f2_);
  9634. }
  9635. inline T0 t0() const
  9636. {
  9637. return t0_;
  9638. }
  9639. inline T1 t1() const
  9640. {
  9641. return t1_;
  9642. }
  9643. inline T2 t2() const
  9644. {
  9645. return t2_;
  9646. }
  9647. inline T3 t3() const
  9648. {
  9649. return t3_;
  9650. }
  9651. inline bfunc_t f0() const
  9652. {
  9653. return f0_;
  9654. }
  9655. inline bfunc_t f1() const
  9656. {
  9657. return f1_;
  9658. }
  9659. inline bfunc_t f2() const
  9660. {
  9661. return f2_;
  9662. }
  9663. inline std::string type_id() const
  9664. {
  9665. return id();
  9666. }
  9667. static inline std::string id()
  9668. {
  9669. return process_mode_t::template id<T0,T1,T2,T3>();
  9670. }
  9671. template <typename Allocator>
  9672. static inline expression_node<T>* allocate(Allocator& allocator,
  9673. T0 p0, T1 p1, T2 p2, T3 p3,
  9674. bfunc_t p4, bfunc_t p5, bfunc_t p6)
  9675. {
  9676. return allocator.template allocate_type<node_type,T0,T1,T2,T3,bfunc_t,bfunc_t>(p0,p1,p2,p3,p4,p5,p6);
  9677. }
  9678. private:
  9679. T0oT1oT2oT3(node_type&) {}
  9680. node_type& operator=(node_type&) { return *this; }
  9681. T0 t0_;
  9682. T1 t1_;
  9683. T2 t2_;
  9684. T3 t3_;
  9685. const bfunc_t f0_;
  9686. const bfunc_t f1_;
  9687. const bfunc_t f2_;
  9688. };
  9689. template <typename T, typename T0, typename T1, typename T2>
  9690. class T0oT1oT2_sf3 : public T0oT1oT2_base_node<T>
  9691. {
  9692. public:
  9693. typedef typename details::functor_t<T> functor_t;
  9694. typedef typename functor_t::tfunc_t tfunc_t;
  9695. typedef T value_type;
  9696. typedef T0oT1oT2_sf3<T,T0,T1,T2> node_type;
  9697. T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
  9698. : t0_(p0),
  9699. t1_(p1),
  9700. t2_(p2),
  9701. f_ (p3)
  9702. {}
  9703. inline typename expression_node<T>::node_type type() const
  9704. {
  9705. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
  9706. return result;
  9707. }
  9708. inline operator_type operation() const
  9709. {
  9710. return e_default;
  9711. }
  9712. inline T value() const
  9713. {
  9714. return f_(t0_,t1_,t2_);
  9715. }
  9716. inline T0 t0() const
  9717. {
  9718. return t0_;
  9719. }
  9720. inline T1 t1() const
  9721. {
  9722. return t1_;
  9723. }
  9724. inline T2 t2() const
  9725. {
  9726. return t2_;
  9727. }
  9728. tfunc_t f() const
  9729. {
  9730. return f_;
  9731. }
  9732. std::string type_id() const
  9733. {
  9734. return id();
  9735. }
  9736. static inline std::string id()
  9737. {
  9738. return "sf3";
  9739. }
  9740. template <typename Allocator>
  9741. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
  9742. {
  9743. return allocator.template allocate_type<node_type,T0,T1,T2,tfunc_t>(p0,p1,p2,p3);
  9744. }
  9745. private:
  9746. T0oT1oT2_sf3(node_type&) {}
  9747. node_type& operator=(node_type&) { return *this; }
  9748. T0 t0_;
  9749. T1 t1_;
  9750. T2 t2_;
  9751. const tfunc_t f_;
  9752. };
  9753. template <typename T, typename T0, typename T1, typename T2>
  9754. class sf3ext_type_node : public T0oT1oT2_base_node<T>
  9755. {
  9756. public:
  9757. virtual T0 t0() const = 0;
  9758. virtual T1 t1() const = 0;
  9759. virtual T2 t2() const = 0;
  9760. };
  9761. template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
  9762. class T0oT1oT2_sf3ext : public sf3ext_type_node<T,T0,T1,T2>
  9763. {
  9764. public:
  9765. typedef typename details::functor_t<T> functor_t;
  9766. typedef typename functor_t::tfunc_t tfunc_t;
  9767. typedef T value_type;
  9768. typedef T0oT1oT2_sf3ext<T,T0,T1,T2,SF3Operation> node_type;
  9769. T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
  9770. : t0_(p0),
  9771. t1_(p1),
  9772. t2_(p2)
  9773. {}
  9774. inline typename expression_node<T>::node_type type() const
  9775. {
  9776. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
  9777. return result;
  9778. }
  9779. inline operator_type operation() const
  9780. {
  9781. return e_default;
  9782. }
  9783. inline T value() const
  9784. {
  9785. return SF3Operation::process(t0_,t1_,t2_);
  9786. }
  9787. T0 t0() const
  9788. {
  9789. return t0_;
  9790. }
  9791. T1 t1() const
  9792. {
  9793. return t1_;
  9794. }
  9795. T2 t2() const
  9796. {
  9797. return t2_;
  9798. }
  9799. std::string type_id() const
  9800. {
  9801. return id();
  9802. }
  9803. static inline std::string id()
  9804. {
  9805. return SF3Operation::id();
  9806. }
  9807. template <typename Allocator>
  9808. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2)
  9809. {
  9810. return allocator.template allocate_type<node_type,T0,T1,T2>(p0,p1,p2);
  9811. }
  9812. private:
  9813. T0oT1oT2_sf3ext(node_type&) {}
  9814. node_type& operator=(node_type&) { return *this; }
  9815. T0 t0_;
  9816. T1 t1_;
  9817. T2 t2_;
  9818. };
  9819. template <typename T>
  9820. inline bool is_sf3ext_node(const expression_node<T>* n)
  9821. {
  9822. switch (n->type())
  9823. {
  9824. case expression_node<T>::e_vovov : return true;
  9825. case expression_node<T>::e_vovoc : return true;
  9826. case expression_node<T>::e_vocov : return true;
  9827. case expression_node<T>::e_covov : return true;
  9828. case expression_node<T>::e_covoc : return true;
  9829. default : return false;
  9830. }
  9831. }
  9832. template <typename T, typename T0, typename T1, typename T2, typename T3>
  9833. class T0oT1oT2oT3_sf4 : public T0oT1oT2_base_node<T>
  9834. {
  9835. public:
  9836. typedef typename details::functor_t<T> functor_t;
  9837. typedef typename functor_t::qfunc_t qfunc_t;
  9838. typedef T value_type;
  9839. typedef T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> node_type;
  9840. T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
  9841. : t0_(p0),
  9842. t1_(p1),
  9843. t2_(p2),
  9844. t3_(p3),
  9845. f_ (p4)
  9846. {}
  9847. inline typename expression_node<T>::node_type type() const
  9848. {
  9849. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
  9850. return result;
  9851. }
  9852. inline operator_type operation() const
  9853. {
  9854. return e_default;
  9855. }
  9856. inline T value() const
  9857. {
  9858. return f_(t0_,t1_,t2_,t3_);
  9859. }
  9860. inline T0 t0() const
  9861. {
  9862. return t0_;
  9863. }
  9864. inline T1 t1() const
  9865. {
  9866. return t1_;
  9867. }
  9868. inline T2 t2() const
  9869. {
  9870. return t2_;
  9871. }
  9872. inline T3 t3() const
  9873. {
  9874. return t3_;
  9875. }
  9876. qfunc_t f() const
  9877. {
  9878. return f_;
  9879. }
  9880. std::string type_id() const
  9881. {
  9882. return id();
  9883. }
  9884. static inline std::string id()
  9885. {
  9886. return "sf4";
  9887. }
  9888. template <typename Allocator>
  9889. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
  9890. {
  9891. return allocator.template allocate_type<node_type,T0,T1,T2,T3,qfunc_t>(p0,p1,p2,p3,p4);
  9892. }
  9893. private:
  9894. T0oT1oT2oT3_sf4(node_type&) {}
  9895. node_type& operator=(node_type&) { return *this; }
  9896. T0 t0_;
  9897. T1 t1_;
  9898. T2 t2_;
  9899. T3 t3_;
  9900. const qfunc_t f_;
  9901. };
  9902. template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation>
  9903. class T0oT1oT2oT3_sf4ext : public T0oT1oT2oT3_base_node<T>
  9904. {
  9905. public:
  9906. typedef typename details::functor_t<T> functor_t;
  9907. typedef typename functor_t::tfunc_t tfunc_t;
  9908. typedef T value_type;
  9909. typedef T0oT1oT2oT3_sf4ext<T,T0,T1,T2,T3,SF4Operation> node_type;
  9910. T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
  9911. : t0_(p0),
  9912. t1_(p1),
  9913. t2_(p2),
  9914. t3_(p3)
  9915. {}
  9916. inline typename expression_node<T>::node_type type() const
  9917. {
  9918. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
  9919. return result;
  9920. }
  9921. inline operator_type operation() const
  9922. {
  9923. return e_default;
  9924. }
  9925. inline T value() const
  9926. {
  9927. return SF4Operation::process(t0_,t1_,t2_,t3_);
  9928. }
  9929. inline T0 t0() const
  9930. {
  9931. return t0_;
  9932. }
  9933. inline T1 t1() const
  9934. {
  9935. return t1_;
  9936. }
  9937. inline T2 t2() const
  9938. {
  9939. return t2_;
  9940. }
  9941. inline T3 t3() const
  9942. {
  9943. return t2_;
  9944. }
  9945. std::string type_id() const
  9946. {
  9947. return id();
  9948. }
  9949. static inline std::string id()
  9950. {
  9951. return SF4Operation::id();
  9952. }
  9953. template <typename Allocator>
  9954. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3)
  9955. {
  9956. return allocator.template allocate_type<node_type,T0,T1,T2,T3>(p0,p1,p2,p3);
  9957. }
  9958. private:
  9959. T0oT1oT2oT3_sf4ext(node_type&) {}
  9960. node_type& operator=(node_type&) { return *this; }
  9961. T0 t0_;
  9962. T1 t1_;
  9963. T2 t2_;
  9964. T3 t3_;
  9965. };
  9966. template <typename T>
  9967. inline bool is_sf4ext_node(const expression_node<T>* n)
  9968. {
  9969. switch (n->type())
  9970. {
  9971. case expression_node<T>::e_vovovov : return true;
  9972. case expression_node<T>::e_vovovoc : return true;
  9973. case expression_node<T>::e_vovocov : return true;
  9974. case expression_node<T>::e_vocovov : return true;
  9975. case expression_node<T>::e_covovov : return true;
  9976. case expression_node<T>::e_covocov : return true;
  9977. case expression_node<T>::e_vocovoc : return true;
  9978. case expression_node<T>::e_covovoc : return true;
  9979. case expression_node<T>::e_vococov : return true;
  9980. default : return false;
  9981. }
  9982. }
  9983. template <typename T, typename T0, typename T1>
  9984. struct T0oT1_define
  9985. {
  9986. typedef details::T0oT1<T,T0,T1> type0;
  9987. };
  9988. template <typename T, typename T0, typename T1, typename T2>
  9989. struct T0oT1oT2_define
  9990. {
  9991. typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode0> type0;
  9992. typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode1> type1;
  9993. typedef details::T0oT1oT2_sf3<T,T0,T1,T2> sf3_type;
  9994. typedef details::sf3ext_type_node<T,T0,T1,T2> sf3_type_node;
  9995. };
  9996. template <typename T, typename T0, typename T1, typename T2, typename T3>
  9997. struct T0oT1oT2oT3_define
  9998. {
  9999. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode0> type0;
  10000. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode1> type1;
  10001. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode2> type2;
  10002. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode3> type3;
  10003. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode4> type4;
  10004. typedef details::T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> sf4_type;
  10005. };
  10006. template <typename T, typename Operation>
  10007. class vov_node : public vov_base_node<T>
  10008. {
  10009. public:
  10010. typedef expression_node<T>* expression_ptr;
  10011. typedef Operation operation_t;
  10012. // variable op variable node
  10013. explicit vov_node(const T& var0, const T& var1)
  10014. : v0_(var0),
  10015. v1_(var1)
  10016. {}
  10017. inline T value() const
  10018. {
  10019. return Operation::process(v0_,v1_);
  10020. }
  10021. inline typename expression_node<T>::node_type type() const
  10022. {
  10023. return Operation::type();
  10024. }
  10025. inline operator_type operation() const
  10026. {
  10027. return Operation::operation();
  10028. }
  10029. inline const T& v0() const
  10030. {
  10031. return v0_;
  10032. }
  10033. inline const T& v1() const
  10034. {
  10035. return v1_;
  10036. }
  10037. protected:
  10038. const T& v0_;
  10039. const T& v1_;
  10040. private:
  10041. vov_node(vov_node<T,Operation>&);
  10042. vov_node<T,Operation>& operator=(vov_node<T,Operation>&);
  10043. };
  10044. template <typename T, typename Operation>
  10045. class cov_node : public cov_base_node<T>
  10046. {
  10047. public:
  10048. typedef expression_node<T>* expression_ptr;
  10049. typedef Operation operation_t;
  10050. // constant op variable node
  10051. explicit cov_node(const T& const_var, const T& var)
  10052. : c_(const_var),
  10053. v_(var)
  10054. {}
  10055. inline T value() const
  10056. {
  10057. return Operation::process(c_,v_);
  10058. }
  10059. inline typename expression_node<T>::node_type type() const
  10060. {
  10061. return Operation::type();
  10062. }
  10063. inline operator_type operation() const
  10064. {
  10065. return Operation::operation();
  10066. }
  10067. inline const T c() const
  10068. {
  10069. return c_;
  10070. }
  10071. inline const T& v() const
  10072. {
  10073. return v_;
  10074. }
  10075. protected:
  10076. const T c_;
  10077. const T& v_;
  10078. private:
  10079. cov_node(const cov_node<T,Operation>&);
  10080. cov_node<T,Operation>& operator=(const cov_node<T,Operation>&);
  10081. };
  10082. template <typename T, typename Operation>
  10083. class voc_node : public voc_base_node<T>
  10084. {
  10085. public:
  10086. typedef expression_node<T>* expression_ptr;
  10087. typedef Operation operation_t;
  10088. // variable op constant node
  10089. explicit voc_node(const T& var, const T& const_var)
  10090. : v_(var),
  10091. c_(const_var)
  10092. {}
  10093. inline T value() const
  10094. {
  10095. return Operation::process(v_,c_);
  10096. }
  10097. inline operator_type operation() const
  10098. {
  10099. return Operation::operation();
  10100. }
  10101. inline const T c() const
  10102. {
  10103. return c_;
  10104. }
  10105. inline const T& v() const
  10106. {
  10107. return v_;
  10108. }
  10109. protected:
  10110. const T& v_;
  10111. const T c_;
  10112. private:
  10113. voc_node(const voc_node<T,Operation>&);
  10114. voc_node<T,Operation>& operator=(const voc_node<T,Operation>&);
  10115. };
  10116. template <typename T, typename Operation>
  10117. class vob_node : public vob_base_node<T>
  10118. {
  10119. public:
  10120. typedef expression_node<T>* expression_ptr;
  10121. typedef std::pair<expression_ptr,bool> branch_t;
  10122. typedef Operation operation_t;
  10123. // variable op constant node
  10124. explicit vob_node(const T& var, const expression_ptr brnch)
  10125. : v_(var)
  10126. {
  10127. init_branches<1>(branch_,brnch);
  10128. }
  10129. ~vob_node()
  10130. {
  10131. cleanup_branches::execute<T,1>(branch_);
  10132. }
  10133. inline T value() const
  10134. {
  10135. return Operation::process(v_,branch_[0].first->value());
  10136. }
  10137. inline operator_type operation() const
  10138. {
  10139. return Operation::operation();
  10140. }
  10141. inline const T& v() const
  10142. {
  10143. return v_;
  10144. }
  10145. inline expression_node<T>* branch(const std::size_t&) const
  10146. {
  10147. return branch_[0].first;
  10148. }
  10149. private:
  10150. vob_node(const vob_node<T,Operation>&);
  10151. vob_node<T,Operation>& operator=(const vob_node<T,Operation>&);
  10152. const T& v_;
  10153. branch_t branch_[1];
  10154. };
  10155. template <typename T, typename Operation>
  10156. class bov_node : public bov_base_node<T>
  10157. {
  10158. public:
  10159. typedef expression_node<T>* expression_ptr;
  10160. typedef std::pair<expression_ptr,bool> branch_t;
  10161. typedef Operation operation_t;
  10162. // variable op constant node
  10163. explicit bov_node(const expression_ptr brnch, const T& var)
  10164. : v_(var)
  10165. {
  10166. init_branches<1>(branch_,brnch);
  10167. }
  10168. ~bov_node()
  10169. {
  10170. cleanup_branches::execute<T,1>(branch_);
  10171. }
  10172. inline T value() const
  10173. {
  10174. return Operation::process(branch_[0].first->value(),v_);
  10175. }
  10176. inline operator_type operation() const
  10177. {
  10178. return Operation::operation();
  10179. }
  10180. inline const T& v() const
  10181. {
  10182. return v_;
  10183. }
  10184. inline expression_node<T>* branch(const std::size_t&) const
  10185. {
  10186. return branch_[0].first;
  10187. }
  10188. private:
  10189. bov_node(const bov_node<T,Operation>&);
  10190. bov_node<T,Operation>& operator=(const bov_node<T,Operation>&);
  10191. const T& v_;
  10192. branch_t branch_[1];
  10193. };
  10194. template <typename T, typename Operation>
  10195. class cob_node : public cob_base_node<T>
  10196. {
  10197. public:
  10198. typedef expression_node<T>* expression_ptr;
  10199. typedef std::pair<expression_ptr,bool> branch_t;
  10200. typedef Operation operation_t;
  10201. // variable op constant node
  10202. explicit cob_node(const T const_var, const expression_ptr brnch)
  10203. : c_(const_var)
  10204. {
  10205. init_branches<1>(branch_,brnch);
  10206. }
  10207. ~cob_node()
  10208. {
  10209. cleanup_branches::execute<T,1>(branch_);
  10210. }
  10211. inline T value() const
  10212. {
  10213. return Operation::process(c_,branch_[0].first->value());
  10214. }
  10215. inline operator_type operation() const
  10216. {
  10217. return Operation::operation();
  10218. }
  10219. inline const T c() const
  10220. {
  10221. return c_;
  10222. }
  10223. inline void set_c(const T new_c)
  10224. {
  10225. (*const_cast<T*>(&c_)) = new_c;
  10226. }
  10227. inline expression_node<T>* branch(const std::size_t&) const
  10228. {
  10229. return branch_[0].first;
  10230. }
  10231. inline expression_node<T>* move_branch(const std::size_t&)
  10232. {
  10233. branch_[0].second = false;
  10234. return branch_[0].first;
  10235. }
  10236. private:
  10237. cob_node(const cob_node<T,Operation>&);
  10238. cob_node<T,Operation>& operator=(const cob_node<T,Operation>&);
  10239. const T c_;
  10240. branch_t branch_[1];
  10241. };
  10242. template <typename T, typename Operation>
  10243. class boc_node : public boc_base_node<T>
  10244. {
  10245. public:
  10246. typedef expression_node<T>* expression_ptr;
  10247. typedef std::pair<expression_ptr,bool> branch_t;
  10248. typedef Operation operation_t;
  10249. // variable op constant node
  10250. explicit boc_node(const expression_ptr brnch, const T const_var)
  10251. : c_(const_var)
  10252. {
  10253. init_branches<1>(branch_,brnch);
  10254. }
  10255. ~boc_node()
  10256. {
  10257. cleanup_branches::execute<T,1>(branch_);
  10258. }
  10259. inline T value() const
  10260. {
  10261. return Operation::process(branch_[0].first->value(),c_);
  10262. }
  10263. inline operator_type operation() const
  10264. {
  10265. return Operation::operation();
  10266. }
  10267. inline const T c() const
  10268. {
  10269. return c_;
  10270. }
  10271. inline void set_c(const T new_c)
  10272. {
  10273. (*const_cast<T*>(&c_)) = new_c;
  10274. }
  10275. inline expression_node<T>* branch(const std::size_t&) const
  10276. {
  10277. return branch_[0].first;
  10278. }
  10279. inline expression_node<T>* move_branch(const std::size_t&)
  10280. {
  10281. branch_[0].second = false;
  10282. return branch_[0].first;
  10283. }
  10284. private:
  10285. boc_node(const boc_node<T,Operation>&);
  10286. boc_node<T,Operation>& operator=(const boc_node<T,Operation>&);
  10287. const T c_;
  10288. branch_t branch_[1];
  10289. };
  10290. #ifndef exprtk_disable_string_capabilities
  10291. template <typename T, typename SType0, typename SType1, typename Operation>
  10292. class sos_node : public sos_base_node<T>
  10293. {
  10294. public:
  10295. typedef expression_node<T>* expression_ptr;
  10296. typedef Operation operation_t;
  10297. // string op string node
  10298. explicit sos_node(SType0 p0, SType1 p1)
  10299. : s0_(p0),
  10300. s1_(p1)
  10301. {}
  10302. inline T value() const
  10303. {
  10304. return Operation::process(s0_,s1_);
  10305. }
  10306. inline typename expression_node<T>::node_type type() const
  10307. {
  10308. return Operation::type();
  10309. }
  10310. inline operator_type operation() const
  10311. {
  10312. return Operation::operation();
  10313. }
  10314. inline std::string& s0()
  10315. {
  10316. return s0_;
  10317. }
  10318. inline std::string& s1()
  10319. {
  10320. return s1_;
  10321. }
  10322. protected:
  10323. SType0 s0_;
  10324. SType1 s1_;
  10325. private:
  10326. sos_node(sos_node<T,SType0,SType1,Operation>&);
  10327. sos_node<T,SType0,SType1,Operation>& operator=(sos_node<T,SType0,SType1,Operation>&);
  10328. };
  10329. template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
  10330. class str_xrox_node : public sos_base_node<T>
  10331. {
  10332. public:
  10333. typedef expression_node<T>* expression_ptr;
  10334. typedef Operation operation_t;
  10335. // string-range op string node
  10336. explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
  10337. : s0_(p0),
  10338. s1_(p1),
  10339. rp0_(rp0)
  10340. {}
  10341. ~str_xrox_node()
  10342. {
  10343. rp0_.free();
  10344. }
  10345. inline T value() const
  10346. {
  10347. std::size_t r0 = 0;
  10348. std::size_t r1 = 0;
  10349. if (rp0_(r0,r1,s0_.size()))
  10350. return Operation::process(s0_.substr(r0,(r1 - r0) + 1),s1_);
  10351. else
  10352. return T(0);
  10353. }
  10354. inline typename expression_node<T>::node_type type() const
  10355. {
  10356. return Operation::type();
  10357. }
  10358. inline operator_type operation() const
  10359. {
  10360. return Operation::operation();
  10361. }
  10362. inline std::string& s0()
  10363. {
  10364. return s0_;
  10365. }
  10366. inline std::string& s1()
  10367. {
  10368. return s1_;
  10369. }
  10370. protected:
  10371. SType0 s0_;
  10372. SType1 s1_;
  10373. RangePack rp0_;
  10374. private:
  10375. str_xrox_node(str_xrox_node<T,SType0,SType1,RangePack,Operation>&);
  10376. str_xrox_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xrox_node<T,SType0,SType1,RangePack,Operation>&);
  10377. };
  10378. template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
  10379. class str_xoxr_node : public sos_base_node<T>
  10380. {
  10381. public:
  10382. typedef expression_node<T>* expression_ptr;
  10383. typedef Operation operation_t;
  10384. // string op string range node
  10385. explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
  10386. : s0_ (p0 ),
  10387. s1_ (p1 ),
  10388. rp1_(rp1)
  10389. {}
  10390. ~str_xoxr_node()
  10391. {
  10392. rp1_.free();
  10393. }
  10394. inline T value() const
  10395. {
  10396. std::size_t r0 = 0;
  10397. std::size_t r1 = 0;
  10398. if (rp1_(r0,r1,s1_.size()))
  10399. return Operation::process(s0_,s1_.substr(r0,(r1 - r0) + 1));
  10400. else
  10401. return T(0);
  10402. }
  10403. inline typename expression_node<T>::node_type type() const
  10404. {
  10405. return Operation::type();
  10406. }
  10407. inline operator_type operation() const
  10408. {
  10409. return Operation::operation();
  10410. }
  10411. inline std::string& s0()
  10412. {
  10413. return s0_;
  10414. }
  10415. inline std::string& s1()
  10416. {
  10417. return s1_;
  10418. }
  10419. protected:
  10420. SType0 s0_;
  10421. SType1 s1_;
  10422. RangePack rp1_;
  10423. private:
  10424. str_xoxr_node(str_xoxr_node<T,SType0,SType1,RangePack,Operation>&);
  10425. str_xoxr_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xoxr_node<T,SType0,SType1,RangePack,Operation>&);
  10426. };
  10427. template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
  10428. class str_xroxr_node : public sos_base_node<T>
  10429. {
  10430. public:
  10431. typedef expression_node<T>* expression_ptr;
  10432. typedef Operation operation_t;
  10433. // string-range op string-range node
  10434. explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
  10435. : s0_ (p0 ),
  10436. s1_ (p1 ),
  10437. rp0_(rp0),
  10438. rp1_(rp1)
  10439. {}
  10440. ~str_xroxr_node()
  10441. {
  10442. rp0_.free();
  10443. rp1_.free();
  10444. }
  10445. inline T value() const
  10446. {
  10447. std::size_t r0_0 = 0;
  10448. std::size_t r0_1 = 0;
  10449. std::size_t r1_0 = 0;
  10450. std::size_t r1_1 = 0;
  10451. if (
  10452. rp0_(r0_0,r1_0,s0_.size()) &&
  10453. rp1_(r0_1,r1_1,s1_.size())
  10454. )
  10455. {
  10456. return Operation::process(
  10457. s0_.substr(r0_0,(r1_0 - r0_0) + 1),
  10458. s1_.substr(r0_1,(r1_1 - r0_1) + 1)
  10459. );
  10460. }
  10461. else
  10462. return T(0);
  10463. }
  10464. inline typename expression_node<T>::node_type type() const
  10465. {
  10466. return Operation::type();
  10467. }
  10468. inline operator_type operation() const
  10469. {
  10470. return Operation::operation();
  10471. }
  10472. inline std::string& s0()
  10473. {
  10474. return s0_;
  10475. }
  10476. inline std::string& s1()
  10477. {
  10478. return s1_;
  10479. }
  10480. protected:
  10481. SType0 s0_;
  10482. SType1 s1_;
  10483. RangePack rp0_;
  10484. RangePack rp1_;
  10485. private:
  10486. str_xroxr_node(str_xroxr_node<T,SType0,SType1,RangePack,Operation>&);
  10487. str_xroxr_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xroxr_node<T,SType0,SType1,RangePack,Operation>&);
  10488. };
  10489. template <typename T, typename Operation>
  10490. class str_sogens_node : public binary_node<T>
  10491. {
  10492. public:
  10493. typedef expression_node <T>* expression_ptr;
  10494. typedef string_base_node<T>* str_base_ptr;
  10495. typedef range_pack <T> range_t;
  10496. typedef range_t* range_ptr;
  10497. typedef range_interface<T> irange_t;
  10498. typedef irange_t* irange_ptr;
  10499. str_sogens_node(const operator_type& opr,
  10500. expression_ptr branch0,
  10501. expression_ptr branch1)
  10502. : binary_node<T>(opr,branch0,branch1),
  10503. str0_base_ptr_ (0),
  10504. str1_base_ptr_ (0),
  10505. str0_range_ptr_(0),
  10506. str1_range_ptr_(0)
  10507. {
  10508. if (is_generally_string_node(binary_node<T>::branch_[0].first))
  10509. {
  10510. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  10511. if (0 == str0_base_ptr_)
  10512. return;
  10513. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  10514. if (0 == range_ptr)
  10515. return;
  10516. str0_range_ptr_ = &(range_ptr->range_ref());
  10517. }
  10518. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  10519. {
  10520. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  10521. if (0 == str1_base_ptr_)
  10522. return;
  10523. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  10524. if (0 == range_ptr)
  10525. return;
  10526. str1_range_ptr_ = &(range_ptr->range_ref());
  10527. }
  10528. }
  10529. inline T value() const
  10530. {
  10531. if (
  10532. str0_base_ptr_ &&
  10533. str1_base_ptr_ &&
  10534. str0_range_ptr_ &&
  10535. str1_range_ptr_
  10536. )
  10537. {
  10538. binary_node<T>::branch_[0].first->value();
  10539. binary_node<T>::branch_[1].first->value();
  10540. std::size_t str0_r0 = 0;
  10541. std::size_t str0_r1 = 0;
  10542. std::size_t str1_r0 = 0;
  10543. std::size_t str1_r1 = 0;
  10544. range_t& range0 = (*str0_range_ptr_);
  10545. range_t& range1 = (*str1_range_ptr_);
  10546. if (
  10547. range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
  10548. range1(str1_r0,str1_r1,str1_base_ptr_->size())
  10549. )
  10550. {
  10551. return Operation::process(
  10552. str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0) + 1),
  10553. str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0) + 1)
  10554. );
  10555. }
  10556. }
  10557. return std::numeric_limits<T>::quiet_NaN();
  10558. }
  10559. inline typename expression_node<T>::node_type type() const
  10560. {
  10561. return Operation::type();
  10562. }
  10563. inline operator_type operation() const
  10564. {
  10565. return Operation::operation();
  10566. }
  10567. private:
  10568. str_sogens_node(str_sogens_node<T,Operation>&);
  10569. str_sogens_node<T,Operation>& operator=(str_sogens_node<T,Operation>&);
  10570. str_base_ptr str0_base_ptr_;
  10571. str_base_ptr str1_base_ptr_;
  10572. range_ptr str0_range_ptr_;
  10573. range_ptr str1_range_ptr_;
  10574. };
  10575. template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
  10576. class sosos_node : public sosos_base_node<T>
  10577. {
  10578. public:
  10579. typedef expression_node<T>* expression_ptr;
  10580. typedef Operation operation_t;
  10581. // variable op variable node
  10582. explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
  10583. : s0_(p0),
  10584. s1_(p1),
  10585. s2_(p2)
  10586. {}
  10587. inline T value() const
  10588. {
  10589. return Operation::process(s0_,s1_,s2_);
  10590. }
  10591. inline typename expression_node<T>::node_type type() const
  10592. {
  10593. return Operation::type();
  10594. }
  10595. inline operator_type operation() const
  10596. {
  10597. return Operation::operation();
  10598. }
  10599. inline std::string& s0()
  10600. {
  10601. return s0_;
  10602. }
  10603. inline std::string& s1()
  10604. {
  10605. return s1_;
  10606. }
  10607. inline std::string& s2()
  10608. {
  10609. return s2_;
  10610. }
  10611. protected:
  10612. SType0 s0_;
  10613. SType1 s1_;
  10614. SType2 s2_;
  10615. private:
  10616. sosos_node(sosos_node<T,SType0,SType1,SType2,Operation>&);
  10617. sosos_node<T,SType0,SType1,SType2,Operation>& operator=(sosos_node<T,SType0,SType1,SType2,Operation>&);
  10618. };
  10619. #endif
  10620. template <typename T, typename PowOp>
  10621. class ipow_node : public expression_node<T>
  10622. {
  10623. public:
  10624. typedef expression_node<T>* expression_ptr;
  10625. typedef PowOp operation_t;
  10626. explicit ipow_node(const T& v)
  10627. : v_(v)
  10628. {}
  10629. inline T value() const
  10630. {
  10631. return PowOp::result(v_);
  10632. }
  10633. inline typename expression_node<T>::node_type type() const
  10634. {
  10635. return expression_node<T>::e_ipow;
  10636. }
  10637. private:
  10638. ipow_node(const ipow_node<T,PowOp>&);
  10639. ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&);
  10640. const T& v_;
  10641. };
  10642. template <typename T, typename PowOp>
  10643. class ipowinv_node : public expression_node<T>
  10644. {
  10645. public:
  10646. typedef expression_node<T>* expression_ptr;
  10647. typedef PowOp operation_t;
  10648. explicit ipowinv_node(const T& v)
  10649. : v_(v)
  10650. {}
  10651. inline T value() const
  10652. {
  10653. return (T(1) / PowOp::result(v_));
  10654. }
  10655. inline typename expression_node<T>::node_type type() const
  10656. {
  10657. return expression_node<T>::e_ipowinv;
  10658. }
  10659. private:
  10660. ipowinv_node(const ipowinv_node<T,PowOp>&);
  10661. ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&);
  10662. const T& v_;
  10663. };
  10664. template <typename T>
  10665. inline bool is_vov_node(const expression_node<T>* node)
  10666. {
  10667. return (0 != dynamic_cast<const vov_base_node<T>*>(node));
  10668. }
  10669. template <typename T>
  10670. inline bool is_cov_node(const expression_node<T>* node)
  10671. {
  10672. return (0 != dynamic_cast<const cov_base_node<T>*>(node));
  10673. }
  10674. template <typename T>
  10675. inline bool is_voc_node(const expression_node<T>* node)
  10676. {
  10677. return (0 != dynamic_cast<const voc_base_node<T>*>(node));
  10678. }
  10679. template <typename T>
  10680. inline bool is_cob_node(const expression_node<T>* node)
  10681. {
  10682. return (0 != dynamic_cast<const cob_base_node<T>*>(node));
  10683. }
  10684. template <typename T>
  10685. inline bool is_boc_node(const expression_node<T>* node)
  10686. {
  10687. return (0 != dynamic_cast<const boc_base_node<T>*>(node));
  10688. }
  10689. template <typename T>
  10690. inline bool is_t0ot1ot2_node(const expression_node<T>* node)
  10691. {
  10692. return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node));
  10693. }
  10694. template <typename T>
  10695. inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node)
  10696. {
  10697. return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node));
  10698. }
  10699. template <typename T>
  10700. inline bool is_uv_node(const expression_node<T>* node)
  10701. {
  10702. return (0 != dynamic_cast<const uv_base_node<T>*>(node));
  10703. }
  10704. template <typename T>
  10705. inline bool is_string_node(const expression_node<T>* node)
  10706. {
  10707. return node && (expression_node<T>::e_stringvar == node->type());
  10708. }
  10709. template <typename T>
  10710. inline bool is_string_range_node(const expression_node<T>* node)
  10711. {
  10712. return node && (expression_node<T>::e_stringvarrng == node->type());
  10713. }
  10714. template <typename T>
  10715. inline bool is_const_string_node(const expression_node<T>* node)
  10716. {
  10717. return node && (expression_node<T>::e_stringconst == node->type());
  10718. }
  10719. template <typename T>
  10720. inline bool is_const_string_range_node(const expression_node<T>* node)
  10721. {
  10722. return node && (expression_node<T>::e_cstringvarrng == node->type());
  10723. }
  10724. template <typename T>
  10725. inline bool is_string_assignment_node(const expression_node<T>* node)
  10726. {
  10727. return node && (expression_node<T>::e_strass == node->type());
  10728. }
  10729. template <typename T>
  10730. inline bool is_string_concat_node(const expression_node<T>* node)
  10731. {
  10732. return node && (expression_node<T>::e_strconcat == node->type());
  10733. }
  10734. template <typename T>
  10735. inline bool is_string_function_node(const expression_node<T>* node)
  10736. {
  10737. return node && (expression_node<T>::e_strfunction == node->type());
  10738. }
  10739. template <typename T>
  10740. inline bool is_genricstring_range_node(const expression_node<T>* node)
  10741. {
  10742. return node && (expression_node<T>::e_strgenrange == node->type());
  10743. }
  10744. template <typename T>
  10745. inline bool is_generally_string_node(const expression_node<T>* node)
  10746. {
  10747. if (node)
  10748. {
  10749. switch (node->type())
  10750. {
  10751. case expression_node<T>::e_stringvar :
  10752. case expression_node<T>::e_stringconst :
  10753. case expression_node<T>::e_stringvarrng :
  10754. case expression_node<T>::e_cstringvarrng :
  10755. case expression_node<T>::e_strgenrange :
  10756. case expression_node<T>::e_strass :
  10757. case expression_node<T>::e_strconcat :
  10758. case expression_node<T>::e_strfunction : return true;
  10759. default : return false;
  10760. }
  10761. }
  10762. return false;
  10763. }
  10764. class node_allocator
  10765. {
  10766. public:
  10767. template <typename ResultNode, typename OpType, typename ExprNode>
  10768. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1])
  10769. {
  10770. return allocate<ResultNode>(operation,branch[0]);
  10771. }
  10772. template <typename ResultNode, typename OpType, typename ExprNode>
  10773. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2])
  10774. {
  10775. return allocate<ResultNode>(operation,branch[0],branch[1]);
  10776. }
  10777. template <typename ResultNode, typename OpType, typename ExprNode>
  10778. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3])
  10779. {
  10780. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2]);
  10781. }
  10782. template <typename ResultNode, typename OpType, typename ExprNode>
  10783. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4])
  10784. {
  10785. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3]);
  10786. }
  10787. template <typename ResultNode, typename OpType, typename ExprNode>
  10788. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5])
  10789. {
  10790. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4]);
  10791. }
  10792. template <typename ResultNode, typename OpType, typename ExprNode>
  10793. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6])
  10794. {
  10795. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4],branch[5]);
  10796. }
  10797. template <typename node_type>
  10798. inline expression_node<typename node_type::value_type>* allocate() const
  10799. {
  10800. return new node_type();
  10801. }
  10802. template <typename node_type,
  10803. typename Type,
  10804. typename Allocator,
  10805. template <typename,typename> class Sequence>
  10806. inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const
  10807. {
  10808. return new node_type(seq);
  10809. }
  10810. template <typename node_type, typename T1>
  10811. inline expression_node<typename node_type::value_type>* allocate(T1& t1) const
  10812. {
  10813. return new node_type(t1);
  10814. }
  10815. template <typename node_type, typename T1>
  10816. inline expression_node<typename node_type::value_type>* allocate_c(const T1& t1) const
  10817. {
  10818. return new node_type(t1);
  10819. }
  10820. template <typename node_type,
  10821. typename T1, typename T2>
  10822. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
  10823. {
  10824. return new node_type(t1,t2);
  10825. }
  10826. template <typename node_type,
  10827. typename T1, typename T2>
  10828. inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const
  10829. {
  10830. return new node_type(t1,t2);
  10831. }
  10832. template <typename node_type,
  10833. typename T1, typename T2>
  10834. inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
  10835. {
  10836. return new node_type(t1,t2);
  10837. }
  10838. template <typename node_type,
  10839. typename T1, typename T2>
  10840. inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const
  10841. {
  10842. return new node_type(t1,t2);
  10843. }
  10844. template <typename node_type,
  10845. typename T1, typename T2>
  10846. inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const
  10847. {
  10848. return new node_type(t1,t2);
  10849. }
  10850. template <typename node_type,
  10851. typename T1, typename T2, typename T3>
  10852. inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const
  10853. {
  10854. return new node_type(t1,t2,t3);
  10855. }
  10856. template <typename node_type,
  10857. typename T1, typename T2, typename T3, typename T4>
  10858. inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
  10859. {
  10860. return new node_type(t1,t2,t3,t4);
  10861. }
  10862. template <typename node_type,
  10863. typename T1, typename T2, typename T3>
  10864. inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const
  10865. {
  10866. return new node_type(t1,t2,t3);
  10867. }
  10868. template <typename node_type,
  10869. typename T1, typename T2, typename T3, typename T4>
  10870. inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const
  10871. {
  10872. return new node_type(t1,t2,t3,t4);
  10873. }
  10874. template <typename node_type,
  10875. typename T1, typename T2, typename T3, typename T4, typename T5>
  10876. inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
  10877. {
  10878. return new node_type(t1,t2,t3,t4,t5);
  10879. }
  10880. template <typename node_type,
  10881. typename T1, typename T2, typename T3>
  10882. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10883. const T3& t3) const
  10884. {
  10885. return new node_type(t1,t2,t3);
  10886. }
  10887. template <typename node_type,
  10888. typename T1, typename T2,
  10889. typename T3, typename T4>
  10890. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10891. const T3& t3, const T4& t4) const
  10892. {
  10893. return new node_type(t1,t2,t3,t4);
  10894. }
  10895. template <typename node_type,
  10896. typename T1, typename T2,
  10897. typename T3, typename T4, typename T5>
  10898. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10899. const T3& t3, const T4& t4,
  10900. const T5& t5) const
  10901. {
  10902. return new node_type(t1,t2,t3,t4,t5);
  10903. }
  10904. template <typename node_type,
  10905. typename T1, typename T2,
  10906. typename T3, typename T4, typename T5, typename T6>
  10907. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10908. const T3& t3, const T4& t4,
  10909. const T5& t5, const T6& t6) const
  10910. {
  10911. return new node_type(t1,t2,t3,t4,t5,t6);
  10912. }
  10913. template <typename node_type,
  10914. typename T1, typename T2,
  10915. typename T3, typename T4,
  10916. typename T5, typename T6, typename T7>
  10917. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10918. const T3& t3, const T4& t4,
  10919. const T5& t5, const T6& t6,
  10920. const T7& t7) const
  10921. {
  10922. return new node_type(t1,t2,t3,t4,t5,t6,t7);
  10923. }
  10924. template <typename node_type,
  10925. typename T1, typename T2,
  10926. typename T3, typename T4,
  10927. typename T5, typename T6,
  10928. typename T7, typename T8>
  10929. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10930. const T3& t3, const T4& t4,
  10931. const T5& t5, const T6& t6,
  10932. const T7& t7, const T8& t8) const
  10933. {
  10934. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8);
  10935. }
  10936. template <typename node_type,
  10937. typename T1, typename T2,
  10938. typename T3, typename T4,
  10939. typename T5, typename T6,
  10940. typename T7, typename T8, typename T9>
  10941. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10942. const T3& t3, const T4& t4,
  10943. const T5& t5, const T6& t6,
  10944. const T7& t7, const T8& t8,
  10945. const T9& t9) const
  10946. {
  10947. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9);
  10948. }
  10949. template <typename node_type,
  10950. typename T1, typename T2,
  10951. typename T3, typename T4,
  10952. typename T5, typename T6,
  10953. typename T7, typename T8,
  10954. typename T9, typename T10>
  10955. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  10956. const T3& t3, const T4& t4,
  10957. const T5& t5, const T6& t6,
  10958. const T7& t7, const T8& t8,
  10959. const T9& t9, const T10& t10) const
  10960. {
  10961. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
  10962. }
  10963. template <typename node_type,
  10964. typename T1, typename T2, typename T3>
  10965. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const
  10966. {
  10967. return new node_type(t1,t2,t3);
  10968. }
  10969. template <typename node_type,
  10970. typename T1, typename T2,
  10971. typename T3, typename T4>
  10972. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
  10973. T3 t3, T4 t4) const
  10974. {
  10975. return new node_type(t1,t2,t3,t4);
  10976. }
  10977. template <typename node_type,
  10978. typename T1, typename T2,
  10979. typename T3, typename T4,
  10980. typename T5>
  10981. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
  10982. T3 t3, T4 t4,
  10983. T5 t5) const
  10984. {
  10985. return new node_type(t1,t2,t3,t4,t5);
  10986. }
  10987. template <typename node_type,
  10988. typename T1, typename T2,
  10989. typename T3, typename T4,
  10990. typename T5, typename T6, typename T7>
  10991. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
  10992. T3 t3, T4 t4,
  10993. T5 t5, T6 t6,
  10994. T7 t7) const
  10995. {
  10996. return new node_type(t1,t2,t3,t4,t5,t6,t7);
  10997. }
  10998. template <typename T>
  10999. void inline free(expression_node<T>*& e) const
  11000. {
  11001. delete e;
  11002. e = 0;
  11003. }
  11004. };
  11005. inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
  11006. {
  11007. #define register_op(Symbol,Type,Args) \
  11008. m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
  11009. register_op( "abs",e_abs , 1)
  11010. register_op( "acos",e_acos , 1)
  11011. register_op( "acosh",e_acosh , 1)
  11012. register_op( "asin",e_asin , 1)
  11013. register_op( "asinh",e_asinh , 1)
  11014. register_op( "atan",e_atan , 1)
  11015. register_op( "atanh",e_atanh , 1)
  11016. register_op( "ceil",e_ceil , 1)
  11017. register_op( "cos",e_cos , 1)
  11018. register_op( "cosh",e_cosh , 1)
  11019. register_op( "exp",e_exp , 1)
  11020. register_op( "expm1",e_expm1 , 1)
  11021. register_op( "floor",e_floor , 1)
  11022. register_op( "log",e_log , 1)
  11023. register_op( "log10",e_log10 , 1)
  11024. register_op( "log2",e_log2 , 1)
  11025. register_op( "log1p",e_log1p , 1)
  11026. register_op( "round",e_round , 1)
  11027. register_op( "sin",e_sin , 1)
  11028. register_op( "sinc",e_sinc , 1)
  11029. register_op( "sinh",e_sinh , 1)
  11030. register_op( "sec",e_sec , 1)
  11031. register_op( "csc",e_csc , 1)
  11032. register_op( "sqrt",e_sqrt , 1)
  11033. register_op( "tan",e_tan , 1)
  11034. register_op( "tanh",e_tanh , 1)
  11035. register_op( "cot",e_cot , 1)
  11036. register_op( "rad2deg",e_r2d , 1)
  11037. register_op( "deg2rad",e_d2r , 1)
  11038. register_op( "deg2grad",e_d2g , 1)
  11039. register_op( "grad2deg",e_g2d , 1)
  11040. register_op( "sgn",e_sgn , 1)
  11041. register_op( "not",e_notl , 1)
  11042. register_op( "erf",e_erf , 1)
  11043. register_op( "erfc",e_erfc , 1)
  11044. register_op( "ncdf",e_ncdf , 1)
  11045. register_op( "frac",e_frac , 1)
  11046. register_op( "trunc",e_trunc , 1)
  11047. register_op( "atan2",e_atan2 , 2)
  11048. register_op( "mod",e_mod , 2)
  11049. register_op( "logn",e_logn , 2)
  11050. register_op( "pow",e_pow , 2)
  11051. register_op( "root",e_root , 2)
  11052. register_op( "roundn",e_roundn , 2)
  11053. register_op( "equal",e_equal , 2)
  11054. register_op("not_equal",e_nequal , 2)
  11055. register_op( "hypot",e_hypot , 2)
  11056. register_op( "shr",e_shr , 2)
  11057. register_op( "shl",e_shl , 2)
  11058. register_op( "clamp",e_clamp , 3)
  11059. register_op( "iclamp",e_iclamp , 3)
  11060. register_op( "inrange",e_inrange , 3)
  11061. #undef register_op
  11062. }
  11063. } // namespace details
  11064. template <typename T>
  11065. class ifunction
  11066. {
  11067. public:
  11068. explicit ifunction(const std::size_t& pc, const bool hse = true)
  11069. : param_count(pc),
  11070. has_side_effects(hse)
  11071. {}
  11072. virtual ~ifunction()
  11073. {}
  11074. inline virtual T operator()()
  11075. {
  11076. return std::numeric_limits<T>::quiet_NaN();
  11077. }
  11078. inline virtual T operator()(const T&)
  11079. {
  11080. return std::numeric_limits<T>::quiet_NaN();
  11081. }
  11082. inline virtual T operator()(const T&,const T&)
  11083. {
  11084. return std::numeric_limits<T>::quiet_NaN();
  11085. }
  11086. inline virtual T operator()(const T&, const T&, const T&)
  11087. {
  11088. return std::numeric_limits<T>::quiet_NaN();
  11089. }
  11090. inline virtual T operator()(const T&, const T&, const T&, const T&)
  11091. {
  11092. return std::numeric_limits<T>::quiet_NaN();
  11093. }
  11094. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&)
  11095. {
  11096. return std::numeric_limits<T>::quiet_NaN();
  11097. }
  11098. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&)
  11099. {
  11100. return std::numeric_limits<T>::quiet_NaN();
  11101. }
  11102. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11103. {
  11104. return std::numeric_limits<T>::quiet_NaN();
  11105. }
  11106. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11107. {
  11108. return std::numeric_limits<T>::quiet_NaN();
  11109. }
  11110. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11111. {
  11112. return std::numeric_limits<T>::quiet_NaN();
  11113. }
  11114. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11115. {
  11116. return std::numeric_limits<T>::quiet_NaN();
  11117. }
  11118. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11119. const T&)
  11120. {
  11121. return std::numeric_limits<T>::quiet_NaN();
  11122. }
  11123. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11124. const T&, const T&)
  11125. {
  11126. return std::numeric_limits<T>::quiet_NaN();
  11127. }
  11128. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11129. const T&, const T&, const T&)
  11130. {
  11131. return std::numeric_limits<T>::quiet_NaN();
  11132. }
  11133. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11134. const T&, const T&, const T&, const T&)
  11135. {
  11136. return std::numeric_limits<T>::quiet_NaN();
  11137. }
  11138. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11139. const T&, const T&, const T&, const T&, const T&)
  11140. {
  11141. return std::numeric_limits<T>::quiet_NaN();
  11142. }
  11143. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11144. const T&, const T&, const T&, const T&, const T&, const T&)
  11145. {
  11146. return std::numeric_limits<T>::quiet_NaN();
  11147. }
  11148. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11149. const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11150. {
  11151. return std::numeric_limits<T>::quiet_NaN();
  11152. }
  11153. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11154. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11155. {
  11156. return std::numeric_limits<T>::quiet_NaN();
  11157. }
  11158. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11159. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11160. {
  11161. return std::numeric_limits<T>::quiet_NaN();
  11162. }
  11163. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11164. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11165. {
  11166. return std::numeric_limits<T>::quiet_NaN();
  11167. }
  11168. std::size_t param_count;
  11169. bool has_side_effects;
  11170. };
  11171. template <typename T>
  11172. class ivararg_function
  11173. {
  11174. public:
  11175. ivararg_function(const bool hse = true)
  11176. : has_side_effects(hse)
  11177. {}
  11178. virtual ~ivararg_function()
  11179. {}
  11180. inline virtual T operator()(const std::vector<T>&)
  11181. {
  11182. exprtk_debug(("ivararg_function::operator() - Operator has not been overriden.\n"));
  11183. return std::numeric_limits<T>::quiet_NaN();
  11184. }
  11185. bool has_side_effects;
  11186. };
  11187. template <typename T>
  11188. class igeneric_function
  11189. {
  11190. public:
  11191. typedef T type;
  11192. typedef type_store<T> generic_type;
  11193. typedef typename generic_type::parameter_list parameter_list_t;
  11194. igeneric_function(const std::string& param_seq = "",
  11195. const bool hse = true)
  11196. : has_side_effects(hse),
  11197. parameter_sequence(param_seq)
  11198. {}
  11199. virtual ~igeneric_function()
  11200. {}
  11201. // f(i_0,i_1,....,i_N) --> Number
  11202. inline virtual T operator()(parameter_list_t)
  11203. {
  11204. exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [1]\n"));
  11205. return std::numeric_limits<T>::quiet_NaN();
  11206. }
  11207. // f(i_0,i_1,....,i_N) --> String
  11208. inline virtual T operator()(std::string&, parameter_list_t)
  11209. {
  11210. exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [2]\n"));
  11211. return std::numeric_limits<T>::quiet_NaN();
  11212. }
  11213. // f(psi,i_0,i_1,....,i_N) --> Number
  11214. inline virtual T operator()(const std::size_t&, parameter_list_t)
  11215. {
  11216. exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [3]\n"));
  11217. return std::numeric_limits<T>::quiet_NaN();
  11218. }
  11219. // f(psi,i_0,i_1,....,i_N) --> String
  11220. inline virtual T operator()(const std::size_t&, std::string&, parameter_list_t)
  11221. {
  11222. exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [4]\n"));
  11223. return std::numeric_limits<T>::quiet_NaN();
  11224. }
  11225. bool has_side_effects;
  11226. std::string parameter_sequence;
  11227. };
  11228. template <typename T> class parser;
  11229. template <typename T> class expression_helper;
  11230. template <typename T>
  11231. class symbol_table
  11232. {
  11233. protected:
  11234. template <typename Type> class parser;
  11235. protected:
  11236. template <typename Type, typename RawType>
  11237. struct type_store
  11238. {
  11239. typedef details::expression_node<T>* expression_ptr;
  11240. typedef typename details::variable_node<T> variable_node_t;
  11241. typedef ifunction<T> ifunction_t;
  11242. typedef ivararg_function<T> ivararg_function_t;
  11243. typedef igeneric_function<T> igeneric_function_t;
  11244. typedef details::vector_holder<T> vector_t;
  11245. #ifndef exprtk_disable_string_capabilities
  11246. typedef typename details::stringvar_node<T> stringvar_node_t;
  11247. #endif
  11248. typedef Type type_t;
  11249. typedef type_t* type_ptr;
  11250. typedef std::pair<bool,type_ptr> type_pair_t;
  11251. typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
  11252. typedef typename type_map_t::iterator tm_itr_t;
  11253. typedef typename type_map_t::const_iterator tm_const_itr_t;
  11254. enum { lut_size = 256 };
  11255. type_map_t map;
  11256. std::size_t size;
  11257. type_store()
  11258. : size(0)
  11259. {}
  11260. inline bool symbol_exists(const std::string& symbol_name) const
  11261. {
  11262. if (symbol_name.empty())
  11263. return false;
  11264. else if (map.end() != map.find(symbol_name))
  11265. return true;
  11266. else
  11267. return false;
  11268. }
  11269. template <typename PtrType>
  11270. inline std::string entity_name(const PtrType& ptr) const
  11271. {
  11272. if (map.empty())
  11273. return std::string();
  11274. tm_const_itr_t itr = map.begin();
  11275. while (map.end() != itr)
  11276. {
  11277. if (itr->second.second == ptr)
  11278. {
  11279. return itr->first;
  11280. }
  11281. else
  11282. ++itr;
  11283. }
  11284. return std::string();
  11285. }
  11286. inline bool is_constant(const std::string& symbol_name) const
  11287. {
  11288. if (symbol_name.empty())
  11289. return false;
  11290. else
  11291. {
  11292. tm_const_itr_t itr = map.find(symbol_name);
  11293. if (map.end() == itr)
  11294. return false;
  11295. else
  11296. return (*itr).second.first;
  11297. }
  11298. }
  11299. template <typename Tie, typename RType>
  11300. inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const)
  11301. {
  11302. if (symbol_name.size() > 1)
  11303. {
  11304. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  11305. {
  11306. if (details::imatch(symbol_name,details::reserved_symbols[i]))
  11307. {
  11308. return false;
  11309. }
  11310. }
  11311. }
  11312. tm_itr_t itr = map.find(symbol_name);
  11313. if (map.end() == itr)
  11314. {
  11315. map[symbol_name] = Tie::make(t,is_const);
  11316. ++size;
  11317. }
  11318. return true;
  11319. }
  11320. struct tie_array
  11321. {
  11322. static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false)
  11323. {
  11324. return std::make_pair(is_const,new vector_t(v.first,v.second));
  11325. }
  11326. };
  11327. struct tie_stdvec
  11328. {
  11329. template <typename Allocator>
  11330. static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false)
  11331. {
  11332. return std::make_pair(is_const,new vector_t(v));
  11333. }
  11334. };
  11335. struct tie_stddeq
  11336. {
  11337. template <typename Allocator>
  11338. static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false)
  11339. {
  11340. return std::make_pair(is_const,new vector_t(v));
  11341. }
  11342. };
  11343. template <std::size_t v_size>
  11344. inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false)
  11345. {
  11346. return add_impl<tie_array,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_const);
  11347. }
  11348. inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false)
  11349. {
  11350. return add_impl<tie_array,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_const);
  11351. }
  11352. template <typename Allocator>
  11353. inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false)
  11354. {
  11355. return add_impl<tie_stdvec,std::vector<T,Allocator>&>(symbol_name,v,is_const);
  11356. }
  11357. template <typename Allocator>
  11358. inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
  11359. {
  11360. return add_impl<tie_stddeq,std::deque<T,Allocator>&>(symbol_name,v,is_const);
  11361. }
  11362. inline bool add(const std::string& symbol_name, RawType& t, const bool is_const = false)
  11363. {
  11364. struct tie
  11365. {
  11366. static inline std::pair<bool,variable_node_t*> make(T& t,const bool is_const = false)
  11367. {
  11368. return std::make_pair(is_const,new variable_node_t(t));
  11369. }
  11370. #ifndef exprtk_disable_string_capabilities
  11371. static inline std::pair<bool,stringvar_node_t*> make(std::string& t,const bool is_const = false)
  11372. {
  11373. return std::make_pair(is_const,new stringvar_node_t(t));
  11374. }
  11375. #endif
  11376. static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
  11377. {
  11378. return std::make_pair(is_constant,&t);
  11379. }
  11380. static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_const = false)
  11381. {
  11382. return std::make_pair(is_const,&t);
  11383. }
  11384. static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false)
  11385. {
  11386. return std::make_pair(is_constant,&t);
  11387. }
  11388. };
  11389. if (symbol_name.size() > 1)
  11390. {
  11391. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  11392. {
  11393. if (details::imatch(symbol_name,details::reserved_symbols[i]))
  11394. {
  11395. return false;
  11396. }
  11397. }
  11398. }
  11399. tm_itr_t itr = map.find(symbol_name);
  11400. if (map.end() == itr)
  11401. {
  11402. map[symbol_name] = tie::make(t,is_const);
  11403. ++size;
  11404. }
  11405. return true;
  11406. }
  11407. inline type_ptr get(const std::string& symbol_name) const
  11408. {
  11409. tm_const_itr_t itr = map.find(symbol_name);
  11410. if (map.end() == itr)
  11411. return reinterpret_cast<type_ptr>(0);
  11412. else
  11413. return itr->second.second;
  11414. }
  11415. template <typename TType, typename TRawType, typename PtrType>
  11416. struct ptr_match
  11417. {
  11418. static inline bool test(const PtrType, const void*)
  11419. {
  11420. return false;
  11421. }
  11422. };
  11423. template <typename TType, typename TRawType>
  11424. struct ptr_match<TType,TRawType,variable_node_t*>
  11425. {
  11426. static inline bool test(const variable_node_t* p, const void* ptr)
  11427. {
  11428. exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p->ref())),ptr));
  11429. return (&(p->ref()) == ptr);
  11430. }
  11431. };
  11432. inline type_ptr get_from_varptr(const void* ptr) const
  11433. {
  11434. tm_const_itr_t itr = map.begin();
  11435. while (map.end() != itr)
  11436. {
  11437. type_ptr ret_ptr = itr->second.second;
  11438. if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr))
  11439. {
  11440. return ret_ptr;
  11441. }
  11442. ++itr;
  11443. }
  11444. return type_ptr(0);
  11445. }
  11446. inline bool remove(const std::string& symbol_name, const bool delete_node = true)
  11447. {
  11448. tm_itr_t itr = map.find(symbol_name);
  11449. if (map.end() != itr)
  11450. {
  11451. struct deleter
  11452. {
  11453. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  11454. static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
  11455. #ifndef exprtk_disable_string_capabilities
  11456. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  11457. #endif
  11458. static inline void process(std::pair<bool,function_t*>&) { }
  11459. };
  11460. if (delete_node)
  11461. {
  11462. deleter::process((*itr).second);
  11463. }
  11464. map.erase(itr);
  11465. --size;
  11466. return true;
  11467. }
  11468. else
  11469. return false;
  11470. }
  11471. inline RawType& type_ref(const std::string& symbol_name)
  11472. {
  11473. struct init_type
  11474. {
  11475. static inline double set(double) { return (0.0); }
  11476. static inline double set(long double) { return (0.0); }
  11477. static inline float set(float) { return (0.0f); }
  11478. static inline std::string set(std::string) { return std::string(""); }
  11479. };
  11480. static RawType null_type = init_type::set(RawType());
  11481. tm_const_itr_t itr = map.find(symbol_name);
  11482. if (map.end() == itr)
  11483. return null_type;
  11484. else
  11485. return itr->second.second->ref();
  11486. }
  11487. inline void clear(const bool delete_node = true)
  11488. {
  11489. struct deleter
  11490. {
  11491. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  11492. static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
  11493. static inline void process(std::pair<bool,function_t*>&) { }
  11494. #ifndef exprtk_disable_string_capabilities
  11495. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  11496. #endif
  11497. };
  11498. if (!map.empty())
  11499. {
  11500. if (delete_node)
  11501. {
  11502. tm_itr_t itr = map.begin();
  11503. tm_itr_t end = map.end();
  11504. while (end != itr)
  11505. {
  11506. deleter::process((*itr).second);
  11507. ++itr;
  11508. }
  11509. }
  11510. map.clear();
  11511. }
  11512. size = 0;
  11513. }
  11514. template <typename Allocator,
  11515. template <typename, typename> class Sequence>
  11516. inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
  11517. {
  11518. std::size_t count = 0;
  11519. if (!map.empty())
  11520. {
  11521. tm_const_itr_t itr = map.begin();
  11522. tm_const_itr_t end = map.end();
  11523. while (end != itr)
  11524. {
  11525. list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
  11526. ++itr;
  11527. ++count;
  11528. }
  11529. }
  11530. return count;
  11531. }
  11532. template <typename Allocator,
  11533. template <typename, typename> class Sequence>
  11534. inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
  11535. {
  11536. std::size_t count = 0;
  11537. if (!map.empty())
  11538. {
  11539. tm_const_itr_t itr = map.begin();
  11540. tm_const_itr_t end = map.end();
  11541. while (end != itr)
  11542. {
  11543. vlist.push_back((*itr).first);
  11544. ++itr;
  11545. ++count;
  11546. }
  11547. }
  11548. return count;
  11549. }
  11550. };
  11551. typedef details::expression_node<T>* expression_ptr;
  11552. typedef typename details::variable_node<T> variable_t;
  11553. typedef typename details::vector_holder<T> vector_holder_t;
  11554. typedef variable_t* variable_ptr;
  11555. #ifndef exprtk_disable_string_capabilities
  11556. typedef typename details::stringvar_node<T> stringvar_t;
  11557. typedef stringvar_t* stringvar_ptr;
  11558. #endif
  11559. typedef ifunction<T> function_t;
  11560. typedef ivararg_function<T> vararg_function_t;
  11561. typedef igeneric_function<T> generic_function_t;
  11562. typedef function_t* function_ptr;
  11563. typedef vararg_function_t* vararg_function_ptr;
  11564. typedef generic_function_t* generic_function_ptr;
  11565. static const std::size_t lut_size = 256;
  11566. // Symbol Table Holder
  11567. struct st_holder
  11568. {
  11569. struct st_data
  11570. {
  11571. type_store<typename details::variable_node<T>,T> variable_store;
  11572. #ifndef exprtk_disable_string_capabilities
  11573. type_store<typename details::stringvar_node<T>,std::string> stringvar_store;
  11574. #endif
  11575. type_store<ifunction<T>,ifunction<T> > function_store;
  11576. type_store<ivararg_function<T>,ivararg_function<T> > vararg_function_store;
  11577. type_store<igeneric_function<T>,igeneric_function<T> > generic_function_store;
  11578. type_store<igeneric_function<T>,igeneric_function<T> > string_function_store;
  11579. type_store<vector_holder_t,vector_holder_t> vector_store;
  11580. st_data()
  11581. {
  11582. for (std::size_t i = 0; i < details::reserved_words_size; ++i)
  11583. {
  11584. reserved_symbol_table_.insert(details::reserved_words[i]);
  11585. }
  11586. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  11587. {
  11588. reserved_symbol_table_.insert(details::reserved_symbols[i]);
  11589. }
  11590. }
  11591. inline bool is_reserved_symbol(const std::string& symbol) const
  11592. {
  11593. return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
  11594. }
  11595. std::list<T> local_symbol_list_;
  11596. std::list<std::string> local_stringvar_list_;
  11597. std::set<std::string> reserved_symbol_table_;
  11598. };
  11599. st_holder()
  11600. : ref_count(1),
  11601. data_(new st_data)
  11602. {}
  11603. st_holder(st_data* data)
  11604. : ref_count(1),
  11605. data_(data)
  11606. {}
  11607. ~st_holder()
  11608. {
  11609. if (data_ && (0 == ref_count))
  11610. {
  11611. delete data_;
  11612. data_ = 0;
  11613. }
  11614. }
  11615. std::size_t ref_count;
  11616. st_data* data_;
  11617. };
  11618. public:
  11619. symbol_table()
  11620. : holder_(new st_holder)
  11621. {
  11622. clear();
  11623. }
  11624. ~symbol_table()
  11625. {
  11626. if (holder_)
  11627. {
  11628. if (0 == --holder_->ref_count)
  11629. {
  11630. clear();
  11631. delete holder_;
  11632. }
  11633. }
  11634. }
  11635. symbol_table(const symbol_table<T>& st)
  11636. {
  11637. holder_ = st.holder_;
  11638. holder_->ref_count++;
  11639. }
  11640. inline symbol_table<T>& operator=(const symbol_table<T>& st)
  11641. {
  11642. if (holder_)
  11643. {
  11644. if (0 == --holder_->ref_count)
  11645. {
  11646. delete holder_;
  11647. }
  11648. holder_ = 0;
  11649. }
  11650. holder_ = st.holder_;
  11651. holder_->ref_count++;
  11652. return *this;
  11653. }
  11654. inline bool operator==(const symbol_table<T>& st)
  11655. {
  11656. return (this == &st) || (holder_ == st.holder_);
  11657. }
  11658. inline void clear_variables(const bool delete_node = true)
  11659. {
  11660. local_data().variable_store.clear(delete_node);
  11661. }
  11662. inline void clear_functions()
  11663. {
  11664. local_data().function_store.clear();
  11665. }
  11666. inline void clear_strings()
  11667. {
  11668. #ifndef exprtk_disable_string_capabilities
  11669. local_data().stringvar_store.clear();
  11670. #endif
  11671. }
  11672. inline void clear_vectors()
  11673. {
  11674. local_data().vector_store.clear();
  11675. }
  11676. inline void clear()
  11677. {
  11678. if (!valid()) return;
  11679. clear_variables();
  11680. clear_functions();
  11681. clear_strings ();
  11682. clear_vectors ();
  11683. }
  11684. inline std::size_t variable_count() const
  11685. {
  11686. if (valid())
  11687. return local_data().variable_store.size;
  11688. else
  11689. return 0;
  11690. }
  11691. #ifndef exprtk_disable_string_capabilities
  11692. inline std::size_t stringvar_count() const
  11693. {
  11694. if (valid())
  11695. return local_data().stringvar_store.size;
  11696. else
  11697. return 0;
  11698. }
  11699. #endif
  11700. inline std::size_t function_count() const
  11701. {
  11702. if (valid())
  11703. return local_data().function_store.size;
  11704. else
  11705. return 0;
  11706. }
  11707. inline std::size_t vector_count() const
  11708. {
  11709. if (valid())
  11710. return local_data().vector_store.size;
  11711. else
  11712. return 0;
  11713. }
  11714. inline variable_ptr get_variable(const std::string& variable_name) const
  11715. {
  11716. if (!valid())
  11717. return reinterpret_cast<variable_ptr>(0);
  11718. else if (!valid_symbol(variable_name))
  11719. return reinterpret_cast<variable_ptr>(0);
  11720. else
  11721. return local_data().variable_store.get(variable_name);
  11722. }
  11723. inline variable_ptr get_variable(const T& var_ref) const
  11724. {
  11725. if (!valid())
  11726. return reinterpret_cast<variable_ptr>(0);
  11727. else
  11728. return local_data().variable_store.get_from_varptr(
  11729. reinterpret_cast<const void*>(&var_ref));
  11730. }
  11731. #ifndef exprtk_disable_string_capabilities
  11732. inline stringvar_ptr get_stringvar(const std::string& string_name) const
  11733. {
  11734. if (!valid())
  11735. return reinterpret_cast<stringvar_ptr>(0);
  11736. else if (!valid_symbol(string_name))
  11737. return reinterpret_cast<stringvar_ptr>(0);
  11738. else
  11739. return local_data().stringvar_store.get(string_name);
  11740. }
  11741. #endif
  11742. inline function_ptr get_function(const std::string& function_name) const
  11743. {
  11744. if (!valid())
  11745. return reinterpret_cast<function_ptr>(0);
  11746. else if (!valid_symbol(function_name))
  11747. return reinterpret_cast<function_ptr>(0);
  11748. else
  11749. return local_data().function_store.get(function_name);
  11750. }
  11751. inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
  11752. {
  11753. if (!valid())
  11754. return reinterpret_cast<vararg_function_ptr>(0);
  11755. else if (!valid_symbol(vararg_function_name))
  11756. return reinterpret_cast<vararg_function_ptr>(0);
  11757. else
  11758. return local_data().vararg_function_store.get(vararg_function_name);
  11759. }
  11760. inline generic_function_ptr get_generic_function(const std::string& function_name) const
  11761. {
  11762. if (!valid())
  11763. return reinterpret_cast<generic_function_ptr>(0);
  11764. else if (!valid_symbol(function_name))
  11765. return reinterpret_cast<generic_function_ptr>(0);
  11766. else
  11767. return local_data().generic_function_store.get(function_name);
  11768. }
  11769. inline generic_function_ptr get_string_function(const std::string& function_name) const
  11770. {
  11771. if (!valid())
  11772. return reinterpret_cast<generic_function_ptr>(0);
  11773. else if (!valid_symbol(function_name))
  11774. return reinterpret_cast<generic_function_ptr>(0);
  11775. else
  11776. return local_data().string_function_store.get(function_name);
  11777. }
  11778. typedef vector_holder_t* vector_holder_ptr;
  11779. inline vector_holder_ptr get_vector(const std::string& vector_name) const
  11780. {
  11781. if (!valid())
  11782. return reinterpret_cast<vector_holder_ptr>(0);
  11783. else if (!valid_symbol(vector_name))
  11784. return reinterpret_cast<vector_holder_ptr>(0);
  11785. else
  11786. return local_data().vector_store.get(vector_name);
  11787. }
  11788. inline T& variable_ref(const std::string& symbol_name)
  11789. {
  11790. static T null_var = T(0);
  11791. if (!valid())
  11792. return null_var;
  11793. else if (!valid_symbol(symbol_name))
  11794. return null_var;
  11795. else
  11796. return local_data().variable_store.type_ref(symbol_name);
  11797. }
  11798. #ifndef exprtk_disable_string_capabilities
  11799. inline std::string& stringvar_ref(const std::string& symbol_name)
  11800. {
  11801. static std::string null_stringvar;
  11802. if (!valid())
  11803. return null_stringvar;
  11804. else if (!valid_symbol(symbol_name))
  11805. return null_stringvar;
  11806. else
  11807. return local_data().stringvar_store.type_ref(symbol_name);
  11808. }
  11809. #endif
  11810. inline bool is_constant_node(const std::string& symbol_name) const
  11811. {
  11812. if (!valid())
  11813. return false;
  11814. else if (!valid_symbol(symbol_name))
  11815. return false;
  11816. else
  11817. return local_data().variable_store.is_constant(symbol_name);
  11818. }
  11819. #ifndef exprtk_disable_string_capabilities
  11820. inline bool is_constant_string(const std::string& symbol_name) const
  11821. {
  11822. if (!valid())
  11823. return false;
  11824. else if (!valid_symbol(symbol_name))
  11825. return false;
  11826. else if (!local_data().stringvar_store.symbol_exists(symbol_name))
  11827. return false;
  11828. else
  11829. return local_data().stringvar_store.is_constant(symbol_name);
  11830. }
  11831. #endif
  11832. inline bool create_variable(const std::string& variable_name, const T& value = T(0))
  11833. {
  11834. if (!valid())
  11835. return false;
  11836. else if (!valid_symbol(variable_name))
  11837. return false;
  11838. else if (symbol_exists(variable_name))
  11839. return false;
  11840. local_data().local_symbol_list_.push_back(value);
  11841. T& t = local_data().local_symbol_list_.back();
  11842. return add_variable(variable_name,t);
  11843. }
  11844. #ifndef exprtk_disable_string_capabilities
  11845. inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
  11846. {
  11847. if (!valid())
  11848. return false;
  11849. else if (!valid_symbol(stringvar_name))
  11850. return false;
  11851. else if (symbol_exists(stringvar_name))
  11852. return false;
  11853. local_data().local_stringvar_list_.push_back(value);
  11854. std::string& s = local_data().local_stringvar_list_.back();
  11855. return add_stringvar(stringvar_name,s);
  11856. }
  11857. #endif
  11858. inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
  11859. {
  11860. if (!valid())
  11861. return false;
  11862. else if (!valid_symbol(variable_name))
  11863. return false;
  11864. else if (symbol_exists(variable_name))
  11865. return false;
  11866. else
  11867. return local_data().variable_store.add(variable_name,t,is_constant);
  11868. }
  11869. inline bool add_constant(const std::string& constant_name, const T& value)
  11870. {
  11871. if (!valid())
  11872. return false;
  11873. else if (!valid_symbol(constant_name))
  11874. return false;
  11875. else if (symbol_exists(constant_name))
  11876. return false;
  11877. local_data().local_symbol_list_.push_back(value);
  11878. T& t = local_data().local_symbol_list_.back();
  11879. return add_variable(constant_name,t,true);
  11880. }
  11881. #ifndef exprtk_disable_string_capabilities
  11882. inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
  11883. {
  11884. if (!valid())
  11885. return false;
  11886. else if (!valid_symbol(stringvar_name))
  11887. return false;
  11888. else if (symbol_exists(stringvar_name))
  11889. return false;
  11890. else
  11891. return local_data().stringvar_store.add(stringvar_name,s,is_constant);
  11892. }
  11893. #endif
  11894. inline bool add_function(const std::string& function_name, function_t& function)
  11895. {
  11896. if (!valid())
  11897. return false;
  11898. else if (!valid_symbol(function_name))
  11899. return false;
  11900. else if (symbol_exists(function_name))
  11901. return false;
  11902. else
  11903. return local_data().function_store.add(function_name,function);
  11904. }
  11905. inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
  11906. {
  11907. if (!valid())
  11908. return false;
  11909. else if (!valid_symbol(vararg_function_name))
  11910. return false;
  11911. else if (symbol_exists(vararg_function_name))
  11912. return false;
  11913. else
  11914. return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
  11915. }
  11916. enum func_type
  11917. {
  11918. e_ft_unknown = 0,
  11919. e_ft_basicfunc = 1,
  11920. e_ft_strfunc = 2
  11921. };
  11922. inline bool add_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
  11923. {
  11924. if (!valid())
  11925. return false;
  11926. else if (!valid_symbol(function_name))
  11927. return false;
  11928. else if (symbol_exists(function_name))
  11929. return false;
  11930. else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
  11931. return false;
  11932. else if (e_ft_basicfunc == ft)
  11933. return local_data().generic_function_store.add(function_name,function);
  11934. else if (e_ft_strfunc == ft)
  11935. return local_data().string_function_store.add(function_name, function);
  11936. else
  11937. return false;
  11938. }
  11939. template <std::size_t N>
  11940. inline bool add_vector(const std::string& vector_name, T (&v)[N])
  11941. {
  11942. if (!valid())
  11943. return false;
  11944. else if (!valid_symbol(vector_name))
  11945. return false;
  11946. else if (symbol_exists(vector_name))
  11947. return false;
  11948. else
  11949. return local_data().vector_store.add(vector_name,v);
  11950. }
  11951. inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
  11952. {
  11953. if (!valid())
  11954. return false;
  11955. else if (!valid_symbol(vector_name))
  11956. return false;
  11957. else if (symbol_exists(vector_name))
  11958. return false;
  11959. else
  11960. return local_data().vector_store.add(vector_name,v,v_size);
  11961. }
  11962. template <typename Allocator>
  11963. inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
  11964. {
  11965. if (!valid())
  11966. return false;
  11967. else if (!valid_symbol(vector_name))
  11968. return false;
  11969. else if (symbol_exists(vector_name))
  11970. return false;
  11971. else
  11972. return local_data().vector_store.add(vector_name,v);
  11973. }
  11974. template <typename Allocator>
  11975. inline bool add_vector(const std::string& vector_name, std::deque<T,Allocator>& v)
  11976. {
  11977. if (!valid())
  11978. return false;
  11979. else if (!valid_symbol(vector_name))
  11980. return false;
  11981. else if (symbol_exists(vector_name))
  11982. return false;
  11983. else
  11984. return local_data().vector_store.add(vector_name,v);
  11985. }
  11986. inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
  11987. {
  11988. if (!valid())
  11989. return false;
  11990. else
  11991. return local_data().variable_store.remove(variable_name, delete_node);
  11992. }
  11993. #ifndef exprtk_disable_string_capabilities
  11994. inline bool remove_stringvar(const std::string& string_name)
  11995. {
  11996. if (!valid())
  11997. return false;
  11998. else
  11999. return local_data().stringvar_store.remove(string_name);
  12000. }
  12001. #endif
  12002. inline bool remove_function(const std::string& function_name)
  12003. {
  12004. if (!valid())
  12005. return false;
  12006. else
  12007. return local_data().function_store.remove(function_name);
  12008. }
  12009. inline bool remove_vararg_function(const std::string& vararg_function_name)
  12010. {
  12011. if (!valid())
  12012. return false;
  12013. else
  12014. return local_data().vararg_function_store.remove(vararg_function_name);
  12015. }
  12016. inline bool remove_vector(const std::string& vector_name)
  12017. {
  12018. if (!valid())
  12019. return false;
  12020. else
  12021. return local_data().vector_store.remove(vector_name);
  12022. }
  12023. inline bool add_constants()
  12024. {
  12025. return add_pi () &&
  12026. add_epsilon () &&
  12027. add_infinity();
  12028. }
  12029. inline bool add_pi()
  12030. {
  12031. static const T local_pi = T(details::numeric::constant::pi);
  12032. return add_constant("pi",local_pi);
  12033. }
  12034. inline bool add_epsilon()
  12035. {
  12036. static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
  12037. return add_constant("epsilon",local_epsilon);
  12038. }
  12039. inline bool add_infinity()
  12040. {
  12041. static const T local_infinity = std::numeric_limits<T>::infinity();
  12042. return add_constant("inf",local_infinity);
  12043. }
  12044. template <typename Allocator,
  12045. template <typename, typename> class Sequence>
  12046. inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
  12047. {
  12048. if (!valid())
  12049. return 0;
  12050. else
  12051. return local_data().variable_store.get_list(vlist);
  12052. }
  12053. template <typename Allocator,
  12054. template <typename, typename> class Sequence>
  12055. inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
  12056. {
  12057. if (!valid())
  12058. return 0;
  12059. else
  12060. return local_data().variable_store.get_list(vlist);
  12061. }
  12062. #ifndef exprtk_disable_string_capabilities
  12063. template <typename Allocator,
  12064. template <typename, typename> class Sequence>
  12065. inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
  12066. {
  12067. if (!valid())
  12068. return 0;
  12069. else
  12070. return local_data().stringvar_store.get_list(svlist);
  12071. }
  12072. template <typename Allocator,
  12073. template <typename, typename> class Sequence>
  12074. inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
  12075. {
  12076. if (!valid())
  12077. return 0;
  12078. else
  12079. return local_data().stringvar_store.get_list(svlist);
  12080. }
  12081. #endif
  12082. template <typename Allocator,
  12083. template <typename, typename> class Sequence>
  12084. inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vlist) const
  12085. {
  12086. if (!valid())
  12087. return 0;
  12088. else
  12089. return local_data().vector_store.get_list(vlist);
  12090. }
  12091. inline bool symbol_exists(const std::string& symbol_name) const
  12092. {
  12093. /*
  12094. Will return true if symbol_name exists as either a reserved symbol,
  12095. variable, stringvar or function name in any of the type stores.
  12096. */
  12097. if (!valid())
  12098. return false;
  12099. else if (local_data().variable_store.symbol_exists(symbol_name))
  12100. return true;
  12101. #ifndef exprtk_disable_string_capabilities
  12102. else if (local_data().stringvar_store.symbol_exists(symbol_name))
  12103. return true;
  12104. #endif
  12105. else if (local_data().function_store.symbol_exists(symbol_name))
  12106. return true;
  12107. else if (local_data().is_reserved_symbol(symbol_name))
  12108. return true;
  12109. else
  12110. return false;
  12111. }
  12112. inline bool is_variable(const std::string& variable_name) const
  12113. {
  12114. if (!valid())
  12115. return false;
  12116. else
  12117. return local_data().variable_store.symbol_exists(variable_name);
  12118. }
  12119. #ifndef exprtk_disable_string_capabilities
  12120. inline bool is_stringvar(const std::string& stringvar_name) const
  12121. {
  12122. if (!valid())
  12123. return false;
  12124. else
  12125. return local_data().stringvar_store.symbol_exists(stringvar_name);
  12126. }
  12127. inline bool is_conststr_stringvar(const std::string& symbol_name) const
  12128. {
  12129. if (!valid())
  12130. return false;
  12131. else if (!valid_symbol(symbol_name))
  12132. return false;
  12133. else if (!local_data().stringvar_store.symbol_exists(symbol_name))
  12134. return false;
  12135. return (
  12136. local_data().stringvar_store.symbol_exists(symbol_name) ||
  12137. local_data().stringvar_store.is_constant (symbol_name)
  12138. );
  12139. }
  12140. #endif
  12141. inline bool is_function(const std::string& function_name) const
  12142. {
  12143. if (!valid())
  12144. return false;
  12145. else
  12146. return local_data().function_store.symbol_exists(function_name);
  12147. }
  12148. inline bool is_vararg_function(const std::string& vararg_function_name) const
  12149. {
  12150. if (!valid())
  12151. return false;
  12152. else
  12153. return local_data().vararg_function_store.symbol_exists(vararg_function_name);
  12154. }
  12155. inline bool is_vector(const std::string& vector_name) const
  12156. {
  12157. if (!valid())
  12158. return false;
  12159. else
  12160. return local_data().vector_store.symbol_exists(vector_name);
  12161. }
  12162. inline std::string get_variable_name(const expression_ptr& ptr) const
  12163. {
  12164. return local_data().variable_store.entity_name(ptr);
  12165. }
  12166. inline std::string get_vector_name(const vector_holder_ptr& ptr) const
  12167. {
  12168. return local_data().vector_store.entity_name(ptr);
  12169. }
  12170. #ifndef exprtk_disable_string_capabilities
  12171. inline std::string get_stringvar_name(const expression_ptr& ptr) const
  12172. {
  12173. return local_data().stringvar_store.entity_name(ptr);
  12174. }
  12175. inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const
  12176. {
  12177. return local_data().stringvar_store.entity_name(ptr);
  12178. }
  12179. #endif
  12180. inline bool valid() const
  12181. {
  12182. // Symbol table sanity check.
  12183. return holder_ && holder_->data_;
  12184. }
  12185. inline void load_from(const symbol_table<T>& st)
  12186. {
  12187. {
  12188. std::vector<std::string> name_list;
  12189. st.local_data().function_store.get_list(name_list);
  12190. if (!name_list.empty())
  12191. {
  12192. for (std::size_t i = 0; i < name_list.size(); ++i)
  12193. {
  12194. exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]);
  12195. add_function(name_list[i],ifunc);
  12196. }
  12197. }
  12198. }
  12199. {
  12200. std::vector<std::string> name_list;
  12201. st.local_data().vararg_function_store.get_list(name_list);
  12202. if (!name_list.empty())
  12203. {
  12204. for (std::size_t i = 0; i < name_list.size(); ++i)
  12205. {
  12206. exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]);
  12207. add_function(name_list[i],ivafunc);
  12208. }
  12209. }
  12210. }
  12211. {
  12212. std::vector<std::string> name_list;
  12213. st.local_data().generic_function_store.get_list(name_list);
  12214. if (!name_list.empty())
  12215. {
  12216. for (std::size_t i = 0; i < name_list.size(); ++i)
  12217. {
  12218. exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]);
  12219. add_function(name_list[i],ifunc);
  12220. }
  12221. }
  12222. }
  12223. {
  12224. std::vector<std::string> name_list;
  12225. st.local_data().string_function_store.get_list(name_list);
  12226. if (!name_list.empty())
  12227. {
  12228. for (std::size_t i = 0; i < name_list.size(); ++i)
  12229. {
  12230. exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
  12231. add_function(name_list[i],ifunc,e_ft_strfunc);
  12232. }
  12233. }
  12234. }
  12235. }
  12236. private:
  12237. inline bool valid_symbol(const std::string& symbol) const
  12238. {
  12239. if (symbol.empty())
  12240. return false;
  12241. if (!details::is_letter(symbol[0]))
  12242. return false;
  12243. else if (symbol.size() > 1)
  12244. {
  12245. for (std::size_t i = 1; i < symbol.size(); ++i)
  12246. {
  12247. if (
  12248. (!details::is_letter(symbol[i])) &&
  12249. (!details:: is_digit(symbol[i])) &&
  12250. ('_' != symbol[i])
  12251. )
  12252. {
  12253. return false;
  12254. }
  12255. }
  12256. }
  12257. return (!local_data().is_reserved_symbol(symbol));
  12258. }
  12259. inline typename st_holder::st_data& local_data()
  12260. {
  12261. return *(holder_->data_);
  12262. }
  12263. inline const typename st_holder::st_data& local_data() const
  12264. {
  12265. return *(holder_->data_);
  12266. }
  12267. st_holder* holder_;
  12268. };
  12269. template <typename T>
  12270. class function_compositor;
  12271. template <typename T>
  12272. class expression
  12273. {
  12274. private:
  12275. typedef details::expression_node<T>* expression_ptr;
  12276. typedef details::vector_holder<T>* vector_holder_ptr;
  12277. struct expression_holder
  12278. {
  12279. enum data_type
  12280. {
  12281. e_unknown ,
  12282. e_expr ,
  12283. e_vecholder,
  12284. e_data ,
  12285. e_vecdata ,
  12286. e_string
  12287. };
  12288. struct data_pack
  12289. {
  12290. data_pack()
  12291. : pointer(0),
  12292. type(e_unknown),
  12293. size(0)
  12294. {}
  12295. data_pack(void* ptr, data_type dt, std::size_t sz = 0)
  12296. : pointer(ptr),
  12297. type(dt),
  12298. size(sz)
  12299. {}
  12300. void* pointer;
  12301. data_type type;
  12302. std::size_t size;
  12303. };
  12304. typedef std::vector<data_pack> local_data_list_t;
  12305. expression_holder()
  12306. : ref_count(0),
  12307. expr(0)
  12308. {}
  12309. expression_holder(expression_ptr e)
  12310. : ref_count(1),
  12311. expr(e)
  12312. {}
  12313. ~expression_holder()
  12314. {
  12315. if (expr && details::branch_deletable(expr))
  12316. {
  12317. delete expr;
  12318. }
  12319. if (!local_data_list.empty())
  12320. {
  12321. for (std::size_t i = 0; i < local_data_list.size(); ++i)
  12322. {
  12323. switch (local_data_list[i].type)
  12324. {
  12325. case e_expr : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer);
  12326. break;
  12327. case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer);
  12328. break;
  12329. case e_data : delete (T*)(local_data_list[i].pointer);
  12330. break;
  12331. case e_vecdata : delete [] (T*)(local_data_list[i].pointer);
  12332. break;
  12333. case e_string : delete (std::string*)(local_data_list[i].pointer);
  12334. break;
  12335. default : break;
  12336. }
  12337. }
  12338. }
  12339. }
  12340. std::size_t ref_count;
  12341. expression_ptr expr;
  12342. local_data_list_t local_data_list;
  12343. friend class function_compositor<T>;
  12344. };
  12345. public:
  12346. expression()
  12347. : expression_holder_(0)
  12348. {
  12349. set_expression(new details::null_node<T>());
  12350. }
  12351. expression(const expression<T>& e)
  12352. : expression_holder_(e.expression_holder_),
  12353. symbol_table_(e.symbol_table_)
  12354. {
  12355. expression_holder_->ref_count++;
  12356. }
  12357. inline expression<T>& operator=(const expression<T>& e)
  12358. {
  12359. if (this != &e)
  12360. {
  12361. if (expression_holder_)
  12362. {
  12363. if (0 == --expression_holder_->ref_count)
  12364. {
  12365. delete expression_holder_;
  12366. }
  12367. expression_holder_ = 0;
  12368. }
  12369. expression_holder_ = e.expression_holder_;
  12370. expression_holder_->ref_count++;
  12371. symbol_table_ = e.symbol_table_;
  12372. }
  12373. return *this;
  12374. }
  12375. inline bool operator==(const expression<T>& e)
  12376. {
  12377. return (this == &e);
  12378. }
  12379. inline bool operator!() const
  12380. {
  12381. return (
  12382. (0 == expression_holder_ ) ||
  12383. (0 == expression_holder_->expr)
  12384. );
  12385. }
  12386. inline expression<T>& release()
  12387. {
  12388. if (expression_holder_)
  12389. {
  12390. if (0 == --expression_holder_->ref_count)
  12391. {
  12392. delete expression_holder_;
  12393. }
  12394. expression_holder_ = 0;
  12395. }
  12396. return *this;
  12397. }
  12398. ~expression()
  12399. {
  12400. if (expression_holder_)
  12401. {
  12402. if (0 == --expression_holder_->ref_count)
  12403. {
  12404. delete expression_holder_;
  12405. }
  12406. }
  12407. }
  12408. inline T value() const
  12409. {
  12410. return expression_holder_->expr->value();
  12411. }
  12412. inline T operator()() const
  12413. {
  12414. return value();
  12415. }
  12416. inline operator T() const
  12417. {
  12418. return value();
  12419. }
  12420. inline operator bool() const
  12421. {
  12422. return details::is_true(value());
  12423. }
  12424. inline void register_symbol_table(symbol_table<T>& st)
  12425. {
  12426. symbol_table_ = st;
  12427. }
  12428. inline const symbol_table<T>& get_symbol_table() const
  12429. {
  12430. return symbol_table_;
  12431. }
  12432. inline symbol_table<T>& get_symbol_table()
  12433. {
  12434. return symbol_table_;
  12435. }
  12436. private:
  12437. inline void set_expression(const expression_ptr expr)
  12438. {
  12439. if (expr)
  12440. {
  12441. if (expression_holder_)
  12442. {
  12443. if (0 == --expression_holder_->ref_count)
  12444. {
  12445. delete expression_holder_;
  12446. }
  12447. }
  12448. expression_holder_ = new expression_holder(expr);
  12449. }
  12450. }
  12451. inline void register_local_var(expression_ptr expr)
  12452. {
  12453. if (expr)
  12454. {
  12455. if (expression_holder_)
  12456. {
  12457. expression_holder_->
  12458. local_data_list.push_back(
  12459. typename expression<T>::expression_holder::
  12460. data_pack(reinterpret_cast<void*>(expr),
  12461. expression_holder::e_expr));
  12462. }
  12463. }
  12464. }
  12465. inline void register_local_var(vector_holder_ptr vec_holder)
  12466. {
  12467. if (vec_holder)
  12468. {
  12469. if (expression_holder_)
  12470. {
  12471. expression_holder_->
  12472. local_data_list.push_back(
  12473. typename expression<T>::expression_holder::
  12474. data_pack(reinterpret_cast<void*>(vec_holder),
  12475. expression_holder::e_vecholder));
  12476. }
  12477. }
  12478. }
  12479. inline void register_local_data(void* data, const std::size_t& size = 0, const bool vectype = false)
  12480. {
  12481. if (data)
  12482. {
  12483. if (expression_holder_)
  12484. {
  12485. expression_holder_->
  12486. local_data_list.push_back(
  12487. typename expression<T>::expression_holder::
  12488. data_pack(reinterpret_cast<void*>(data),
  12489. vectype ? expression_holder::e_vecdata :
  12490. expression_holder::e_data,
  12491. size));
  12492. }
  12493. }
  12494. }
  12495. inline const typename expression_holder::local_data_list_t& local_data_list()
  12496. {
  12497. if (expression_holder_)
  12498. {
  12499. return expression_holder_->local_data_list;
  12500. }
  12501. else
  12502. {
  12503. static typename expression_holder::local_data_list_t null_local_data_list;
  12504. return null_local_data_list;
  12505. }
  12506. }
  12507. expression_holder* expression_holder_;
  12508. symbol_table<T> symbol_table_;
  12509. friend class parser<T>;
  12510. friend class expression_helper<T>;
  12511. friend class function_compositor<T>;
  12512. };
  12513. template <typename T>
  12514. class expression_helper
  12515. {
  12516. public:
  12517. static inline bool is_constant(const expression<T>& expr)
  12518. {
  12519. return details::is_constant_node(expr.expression_holder_->expr);
  12520. }
  12521. static inline bool is_variable(const expression<T>& expr)
  12522. {
  12523. return details::is_variable_node(expr.expression_holder_->expr);
  12524. }
  12525. static inline bool is_unary(const expression<T>& expr)
  12526. {
  12527. return details::is_unary_node(expr.expression_holder_->expr);
  12528. }
  12529. static inline bool is_binary(const expression<T>& expr)
  12530. {
  12531. return details::is_binary_node(expr.expression_holder_->expr);
  12532. }
  12533. static inline bool is_function(const expression<T>& expr)
  12534. {
  12535. return details::is_function(expr.expression_holder_->expr);
  12536. }
  12537. };
  12538. namespace parser_error
  12539. {
  12540. enum error_mode
  12541. {
  12542. e_unknown = 0,
  12543. e_syntax = 1,
  12544. e_token = 2,
  12545. e_numeric = 4,
  12546. e_symtab = 5,
  12547. e_lexer = 6,
  12548. e_helper = 7
  12549. };
  12550. struct type
  12551. {
  12552. type()
  12553. : mode(parser_error::e_unknown),
  12554. line_no (0),
  12555. column_no(0)
  12556. {}
  12557. lexer::token token;
  12558. error_mode mode;
  12559. std::string diagnostic;
  12560. std::string error_line;
  12561. std::size_t line_no;
  12562. std::size_t column_no;
  12563. };
  12564. inline type make_error(error_mode mode, const std::string& diagnostic = "")
  12565. {
  12566. type t;
  12567. t.mode = mode;
  12568. t.token.type = lexer::token::e_error;
  12569. t.diagnostic = diagnostic;
  12570. exprtk_debug(((diagnostic + "\n").c_str()));
  12571. return t;
  12572. }
  12573. inline type make_error(error_mode mode, const lexer::token& tk, const std::string& diagnostic = "")
  12574. {
  12575. type t;
  12576. t.mode = mode;
  12577. t.token = tk;
  12578. t.diagnostic = diagnostic;
  12579. exprtk_debug(((diagnostic + "\n").c_str()));
  12580. return t;
  12581. }
  12582. inline std::string to_str(error_mode mode)
  12583. {
  12584. switch (mode)
  12585. {
  12586. case e_unknown : return std::string("Unknown Error");
  12587. case e_syntax : return std::string("Syntax Error" );
  12588. case e_token : return std::string("Token Error" );
  12589. case e_numeric : return std::string("Numeric Error");
  12590. case e_symtab : return std::string("Symbol Error" );
  12591. case e_lexer : return std::string("Lexer Error" );
  12592. case e_helper : return std::string("Helper Error" );
  12593. default : return std::string("Unknown Error");
  12594. }
  12595. }
  12596. inline bool update_error(type& error, const std::string& expression)
  12597. {
  12598. if (
  12599. expression.empty() ||
  12600. (error.token.position > expression.size()) ||
  12601. (std::numeric_limits<std::size_t>::max() == error.token.position)
  12602. )
  12603. {
  12604. return false;
  12605. }
  12606. std::size_t error_line_start = 0;
  12607. for (std::size_t i = error.token.position; i > 0; --i)
  12608. {
  12609. const char c = expression[i];
  12610. if (('\n' == c) || ('\r' == c))
  12611. {
  12612. error_line_start = i + 1;
  12613. break;
  12614. }
  12615. }
  12616. std::size_t next_nl_position = std::min(expression.size(),
  12617. expression.find_first_of('\n',error.token.position + 1));
  12618. error.column_no = error.token.position - error_line_start;
  12619. error.error_line = expression.substr(error_line_start,
  12620. next_nl_position - error_line_start);
  12621. error.line_no = 0;
  12622. for (std::size_t i = 0; i < next_nl_position; ++i)
  12623. {
  12624. if ('\n' == expression[i])
  12625. ++error.line_no;
  12626. }
  12627. return true;
  12628. }
  12629. inline void dump_error(const type& error)
  12630. {
  12631. printf("Position: %02d Type: [%s] Msg: %s\n",
  12632. static_cast<int>(error.token.position),
  12633. exprtk::parser_error::to_str(error.mode).c_str(),
  12634. error.diagnostic.c_str());
  12635. }
  12636. }
  12637. template <typename T>
  12638. class parser
  12639. {
  12640. private:
  12641. enum precedence_level
  12642. {
  12643. e_level00,
  12644. e_level01,
  12645. e_level02,
  12646. e_level03,
  12647. e_level04,
  12648. e_level05,
  12649. e_level06,
  12650. e_level07,
  12651. e_level08,
  12652. e_level09,
  12653. e_level10,
  12654. e_level11,
  12655. e_level12,
  12656. e_level13,
  12657. e_level14
  12658. };
  12659. typedef const T& cref_t;
  12660. typedef const T const_t;
  12661. typedef ifunction <T> F;
  12662. typedef ivararg_function <T> VAF;
  12663. typedef igeneric_function <T> GF;
  12664. typedef ifunction <T> ifunction_t;
  12665. typedef ivararg_function <T> ivararg_function_t;
  12666. typedef igeneric_function <T> igeneric_function_t;
  12667. typedef details::expression_node <T> expression_node_t;
  12668. typedef details::literal_node <T> literal_node_t;
  12669. typedef details::unary_node <T> unary_node_t;
  12670. typedef details::binary_node <T> binary_node_t;
  12671. typedef details::trinary_node <T> trinary_node_t;
  12672. typedef details::quaternary_node <T> quaternary_node_t;
  12673. typedef details::quinary_node <T> quinary_node_t;
  12674. typedef details::senary_node <T> senary_node_t;
  12675. typedef details::conditional_node<T> conditional_node_t;
  12676. typedef details::cons_conditional_node<T> cons_conditional_node_t;
  12677. typedef details::while_loop_node <T> while_loop_node_t;
  12678. typedef details::repeat_until_loop_node<T> repeat_until_loop_node_t;
  12679. typedef details::for_loop_node <T> for_loop_node_t;
  12680. #ifndef exprtk_disable_break_continue
  12681. typedef details::while_loop_bc_node <T> while_loop_bc_node_t;
  12682. typedef details::repeat_until_loop_bc_node<T> repeat_until_loop_bc_node_t;
  12683. typedef details::for_loop_bc_node<T> for_loop_bc_node_t;
  12684. #endif
  12685. typedef details::switch_node <T> switch_node_t;
  12686. typedef details::variable_node <T> variable_node_t;
  12687. typedef details::vector_elem_node<T> vector_elem_node_t;
  12688. typedef details::vector_node <T> vector_node_t;
  12689. #ifndef exprtk_disable_string_capabilities
  12690. typedef details::range_pack <T> range_t;
  12691. typedef details::stringvar_node <T> stringvar_node_t;
  12692. typedef details::string_literal_node<T> string_literal_node_t;
  12693. typedef details::string_range_node <T> string_range_node_t;
  12694. typedef details::const_string_range_node<T> const_string_range_node_t;
  12695. typedef details::generic_string_range_node<T> generic_string_range_node_t;
  12696. typedef details::string_concat_node <T> string_concat_node_t;
  12697. typedef details::assignment_string_node<T> assignment_string_node_t;
  12698. typedef details::assignment_string_range_node<T> assignment_string_range_node_t;
  12699. #endif
  12700. typedef details::assignment_node<T> assignment_node_t;
  12701. typedef details::assignment_vec_elem_node<T> assignment_vec_elem_node_t;
  12702. typedef details::assignment_vec_node <T> assignment_vec_node_t;
  12703. typedef details::assignment_vecvec_node <T> assignment_vecvec_node_t;
  12704. typedef details::scand_node<T> scand_node_t;
  12705. typedef details::scor_node<T> scor_node_t;
  12706. typedef lexer::token token_t;
  12707. typedef expression_node_t* expression_node_ptr;
  12708. typedef symbol_table<T> symbol_table_t;
  12709. typedef details::vector_holder<T>* vector_holder_ptr;
  12710. typedef typename details::functor_t<T> functor_t;
  12711. typedef typename functor_t::qfunc_t quaternary_functor_t;
  12712. typedef typename functor_t::tfunc_t trinary_functor_t;
  12713. typedef typename functor_t::bfunc_t binary_functor_t;
  12714. typedef typename functor_t::ufunc_t unary_functor_t;
  12715. typedef details::operator_type operator_t;
  12716. typedef std::map<operator_t, unary_functor_t> unary_op_map_t;
  12717. typedef std::map<operator_t, binary_functor_t> binary_op_map_t;
  12718. typedef std::map<operator_t,trinary_functor_t> trinary_op_map_t;
  12719. typedef std::map<std::string,std::pair<trinary_functor_t ,operator_t> > sf3_map_t;
  12720. typedef std::map<std::string,std::pair<quaternary_functor_t,operator_t> > sf4_map_t;
  12721. typedef std::map<binary_functor_t,operator_t> inv_binary_op_map_t;
  12722. typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_t;
  12723. typedef details::T0oT1_define<T, cref_t, cref_t> vov_t;
  12724. typedef details::T0oT1_define<T,const_t, cref_t> cov_t;
  12725. typedef details::T0oT1_define<T, cref_t,const_t> voc_t;
  12726. typedef details::T0oT1oT2_define<T, cref_t, cref_t, cref_t> vovov_t;
  12727. typedef details::T0oT1oT2_define<T, cref_t, cref_t,const_t> vovoc_t;
  12728. typedef details::T0oT1oT2_define<T, cref_t,const_t, cref_t> vocov_t;
  12729. typedef details::T0oT1oT2_define<T,const_t, cref_t, cref_t> covov_t;
  12730. typedef details::T0oT1oT2_define<T,const_t, cref_t,const_t> covoc_t;
  12731. typedef details::T0oT1oT2_define<T,const_t,const_t, cref_t> cocov_t;
  12732. typedef details::T0oT1oT2_define<T,cref_t,const_t, const_t> vococ_t;
  12733. typedef details::T0oT1oT2oT3_define<T, cref_t, cref_t, cref_t, cref_t> vovovov_t;
  12734. typedef details::T0oT1oT2oT3_define<T, cref_t, cref_t, cref_t,const_t> vovovoc_t;
  12735. typedef details::T0oT1oT2oT3_define<T, cref_t, cref_t,const_t, cref_t> vovocov_t;
  12736. typedef details::T0oT1oT2oT3_define<T, cref_t,const_t, cref_t, cref_t> vocovov_t;
  12737. typedef details::T0oT1oT2oT3_define<T,const_t, cref_t, cref_t, cref_t> covovov_t;
  12738. typedef details::T0oT1oT2oT3_define<T,const_t, cref_t,const_t, cref_t> covocov_t;
  12739. typedef details::T0oT1oT2oT3_define<T, cref_t,const_t, cref_t,const_t> vocovoc_t;
  12740. typedef details::T0oT1oT2oT3_define<T,const_t, cref_t, cref_t,const_t> covovoc_t;
  12741. typedef details::T0oT1oT2oT3_define<T, cref_t,const_t,const_t, cref_t> vococov_t;
  12742. struct scope_element
  12743. {
  12744. enum element_type
  12745. {
  12746. e_none ,
  12747. e_variable,
  12748. e_vector ,
  12749. e_vecelem ,
  12750. e_string
  12751. };
  12752. typedef variable_node_t* variable_node_ptr;
  12753. typedef details::vector_holder<T> vector_holder_t;
  12754. typedef vector_holder_t* vector_holder_ptr;
  12755. scope_element()
  12756. : name("???"),
  12757. size (std::numeric_limits<std::size_t>::max()),
  12758. index(std::numeric_limits<std::size_t>::max()),
  12759. depth(std::numeric_limits<std::size_t>::max()),
  12760. ref_count(0),
  12761. ip_index (0),
  12762. type (e_none),
  12763. active(false),
  12764. data (0),
  12765. var_node(0),
  12766. vec_node(0)
  12767. {}
  12768. bool operator < (const scope_element& se) const
  12769. {
  12770. if (ip_index < se.ip_index)
  12771. return true;
  12772. else if (ip_index > se.ip_index)
  12773. return false;
  12774. else if (depth < se.depth)
  12775. return true;
  12776. else if (depth > se.depth)
  12777. return false;
  12778. else if (index < se.index)
  12779. return true;
  12780. else if (index > se.index)
  12781. return false;
  12782. else
  12783. return (name < se.name);
  12784. }
  12785. std::string name;
  12786. std::size_t size;
  12787. std::size_t index;
  12788. std::size_t depth;
  12789. std::size_t ref_count;
  12790. std::size_t ip_index;
  12791. element_type type;
  12792. bool active;
  12793. void* data;
  12794. variable_node_ptr var_node;
  12795. vector_holder_ptr vec_node;
  12796. };
  12797. class scope_element_manager
  12798. {
  12799. public:
  12800. typedef variable_node_t* variable_node_ptr;
  12801. typedef parser<T> parser_t;
  12802. scope_element_manager(parser<T>& p)
  12803. : parser_(p),
  12804. input_param_cnt_(0)
  12805. {}
  12806. inline std::size_t size() const
  12807. {
  12808. return element_.size();
  12809. }
  12810. inline bool empty() const
  12811. {
  12812. return element_.empty();
  12813. }
  12814. inline scope_element& get_element(const std::size_t& index)
  12815. {
  12816. if (index < element_.size())
  12817. return element_[index];
  12818. else
  12819. return null_element_;
  12820. }
  12821. inline scope_element& get_element(const std::string& var_name,
  12822. const std::size_t index = std::numeric_limits<std::size_t>::max())
  12823. {
  12824. for (std::size_t i = 0; i < element_.size(); ++i)
  12825. {
  12826. scope_element& se = element_[i];
  12827. if (se.depth > parser_.scope_depth_)
  12828. return null_element_;
  12829. else if (
  12830. (se.name == var_name) &&
  12831. (se.index == index)
  12832. )
  12833. return se;
  12834. }
  12835. return null_element_;
  12836. }
  12837. inline bool add_element(const scope_element& se)
  12838. {
  12839. for (std::size_t j = 0; j < element_.size(); ++j)
  12840. {
  12841. if (
  12842. (element_[j].name == se.name ) &&
  12843. (element_[j].depth <= se.depth) &&
  12844. (element_[j].index == se.index) &&
  12845. (element_[j].size == se.size )
  12846. )
  12847. return false;
  12848. }
  12849. element_.push_back(se);
  12850. std::sort(element_.begin(),element_.end());
  12851. return true;
  12852. }
  12853. inline void deactivate(const std::size_t& scope_depth)
  12854. {
  12855. for (std::size_t j = 0; j < element_.size(); ++j)
  12856. {
  12857. if (element_[j].depth >= scope_depth)
  12858. {
  12859. element_[j].active = false;
  12860. }
  12861. }
  12862. }
  12863. void cleanup()
  12864. {
  12865. for (std::size_t i = 0; i < element_.size(); ++i)
  12866. {
  12867. if (element_[i].var_node)
  12868. {
  12869. delete element_[i].var_node;
  12870. }
  12871. if (element_[i].vec_node)
  12872. {
  12873. delete element_[i].vec_node;
  12874. }
  12875. T* data = (T*)(element_[i].data);
  12876. switch (element_[i].type)
  12877. {
  12878. case scope_element::e_variable : delete data; break;
  12879. case scope_element::e_vector : delete [] data; break;
  12880. default : break;
  12881. }
  12882. }
  12883. element_.clear();
  12884. input_param_cnt_ = 0;
  12885. }
  12886. inline std::size_t next_ip_index()
  12887. {
  12888. return ++input_param_cnt_;
  12889. }
  12890. inline variable_node_ptr get_variable(const T& v)
  12891. {
  12892. for (std::size_t i = 0; i < element_.size(); ++i)
  12893. {
  12894. scope_element& se = element_[i];
  12895. if (se.active && se.var_node)
  12896. {
  12897. if (&se.var_node->ref() == (&v))
  12898. {
  12899. return se.var_node;
  12900. }
  12901. }
  12902. }
  12903. return variable_node_ptr(0);
  12904. }
  12905. private:
  12906. scope_element_manager& operator=(const scope_element_manager&);
  12907. parser_t& parser_;
  12908. std::vector<scope_element> element_;
  12909. scope_element null_element_;
  12910. std::size_t input_param_cnt_;
  12911. };
  12912. class scope_handler
  12913. {
  12914. public:
  12915. typedef parser<T> parser_t;
  12916. scope_handler(parser<T>& p)
  12917. : parser_(p)
  12918. {
  12919. parser_.scope_depth_++;
  12920. #ifdef exprtk_enable_debugging
  12921. std::string depth(2 * parser_.scope_depth_,'-');
  12922. exprtk_debug(("%s> Scope Depth: %02d\n",depth.c_str(),static_cast<int>(parser_.scope_depth_)));
  12923. #endif
  12924. }
  12925. ~scope_handler()
  12926. {
  12927. parser_.scope_depth_--;
  12928. parser_.sem_.deactivate(parser_.scope_depth_);
  12929. #ifdef exprtk_enable_debugging
  12930. std::string depth(2 * parser_.scope_depth_,'-');
  12931. exprtk_debug(("<%s Scope Depth: %02d\n",depth.c_str(),static_cast<int>(parser_.scope_depth_)));
  12932. #endif
  12933. }
  12934. private:
  12935. scope_handler& operator=(const scope_handler&);
  12936. parser_t& parser_;
  12937. };
  12938. public:
  12939. enum compilation_options
  12940. {
  12941. e_unknown = 0,
  12942. e_replacer = 1,
  12943. e_joiner = 2,
  12944. e_numeric_check = 4,
  12945. e_bracket_check = 8,
  12946. e_sequence_check = 16,
  12947. e_commutative_check = 32,
  12948. e_strength_reduction = 64,
  12949. e_disable_vardef = 128,
  12950. e_collect_vars = 256,
  12951. e_collect_funcs = 512,
  12952. e_collect_assings = 1024
  12953. };
  12954. struct unknown_symbol_resolver
  12955. {
  12956. enum usr_symbol_type
  12957. {
  12958. e_usr_variable_type = 0,
  12959. e_usr_constant_type = 1
  12960. };
  12961. virtual ~unknown_symbol_resolver()
  12962. {}
  12963. virtual bool process(const std::string& /*unknown_symbol*/,
  12964. usr_symbol_type& st,
  12965. T& default_value,
  12966. std::string& error_message)
  12967. {
  12968. st = e_usr_variable_type;
  12969. default_value = T(0);
  12970. error_message = "";
  12971. return true;
  12972. }
  12973. };
  12974. enum collect_type
  12975. {
  12976. e_ct_none = 0,
  12977. e_ct_variables = 1,
  12978. e_ct_functions = 2,
  12979. e_ct_assignments = 4
  12980. };
  12981. enum symbol_type
  12982. {
  12983. e_st_unknown = 0,
  12984. e_st_variable = 1,
  12985. e_st_vector = 2,
  12986. e_st_string = 3,
  12987. e_st_function = 4,
  12988. e_st_local_variable = 5,
  12989. e_st_local_vector = 6,
  12990. e_st_local_string = 7
  12991. };
  12992. class dependent_entity_collector
  12993. {
  12994. public:
  12995. typedef std::pair<std::string,symbol_type> symbol_t;
  12996. typedef std::vector<symbol_t> symbol_list_t;
  12997. dependent_entity_collector(const std::size_t options = e_ct_none)
  12998. : options_(options),
  12999. collect_variables_ ((options_ & e_ct_variables ) == e_ct_variables ),
  13000. collect_functions_ ((options_ & e_ct_functions ) == e_ct_functions ),
  13001. collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments)
  13002. {}
  13003. template <typename Allocator,
  13004. template <typename,typename> class Sequence>
  13005. inline std::size_t symbols(Sequence<symbol_t,Allocator>& symbols_list)
  13006. {
  13007. if (!collect_variables_ && !collect_functions_)
  13008. return 0;
  13009. else if (symbol_name_list_.empty())
  13010. return 0;
  13011. for (std::size_t i = 0; i < symbol_name_list_.size(); ++i)
  13012. {
  13013. std::string& s = symbol_name_list_[i].first;
  13014. std::transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(std::tolower));
  13015. }
  13016. std::sort(symbol_name_list_.begin(),symbol_name_list_.end());
  13017. std::unique_copy(symbol_name_list_.begin(),
  13018. symbol_name_list_.end(),
  13019. std::back_inserter(symbols_list));
  13020. return symbols_list.size();
  13021. }
  13022. template <typename Allocator,
  13023. template <typename,typename> class Sequence>
  13024. inline std::size_t assignment_symbols(Sequence<symbol_t,Allocator>& assignment_list)
  13025. {
  13026. if (!collect_assignments_)
  13027. return 0;
  13028. else if (assignment_name_list_.empty())
  13029. return 0;
  13030. for (std::size_t i = 0; i < assignment_name_list_.size(); ++i)
  13031. {
  13032. std::string& s = assignment_name_list_[i].first;
  13033. std::transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(std::tolower));
  13034. }
  13035. std::sort(assignment_name_list_.begin(),assignment_name_list_.end());
  13036. std::unique_copy(assignment_name_list_.begin(),
  13037. assignment_name_list_.end(),
  13038. std::back_inserter(assignment_list));
  13039. return assignment_list.size();
  13040. }
  13041. void clear()
  13042. {
  13043. symbol_name_list_ .clear();
  13044. assignment_name_list_.clear();
  13045. }
  13046. bool& collect_variables()
  13047. {
  13048. return collect_variables_;
  13049. }
  13050. bool& collect_functions()
  13051. {
  13052. return collect_functions_;
  13053. }
  13054. bool& collect_assignments()
  13055. {
  13056. return collect_assignments_;
  13057. }
  13058. private:
  13059. inline void add_symbol(const std::string& symbol, const symbol_type st)
  13060. {
  13061. switch (st)
  13062. {
  13063. case e_st_variable :
  13064. case e_st_vector :
  13065. case e_st_string :
  13066. case e_st_local_variable :
  13067. case e_st_local_vector :
  13068. case e_st_local_string :
  13069. case e_st_function :
  13070. if (collect_variables_ || collect_functions_)
  13071. symbol_name_list_.push_back(std::make_pair(symbol,st));
  13072. break;
  13073. default : return;
  13074. }
  13075. }
  13076. inline void add_assignment(const std::string& symbol, const symbol_type st)
  13077. {
  13078. switch (st)
  13079. {
  13080. case e_st_variable :
  13081. case e_st_vector :
  13082. case e_st_string :
  13083. if (collect_assignments_)
  13084. assignment_name_list_.push_back(std::make_pair(symbol,st));
  13085. break;
  13086. default : return;
  13087. }
  13088. }
  13089. std::size_t options_;
  13090. bool collect_variables_;
  13091. bool collect_functions_;
  13092. bool collect_assignments_;
  13093. symbol_list_t symbol_name_list_;
  13094. symbol_list_t assignment_name_list_;
  13095. friend class parser<T>;
  13096. };
  13097. static const std::size_t compile_all_opts = e_replacer +
  13098. e_joiner +
  13099. e_numeric_check +
  13100. e_bracket_check +
  13101. e_sequence_check +
  13102. e_commutative_check +
  13103. e_strength_reduction;
  13104. parser(const std::size_t compile_options = compile_all_opts)
  13105. : compile_options_(compile_options),
  13106. resolve_unknown_symbol_(false),
  13107. vardef_disabled_((compile_options & e_disable_vardef) == e_disable_vardef),
  13108. scope_depth_(0),
  13109. unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver*>(0)),
  13110. #ifdef _MSC_VER
  13111. #pragma warning(push)
  13112. #pragma warning (disable:4355)
  13113. #endif
  13114. sem_(*this),
  13115. #ifdef _MSC_VER
  13116. #pragma warning(pop)
  13117. #endif
  13118. operator_joiner_2_(2),
  13119. operator_joiner_3_(3)
  13120. {
  13121. init_precompilation();
  13122. load_operations_map(base_ops_map_);
  13123. load_unary_operations_map(unary_op_map_);
  13124. load_binary_operations_map(binary_op_map_);
  13125. load_inv_binary_operations_map(inv_binary_op_map_);
  13126. load_sf3_map(sf3_map_);
  13127. load_sf4_map(sf4_map_);
  13128. expression_generator_.init_synthesize_map();
  13129. expression_generator_.set_parser(*this);
  13130. expression_generator_.set_uom(unary_op_map_);
  13131. expression_generator_.set_bom(binary_op_map_);
  13132. expression_generator_.set_ibom(inv_binary_op_map_);
  13133. expression_generator_.set_sf3m(sf3_map_);
  13134. expression_generator_.set_sf4m(sf4_map_);
  13135. expression_generator_.set_strength_reduction_state(strength_reduction_enabled());
  13136. }
  13137. ~parser()
  13138. {}
  13139. inline void init_precompilation()
  13140. {
  13141. if (collect_variables_enabled())
  13142. dec_.collect_variables() = true;
  13143. if (collect_functions_enabled())
  13144. dec_.collect_functions() = true;
  13145. if (collect_assignments_enabled())
  13146. dec_.collect_assignments() = true;
  13147. if (replacer_enabled())
  13148. {
  13149. symbol_replacer_.clear();
  13150. symbol_replacer_.add_replace("true" ,"1",lexer::token::e_number);
  13151. symbol_replacer_.add_replace("false","0",lexer::token::e_number);
  13152. helper_assembly_.token_modifier_list.clear();
  13153. helper_assembly_.register_modifier(&symbol_replacer_);
  13154. }
  13155. if (commutative_check_enabled())
  13156. {
  13157. for (std::size_t i = 0; i < details::reserved_words_size; ++i)
  13158. {
  13159. commutative_inserter_.ignore_symbol(details::reserved_words[i]);
  13160. }
  13161. helper_assembly_.token_inserter_list.clear();
  13162. helper_assembly_.register_inserter(&commutative_inserter_);
  13163. }
  13164. if (joiner_enabled())
  13165. {
  13166. helper_assembly_.token_joiner_list.clear();
  13167. helper_assembly_.register_joiner(&operator_joiner_2_);
  13168. helper_assembly_.register_joiner(&operator_joiner_3_);
  13169. }
  13170. if (
  13171. numeric_check_enabled () ||
  13172. bracket_check_enabled () ||
  13173. sequence_check_enabled()
  13174. )
  13175. {
  13176. helper_assembly_.token_scanner_list.clear();
  13177. if (numeric_check_enabled())
  13178. {
  13179. helper_assembly_.register_scanner(&numeric_checker_);
  13180. }
  13181. if (bracket_check_enabled())
  13182. {
  13183. helper_assembly_.register_scanner(&bracket_checker_);
  13184. }
  13185. if (sequence_check_enabled())
  13186. {
  13187. helper_assembly_.register_scanner(&sequence_validator_);
  13188. }
  13189. }
  13190. }
  13191. inline bool compile(const std::string& expression_string, expression<T>& expr)
  13192. {
  13193. error_list_ .clear();
  13194. brkcnt_list_ .clear();
  13195. synthesis_error_.clear();
  13196. sem_ .cleanup();
  13197. expression_generator_.set_allocator(node_allocator_);
  13198. scope_depth_ = 0;
  13199. if (expression_string.empty())
  13200. {
  13201. set_error(
  13202. make_error(parser_error::e_syntax,
  13203. "ERR00 - Empty expression!"));
  13204. return false;
  13205. }
  13206. if (!lexer_.process(expression_string))
  13207. {
  13208. process_lexer_errors();
  13209. return false;
  13210. }
  13211. if (lexer_.empty())
  13212. {
  13213. set_error(
  13214. make_error(parser_error::e_syntax,
  13215. "ERR01 - Empty expression!"));
  13216. return false;
  13217. }
  13218. if (!run_assemblies())
  13219. {
  13220. return false;
  13221. }
  13222. symbol_table_ = expr.get_symbol_table();
  13223. dec_.clear();
  13224. lexer_.begin();
  13225. next_token();
  13226. expression_node_ptr e = parse_corpus();
  13227. if ((0 != e) && (token_t::e_eof == current_token_.type))
  13228. {
  13229. expr.set_expression(e);
  13230. register_local_vars(expr);
  13231. return !(!expr);
  13232. }
  13233. else
  13234. {
  13235. if (error_list_.empty())
  13236. {
  13237. set_error(
  13238. make_error(parser_error::e_syntax,
  13239. current_token_,
  13240. "ERR02 - Invalid expression encountered"));
  13241. }
  13242. dec_.clear ();
  13243. sem_.cleanup();
  13244. if (0 != e)
  13245. {
  13246. delete e;
  13247. }
  13248. return false;
  13249. }
  13250. }
  13251. void process_lexer_errors()
  13252. {
  13253. for (std::size_t i = 0; i < lexer_.size(); ++i)
  13254. {
  13255. if (lexer_[i].is_error())
  13256. {
  13257. std::string diagnostic = "ERR03 - ";
  13258. switch (lexer_[i].type)
  13259. {
  13260. case lexer::token::e_error : diagnostic += "General token error";
  13261. break;
  13262. case lexer::token::e_err_symbol : diagnostic += "Symbol error";
  13263. break;
  13264. case lexer::token::e_err_number : diagnostic += "Invalid numeric token";
  13265. break;
  13266. case lexer::token::e_err_string : diagnostic += "Invalid string token";
  13267. break;
  13268. case lexer::token::e_err_sfunc : diagnostic += "Invalid special function token";
  13269. break;
  13270. default : diagnostic += "Unknown compiler error";
  13271. }
  13272. set_error(
  13273. make_error(parser_error::e_lexer,
  13274. lexer_[i],
  13275. diagnostic + ": " + lexer_[i].value));
  13276. }
  13277. }
  13278. }
  13279. inline bool replacer_enabled() const
  13280. {
  13281. return ((compile_options_ & e_replacer) == e_replacer);
  13282. }
  13283. inline bool commutative_check_enabled() const
  13284. {
  13285. return ((compile_options_ & e_commutative_check) == e_commutative_check);
  13286. }
  13287. inline bool joiner_enabled() const
  13288. {
  13289. return ((compile_options_ & e_joiner) == e_joiner);
  13290. }
  13291. inline bool numeric_check_enabled() const
  13292. {
  13293. return ((compile_options_ & e_numeric_check) == e_numeric_check);
  13294. }
  13295. inline bool bracket_check_enabled() const
  13296. {
  13297. return ((compile_options_ & e_bracket_check) == e_bracket_check);
  13298. }
  13299. inline bool sequence_check_enabled() const
  13300. {
  13301. return ((compile_options_ & e_sequence_check) == e_sequence_check);
  13302. }
  13303. inline bool strength_reduction_enabled() const
  13304. {
  13305. return ((compile_options_ & e_strength_reduction) == e_strength_reduction);
  13306. }
  13307. inline bool collect_variables_enabled() const
  13308. {
  13309. return ((compile_options_ & e_collect_vars) == e_collect_vars);
  13310. }
  13311. inline bool collect_functions_enabled() const
  13312. {
  13313. return ((compile_options_ & e_collect_funcs) == e_collect_funcs);
  13314. }
  13315. inline bool collect_assignments_enabled() const
  13316. {
  13317. return ((compile_options_ & e_collect_assings) == e_collect_assings);
  13318. }
  13319. inline bool run_assemblies()
  13320. {
  13321. if (commutative_check_enabled())
  13322. {
  13323. helper_assembly_.run_inserters(lexer_);
  13324. }
  13325. if (joiner_enabled())
  13326. {
  13327. helper_assembly_.run_joiners(lexer_);
  13328. }
  13329. if (replacer_enabled())
  13330. {
  13331. helper_assembly_.run_modifiers(lexer_);
  13332. }
  13333. if (
  13334. numeric_check_enabled () ||
  13335. bracket_check_enabled () ||
  13336. sequence_check_enabled()
  13337. )
  13338. {
  13339. if (!helper_assembly_.run_scanners(lexer_))
  13340. {
  13341. if (helper_assembly_.error_token_scanner)
  13342. {
  13343. lexer::helper::bracket_checker* bracket_checker_ptr = 0;
  13344. lexer::helper::numeric_checker* numeric_checker_ptr = 0;
  13345. lexer::helper::sequence_validator* sequence_validator_ptr = 0;
  13346. if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
  13347. {
  13348. set_error(
  13349. make_error(parser_error::e_token,
  13350. bracket_checker_ptr->error_token(),
  13351. "ERR04 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'"));
  13352. }
  13353. else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker*>(helper_assembly_.error_token_scanner)))
  13354. {
  13355. for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i)
  13356. {
  13357. lexer::token error_token = lexer_[numeric_checker_ptr->error_index(i)];
  13358. set_error(
  13359. make_error(parser_error::e_token,
  13360. error_token,
  13361. "ERR05 - Invalid numeric token: '" + error_token.value + "'"));
  13362. }
  13363. if (numeric_checker_ptr->error_count())
  13364. {
  13365. numeric_checker_ptr->clear_errors();
  13366. }
  13367. }
  13368. else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner)))
  13369. {
  13370. for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i)
  13371. {
  13372. std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i);
  13373. set_error(
  13374. make_error(parser_error::e_token,
  13375. error_token.first,
  13376. "ERR06 - Invalid token sequence: '" +
  13377. error_token.first.value + "' and '" +
  13378. error_token.second.value + "'"));
  13379. }
  13380. if (sequence_validator_ptr->error_count())
  13381. {
  13382. sequence_validator_ptr->clear_errors();
  13383. }
  13384. }
  13385. }
  13386. return false;
  13387. }
  13388. }
  13389. return true;
  13390. }
  13391. inline parser_error::type get_error(const std::size_t& index)
  13392. {
  13393. if (index < error_list_.size())
  13394. return error_list_[index];
  13395. else
  13396. throw std::invalid_argument("parser::get_error() - Invalid error index specificed");
  13397. }
  13398. inline std::string error() const
  13399. {
  13400. if (!error_list_.empty())
  13401. {
  13402. return error_list_[0].diagnostic;
  13403. }
  13404. else
  13405. return std::string("No Error");
  13406. }
  13407. inline std::size_t error_count() const
  13408. {
  13409. return error_list_.size();
  13410. }
  13411. inline dependent_entity_collector& dec()
  13412. {
  13413. return dec_;
  13414. }
  13415. inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol)
  13416. {
  13417. if (!replacer_enabled())
  13418. return false;
  13419. else if (details::is_reserved_word(old_symbol))
  13420. return false;
  13421. else
  13422. return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol);
  13423. }
  13424. inline bool remove_replace_symbol(const std::string& symbol)
  13425. {
  13426. if (!replacer_enabled())
  13427. return false;
  13428. else if (details::is_reserved_word(symbol))
  13429. return false;
  13430. else
  13431. return symbol_replacer_.remove(symbol);
  13432. }
  13433. inline void enable_unknown_symbol_resolver(unknown_symbol_resolver* usr = reinterpret_cast<unknown_symbol_resolver*>(0))
  13434. {
  13435. resolve_unknown_symbol_ = true;
  13436. if (usr)
  13437. unknown_symbol_resolver_ = usr;
  13438. else
  13439. unknown_symbol_resolver_ = &default_usr_;
  13440. }
  13441. inline void disable_unknown_symbol_resolver()
  13442. {
  13443. resolve_unknown_symbol_ = false;
  13444. unknown_symbol_resolver_ = &default_usr_;
  13445. }
  13446. private:
  13447. inline bool valid_base_operation(const std::string& symbol)
  13448. {
  13449. const std::size_t length = symbol.size();
  13450. if (
  13451. (length < 3) || // Shortest base op symbol length
  13452. (length > 9) // Longest base op symbol length
  13453. )
  13454. return false;
  13455. else
  13456. return (base_ops_map_.end() != base_ops_map_.find(symbol));
  13457. }
  13458. inline bool valid_vararg_operation(const std::string& symbol)
  13459. {
  13460. static const std::string s_sum = "sum" ;
  13461. static const std::string s_mul = "mul" ;
  13462. static const std::string s_avg = "avg" ;
  13463. static const std::string s_min = "min" ;
  13464. static const std::string s_max = "max" ;
  13465. static const std::string s_mand = "mand";
  13466. static const std::string s_mor = "mor" ;
  13467. static const std::string s_multi = "~" ;
  13468. static const std::string s_mswitch = "[*]" ;
  13469. return
  13470. (
  13471. details::imatch(symbol,s_sum ) ||
  13472. details::imatch(symbol,s_mul ) ||
  13473. details::imatch(symbol,s_avg ) ||
  13474. details::imatch(symbol,s_min ) ||
  13475. details::imatch(symbol,s_max ) ||
  13476. details::imatch(symbol,s_mand ) ||
  13477. details::imatch(symbol,s_mor ) ||
  13478. details::imatch(symbol,s_multi ) ||
  13479. details::imatch(symbol,s_mswitch)
  13480. );
  13481. }
  13482. inline void store_token()
  13483. {
  13484. lexer_.store();
  13485. store_current_token_ = current_token_;
  13486. }
  13487. inline void restore_token()
  13488. {
  13489. lexer_.restore();
  13490. current_token_ = store_current_token_;
  13491. }
  13492. #ifndef exprtk_enable_debugging
  13493. inline void next_token()
  13494. {
  13495. current_token_ = lexer_.next_token();
  13496. }
  13497. #else
  13498. inline void next_token()
  13499. {
  13500. std::string ct_str = current_token_.value;
  13501. current_token_ = lexer_.next_token();
  13502. std::string depth(2 * scope_depth_,' ');
  13503. exprtk_debug(("%s"
  13504. "prev[%s] --> curr[%s]\n",
  13505. depth.c_str(),
  13506. ct_str.c_str(),
  13507. current_token_.value.c_str()));
  13508. }
  13509. #endif
  13510. inline const lexer::token& current_token() const
  13511. {
  13512. return current_token_;
  13513. }
  13514. inline expression_node_ptr parse_corpus()
  13515. {
  13516. std::vector<expression_node_ptr> arg_list;
  13517. expression_node_ptr result = error_node();
  13518. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  13519. for (;;)
  13520. {
  13521. expression_node_ptr arg = parse_expression();
  13522. if (0 == arg)
  13523. {
  13524. if (error_list_.empty())
  13525. {
  13526. set_error(
  13527. make_error(parser_error::e_syntax,
  13528. current_token_,
  13529. "ERR07 - Invalid expression encountered"));
  13530. }
  13531. return error_node();
  13532. }
  13533. else
  13534. arg_list.push_back(arg);
  13535. if (lexer_.finished())
  13536. break;
  13537. else if (token_is(token_t::e_eof,false))
  13538. {
  13539. if (lexer_.finished())
  13540. break;
  13541. else
  13542. next_token();
  13543. }
  13544. }
  13545. result = simplify(arg_list);
  13546. sdd.delete_ptr = (0 == result);
  13547. return result;
  13548. }
  13549. static const precedence_level default_precedence = e_level00;
  13550. struct state_t
  13551. {
  13552. inline void set(const precedence_level& l,
  13553. const precedence_level& r,
  13554. const details::operator_type& o)
  13555. {
  13556. left = l;
  13557. right = r;
  13558. operation = o;
  13559. }
  13560. inline void reset()
  13561. {
  13562. left = e_level00;
  13563. right = e_level00;
  13564. }
  13565. precedence_level left;
  13566. precedence_level right;
  13567. details::operator_type operation;
  13568. };
  13569. inline expression_node_ptr parse_expression(precedence_level precedence = e_level00)
  13570. {
  13571. expression_node_ptr expression = parse_branch(precedence);
  13572. if (0 == expression)
  13573. {
  13574. return error_node();
  13575. }
  13576. bool break_loop = false;
  13577. state_t current_state;
  13578. for ( ; ; )
  13579. {
  13580. current_state.reset();
  13581. switch (current_token_.type)
  13582. {
  13583. case token_t::e_assign : current_state.set(e_level00,e_level00,details::e_assign); break;
  13584. case token_t::e_addass : current_state.set(e_level00,e_level00,details::e_addass); break;
  13585. case token_t::e_subass : current_state.set(e_level00,e_level00,details::e_subass); break;
  13586. case token_t::e_mulass : current_state.set(e_level00,e_level00,details::e_mulass); break;
  13587. case token_t::e_divass : current_state.set(e_level00,e_level00,details::e_divass); break;
  13588. case token_t::e_modass : current_state.set(e_level00,e_level00,details::e_modass); break;
  13589. case token_t::e_swap : current_state.set(e_level00,e_level00,details::e_swap ); break;
  13590. case token_t::e_lt : current_state.set(e_level05,e_level06,details:: e_lt); break;
  13591. case token_t::e_lte : current_state.set(e_level05,e_level06,details:: e_lte); break;
  13592. case token_t::e_eq : current_state.set(e_level05,e_level06,details:: e_eq); break;
  13593. case token_t::e_ne : current_state.set(e_level05,e_level06,details:: e_ne); break;
  13594. case token_t::e_gte : current_state.set(e_level05,e_level06,details:: e_gte); break;
  13595. case token_t::e_gt : current_state.set(e_level05,e_level06,details:: e_gt); break;
  13596. case token_t::e_add : current_state.set(e_level07,e_level08,details:: e_add); break;
  13597. case token_t::e_sub : current_state.set(e_level07,e_level08,details:: e_sub); break;
  13598. case token_t::e_div : current_state.set(e_level10,e_level11,details:: e_div); break;
  13599. case token_t::e_mul : current_state.set(e_level10,e_level11,details:: e_mul); break;
  13600. case token_t::e_mod : current_state.set(e_level10,e_level11,details:: e_mod); break;
  13601. case token_t::e_pow : current_state.set(e_level12,e_level12,details:: e_pow); break;
  13602. default : if (token_t::e_symbol == current_token_.type)
  13603. {
  13604. static const std::string s_and = "and";
  13605. static const std::string s_nand = "nand";
  13606. static const std::string s_or = "or";
  13607. static const std::string s_nor = "nor";
  13608. static const std::string s_xor = "xor";
  13609. static const std::string s_xnor = "xnor";
  13610. static const std::string s_in = "in";
  13611. static const std::string s_like = "like";
  13612. static const std::string s_ilike = "ilike";
  13613. static const std::string s_and1 = "&";
  13614. static const std::string s_or1 = "|";
  13615. if (details::imatch(current_token_.value,s_and))
  13616. {
  13617. current_state.set(e_level01,e_level02,details::e_and);
  13618. break;
  13619. }
  13620. else if (details::imatch(current_token_.value,s_and1))
  13621. {
  13622. #ifndef exprtk_disable_sc_andor
  13623. current_state.set(e_level01,e_level02,details::e_scand);
  13624. #else
  13625. current_state.set(e_level01,e_level02,details::e_and);
  13626. #endif
  13627. break;
  13628. }
  13629. else if (details::imatch(current_token_.value,s_nand))
  13630. {
  13631. current_state.set(e_level01,e_level02,details::e_nand);
  13632. break;
  13633. }
  13634. else if (details::imatch(current_token_.value,s_or))
  13635. {
  13636. current_state.set(e_level03,e_level04,details::e_or);
  13637. break;
  13638. }
  13639. else if (details::imatch(current_token_.value,s_or1))
  13640. {
  13641. #ifndef exprtk_disable_sc_andor
  13642. current_state.set(e_level03,e_level04,details::e_scor);
  13643. #else
  13644. current_state.set(e_level03,e_level04,details::e_or);
  13645. #endif
  13646. break;
  13647. }
  13648. else if (details::imatch(current_token_.value,s_nor))
  13649. {
  13650. current_state.set(e_level03,e_level04,details::e_nor);
  13651. break;
  13652. }
  13653. else if (details::imatch(current_token_.value,s_xor))
  13654. {
  13655. current_state.set(e_level03,e_level04,details::e_xor);
  13656. break;
  13657. }
  13658. else if (details::imatch(current_token_.value,s_xnor))
  13659. {
  13660. current_state.set(e_level03,e_level04,details::e_xnor);
  13661. break;
  13662. }
  13663. else if (details::imatch(current_token_.value,s_in))
  13664. {
  13665. current_state.set(e_level03,e_level04,details::e_in);
  13666. break;
  13667. }
  13668. else if (details::imatch(current_token_.value,s_like))
  13669. {
  13670. current_state.set(e_level03,e_level04,details::e_like);
  13671. break;
  13672. }
  13673. else if (details::imatch(current_token_.value,s_ilike))
  13674. {
  13675. current_state.set(e_level03,e_level04,details::e_ilike);
  13676. break;
  13677. }
  13678. }
  13679. break_loop = true;
  13680. }
  13681. if (break_loop)
  13682. {
  13683. parse_pending_string_rangesize(expression);
  13684. break;
  13685. }
  13686. else if (current_state.left < precedence)
  13687. break;
  13688. lexer::token prev_token = current_token_;
  13689. next_token();
  13690. expression_node_ptr right_branch = error_node();
  13691. expression_node_ptr new_expression = error_node();
  13692. if ((right_branch = parse_expression(current_state.right)))
  13693. {
  13694. new_expression = expression_generator_
  13695. (
  13696. current_state.operation,
  13697. expression,
  13698. right_branch
  13699. );
  13700. }
  13701. if (0 == new_expression)
  13702. {
  13703. if (error_list_.empty())
  13704. {
  13705. set_error(
  13706. make_error(parser_error::e_syntax,
  13707. prev_token,
  13708. !synthesis_error_.empty() ?
  13709. synthesis_error_ :
  13710. "ERR08 - General parsing error at token: '" + prev_token.value + "'"));
  13711. }
  13712. free_node(node_allocator_,expression);
  13713. return error_node();
  13714. }
  13715. else
  13716. {
  13717. expression = new_expression;
  13718. if (token_is(token_t::e_ternary,false) && (precedence == e_level00))
  13719. {
  13720. expression = parse_ternary_conditional_statement(expression);
  13721. }
  13722. parse_pending_string_rangesize(expression);
  13723. }
  13724. }
  13725. return expression;
  13726. }
  13727. bool simplify_unary_negation_branch(expression_node_ptr& node)
  13728. {
  13729. {
  13730. typedef details::unary_branch_node<T,details::neg_op<T> > ubn_t;
  13731. ubn_t* n = dynamic_cast<ubn_t*>(node);
  13732. if (n)
  13733. {
  13734. expression_node_ptr un_r = n->branch(0);
  13735. n->release();
  13736. free_node(node_allocator_,node);
  13737. node = un_r;
  13738. return true;
  13739. }
  13740. }
  13741. {
  13742. typedef details::unary_variable_node<T,details::neg_op<T> > ubn_t;
  13743. ubn_t* n = dynamic_cast<ubn_t*>(node);
  13744. if (n)
  13745. {
  13746. const T& v = n->v();
  13747. expression_node_ptr return_node = error_node();
  13748. if (
  13749. (return_node = symbol_table_.get_variable(v)) ||
  13750. (return_node = sem_ .get_variable(v))
  13751. )
  13752. {
  13753. free_node(node_allocator_,node);
  13754. node = return_node;
  13755. return true;
  13756. }
  13757. else
  13758. {
  13759. set_error(
  13760. make_error(parser_error::e_syntax,
  13761. current_token_,
  13762. "ERR09 - Failed to find variable node in symbol table"));
  13763. free_node(node_allocator_,node);
  13764. return false;
  13765. }
  13766. }
  13767. }
  13768. return false;
  13769. }
  13770. static inline expression_node_ptr error_node()
  13771. {
  13772. return reinterpret_cast<expression_node_ptr>(0);
  13773. }
  13774. template <typename Type, std::size_t N>
  13775. struct scoped_delete
  13776. {
  13777. typedef Type* ptr_t;
  13778. scoped_delete(parser<T>& pr, ptr_t& p)
  13779. : delete_ptr(true),
  13780. parser_(pr),
  13781. p_(&p)
  13782. {}
  13783. scoped_delete(parser<T>& pr, ptr_t (&p)[N])
  13784. : delete_ptr(true),
  13785. parser_(pr),
  13786. p_(&p[0])
  13787. {}
  13788. ~scoped_delete()
  13789. {
  13790. if (delete_ptr)
  13791. {
  13792. for (std::size_t i = 0; i < N; ++i)
  13793. {
  13794. free_node(parser_.node_allocator_,p_[i]);
  13795. }
  13796. }
  13797. }
  13798. bool delete_ptr;
  13799. parser<T>& parser_;
  13800. ptr_t* p_;
  13801. private:
  13802. scoped_delete<Type,N>& operator=(const scoped_delete<Type,N>&);
  13803. };
  13804. template <typename Type>
  13805. struct scoped_deq_delete
  13806. {
  13807. typedef Type* ptr_t;
  13808. scoped_deq_delete(parser<T>& pr, std::deque<ptr_t>& deq)
  13809. : delete_ptr(true),
  13810. parser_(pr),
  13811. deq_(deq)
  13812. {}
  13813. ~scoped_deq_delete()
  13814. {
  13815. if (delete_ptr && !deq_.empty())
  13816. {
  13817. for (std::size_t i = 0; i < deq_.size(); ++i)
  13818. {
  13819. free_node(parser_.node_allocator_,deq_[i]);
  13820. }
  13821. deq_.clear();
  13822. }
  13823. }
  13824. bool delete_ptr;
  13825. parser<T>& parser_;
  13826. std::deque<ptr_t>& deq_;
  13827. private:
  13828. scoped_deq_delete<Type>& operator=(const scoped_deq_delete<Type>&);
  13829. };
  13830. template <typename Type>
  13831. struct scoped_vec_delete
  13832. {
  13833. typedef Type* ptr_t;
  13834. scoped_vec_delete(parser<T>& pr, std::vector<ptr_t>& vec)
  13835. : delete_ptr(true),
  13836. parser_(pr),
  13837. vec_(vec)
  13838. {}
  13839. ~scoped_vec_delete()
  13840. {
  13841. if (delete_ptr && !vec_.empty())
  13842. {
  13843. for (std::size_t i = 0; i < vec_.size(); ++i)
  13844. {
  13845. free_node(parser_.node_allocator_,vec_[i]);
  13846. }
  13847. vec_.clear();
  13848. }
  13849. }
  13850. bool delete_ptr;
  13851. parser<T>& parser_;
  13852. std::vector<ptr_t>& vec_;
  13853. private:
  13854. scoped_vec_delete<Type>& operator=(const scoped_vec_delete<Type>&);
  13855. };
  13856. inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name)
  13857. {
  13858. expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0);
  13859. switch (function->param_count)
  13860. {
  13861. case 0 : func_node = parse_function_call_0 (function,function_name); break;
  13862. case 1 : func_node = parse_function_call< 1>(function,function_name); break;
  13863. case 2 : func_node = parse_function_call< 2>(function,function_name); break;
  13864. case 3 : func_node = parse_function_call< 3>(function,function_name); break;
  13865. case 4 : func_node = parse_function_call< 4>(function,function_name); break;
  13866. case 5 : func_node = parse_function_call< 5>(function,function_name); break;
  13867. case 6 : func_node = parse_function_call< 6>(function,function_name); break;
  13868. case 7 : func_node = parse_function_call< 7>(function,function_name); break;
  13869. case 8 : func_node = parse_function_call< 8>(function,function_name); break;
  13870. case 9 : func_node = parse_function_call< 9>(function,function_name); break;
  13871. case 10 : func_node = parse_function_call<10>(function,function_name); break;
  13872. case 11 : func_node = parse_function_call<11>(function,function_name); break;
  13873. case 12 : func_node = parse_function_call<12>(function,function_name); break;
  13874. case 13 : func_node = parse_function_call<13>(function,function_name); break;
  13875. case 14 : func_node = parse_function_call<14>(function,function_name); break;
  13876. case 15 : func_node = parse_function_call<15>(function,function_name); break;
  13877. case 16 : func_node = parse_function_call<16>(function,function_name); break;
  13878. case 17 : func_node = parse_function_call<17>(function,function_name); break;
  13879. case 18 : func_node = parse_function_call<18>(function,function_name); break;
  13880. case 19 : func_node = parse_function_call<19>(function,function_name); break;
  13881. case 20 : func_node = parse_function_call<20>(function,function_name); break;
  13882. default : {
  13883. set_error(
  13884. make_error(parser_error::e_syntax,
  13885. current_token_,
  13886. "ERR10 - Invalid number of parameters for function: '" + function_name + "'"));
  13887. return error_node();
  13888. }
  13889. }
  13890. if (func_node)
  13891. return func_node;
  13892. else
  13893. {
  13894. set_error(
  13895. make_error(parser_error::e_syntax,
  13896. current_token_,
  13897. "ERR11 - Failed to generate call to function: '" + function_name + "'"));
  13898. return error_node();
  13899. }
  13900. }
  13901. template <std::size_t NumberofParameters>
  13902. inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name)
  13903. {
  13904. if (0 == NumberofParameters)
  13905. {
  13906. set_error(
  13907. make_error(parser_error::e_syntax,
  13908. current_token_,
  13909. "ERR12 - Expecting ifunction '" + function_name + "' to have non-zero parameter count"));
  13910. return error_node();
  13911. }
  13912. expression_node_ptr branch[NumberofParameters];
  13913. expression_node_ptr result = error_node();
  13914. std::fill_n(branch,NumberofParameters,reinterpret_cast<expression_node_ptr>(0));
  13915. scoped_delete<expression_node_t,NumberofParameters> sd(*this,branch);
  13916. next_token();
  13917. if (!token_is(token_t::e_lbracket))
  13918. {
  13919. set_error(
  13920. make_error(parser_error::e_syntax,
  13921. current_token_,
  13922. "ERR13 - Expecting argument list for function: '" + function_name + "'"));
  13923. return error_node();
  13924. }
  13925. for (int i = 0; i < static_cast<int>(NumberofParameters); ++i)
  13926. {
  13927. branch[i] = parse_expression();
  13928. if (0 == branch[i])
  13929. {
  13930. set_error(
  13931. make_error(parser_error::e_syntax,
  13932. current_token_,
  13933. "ERR14 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'"));
  13934. return error_node();
  13935. }
  13936. else if (i < static_cast<int>(NumberofParameters - 1))
  13937. {
  13938. if (!token_is(token_t::e_comma))
  13939. {
  13940. set_error(
  13941. make_error(parser_error::e_syntax,
  13942. current_token_,
  13943. "ERR15 - Invalid number of arguments for function: '" + function_name + "'"));
  13944. return error_node();
  13945. }
  13946. }
  13947. }
  13948. if (!token_is(token_t::e_rbracket))
  13949. {
  13950. set_error(
  13951. make_error(parser_error::e_syntax,
  13952. current_token_,
  13953. "ERR16 - Invalid number of arguments for function: '" + function_name + "'"));
  13954. return error_node();
  13955. }
  13956. else
  13957. result = expression_generator_.function(function,branch);
  13958. sd.delete_ptr = false;
  13959. return result;
  13960. }
  13961. inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name)
  13962. {
  13963. expression_node_ptr result = expression_generator_.function(function);
  13964. next_token();
  13965. if (
  13966. token_is(token_t::e_lbracket) &&
  13967. !token_is(token_t::e_rbracket)
  13968. )
  13969. {
  13970. set_error(
  13971. make_error(parser_error::e_syntax,
  13972. current_token_,
  13973. "ERR17 - Expecting '()' to proceed call to function: '" + function_name + "'"));
  13974. free_node(node_allocator_,result);
  13975. return error_node();
  13976. }
  13977. else
  13978. return result;
  13979. }
  13980. template <std::size_t MaxNumberofParameters>
  13981. inline int parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters])
  13982. {
  13983. std::fill_n(param_list,MaxNumberofParameters,reinterpret_cast<expression_node_ptr>(0));
  13984. scoped_delete<expression_node_t,MaxNumberofParameters> sd(*this,param_list);
  13985. next_token();
  13986. if (!token_is(token_t::e_lbracket))
  13987. {
  13988. set_error(
  13989. make_error(parser_error::e_syntax,
  13990. current_token_,
  13991. "ERR18 - Expected a '(' at start of function call, instead got: '" + current_token_.value + "'"));
  13992. return 0;
  13993. }
  13994. int param_index = 0;
  13995. for (; param_index < static_cast<int>(MaxNumberofParameters); ++param_index)
  13996. {
  13997. param_list[param_index] = parse_expression();
  13998. if (0 == param_list[param_index])
  13999. {
  14000. return 0;
  14001. }
  14002. else if (token_is(token_t::e_rbracket))
  14003. break;
  14004. else if (token_is(token_t::e_comma))
  14005. continue;
  14006. else
  14007. {
  14008. set_error(
  14009. make_error(parser_error::e_syntax,
  14010. current_token_,
  14011. "ERR19 - Expected a ',' between function input parameters, instead got: '" + current_token_.value + "'"));
  14012. return 0;
  14013. }
  14014. }
  14015. sd.delete_ptr = false;
  14016. return (param_index + 1);
  14017. }
  14018. inline expression_node_ptr parse_base_operation()
  14019. {
  14020. typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t;
  14021. const std::string operation_name = current_token_.value;
  14022. map_range_t itr_range = base_ops_map_.equal_range(operation_name);
  14023. if (0 == std::distance(itr_range.first,itr_range.second))
  14024. {
  14025. set_error(
  14026. make_error(parser_error::e_syntax,
  14027. current_token_,
  14028. "ERR20 - No entry found for base operation: " + operation_name));
  14029. return error_node();
  14030. }
  14031. const std::size_t MaxNumberofParameters = 6;
  14032. expression_node_ptr param_list[MaxNumberofParameters] = {0};
  14033. std::size_t parameter_count = parse_base_function_call(param_list);
  14034. if (0 == parameter_count)
  14035. {
  14036. return error_node();
  14037. }
  14038. else if (parameter_count <= 6)
  14039. {
  14040. for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
  14041. {
  14042. details::base_operation_t& operation = itr->second;
  14043. if (operation.num_params == parameter_count)
  14044. {
  14045. switch (parameter_count)
  14046. {
  14047. #define base_opr_case(N) \
  14048. case N : { \
  14049. expression_node_ptr pl##N[N] = {0}; \
  14050. std::copy(param_list,param_list + N,pl##N); \
  14051. lodge_symbol(operation_name,e_st_function); \
  14052. return expression_generator_(operation.type,pl##N);\
  14053. } \
  14054. base_opr_case(1)
  14055. base_opr_case(2)
  14056. base_opr_case(3)
  14057. base_opr_case(4)
  14058. base_opr_case(5)
  14059. base_opr_case(6)
  14060. #undef base_opr_case
  14061. }
  14062. }
  14063. }
  14064. }
  14065. for (std::size_t i = 0; i < MaxNumberofParameters; ++i)
  14066. {
  14067. free_node(node_allocator_,param_list[i]);
  14068. }
  14069. set_error(
  14070. make_error(parser_error::e_syntax,
  14071. current_token_,
  14072. "ERR21 - Invalid number of parameters for call to function: '" + operation_name + "'"));
  14073. return error_node();
  14074. }
  14075. inline expression_node_ptr parse_conditional_statement_01(expression_node_ptr condition)
  14076. {
  14077. // Parse: [if][(][condition][,][consequent][,][alternative][)]
  14078. expression_node_ptr consequent = error_node();
  14079. expression_node_ptr alternative = error_node();
  14080. bool result = true;
  14081. if (!token_is(token_t::e_comma))
  14082. {
  14083. set_error(
  14084. make_error(parser_error::e_syntax,
  14085. current_token_,
  14086. "ERR22 - Expected ',' between if-statement condition and consequent"));
  14087. result = false;
  14088. }
  14089. else if (0 == (consequent = parse_expression()))
  14090. {
  14091. set_error(
  14092. make_error(parser_error::e_syntax,
  14093. current_token_,
  14094. "ERR23 - Failed to parse consequent for if-statement"));
  14095. result = false;
  14096. }
  14097. else if (!token_is(token_t::e_comma))
  14098. {
  14099. set_error(
  14100. make_error(parser_error::e_syntax,
  14101. current_token_,
  14102. "ERR24 - Expected ',' between if-statement consequent and alternative"));
  14103. result = false;
  14104. }
  14105. else if (0 == (alternative = parse_expression()))
  14106. {
  14107. set_error(
  14108. make_error(parser_error::e_syntax,
  14109. current_token_,
  14110. "ERR25 - Failed to parse alternative for if-statement"));
  14111. result = false;
  14112. }
  14113. else if (!token_is(token_t::e_rbracket))
  14114. {
  14115. set_error(
  14116. make_error(parser_error::e_syntax,
  14117. current_token_,
  14118. "ERR26 - Expected ')' at the end of if-statement"));
  14119. result = false;
  14120. }
  14121. if (!result)
  14122. {
  14123. free_node(node_allocator_, condition);
  14124. free_node(node_allocator_, consequent);
  14125. free_node(node_allocator_,alternative);
  14126. return error_node();
  14127. }
  14128. else
  14129. return expression_generator_.conditional(condition,consequent,alternative);
  14130. }
  14131. inline expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition)
  14132. {
  14133. expression_node_ptr consequent = error_node();
  14134. expression_node_ptr alternative = error_node();
  14135. bool result = true;
  14136. if (token_is(token_t::e_lcrlbracket,false))
  14137. {
  14138. if (0 == (consequent = parse_multi_sequence("if-statement-01")))
  14139. {
  14140. set_error(
  14141. make_error(parser_error::e_syntax,
  14142. current_token_,
  14143. "ERR27 - Failed to parse body of consequent for if-statement"));
  14144. result = false;
  14145. }
  14146. }
  14147. else
  14148. {
  14149. if (
  14150. commutative_check_enabled() &&
  14151. token_is(token_t::e_mul,false)
  14152. )
  14153. {
  14154. next_token();
  14155. }
  14156. if (0 != (consequent = parse_expression()))
  14157. {
  14158. if (!token_is(token_t::e_eof))
  14159. {
  14160. set_error(
  14161. make_error(parser_error::e_syntax,
  14162. current_token_,
  14163. "ERR28 - Expected ';' at the end of the consequent for if-statement"));
  14164. result = false;
  14165. }
  14166. }
  14167. else
  14168. {
  14169. set_error(
  14170. make_error(parser_error::e_syntax,
  14171. current_token_,
  14172. "ERR29 - Failed to parse body of consequent for if-statement"));
  14173. result = false;
  14174. }
  14175. }
  14176. if (result)
  14177. {
  14178. if (details::imatch(current_token_.value,"else"))
  14179. {
  14180. next_token();
  14181. if (token_is(token_t::e_lcrlbracket,false))
  14182. {
  14183. if (0 == (alternative = parse_multi_sequence("else-statement-01")))
  14184. {
  14185. set_error(
  14186. make_error(parser_error::e_syntax,
  14187. current_token_,
  14188. "ERR30 - Failed to parse body of the 'else' for if-statement"));
  14189. result = false;
  14190. }
  14191. }
  14192. else if (details::imatch(current_token_.value,"if"))
  14193. {
  14194. if (0 == (alternative = parse_conditional_statement()))
  14195. {
  14196. set_error(
  14197. make_error(parser_error::e_syntax,
  14198. current_token_,
  14199. "ERR31 - Failed to parse body of if-else statement"));
  14200. result = false;
  14201. }
  14202. }
  14203. else if (0 != (alternative = parse_expression()))
  14204. {
  14205. if (!token_is(token_t::e_eof))
  14206. {
  14207. set_error(
  14208. make_error(parser_error::e_syntax,
  14209. current_token_,
  14210. "ERR32 - Expected ';' at the end of the 'else-if' for the if-statement"));
  14211. result = false;
  14212. }
  14213. }
  14214. else
  14215. {
  14216. set_error(
  14217. make_error(parser_error::e_syntax,
  14218. current_token_,
  14219. "ERR33 - Failed to parse body of the 'else' for if-statement"));
  14220. result = false;
  14221. }
  14222. }
  14223. }
  14224. if (!result)
  14225. {
  14226. free_node(node_allocator_, condition);
  14227. free_node(node_allocator_, consequent);
  14228. free_node(node_allocator_,alternative);
  14229. return error_node();
  14230. }
  14231. else
  14232. return expression_generator_.conditional(condition,consequent,alternative);
  14233. }
  14234. inline expression_node_ptr parse_conditional_statement()
  14235. {
  14236. expression_node_ptr condition = error_node();
  14237. next_token();
  14238. if (!token_is(token_t::e_lbracket))
  14239. {
  14240. set_error(
  14241. make_error(parser_error::e_syntax,
  14242. current_token_,
  14243. "ERR34 - Expected '(' at start of if-statement, instead got: '" + current_token_.value + "'"));
  14244. return error_node();
  14245. }
  14246. else if (0 == (condition = parse_expression()))
  14247. {
  14248. set_error(
  14249. make_error(parser_error::e_syntax,
  14250. current_token_,
  14251. "ERR35 - Failed to parse condition for if-statement"));
  14252. return error_node();
  14253. }
  14254. else if (token_is(token_t::e_comma,false))
  14255. {
  14256. // if (x,y,z)
  14257. return parse_conditional_statement_01(condition);
  14258. }
  14259. else if (token_is(token_t::e_rbracket))
  14260. {
  14261. // 00. if (x) y;
  14262. // 01. if (x) y; else z;
  14263. // 02. if (x) y; else {z0; ... zn;}
  14264. // 03. if (x) y; else if (z) w;
  14265. // 04. if (x) y; else if (z) w; else u;
  14266. // 05. if (x) y; else if (z) w; else {u0; ... un;}
  14267. // 06. if (x) y; else if (z) {w0; ... wn;}
  14268. // 07. if (x) {y0; ... yn;}
  14269. // 08. if (x) {y0; ... yn;} else z;
  14270. // 09. if (x) {y0; ... yn;} else {z0; ... zn;};
  14271. // 10. if (x) {y0; ... yn;} else if (z) w;
  14272. // 11. if (x) {y0; ... yn;} else if (z) w; else u;
  14273. // 12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;}
  14274. // 13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;}
  14275. return parse_conditional_statement_02(condition);
  14276. }
  14277. set_error(
  14278. make_error(parser_error::e_syntax,
  14279. current_token_,
  14280. "ERR36 - Invalid if-statement"));
  14281. free_node(node_allocator_,condition);
  14282. return error_node();
  14283. }
  14284. inline expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition)
  14285. {
  14286. // Parse: [condition][?][consequent][:][alternative]
  14287. expression_node_ptr consequent = error_node();
  14288. expression_node_ptr alternative = error_node();
  14289. bool result = true;
  14290. if (0 == condition)
  14291. {
  14292. set_error(
  14293. make_error(parser_error::e_syntax,
  14294. current_token_,
  14295. "ERR37 - Encountered invalid condition branch for ternary if-statement"));
  14296. return error_node();
  14297. }
  14298. else if (!token_is(token_t::e_ternary))
  14299. {
  14300. set_error(
  14301. make_error(parser_error::e_syntax,
  14302. current_token_,
  14303. "ERR38 - Expected '?' after condition of ternary if-statement"));
  14304. result = false;
  14305. }
  14306. else if (0 == (consequent = parse_expression()))
  14307. {
  14308. set_error(
  14309. make_error(parser_error::e_syntax,
  14310. current_token_,
  14311. "ERR39 - Failed to parse consequent for if-statement"));
  14312. result = false;
  14313. }
  14314. else if (!token_is(token_t::e_colon))
  14315. {
  14316. set_error(
  14317. make_error(parser_error::e_syntax,
  14318. current_token_,
  14319. "ERR40 - Expected ':' between ternary if-statement consequent and alternative"));
  14320. result = false;
  14321. }
  14322. else if (0 == (alternative = parse_expression()))
  14323. {
  14324. set_error(
  14325. make_error(parser_error::e_syntax,
  14326. current_token_,
  14327. "ERR41 - Failed to parse alternative for if-statement"));
  14328. result = false;
  14329. }
  14330. if (!result)
  14331. {
  14332. free_node(node_allocator_, condition);
  14333. free_node(node_allocator_, consequent);
  14334. free_node(node_allocator_,alternative);
  14335. return error_node();
  14336. }
  14337. else
  14338. return expression_generator_.conditional(condition,consequent,alternative);
  14339. }
  14340. inline expression_node_ptr parse_while_loop()
  14341. {
  14342. // Parse: [while][(][test expr][)][{][expression][}]
  14343. expression_node_ptr condition = error_node();
  14344. expression_node_ptr branch = error_node();
  14345. expression_node_ptr result_node = error_node();
  14346. bool result = true;
  14347. next_token();
  14348. if (!token_is(token_t::e_lbracket))
  14349. {
  14350. set_error(
  14351. make_error(parser_error::e_syntax,
  14352. current_token_,
  14353. "ERR42 - Expected '(' at start of while-loop condition statement"));
  14354. return error_node();
  14355. }
  14356. else if (0 == (condition = parse_expression()))
  14357. {
  14358. set_error(
  14359. make_error(parser_error::e_syntax,
  14360. current_token_,
  14361. "ERR43 - Failed to parse condition for while-loop"));
  14362. return error_node();
  14363. }
  14364. else if (!token_is(token_t::e_rbracket))
  14365. {
  14366. set_error(
  14367. make_error(parser_error::e_syntax,
  14368. current_token_,
  14369. "ERR44 - Expected ')' at end of while-loop condition statement"));
  14370. result = false;
  14371. }
  14372. brkcnt_list_.push_front(false);
  14373. if (result)
  14374. {
  14375. if (0 == (branch = parse_multi_sequence("while-loop")))
  14376. {
  14377. set_error(
  14378. make_error(parser_error::e_syntax,
  14379. current_token_,
  14380. "ERR45 - Failed to parse body of while-loop"));
  14381. result = false;
  14382. }
  14383. else if (0 == (result_node = expression_generator_.while_loop(condition,
  14384. branch,
  14385. brkcnt_list_.front())))
  14386. {
  14387. set_error(
  14388. make_error(parser_error::e_syntax,
  14389. current_token_,
  14390. "ERR46 - Failed to synthesize while-loop"));
  14391. result = false;
  14392. }
  14393. }
  14394. if (!result)
  14395. {
  14396. free_node(node_allocator_, branch);
  14397. free_node(node_allocator_, condition);
  14398. free_node(node_allocator_,result_node);
  14399. brkcnt_list_.pop_front();
  14400. return error_node();
  14401. }
  14402. else
  14403. return result_node;
  14404. }
  14405. inline expression_node_ptr parse_repeat_until_loop()
  14406. {
  14407. // Parse: [repeat][{][expression][}][until][(][test expr][)]
  14408. expression_node_ptr condition = error_node();
  14409. expression_node_ptr branch = error_node();
  14410. next_token();
  14411. std::vector<expression_node_ptr> arg_list;
  14412. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  14413. brkcnt_list_.push_front(false);
  14414. if (details::imatch(current_token_.value,"until"))
  14415. {
  14416. next_token();
  14417. branch = node_allocator_.allocate<details::null_node<T> >();
  14418. }
  14419. else
  14420. {
  14421. token_t::token_type seperator = token_t::e_eof;
  14422. scope_handler sh(*this);
  14423. for (;;)
  14424. {
  14425. expression_node_ptr arg = parse_expression();
  14426. if (0 == arg)
  14427. return error_node();
  14428. else
  14429. arg_list.push_back(arg);
  14430. if (details::imatch(current_token_.value,"until"))
  14431. {
  14432. next_token();
  14433. break;
  14434. }
  14435. bool is_next_until = peek_token_is(token_t::e_symbol) &&
  14436. peek_token_is("until");
  14437. if (!token_is(seperator) && is_next_until)
  14438. {
  14439. set_error(
  14440. make_error(parser_error::e_syntax,
  14441. current_token_,
  14442. "ERR47 - Expected '" + token_t::to_str(seperator) + "' for body of repeat until loop"));
  14443. return error_node();
  14444. }
  14445. if (details::imatch(current_token_.value,"until"))
  14446. {
  14447. next_token();
  14448. break;
  14449. }
  14450. }
  14451. branch = simplify(arg_list);
  14452. if ((sdd.delete_ptr = (0 == branch)))
  14453. {
  14454. brkcnt_list_.pop_front();
  14455. set_error(
  14456. make_error(parser_error::e_syntax,
  14457. current_token_,
  14458. "ERR48 - Failed to parse body of repeat until loop"));
  14459. return error_node();
  14460. }
  14461. }
  14462. if (!token_is(token_t::e_lbracket))
  14463. {
  14464. brkcnt_list_.pop_front();
  14465. set_error(
  14466. make_error(parser_error::e_syntax,
  14467. current_token_,
  14468. "ERR49 - Expected '(' before condition statement of repeat until loop"));
  14469. free_node(node_allocator_,branch);
  14470. return error_node();
  14471. }
  14472. else if (0 == (condition = parse_expression()))
  14473. {
  14474. brkcnt_list_.pop_front();
  14475. set_error(
  14476. make_error(parser_error::e_syntax,
  14477. current_token_,
  14478. "ERR50 - Failed to parse condition for repeat until loop"));
  14479. free_node(node_allocator_,branch);
  14480. return error_node();
  14481. }
  14482. else if (!token_is(token_t::e_rbracket))
  14483. {
  14484. set_error(
  14485. make_error(parser_error::e_syntax,
  14486. current_token_,
  14487. "ERR51 - Expected ')' after condition of repeat until loop"));
  14488. free_node(node_allocator_, branch);
  14489. free_node(node_allocator_, condition);
  14490. brkcnt_list_.pop_front();
  14491. return error_node();
  14492. }
  14493. expression_node_ptr result;
  14494. result = expression_generator_
  14495. .repeat_until_loop(condition,branch,brkcnt_list_.front());
  14496. if (0 == result)
  14497. {
  14498. set_error(
  14499. make_error(parser_error::e_syntax,
  14500. current_token_,
  14501. "ERR52 - Failed to synthesize repeat until loop"));
  14502. free_node(node_allocator_, condition);
  14503. brkcnt_list_.pop_front();
  14504. return error_node();
  14505. }
  14506. else
  14507. {
  14508. brkcnt_list_.pop_front();
  14509. return result;
  14510. }
  14511. }
  14512. inline expression_node_ptr parse_for_loop()
  14513. {
  14514. expression_node_ptr initialiser = error_node();
  14515. expression_node_ptr condition = error_node();
  14516. expression_node_ptr incrementor = error_node();
  14517. expression_node_ptr loop_body = error_node();
  14518. scope_element* se = 0;
  14519. bool result = true;
  14520. std::string loop_counter_symbol;
  14521. next_token();
  14522. scope_handler sh(*this);
  14523. if (!token_is(token_t::e_lbracket))
  14524. {
  14525. set_error(
  14526. make_error(parser_error::e_syntax,
  14527. current_token_,
  14528. "ERR53 - Expected '(' at start of for-loop"));
  14529. return error_node();
  14530. }
  14531. if (!token_is(token_t::e_eof))
  14532. {
  14533. if (
  14534. !token_is(token_t::e_symbol,false) &&
  14535. details::imatch(current_token_.value,"var")
  14536. )
  14537. {
  14538. next_token();
  14539. if (!token_is(token_t::e_symbol,false))
  14540. {
  14541. set_error(
  14542. make_error(parser_error::e_syntax,
  14543. current_token_,
  14544. "ERR54 - Expected a variable at the start of initialiser section of for-loop"));
  14545. return error_node();
  14546. }
  14547. else if (!peek_token_is(token_t::e_assign))
  14548. {
  14549. set_error(
  14550. make_error(parser_error::e_syntax,
  14551. current_token_,
  14552. "ERR55 - Expected variable assignment of initialiser section of for-loop"));
  14553. return error_node();
  14554. }
  14555. loop_counter_symbol = current_token_.value;
  14556. se = &sem_.get_element(loop_counter_symbol);
  14557. if ((se->name == loop_counter_symbol) && se->active)
  14558. {
  14559. set_error(
  14560. make_error(parser_error::e_syntax,
  14561. current_token_,
  14562. "ERR56 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration"));
  14563. return error_node();
  14564. }
  14565. else if (!symbol_table_.is_variable(loop_counter_symbol))
  14566. {
  14567. if (
  14568. !se->active &&
  14569. (se->name == loop_counter_symbol) &&
  14570. (se->type == scope_element::e_variable)
  14571. )
  14572. {
  14573. se->active = true;
  14574. se->ref_count++;
  14575. }
  14576. else
  14577. {
  14578. scope_element nse;
  14579. nse.name = loop_counter_symbol;
  14580. nse.type = scope_element::e_variable;
  14581. nse.depth = scope_depth_;
  14582. nse.data = new T(T(0));
  14583. nse.var_node = new variable_node_t(*(T*)(nse.data));
  14584. if (!sem_.add_element(nse))
  14585. {
  14586. set_error(
  14587. make_error(parser_error::e_syntax,
  14588. current_token_,
  14589. "ERR57 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM"));
  14590. result = false;
  14591. }
  14592. else
  14593. exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str()));
  14594. }
  14595. }
  14596. }
  14597. if (0 == (initialiser = parse_expression()))
  14598. {
  14599. set_error(
  14600. make_error(parser_error::e_syntax,
  14601. current_token_,
  14602. "ERR58 - Failed to parse initialiser of for-loop"));
  14603. result = false;
  14604. }
  14605. if (!token_is(token_t::e_eof))
  14606. {
  14607. set_error(
  14608. make_error(parser_error::e_syntax,
  14609. current_token_,
  14610. "ERR59 - Expected ';' after initialiser of for-loop"));
  14611. result = false;
  14612. }
  14613. }
  14614. if (!token_is(token_t::e_eof))
  14615. {
  14616. if (0 == (condition = parse_expression()))
  14617. {
  14618. set_error(
  14619. make_error(parser_error::e_syntax,
  14620. current_token_,
  14621. "ERR60 - Failed to parse condition of for-loop"));
  14622. result = false;
  14623. }
  14624. else if (!token_is(token_t::e_eof))
  14625. {
  14626. set_error(
  14627. make_error(parser_error::e_syntax,
  14628. current_token_,
  14629. "ERR61 - Expected ';' after condition section of for-loop"));
  14630. result = false;
  14631. }
  14632. }
  14633. if (!token_is(token_t::e_rbracket))
  14634. {
  14635. if (0 == (incrementor = parse_expression()))
  14636. {
  14637. set_error(
  14638. make_error(parser_error::e_syntax,
  14639. current_token_,
  14640. "ERR62 - Failed to parse incrementor of for-loop"));
  14641. result = false;
  14642. }
  14643. else if (!token_is(token_t::e_rbracket))
  14644. {
  14645. set_error(
  14646. make_error(parser_error::e_syntax,
  14647. current_token_,
  14648. "ERR63 - Expected ')' after incrementor section of for-loop"));
  14649. result = false;
  14650. }
  14651. }
  14652. if (result)
  14653. {
  14654. brkcnt_list_.push_front(false);
  14655. if (0 == (loop_body = parse_multi_sequence("for-loop")))
  14656. {
  14657. set_error(
  14658. make_error(parser_error::e_syntax,
  14659. current_token_,
  14660. "ERR64 - Failed to parse body of for-loop"));
  14661. result = false;
  14662. }
  14663. }
  14664. if (!result)
  14665. {
  14666. if (se)
  14667. {
  14668. se->ref_count--;
  14669. }
  14670. sem_.cleanup();
  14671. free_node(node_allocator_,initialiser);
  14672. free_node(node_allocator_, condition);
  14673. free_node(node_allocator_,incrementor);
  14674. free_node(node_allocator_, loop_body);
  14675. if (!brkcnt_list_.empty())
  14676. {
  14677. brkcnt_list_.pop_front();
  14678. }
  14679. return error_node();
  14680. }
  14681. else
  14682. {
  14683. expression_node_ptr result_node =
  14684. expression_generator_.for_loop(initialiser,
  14685. condition,
  14686. incrementor,
  14687. loop_body,
  14688. brkcnt_list_.front());
  14689. brkcnt_list_.pop_front();
  14690. return result_node;
  14691. }
  14692. }
  14693. inline expression_node_ptr parse_switch_statement()
  14694. {
  14695. std::vector<expression_node_ptr> arg_list;
  14696. expression_node_ptr result = error_node();
  14697. if (!details::imatch(current_token_.value,"switch"))
  14698. {
  14699. set_error(
  14700. make_error(parser_error::e_syntax,
  14701. current_token_,
  14702. "ERR65 - Expected keyword 'switch'"));
  14703. return error_node();
  14704. }
  14705. scoped_vec_delete<expression_node_t> svd(*this,arg_list);
  14706. next_token();
  14707. if (!token_is(token_t::e_lcrlbracket))
  14708. {
  14709. set_error(
  14710. make_error(parser_error::e_syntax,
  14711. current_token_,
  14712. "ERR66 - Expected '{' for call to switch statement"));
  14713. return error_node();
  14714. }
  14715. for ( ; ; )
  14716. {
  14717. if (!details::imatch("case",current_token_.value))
  14718. {
  14719. set_error(
  14720. make_error(parser_error::e_syntax,
  14721. current_token_,
  14722. "ERR67 - Expected either a 'case' or 'default' statement"));
  14723. return error_node();
  14724. }
  14725. next_token();
  14726. expression_node_ptr condition = parse_expression();
  14727. if (0 == condition)
  14728. return error_node();
  14729. else if (!token_is(token_t::e_colon))
  14730. {
  14731. set_error(
  14732. make_error(parser_error::e_syntax,
  14733. current_token_,
  14734. "ERR68 - Expected ':' for case of switch statement"));
  14735. return error_node();
  14736. }
  14737. expression_node_ptr consequent = parse_expression();
  14738. if (0 == consequent)
  14739. return error_node();
  14740. else if (!token_is(token_t::e_eof))
  14741. {
  14742. set_error(
  14743. make_error(parser_error::e_syntax,
  14744. current_token_,
  14745. "ERR69 - Expected ';' at end of case for switch statement"));
  14746. return error_node();
  14747. }
  14748. // Can we optimize away the case statement?
  14749. if (is_constant_node(condition) && is_false(condition))
  14750. {
  14751. free_node(node_allocator_, condition);
  14752. free_node(node_allocator_,consequent);
  14753. condition = 0;
  14754. consequent = 0;
  14755. }
  14756. else
  14757. {
  14758. arg_list.push_back(condition);
  14759. arg_list.push_back(consequent);
  14760. }
  14761. if (details::imatch("default",current_token_.value))
  14762. {
  14763. next_token();
  14764. if (!token_is(token_t::e_colon))
  14765. {
  14766. set_error(
  14767. make_error(parser_error::e_syntax,
  14768. current_token_,
  14769. "ERR70 - Expected ':' for default of switch statement"));
  14770. return error_node();
  14771. }
  14772. expression_node_ptr default_statement = parse_expression();
  14773. if (0 == default_statement)
  14774. return error_node();
  14775. else if (!token_is(token_t::e_eof))
  14776. {
  14777. set_error(
  14778. make_error(parser_error::e_syntax,
  14779. current_token_,
  14780. "ERR71 - Expected ';' at end of default for switch statement"));
  14781. return error_node();
  14782. }
  14783. arg_list.push_back(default_statement);
  14784. break;
  14785. }
  14786. }
  14787. if (!token_is(token_t::e_rcrlbracket))
  14788. {
  14789. set_error(
  14790. make_error(parser_error::e_syntax,
  14791. current_token_,
  14792. "ERR72 - Expected '}' at end of switch statement"));
  14793. return error_node();
  14794. }
  14795. result = expression_generator_.switch_statement(arg_list);
  14796. svd.delete_ptr = (0 == result);
  14797. return result;
  14798. }
  14799. inline expression_node_ptr parse_multi_switch_statement()
  14800. {
  14801. std::vector<expression_node_ptr> arg_list;
  14802. expression_node_ptr result = error_node();
  14803. if (!details::imatch(current_token_.value,"[*]"))
  14804. {
  14805. set_error(
  14806. make_error(parser_error::e_syntax,
  14807. current_token_,
  14808. "ERR73 - Expected token '[*]'"));
  14809. return error_node();
  14810. }
  14811. scoped_vec_delete<expression_node_t> svd(*this,arg_list);
  14812. next_token();
  14813. if (!token_is(token_t::e_lcrlbracket))
  14814. {
  14815. set_error(
  14816. make_error(parser_error::e_syntax,
  14817. current_token_,
  14818. "ERR74 - Expected '{' for call to [*] statement"));
  14819. return error_node();
  14820. }
  14821. for ( ; ; )
  14822. {
  14823. if (!details::imatch("case",current_token_.value))
  14824. {
  14825. set_error(
  14826. make_error(parser_error::e_syntax,
  14827. current_token_,
  14828. "ERR75 - Expected a 'case' statement for multi-switch"));
  14829. return error_node();
  14830. }
  14831. next_token();
  14832. expression_node_ptr condition = parse_expression();
  14833. if (0 == condition)
  14834. return error_node();
  14835. if (!token_is(token_t::e_colon))
  14836. {
  14837. set_error(
  14838. make_error(parser_error::e_syntax,
  14839. current_token_,
  14840. "ERR76 - Expected ':' for case of [*] statement"));
  14841. return error_node();
  14842. }
  14843. expression_node_ptr consequent = parse_expression();
  14844. if (0 == consequent)
  14845. return error_node();
  14846. if (!token_is(token_t::e_eof))
  14847. {
  14848. set_error(
  14849. make_error(parser_error::e_syntax,
  14850. current_token_,
  14851. "ERR77 - Expected ';' at end of case for [*] statement"));
  14852. return error_node();
  14853. }
  14854. // Can we optimize away the case statement?
  14855. if (is_constant_node(condition) && is_false(condition))
  14856. {
  14857. free_node(node_allocator_, condition);
  14858. free_node(node_allocator_,consequent);
  14859. condition = 0;
  14860. consequent = 0;
  14861. }
  14862. else
  14863. {
  14864. arg_list.push_back(condition);
  14865. arg_list.push_back(consequent);
  14866. }
  14867. if (token_is(token_t::e_rcrlbracket,false))
  14868. {
  14869. break;
  14870. }
  14871. }
  14872. if (!token_is(token_t::e_rcrlbracket))
  14873. {
  14874. set_error(
  14875. make_error(parser_error::e_syntax,
  14876. current_token_,
  14877. "ERR78 - Expected '}' at end of [*] statement"));
  14878. return error_node();
  14879. }
  14880. result = expression_generator_.multi_switch_statement(arg_list);
  14881. svd.delete_ptr = (0 == result);
  14882. return result;
  14883. }
  14884. inline expression_node_ptr parse_vararg_function()
  14885. {
  14886. std::vector<expression_node_ptr> arg_list;
  14887. expression_node_ptr result = error_node();
  14888. details::operator_type opt_type = details::e_default;
  14889. const std::string symbol = current_token_.value;
  14890. if (details::imatch(symbol,"~"))
  14891. {
  14892. next_token();
  14893. return parse_multi_sequence();
  14894. }
  14895. else if (details::imatch(symbol,"[*]"))
  14896. {
  14897. return parse_multi_switch_statement();
  14898. }
  14899. else if (details::imatch(symbol,"avg" )) opt_type = details::e_avg;
  14900. else if (details::imatch(symbol,"mand")) opt_type = details::e_mand;
  14901. else if (details::imatch(symbol,"max" )) opt_type = details::e_max;
  14902. else if (details::imatch(symbol,"min" )) opt_type = details::e_min;
  14903. else if (details::imatch(symbol,"mor" )) opt_type = details::e_mor;
  14904. else if (details::imatch(symbol,"mul" )) opt_type = details::e_prod;
  14905. else if (details::imatch(symbol,"sum" )) opt_type = details::e_sum;
  14906. else
  14907. {
  14908. set_error(
  14909. make_error(parser_error::e_syntax,
  14910. current_token_,
  14911. "ERR79 - Unsupported vararg function: " + symbol));
  14912. return error_node();
  14913. }
  14914. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  14915. next_token();
  14916. if (!token_is(token_t::e_lbracket))
  14917. {
  14918. set_error(
  14919. make_error(parser_error::e_syntax,
  14920. current_token_,
  14921. "ERR80 - Expected '(' for call to vararg function: " + symbol));
  14922. return error_node();
  14923. }
  14924. for ( ; ; )
  14925. {
  14926. expression_node_ptr arg = parse_expression();
  14927. if (0 == arg)
  14928. return error_node();
  14929. else
  14930. arg_list.push_back(arg);
  14931. if (token_is(token_t::e_rbracket))
  14932. break;
  14933. else if (!token_is(token_t::e_comma))
  14934. {
  14935. set_error(
  14936. make_error(parser_error::e_syntax,
  14937. current_token_,
  14938. "ERR81 - Expected ',' for call to vararg function: " + symbol));
  14939. return error_node();
  14940. }
  14941. }
  14942. result = expression_generator_.vararg_function(opt_type,arg_list);
  14943. sdd.delete_ptr = (0 == result);
  14944. return result;
  14945. }
  14946. inline expression_node_ptr parse_string_range_statement(expression_node_ptr& expression)
  14947. {
  14948. if (!token_is(token_t::e_lsqrbracket))
  14949. {
  14950. set_error(
  14951. make_error(parser_error::e_syntax,
  14952. current_token_,
  14953. "ERR82 - Expected '[' as start of string range definition"));
  14954. free_node(node_allocator_,expression);
  14955. return error_node();
  14956. }
  14957. else if (token_is(token_t::e_rsqrbracket))
  14958. {
  14959. return node_allocator_.allocate<details::string_size_node<T> >(expression);
  14960. }
  14961. range_t rp;
  14962. if (!parse_range(rp,true))
  14963. {
  14964. free_node(node_allocator_,expression);
  14965. return error_node();
  14966. }
  14967. expression_node_ptr result = expression_generator_(expression,rp);
  14968. if (0 == result)
  14969. {
  14970. set_error(
  14971. make_error(parser_error::e_syntax,
  14972. current_token_,
  14973. "ERR83 - Failed to generate string range node"));
  14974. free_node(node_allocator_,expression);
  14975. }
  14976. rp.clear();
  14977. return result;
  14978. }
  14979. inline void parse_pending_string_rangesize(expression_node_ptr& expression)
  14980. {
  14981. const std::size_t max_rangesize_parses = 100;
  14982. std::size_t i = 0;
  14983. while
  14984. (
  14985. (0 != expression) &&
  14986. (i++ < max_rangesize_parses) &&
  14987. error_list_.empty() &&
  14988. token_is(token_t::e_lsqrbracket,false) &&
  14989. is_generally_string_node(expression)
  14990. )
  14991. {
  14992. expression = parse_string_range_statement(expression);
  14993. }
  14994. }
  14995. template <typename Allocator,
  14996. template <typename,typename> class Sequence>
  14997. inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator>& expression_list)
  14998. {
  14999. if (expression_list.empty())
  15000. return error_node();
  15001. else if (1 == expression_list.size())
  15002. return expression_list[0];
  15003. Sequence<expression_node_ptr,Allocator> tmp_expression_list;
  15004. for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
  15005. {
  15006. if (is_variable_node(expression_list[i]))
  15007. continue;
  15008. else if (
  15009. is_constant_node(expression_list[i]) ||
  15010. is_null_node (expression_list[i])
  15011. )
  15012. {
  15013. free_node(node_allocator_,expression_list[i]);
  15014. continue;
  15015. }
  15016. else
  15017. tmp_expression_list.push_back(expression_list[i]);
  15018. }
  15019. tmp_expression_list.push_back(expression_list.back());
  15020. expression_list.swap(tmp_expression_list);
  15021. if (1 == expression_list.size())
  15022. return expression_list[0];
  15023. else
  15024. return expression_generator_.vararg_function(details::e_multi,expression_list);
  15025. }
  15026. inline expression_node_ptr parse_multi_sequence(const std::string& source = "")
  15027. {
  15028. token_t::token_type close_bracket = token_t::e_rcrlbracket;
  15029. token_t::token_type seperator = token_t::e_eof;
  15030. if (!token_is(token_t::e_lcrlbracket))
  15031. {
  15032. if (token_is(token_t::e_lbracket))
  15033. {
  15034. close_bracket = token_t::e_rbracket;
  15035. seperator = token_t::e_comma;
  15036. }
  15037. else
  15038. {
  15039. set_error(
  15040. make_error(parser_error::e_syntax,
  15041. current_token_,
  15042. "ERR84 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
  15043. ((!source.empty()) ? std::string(" section of " + source): "")));
  15044. return error_node();
  15045. }
  15046. }
  15047. else if (token_is(token_t::e_rcrlbracket))
  15048. {
  15049. return node_allocator_.allocate<details::null_node<T> >();
  15050. }
  15051. std::vector<expression_node_ptr> arg_list;
  15052. expression_node_ptr result = error_node();
  15053. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  15054. scope_handler sh(*this);
  15055. for (;;)
  15056. {
  15057. expression_node_ptr arg = parse_expression();
  15058. if (0 == arg)
  15059. return error_node();
  15060. else
  15061. arg_list.push_back(arg);
  15062. if (token_is(close_bracket))
  15063. break;
  15064. bool is_next_close = peek_token_is(close_bracket);
  15065. if (!token_is(seperator) && is_next_close)
  15066. {
  15067. set_error(
  15068. make_error(parser_error::e_syntax,
  15069. current_token_,
  15070. "ERR85 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source));
  15071. return error_node();
  15072. }
  15073. if (token_is(close_bracket))
  15074. break;
  15075. }
  15076. result = simplify(arg_list);
  15077. sdd.delete_ptr = (0 == result);
  15078. return result;
  15079. }
  15080. inline bool parse_range(range_t& rp, const bool skip_lsqr = false)
  15081. {
  15082. // Examples of valid ranges:
  15083. // 1. [1:5] -> 1..5
  15084. // 2. [ :5] -> 0..5
  15085. // 3. [1: ] -> 1..end
  15086. // 4. [x:y] -> x..y where x <= y
  15087. // 5. [x+1:y/2] -> x+1..y/2 where x+1 <= y/2
  15088. // 6. [ :y] -> 0..y where 0 <= y
  15089. // 7. [x: ] -> x..end where x <= end
  15090. rp.clear();
  15091. if (!skip_lsqr && !token_is(token_t::e_lsqrbracket))
  15092. {
  15093. set_error(
  15094. make_error(parser_error::e_syntax,
  15095. current_token_,
  15096. "ERR86 - Expected '[' for start of range"));
  15097. return false;
  15098. }
  15099. if (token_is(token_t::e_colon))
  15100. {
  15101. rp.n0_c.first = true;
  15102. rp.n0_c.second = 0;
  15103. rp.cache.first = 0;
  15104. }
  15105. else
  15106. {
  15107. expression_node_ptr r0 = parse_expression();
  15108. if (0 == r0)
  15109. {
  15110. set_error(
  15111. make_error(parser_error::e_syntax,
  15112. current_token_,
  15113. "ERR87 - Failed parse begin section of range"));
  15114. return false;
  15115. }
  15116. else if (is_constant_node(r0))
  15117. {
  15118. T r0_value = r0->value();
  15119. if (r0_value >= T(0))
  15120. {
  15121. rp.n0_c.first = true;
  15122. rp.n0_c.second = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
  15123. rp.cache.first = rp.n0_c.second;
  15124. }
  15125. free_node(node_allocator_,r0);
  15126. if (r0_value < T(0))
  15127. {
  15128. set_error(
  15129. make_error(parser_error::e_syntax,
  15130. current_token_,
  15131. "ERR88 - Range lower bound less than zero! Constraint: r0 >= 0"));
  15132. return false;
  15133. }
  15134. }
  15135. else
  15136. {
  15137. rp.n0_e.first = true;
  15138. rp.n0_e.second = r0;
  15139. }
  15140. if (!token_is(token_t::e_colon))
  15141. {
  15142. set_error(
  15143. make_error(parser_error::e_syntax,
  15144. current_token_,
  15145. "ERR89 - Expected ':' for break in range"));
  15146. rp.free();
  15147. return false;
  15148. }
  15149. }
  15150. if (token_is(token_t::e_rsqrbracket))
  15151. {
  15152. rp.n1_c.first = true;
  15153. rp.n1_c.second = std::numeric_limits<std::size_t>::max();
  15154. }
  15155. else
  15156. {
  15157. expression_node_ptr r1 = parse_expression();
  15158. if (0 == r1)
  15159. {
  15160. set_error(
  15161. make_error(parser_error::e_syntax,
  15162. current_token_,
  15163. "ERR90 - Failed parse end section of range"));
  15164. rp.free();
  15165. return false;
  15166. }
  15167. else if (is_constant_node(r1))
  15168. {
  15169. T r1_value = r1->value();
  15170. if (r1_value >= T(0))
  15171. {
  15172. rp.n1_c.first = true;
  15173. rp.n1_c.second = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
  15174. rp.cache.second = rp.n1_c.second;
  15175. }
  15176. free_node(node_allocator_,r1);
  15177. if (r1_value < T(0))
  15178. {
  15179. set_error(
  15180. make_error(parser_error::e_syntax,
  15181. current_token_,
  15182. "ERR91 - Range upper bound less than zero! Constraint: r1 >= 0"));
  15183. return false;
  15184. }
  15185. }
  15186. else
  15187. {
  15188. rp.n1_e.first = true;
  15189. rp.n1_e.second = r1;
  15190. }
  15191. if (!token_is(token_t::e_rsqrbracket))
  15192. {
  15193. set_error(
  15194. make_error(parser_error::e_syntax,
  15195. current_token_,
  15196. "ERR92 - Expected ']' for start of range"));
  15197. rp.free();
  15198. return false;
  15199. }
  15200. }
  15201. if (rp.const_range())
  15202. {
  15203. std::size_t r0 = 0;
  15204. std::size_t r1 = 0;
  15205. bool rp_result = rp(r0,r1);
  15206. if (!rp_result || (r0 > r1))
  15207. {
  15208. set_error(
  15209. make_error(parser_error::e_syntax,
  15210. current_token_,
  15211. "ERR93 - Invalid range, Constraint: r0 <= r1"));
  15212. return false;
  15213. }
  15214. }
  15215. return true;
  15216. }
  15217. inline void lodge_symbol(const std::string& symbol,
  15218. const symbol_type st)
  15219. {
  15220. dec_.add_symbol(symbol,st);
  15221. }
  15222. inline expression_node_ptr parse_string()
  15223. {
  15224. const std::string symbol = current_token_.value;
  15225. if (!symbol_table_.is_conststr_stringvar(symbol))
  15226. {
  15227. set_error(
  15228. make_error(parser_error::e_syntax,
  15229. current_token_,
  15230. "ERR94 - Unknown string symbol"));
  15231. return error_node();
  15232. }
  15233. expression_node_ptr result = symbol_table_.get_stringvar(symbol);
  15234. typedef details::stringvar_node<T>* strvar_node_t;
  15235. strvar_node_t const_str_node = static_cast<strvar_node_t>(0);
  15236. const bool is_const_string = symbol_table_.is_constant_string(symbol);
  15237. if (is_const_string)
  15238. {
  15239. const_str_node = static_cast<strvar_node_t>(result);
  15240. result = expression_generator_(const_str_node->str());
  15241. }
  15242. lodge_symbol(symbol,e_st_string);
  15243. if (peek_token_is(token_t::e_lsqrbracket))
  15244. {
  15245. next_token();
  15246. if (peek_token_is(token_t::e_rsqrbracket))
  15247. {
  15248. next_token();
  15249. next_token();
  15250. if (const_str_node)
  15251. {
  15252. free_node(node_allocator_,result);
  15253. return expression_generator_(T(const_str_node->size()));
  15254. }
  15255. else
  15256. return node_allocator_.allocate<details::stringvar_size_node<T> >
  15257. (static_cast<details::stringvar_node<T>*>(result)->ref());
  15258. }
  15259. range_t rp;
  15260. if (!parse_range(rp))
  15261. {
  15262. free_node(node_allocator_,result);
  15263. return error_node();
  15264. }
  15265. else if (const_str_node)
  15266. {
  15267. free_node(node_allocator_,result);
  15268. result = expression_generator_(const_str_node->ref(),rp);
  15269. }
  15270. else
  15271. result = expression_generator_(static_cast<details::stringvar_node<T>*>(result)->ref(),rp);
  15272. if (result)
  15273. rp.clear();
  15274. }
  15275. else
  15276. next_token();
  15277. return result;
  15278. }
  15279. inline expression_node_ptr parse_const_string()
  15280. {
  15281. const std::string const_str = current_token_.value;
  15282. expression_node_ptr result = expression_generator_(const_str);
  15283. if (peek_token_is(token_t::e_lsqrbracket))
  15284. {
  15285. next_token();
  15286. if (peek_token_is(token_t::e_rsqrbracket))
  15287. {
  15288. next_token();
  15289. next_token();
  15290. free_node(node_allocator_,result);
  15291. return expression_generator_(T(const_str.size()));
  15292. }
  15293. range_t rp;
  15294. if (!parse_range(rp))
  15295. {
  15296. free_node(node_allocator_,result);
  15297. return error_node();
  15298. }
  15299. free_node(node_allocator_,result);
  15300. if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max()))
  15301. {
  15302. rp.n1_c.second = const_str.size() - 1;
  15303. rp.cache.second = rp.n1_c.second;
  15304. }
  15305. if (
  15306. (rp.n0_c.first && (rp.n0_c.second >= const_str.size())) ||
  15307. (rp.n1_c.first && (rp.n1_c.second >= const_str.size()))
  15308. )
  15309. {
  15310. set_error(
  15311. make_error(parser_error::e_syntax,
  15312. current_token_,
  15313. "ERR95 - Overflow in range for string: '" + const_str + "'[" +
  15314. (rp.n0_c.first ? details::to_str(rp.n0_c.second) : "?") + ":" +
  15315. (rp.n1_c.first ? details::to_str(rp.n1_c.second) : "?") + "]"));
  15316. return error_node();
  15317. }
  15318. result = expression_generator_(const_str,rp);
  15319. if (result)
  15320. rp.clear();
  15321. }
  15322. else
  15323. next_token();
  15324. return result;
  15325. }
  15326. inline expression_node_ptr parse_vector()
  15327. {
  15328. const std::string symbol = current_token_.value;
  15329. vector_holder_ptr vec = vector_holder_ptr(0);
  15330. const scope_element& se = sem_.get_element(symbol);
  15331. if (
  15332. (se.name != symbol) ||
  15333. (se.depth > scope_depth_) ||
  15334. (scope_element::e_vector != se.type)
  15335. )
  15336. {
  15337. if (0 == (vec = symbol_table_.get_vector(symbol)))
  15338. {
  15339. set_error(
  15340. make_error(parser_error::e_syntax,
  15341. current_token_,
  15342. "ERR96 - Symbol '" + symbol+ " not a vector"));
  15343. return error_node();
  15344. }
  15345. }
  15346. else
  15347. vec = se.vec_node;
  15348. expression_node_ptr index_expr = error_node();
  15349. next_token();
  15350. if (!token_is(token_t::e_lsqrbracket))
  15351. {
  15352. return node_allocator_.allocate<vector_node_t>(vec);
  15353. }
  15354. else if (token_is(token_t::e_rsqrbracket))
  15355. {
  15356. return expression_generator_(T(vec->size()));
  15357. }
  15358. else if (0 == (index_expr = parse_expression()))
  15359. {
  15360. set_error(
  15361. make_error(parser_error::e_syntax,
  15362. current_token_,
  15363. "ERR97 - Failed to parse index for vector: '" + symbol + "'"));
  15364. return error_node();
  15365. }
  15366. else if (!token_is(token_t::e_rsqrbracket))
  15367. {
  15368. set_error(
  15369. make_error(parser_error::e_syntax,
  15370. current_token_,
  15371. "ERR98 - Expected ']' for index of vector: '" + symbol + "'"));
  15372. free_node(node_allocator_,index_expr);
  15373. return error_node();
  15374. }
  15375. return expression_generator_.vector_element(symbol,vec,index_expr);
  15376. }
  15377. inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name)
  15378. {
  15379. std::vector<expression_node_ptr> arg_list;
  15380. expression_node_ptr result = error_node();
  15381. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  15382. next_token();
  15383. if (token_is(token_t::e_lbracket))
  15384. {
  15385. if (!token_is(token_t::e_rbracket))
  15386. {
  15387. for ( ; ; )
  15388. {
  15389. expression_node_ptr arg = parse_expression();
  15390. if (0 == arg)
  15391. return error_node();
  15392. else
  15393. arg_list.push_back(arg);
  15394. if (token_is(token_t::e_rbracket))
  15395. break;
  15396. else if (!token_is(token_t::e_comma))
  15397. {
  15398. set_error(
  15399. make_error(parser_error::e_syntax,
  15400. current_token_,
  15401. "ERR99 - Expected ',' for call to vararg function: " + vararg_function_name));
  15402. return error_node();
  15403. }
  15404. }
  15405. }
  15406. }
  15407. result = expression_generator_.vararg_function_call(vararg_function,arg_list);
  15408. sdd.delete_ptr = (0 == result);
  15409. return result;
  15410. }
  15411. class type_checker
  15412. {
  15413. public:
  15414. typedef parser<T> parser_t;
  15415. typedef std::vector<std::string> param_seq_list_t;
  15416. type_checker(parser_t& p,
  15417. const std::string& func_name,
  15418. const std::string& param_seq)
  15419. : invalid_state_(true),
  15420. parser_(p),
  15421. function_name_(func_name)
  15422. {
  15423. split(param_seq);
  15424. }
  15425. bool verify(const std::string& param_seq, std::size_t& pseq_index)
  15426. {
  15427. if (param_seq_list_.empty())
  15428. return true;
  15429. std::vector<std::pair<std::size_t,char> > error_list;
  15430. for (std::size_t i = 0; i < param_seq_list_.size(); ++i)
  15431. {
  15432. std::size_t diff_index = 0;
  15433. char diff_value = 0;
  15434. bool result = details::sequence_match(param_seq_list_[i],
  15435. param_seq,
  15436. diff_index,diff_value);
  15437. if (result)
  15438. {
  15439. pseq_index = i;
  15440. return true;
  15441. }
  15442. else
  15443. error_list.push_back(std::make_pair(diff_index,diff_value));
  15444. }
  15445. if (1 == error_list.size())
  15446. {
  15447. parser_.
  15448. set_error(
  15449. make_error(parser_error::e_syntax,
  15450. parser_.current_token(),
  15451. "ERR100 - Failed parameter type check for function '" + function_name_ + "', "
  15452. "Expected '" + param_seq_list_[0] + "' call set: '" + param_seq +"'"));
  15453. }
  15454. else
  15455. {
  15456. // find first with largest diff_index;
  15457. std::size_t max_diff_index = 0;
  15458. for (std::size_t i = 1; i < error_list.size(); ++i)
  15459. {
  15460. if (error_list[i].first > error_list[max_diff_index].first)
  15461. {
  15462. max_diff_index = i;
  15463. }
  15464. }
  15465. parser_.
  15466. set_error(
  15467. make_error(parser_error::e_syntax,
  15468. parser_.current_token(),
  15469. "ERR101 - Failed parameter type check for function '" + function_name_ + "', "
  15470. "Best match: '" + param_seq_list_[max_diff_index] + "' call set: '" + param_seq +"'"));
  15471. }
  15472. return false;
  15473. }
  15474. std::size_t paramseq_count() const
  15475. {
  15476. return param_seq_list_.size();
  15477. }
  15478. std::string paramseq(const std::size_t& index) const
  15479. {
  15480. return param_seq_list_[index];
  15481. }
  15482. bool invalid() const
  15483. {
  15484. return !invalid_state_;
  15485. }
  15486. private:
  15487. void split(const std::string& s)
  15488. {
  15489. if (s.empty())
  15490. return;
  15491. std::size_t start = 0;
  15492. std::size_t end = 0;
  15493. param_seq_list_t param_seq_list;
  15494. struct token_validator
  15495. {
  15496. static inline bool process(const std::string& str,
  15497. std::size_t s, std::size_t e,
  15498. param_seq_list_t& psl)
  15499. {
  15500. if (
  15501. (e - s) &&
  15502. (std::string::npos == str.find("?*")) &&
  15503. (std::string::npos == str.find("**"))
  15504. )
  15505. {
  15506. const std::string curr_str = str.substr(s,e - s);
  15507. if (std::string::npos == curr_str.find_first_not_of("STV*?|"))
  15508. {
  15509. psl.push_back(curr_str);
  15510. return true;
  15511. }
  15512. }
  15513. return false;
  15514. }
  15515. };
  15516. while (std::string::npos != (end = s.find('|',start)))
  15517. {
  15518. if (!token_validator::process(s,start,end,param_seq_list))
  15519. {
  15520. invalid_state_ = false;
  15521. const std::string err_param_seq = s.substr(start,end - start);
  15522. parser_.
  15523. set_error(
  15524. make_error(parser_error::e_syntax,
  15525. parser_.current_token(),
  15526. "ERR102 - Invalid parameter sequence of '" + err_param_seq +
  15527. "' for function: " + function_name_));
  15528. return;
  15529. }
  15530. else
  15531. start = end + 1;
  15532. }
  15533. if (start < s.size())
  15534. {
  15535. if (token_validator::process(s,start,s.size(),param_seq_list))
  15536. param_seq_list_ = param_seq_list;
  15537. else
  15538. {
  15539. const std::string err_param_seq = s.substr(start,s.size() - start);
  15540. parser_.
  15541. set_error(
  15542. make_error(parser_error::e_syntax,
  15543. parser_.current_token(),
  15544. "ERR103 - Invalid parameter sequence of '" + err_param_seq +
  15545. "' for function: " + function_name_));
  15546. return;
  15547. }
  15548. }
  15549. }
  15550. type_checker(const type_checker&);
  15551. type_checker& operator=(const type_checker&);
  15552. bool invalid_state_;
  15553. parser_t& parser_;
  15554. std::string function_name_;
  15555. param_seq_list_t param_seq_list_;
  15556. };
  15557. inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name)
  15558. {
  15559. std::vector<expression_node_ptr> arg_list;
  15560. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  15561. next_token();
  15562. std::string param_type_list;
  15563. type_checker tc(*this,function_name,function->parameter_sequence);
  15564. if (tc.invalid())
  15565. {
  15566. set_error(
  15567. make_error(parser_error::e_syntax,
  15568. current_token_,
  15569. "ERR104 - Type checker instantiation failure for generic function: " + function_name));
  15570. return error_node();
  15571. }
  15572. if (token_is(token_t::e_lbracket))
  15573. {
  15574. if (!token_is(token_t::e_rbracket))
  15575. {
  15576. for ( ; ; )
  15577. {
  15578. expression_node_ptr arg = parse_expression();
  15579. if (0 == arg)
  15580. return error_node();
  15581. if (is_ivector_node(arg))
  15582. param_type_list += 'V';
  15583. else if (is_generally_string_node(arg))
  15584. param_type_list += 'S';
  15585. else // Everything else is assumed to be scalar returning expression
  15586. param_type_list += 'T';
  15587. arg_list.push_back(arg);
  15588. if (token_is(token_t::e_rbracket))
  15589. break;
  15590. else if (!token_is(token_t::e_comma))
  15591. {
  15592. set_error(
  15593. make_error(parser_error::e_syntax,
  15594. current_token_,
  15595. "ERR105 - Expected ',' for call to generic function: " + function_name));
  15596. return error_node();
  15597. }
  15598. }
  15599. }
  15600. }
  15601. std::size_t param_seq_index = 0;
  15602. if (!tc.verify(param_type_list, param_seq_index))
  15603. {
  15604. set_error(
  15605. make_error(parser_error::e_syntax,
  15606. current_token_,
  15607. "ERR106 - Expected ',' for call to generic function: " + function_name));
  15608. return error_node();
  15609. }
  15610. expression_node_ptr result = error_node();
  15611. if (tc.paramseq_count() <= 1)
  15612. result = expression_generator_
  15613. .generic_function_call(function,arg_list);
  15614. else
  15615. result = expression_generator_
  15616. .generic_function_call(function,arg_list,param_seq_index);
  15617. sdd.delete_ptr = (0 == result);
  15618. return result;
  15619. }
  15620. inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name)
  15621. {
  15622. std::vector<expression_node_ptr> arg_list;
  15623. scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
  15624. next_token();
  15625. std::string param_type_list;
  15626. type_checker tc(*this,function_name,function->parameter_sequence);
  15627. if (
  15628. (!function->parameter_sequence.empty()) &&
  15629. (0 == tc.paramseq_count())
  15630. )
  15631. {
  15632. return error_node();
  15633. }
  15634. if (token_is(token_t::e_lbracket))
  15635. {
  15636. if (!token_is(token_t::e_rbracket))
  15637. {
  15638. for ( ; ; )
  15639. {
  15640. expression_node_ptr arg = parse_expression();
  15641. if (0 == arg)
  15642. return error_node();
  15643. if (is_ivector_node(arg))
  15644. param_type_list += 'V';
  15645. else if (is_generally_string_node(arg))
  15646. param_type_list += 'S';
  15647. else // Everything else is a scalar returning expression
  15648. param_type_list += 'T';
  15649. arg_list.push_back(arg);
  15650. if (token_is(token_t::e_rbracket))
  15651. break;
  15652. else if (!token_is(token_t::e_comma))
  15653. {
  15654. set_error(
  15655. make_error(parser_error::e_syntax,
  15656. current_token_,
  15657. "ERR107 - Expected ',' for call to string function: " + function_name));
  15658. return error_node();
  15659. }
  15660. }
  15661. }
  15662. }
  15663. std::size_t param_seq_index = 0;
  15664. if (!tc.verify(param_type_list, param_seq_index))
  15665. {
  15666. set_error(
  15667. make_error(parser_error::e_syntax,
  15668. current_token_,
  15669. "ERR108 - Expected ',' for call to string function: " + function_name));
  15670. return error_node();
  15671. }
  15672. expression_node_ptr result = error_node();
  15673. if (tc.paramseq_count() <= 1)
  15674. result = expression_generator_
  15675. .string_function_call(function,arg_list);
  15676. else
  15677. result = expression_generator_
  15678. .string_function_call(function,arg_list,param_seq_index);
  15679. sdd.delete_ptr = (0 == result);
  15680. return result;
  15681. }
  15682. template <typename Type, std::size_t NumberOfParameters>
  15683. struct parse_special_function_impl
  15684. {
  15685. static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type)
  15686. {
  15687. expression_node_ptr branch[NumberOfParameters];
  15688. expression_node_ptr result = error_node();
  15689. std::fill_n(branch,NumberOfParameters,reinterpret_cast<expression_node_ptr>(0));
  15690. scoped_delete<expression_node_t,NumberOfParameters> sd(p,branch);
  15691. p.next_token();
  15692. if (!p.token_is(token_t::e_lbracket))
  15693. {
  15694. p.set_error(
  15695. make_error(parser_error::e_syntax,
  15696. p.current_token(),
  15697. "ERR109 - Expected '(' for special function"));
  15698. return error_node();
  15699. }
  15700. for (std::size_t i = 0; i < NumberOfParameters; ++i)
  15701. {
  15702. branch[i] = p.parse_expression();
  15703. if (0 == branch[i])
  15704. {
  15705. return p.error_node();
  15706. }
  15707. else if (i < (NumberOfParameters - 1))
  15708. {
  15709. if (!p.token_is(token_t::e_comma))
  15710. {
  15711. p.set_error(
  15712. make_error(parser_error::e_syntax,
  15713. p.current_token(),
  15714. "ERR110 - Expected ',' before next parameter of special function"));
  15715. return p.error_node();
  15716. }
  15717. }
  15718. }
  15719. if (!p.token_is(token_t::e_rbracket))
  15720. return p.error_node();
  15721. else
  15722. result = p.expression_generator_.special_function(opt_type,branch);
  15723. sd.delete_ptr = (0 == result);
  15724. return result;
  15725. }
  15726. };
  15727. inline expression_node_ptr parse_special_function()
  15728. {
  15729. // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
  15730. if (
  15731. !details::is_digit(current_token_.value[2]) ||
  15732. !details::is_digit(current_token_.value[3])
  15733. )
  15734. {
  15735. set_error(
  15736. make_error(parser_error::e_token,
  15737. current_token_,
  15738. "ERR111 - Invalid special function[1]: " + current_token_.value));
  15739. return error_node();
  15740. }
  15741. const unsigned int id = (current_token_.value[2] - '0') * 10 + (current_token_.value[3] - '0');
  15742. if (id >= details::e_sffinal)
  15743. {
  15744. set_error(
  15745. make_error(parser_error::e_token,
  15746. current_token_,
  15747. "ERR112 - Invalid special function[2]: " + current_token_.value));
  15748. return error_node();
  15749. }
  15750. const std::size_t sf_3_to_4 = details::e_sf48;
  15751. const details::operator_type opt_type = details::operator_type(id + 1000);
  15752. const std::size_t NumberOfParameters = (id < (sf_3_to_4 - 1000)) ? 3 : 4;
  15753. switch (NumberOfParameters)
  15754. {
  15755. case 3 : return parse_special_function_impl<T,3>::process(*this,opt_type);
  15756. case 4 : return parse_special_function_impl<T,4>::process(*this,opt_type);
  15757. default : return error_node();
  15758. }
  15759. }
  15760. inline expression_node_ptr parse_null_statement()
  15761. {
  15762. next_token();
  15763. return node_allocator_.allocate<details::null_node<T> >();
  15764. }
  15765. #ifndef exprtk_disable_break_continue
  15766. inline expression_node_ptr parse_break_statement()
  15767. {
  15768. if (!brkcnt_list_.empty())
  15769. {
  15770. next_token();
  15771. brkcnt_list_.front() = true;
  15772. expression_node_ptr return_expr = error_node();
  15773. if (token_is(token_t::e_lsqrbracket))
  15774. {
  15775. if (0 == (return_expr = parse_expression()))
  15776. {
  15777. set_error(
  15778. make_error(parser_error::e_syntax,
  15779. current_token_,
  15780. "ERR113 - Failed to parse return expression for 'break' statement"));
  15781. return error_node();
  15782. }
  15783. else if (!token_is(token_t::e_rsqrbracket))
  15784. {
  15785. set_error(
  15786. make_error(parser_error::e_syntax,
  15787. current_token_,
  15788. "ERR114 - Expected ']' at the completion of break's return expression"));
  15789. free_node(node_allocator_,return_expr);
  15790. return error_node();
  15791. }
  15792. }
  15793. return node_allocator_.allocate<details::break_node<T> >(return_expr);
  15794. }
  15795. else
  15796. {
  15797. set_error(
  15798. make_error(parser_error::e_syntax,
  15799. current_token_,
  15800. "ERR115 - Invalid use of 'break', allowed only in the scope of a loop"));
  15801. }
  15802. return error_node();
  15803. }
  15804. inline expression_node_ptr parse_continue_statement()
  15805. {
  15806. if (!brkcnt_list_.empty())
  15807. {
  15808. next_token();
  15809. brkcnt_list_.front() = true;
  15810. return node_allocator_.allocate<details::continue_node<T> >();
  15811. }
  15812. else
  15813. {
  15814. set_error(
  15815. make_error(parser_error::e_syntax,
  15816. current_token_,
  15817. "ERR116 - Invalid use of 'continue', allowed only in the scope of a loop"));
  15818. return error_node();
  15819. }
  15820. }
  15821. #endif
  15822. inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name)
  15823. {
  15824. expression_node_ptr size_expr = error_node();
  15825. if (!token_is(token_t::e_lsqrbracket))
  15826. {
  15827. set_error(
  15828. make_error(parser_error::e_syntax,
  15829. current_token_,
  15830. "ERR117 - Expected '[' as part of vector size definition"));
  15831. return error_node();
  15832. }
  15833. else if (0 == (size_expr = parse_expression()))
  15834. {
  15835. set_error(
  15836. make_error(parser_error::e_syntax,
  15837. current_token_,
  15838. "ERR118 - Failed to determine size of vector '" + vec_name + "'"));
  15839. return error_node();
  15840. }
  15841. else if (!is_constant_node(size_expr))
  15842. {
  15843. free_node(node_allocator_,size_expr);
  15844. set_error(
  15845. make_error(parser_error::e_syntax,
  15846. current_token_,
  15847. "ERR119 - Expected a literal number as size of vector '" + vec_name + "'"));
  15848. return error_node();
  15849. }
  15850. T vector_size = size_expr->value();
  15851. free_node(node_allocator_,size_expr);
  15852. if (
  15853. (vector_size <= T(0)) ||
  15854. std::not_equal_to<T>()
  15855. (T(0),vector_size - details::numeric::trunc(vector_size))
  15856. )
  15857. {
  15858. set_error(
  15859. make_error(parser_error::e_syntax,
  15860. current_token_,
  15861. "ERR120 - Invalid vector size. Must be an integer greater than zero, size: " +
  15862. details::to_str(details::numeric::to_int32(vector_size))));
  15863. return error_node();
  15864. }
  15865. std::vector<expression_node_ptr> vec_initilizer_list;
  15866. scoped_vec_delete<expression_node_t> svd(*this,vec_initilizer_list);
  15867. bool single_value_initialiser = false;
  15868. if (!token_is(token_t::e_rsqrbracket))
  15869. {
  15870. set_error(
  15871. make_error(parser_error::e_syntax,
  15872. current_token_,
  15873. "ERR121 - Expected ']' as part of vector size definition"));
  15874. return error_node();
  15875. }
  15876. else if (!token_is(token_t::e_eof))
  15877. {
  15878. if (!token_is(token_t::e_assign))
  15879. {
  15880. set_error(
  15881. make_error(parser_error::e_syntax,
  15882. current_token_,
  15883. "ERR122 - Expected ':=' as part of vector definition"));
  15884. return error_node();
  15885. }
  15886. else if (token_is(token_t::e_lsqrbracket))
  15887. {
  15888. expression_node_ptr initialiser = parse_expression();
  15889. if (0 == initialiser)
  15890. {
  15891. set_error(
  15892. make_error(parser_error::e_syntax,
  15893. current_token_,
  15894. "ERR123 - Failed to parse single vector initialiser"));
  15895. return error_node();
  15896. }
  15897. vec_initilizer_list.push_back(initialiser);
  15898. if (!token_is(token_t::e_rsqrbracket))
  15899. {
  15900. set_error(
  15901. make_error(parser_error::e_syntax,
  15902. current_token_,
  15903. "ERR124 - Expected ']' to close single value vector initialiser"));
  15904. return error_node();
  15905. }
  15906. single_value_initialiser = true;
  15907. }
  15908. else if (!token_is(token_t::e_lcrlbracket))
  15909. {
  15910. set_error(
  15911. make_error(parser_error::e_syntax,
  15912. current_token_,
  15913. "ERR125 - Expected '{' as part of vector initialiser list"));
  15914. return error_node();
  15915. }
  15916. else if (!token_is(token_t::e_rcrlbracket))
  15917. {
  15918. for (;;)
  15919. {
  15920. expression_node_ptr initialiser = parse_expression();
  15921. if (0 == initialiser)
  15922. {
  15923. set_error(
  15924. make_error(parser_error::e_syntax,
  15925. current_token_,
  15926. "ERR126 - Expected '{' as part of vector initialiser list"));
  15927. return error_node();
  15928. }
  15929. else
  15930. vec_initilizer_list.push_back(initialiser);
  15931. if (token_is(token_t::e_rcrlbracket))
  15932. break;
  15933. bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
  15934. if (!token_is(token_t::e_comma) && is_next_close)
  15935. {
  15936. set_error(
  15937. make_error(parser_error::e_syntax,
  15938. current_token_,
  15939. "ERR127 - Expected ',' between vector initialisers"));
  15940. return error_node();
  15941. }
  15942. if (token_is(token_t::e_rcrlbracket))
  15943. break;
  15944. }
  15945. }
  15946. if (
  15947. !token_is(token_t::e_rbracket ,false) &&
  15948. !token_is(token_t::e_rcrlbracket,false) &&
  15949. !token_is(token_t::e_rsqrbracket,false)
  15950. )
  15951. {
  15952. if (!token_is(token_t::e_eof))
  15953. {
  15954. set_error(
  15955. make_error(parser_error::e_syntax,
  15956. current_token_,
  15957. "ERR128 - Expected ';' at end of vector definition"));
  15958. return error_node();
  15959. }
  15960. }
  15961. if (vec_initilizer_list.size() > vector_size)
  15962. {
  15963. set_error(
  15964. make_error(parser_error::e_syntax,
  15965. current_token_,
  15966. "ERR129 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'"));
  15967. return error_node();
  15968. }
  15969. }
  15970. typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0);
  15971. std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size));
  15972. scope_element& se = sem_.get_element(vec_name);
  15973. if (se.name == vec_name)
  15974. {
  15975. if (se.active)
  15976. {
  15977. set_error(
  15978. make_error(parser_error::e_syntax,
  15979. current_token_,
  15980. "ERR130 - Illegal redefinition of local vector: '" + vec_name + "'"));
  15981. return error_node();
  15982. }
  15983. else if (
  15984. (se.size == vec_size) &&
  15985. (scope_element::e_vector == se.type)
  15986. )
  15987. {
  15988. vec_holder = se.vec_node;
  15989. se.active = true;
  15990. se.ref_count++;
  15991. }
  15992. }
  15993. if (0 == vec_holder)
  15994. {
  15995. scope_element nse;
  15996. nse.name = vec_name;
  15997. nse.type = scope_element::e_vector;
  15998. nse.depth = scope_depth_;
  15999. nse.size = vec_size;
  16000. nse.data = new T[vec_size];
  16001. nse.vec_node = new typename scope_element::vector_holder_t((T*)(nse.data),nse.size);
  16002. if (!sem_.add_element(nse))
  16003. {
  16004. set_error(
  16005. make_error(parser_error::e_syntax,
  16006. current_token_,
  16007. "ERR131 - Failed to add new local vector '" + vec_name + "' to SEM"));
  16008. return error_node();
  16009. }
  16010. vec_holder = nse.vec_node;
  16011. exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n",
  16012. nse.name.c_str(),
  16013. static_cast<int>(nse.size)));
  16014. }
  16015. lodge_symbol(vec_name,e_st_local_vector);
  16016. expression_node_ptr result =
  16017. node_allocator_
  16018. .allocate<details::vector_assignment_node<T> >(
  16019. (*vec_holder)[0],
  16020. vec_size,
  16021. vec_initilizer_list,
  16022. single_value_initialiser);
  16023. svd.delete_ptr = (0 == result);
  16024. return result;
  16025. }
  16026. inline bool local_variable_is_shadowed(const std::string& symbol)
  16027. {
  16028. const scope_element& se = sem_.get_element(symbol);
  16029. return (se.name == symbol) && se.active;
  16030. }
  16031. inline expression_node_ptr parse_define_var_statement()
  16032. {
  16033. if (vardef_disabled_)
  16034. {
  16035. set_error(
  16036. make_error(parser_error::e_syntax,
  16037. current_token_,
  16038. "ERR132 - Illegal variable definition"));
  16039. return error_node();
  16040. }
  16041. else if (!details::imatch(current_token_.value,"var"))
  16042. {
  16043. return error_node();
  16044. }
  16045. else
  16046. next_token();
  16047. const std::string var_name = current_token_.value;
  16048. expression_node_ptr initialisation_expression = error_node();
  16049. if (!token_is(token_t::e_symbol))
  16050. {
  16051. set_error(
  16052. make_error(parser_error::e_syntax,
  16053. current_token_,
  16054. "ERR133 - Expected a symbol for variable definition"));
  16055. return error_node();
  16056. }
  16057. else if (details::is_reserved_symbol(var_name))
  16058. {
  16059. set_error(
  16060. make_error(parser_error::e_syntax,
  16061. current_token_,
  16062. "ERR134 - Illegal redefinition of reserved keyword: '" + var_name + "'"));
  16063. return error_node();
  16064. }
  16065. else if (symbol_table_.symbol_exists(var_name))
  16066. {
  16067. set_error(
  16068. make_error(parser_error::e_syntax,
  16069. current_token_,
  16070. "ERR135 - Illegal redefinition of variable '" + var_name + "'"));
  16071. return error_node();
  16072. }
  16073. else if (local_variable_is_shadowed(var_name))
  16074. {
  16075. set_error(
  16076. make_error(parser_error::e_syntax,
  16077. current_token_,
  16078. "ERR136 - Illegal redefinition of local variable: '" + var_name + "'"));
  16079. return error_node();
  16080. }
  16081. else if (token_is(token_t::e_lsqrbracket,false))
  16082. {
  16083. return parse_define_vector_statement(var_name);
  16084. }
  16085. else if (token_is(token_t::e_lcrlbracket,false))
  16086. {
  16087. return parse_uninitialised_var_statement(var_name);
  16088. }
  16089. else if (token_is(token_t::e_assign))
  16090. {
  16091. if (0 == (initialisation_expression = parse_expression()))
  16092. {
  16093. set_error(
  16094. make_error(parser_error::e_syntax,
  16095. current_token_,
  16096. "ERR137 - Failed to parse initialisation expression"));
  16097. return error_node();
  16098. }
  16099. }
  16100. if (
  16101. !token_is(token_t::e_rbracket ,false) &&
  16102. !token_is(token_t::e_rcrlbracket,false) &&
  16103. !token_is(token_t::e_rsqrbracket,false)
  16104. )
  16105. {
  16106. if (!token_is(token_t::e_eof,false))
  16107. {
  16108. set_error(
  16109. make_error(parser_error::e_syntax,
  16110. current_token_,
  16111. "ERR138 - Expected ';' after variable definition"));
  16112. free_node(node_allocator_,initialisation_expression);
  16113. return error_node();
  16114. }
  16115. }
  16116. variable_node_t* var_node = reinterpret_cast<variable_node_t*>(0);
  16117. scope_element& se = sem_.get_element(var_name);
  16118. if (se.name == var_name)
  16119. {
  16120. if (se.active)
  16121. {
  16122. set_error(
  16123. make_error(parser_error::e_syntax,
  16124. current_token_,
  16125. "ERR139 - Illegal redefinition of local variable: '" + var_name + "'"));
  16126. free_node(node_allocator_,initialisation_expression);
  16127. return error_node();
  16128. }
  16129. else if (scope_element::e_variable == se.type)
  16130. {
  16131. var_node = se.var_node;
  16132. se.active = true;
  16133. se.ref_count++;
  16134. }
  16135. }
  16136. if (0 == var_node)
  16137. {
  16138. scope_element nse;
  16139. nse.name = var_name;
  16140. nse.active = true;
  16141. nse.ref_count = 1;
  16142. nse.type = scope_element::e_variable;
  16143. nse.depth = scope_depth_;
  16144. nse.data = new T(T(0));
  16145. nse.var_node = new variable_node_t(*(T*)(nse.data));
  16146. if (!sem_.add_element(nse))
  16147. {
  16148. set_error(
  16149. make_error(parser_error::e_syntax,
  16150. current_token_,
  16151. "ERR140 - Failed to add new local variable '" + var_name + "' to SEM"));
  16152. free_node(node_allocator_,initialisation_expression);
  16153. return error_node();
  16154. }
  16155. var_node = nse.var_node;
  16156. exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str()));
  16157. }
  16158. lodge_symbol(var_name,e_st_local_variable);
  16159. expression_node_ptr branch[2] = {0};
  16160. branch[0] = var_node;
  16161. branch[1] = initialisation_expression ? initialisation_expression : expression_generator_(T(0));
  16162. return expression_generator_(details::e_assign,branch);
  16163. }
  16164. inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name)
  16165. {
  16166. if (
  16167. !token_is(token_t::e_lcrlbracket) ||
  16168. !token_is(token_t::e_rcrlbracket)
  16169. )
  16170. {
  16171. set_error(
  16172. make_error(parser_error::e_syntax,
  16173. current_token_,
  16174. "ERR141 - Expected a '{}' for uninitialised var definition"));
  16175. return error_node();
  16176. }
  16177. else if (!token_is(token_t::e_eof,false))
  16178. {
  16179. set_error(
  16180. make_error(parser_error::e_syntax,
  16181. current_token_,
  16182. "ERR142 - Expected ';' after uninitialised variable definition"));
  16183. return error_node();
  16184. }
  16185. variable_node_t* var_node = reinterpret_cast<variable_node_t*>(0);
  16186. scope_element& se = sem_.get_element(var_name);
  16187. if (se.name == var_name)
  16188. {
  16189. if (se.active)
  16190. {
  16191. set_error(
  16192. make_error(parser_error::e_syntax,
  16193. current_token_,
  16194. "ERR143 - Illegal redefinition of local variable: '" + var_name + "'"));
  16195. return error_node();
  16196. }
  16197. else if (scope_element::e_variable == se.type)
  16198. {
  16199. var_node = se.var_node;
  16200. se.active = true;
  16201. se.ref_count++;
  16202. }
  16203. }
  16204. if (0 == var_node)
  16205. {
  16206. scope_element nse;
  16207. nse.name = var_name;
  16208. nse.active = true;
  16209. nse.ref_count = 1;
  16210. nse.type = scope_element::e_variable;
  16211. nse.depth = scope_depth_;
  16212. nse.ip_index = sem_.next_ip_index();
  16213. nse.data = new T(T(0));
  16214. nse.var_node = new variable_node_t(*(T*)(nse.data));
  16215. if (!sem_.add_element(nse))
  16216. {
  16217. set_error(
  16218. make_error(parser_error::e_syntax,
  16219. current_token_,
  16220. "ERR144 - Failed to add new local variable '" + var_name + "' to SEM"));
  16221. return error_node();
  16222. }
  16223. exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str()));
  16224. }
  16225. lodge_symbol(var_name,e_st_local_variable);
  16226. return expression_generator_(T(0));
  16227. }
  16228. inline expression_node_ptr parse_swap_statement()
  16229. {
  16230. if (!details::imatch(current_token_.value,"swap"))
  16231. {
  16232. return error_node();
  16233. }
  16234. else
  16235. next_token();
  16236. if (!token_is(token_t::e_lbracket))
  16237. {
  16238. set_error(
  16239. make_error(parser_error::e_syntax,
  16240. current_token_,
  16241. "ERR145 - Expected '(' at start of swap statement"));
  16242. return error_node();
  16243. }
  16244. expression_node_ptr variable0 = error_node();
  16245. expression_node_ptr variable1 = error_node();
  16246. bool variable0_generated = false;
  16247. bool variable1_generated = false;
  16248. const std::string var0_name = current_token_.value;
  16249. if (!token_is(token_t::e_symbol,false))
  16250. {
  16251. set_error(
  16252. make_error(parser_error::e_syntax,
  16253. current_token_,
  16254. "ERR146 - Expected a symbol for variable or vector element definition"));
  16255. return error_node();
  16256. }
  16257. else if (peek_token_is(token_t::e_lsqrbracket))
  16258. {
  16259. if (0 == (variable0 = parse_vector()))
  16260. {
  16261. set_error(
  16262. make_error(parser_error::e_syntax,
  16263. current_token_,
  16264. "ERR147 - First parameter to swap is an invalid vector element: '" + var0_name + "'"));
  16265. return error_node();
  16266. }
  16267. variable0_generated = true;
  16268. }
  16269. else
  16270. {
  16271. if (symbol_table_.is_variable(var0_name))
  16272. {
  16273. variable0 = symbol_table_.get_variable(var0_name);
  16274. }
  16275. scope_element& se = sem_.get_element(var0_name);
  16276. if (
  16277. (se.active) &&
  16278. (se.name == var0_name) &&
  16279. (scope_element::e_variable == se.type)
  16280. )
  16281. {
  16282. variable0 = se.var_node;
  16283. }
  16284. lodge_symbol(var0_name,e_st_variable);
  16285. if (0 == variable0)
  16286. {
  16287. set_error(
  16288. make_error(parser_error::e_syntax,
  16289. current_token_,
  16290. "ERR148 - First parameter to swap is an invalid variable: '" + var0_name + "'"));
  16291. return error_node();
  16292. }
  16293. else
  16294. next_token();
  16295. }
  16296. if (!token_is(token_t::e_comma))
  16297. {
  16298. set_error(
  16299. make_error(parser_error::e_syntax,
  16300. current_token(),
  16301. "ERR149 - Expected ',' between parameters to swap"));
  16302. if (variable0_generated)
  16303. {
  16304. free_node(node_allocator_,variable0);
  16305. }
  16306. return error_node();
  16307. }
  16308. const std::string var1_name = current_token_.value;
  16309. if (!token_is(token_t::e_symbol,false))
  16310. {
  16311. set_error(
  16312. make_error(parser_error::e_syntax,
  16313. current_token_,
  16314. "ERR150 - Expected a symbol for variable or vector element definition"));
  16315. if (variable0_generated)
  16316. {
  16317. free_node(node_allocator_,variable0);
  16318. }
  16319. return error_node();
  16320. }
  16321. else if (peek_token_is(token_t::e_lsqrbracket))
  16322. {
  16323. if (0 == (variable1 = parse_vector()))
  16324. {
  16325. set_error(
  16326. make_error(parser_error::e_syntax,
  16327. current_token_,
  16328. "ERR151 - Second parameter to swap is an invalid vector element: '" + var1_name + "'"));
  16329. if (variable0_generated)
  16330. {
  16331. free_node(node_allocator_,variable0);
  16332. }
  16333. return error_node();
  16334. }
  16335. variable1_generated = true;
  16336. }
  16337. else
  16338. {
  16339. if (symbol_table_.is_variable(var1_name))
  16340. {
  16341. variable1 = symbol_table_.get_variable(var1_name);
  16342. }
  16343. scope_element& se = sem_.get_element(var1_name);
  16344. if (
  16345. (se.active) &&
  16346. (se.name == var1_name) &&
  16347. (scope_element::e_variable == se.type)
  16348. )
  16349. {
  16350. variable1 = se.var_node;
  16351. }
  16352. lodge_symbol(var1_name,e_st_variable);
  16353. if (0 == variable1)
  16354. {
  16355. set_error(
  16356. make_error(parser_error::e_syntax,
  16357. current_token_,
  16358. "ERR152 - Second parameter to swap is an invalid variable: '" + var1_name + "'"));
  16359. if (variable0_generated)
  16360. {
  16361. free_node(node_allocator_,variable0);
  16362. }
  16363. return error_node();
  16364. }
  16365. else
  16366. next_token();
  16367. }
  16368. if (!token_is(token_t::e_rbracket))
  16369. {
  16370. set_error(
  16371. make_error(parser_error::e_syntax,
  16372. current_token_,
  16373. "ERR153 - Expected ')' at end of swap statement"));
  16374. if (variable0_generated)
  16375. {
  16376. free_node(node_allocator_,variable0);
  16377. }
  16378. if (variable1_generated)
  16379. {
  16380. free_node(node_allocator_,variable1);
  16381. }
  16382. return error_node();
  16383. }
  16384. typedef details::variable_node<T>* variable_node_ptr;
  16385. variable_node_ptr v0 = variable_node_ptr(0);
  16386. variable_node_ptr v1 = variable_node_ptr(0);
  16387. if (
  16388. (0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) &&
  16389. (0 != (v1 = dynamic_cast<variable_node_ptr>(variable1)))
  16390. )
  16391. {
  16392. expression_node_ptr result = node_allocator_.allocate<details::swap_node<T> >(v0,v1);
  16393. if (variable0_generated)
  16394. {
  16395. free_node(node_allocator_,variable0);
  16396. }
  16397. if (variable1_generated)
  16398. {
  16399. free_node(node_allocator_,variable1);
  16400. }
  16401. return result;
  16402. }
  16403. else
  16404. return node_allocator_.allocate<details::swap_generic_node<T> >(variable0,variable1);
  16405. }
  16406. inline bool post_variable_process(const std::string& symbol)
  16407. {
  16408. if (
  16409. peek_token_is(token_t::e_lbracket ) ||
  16410. peek_token_is(token_t::e_lcrlbracket) ||
  16411. peek_token_is(token_t::e_lsqrbracket)
  16412. )
  16413. {
  16414. if (!commutative_check_enabled())
  16415. {
  16416. set_error(
  16417. make_error(parser_error::e_syntax,
  16418. current_token_,
  16419. "ERR154 - Invalid sequence of variable '"+ symbol + "' and bracket"));
  16420. return false;
  16421. }
  16422. lexer_.insert_front(token_t::e_mul);
  16423. }
  16424. return true;
  16425. }
  16426. inline bool post_bracket_process(const typename token_t::token_type& token, expression_node_ptr& branch)
  16427. {
  16428. bool implied_mul = false;
  16429. if (is_generally_string_node(branch))
  16430. return true;
  16431. switch (token)
  16432. {
  16433. case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket ,false) ||
  16434. token_is(token_t::e_lcrlbracket,false) ||
  16435. token_is(token_t::e_lsqrbracket,false) ;
  16436. break;
  16437. case token_t::e_lbracket : implied_mul = token_is(token_t::e_lbracket ,false) ||
  16438. token_is(token_t::e_lcrlbracket,false) ||
  16439. token_is(token_t::e_lsqrbracket,false) ;
  16440. break;
  16441. case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket ,false) ||
  16442. token_is(token_t::e_lcrlbracket,false) ||
  16443. token_is(token_t::e_lsqrbracket,false) ;
  16444. break;
  16445. default : return true;
  16446. }
  16447. if (implied_mul)
  16448. {
  16449. if (!commutative_check_enabled())
  16450. {
  16451. set_error(
  16452. make_error(parser_error::e_syntax,
  16453. current_token_,
  16454. "ERR155 - Invalid sequence of brackets"));
  16455. return false;
  16456. }
  16457. else if (token_t::e_eof != current_token_.type)
  16458. {
  16459. lexer_.insert_front(current_token_.type);
  16460. lexer_.insert_front(token_t::e_mul);
  16461. next_token();
  16462. }
  16463. }
  16464. return true;
  16465. }
  16466. inline expression_node_ptr parse_symtab_symbol()
  16467. {
  16468. const std::string symbol = current_token_.value;
  16469. // Are we dealing with a variable or a special constant?
  16470. expression_node_ptr variable = symbol_table_.get_variable(symbol);
  16471. if (variable)
  16472. {
  16473. if (symbol_table_.is_constant_node(symbol))
  16474. {
  16475. variable = expression_generator_(variable->value());
  16476. }
  16477. if (!post_variable_process(symbol))
  16478. return error_node();
  16479. lodge_symbol(symbol,e_st_variable);
  16480. next_token();
  16481. return variable;
  16482. }
  16483. // Are we dealing with a locally defined variable or vector?
  16484. if (!sem_.empty())
  16485. {
  16486. scope_element& se = sem_.get_element(symbol);
  16487. if (se.name == symbol)
  16488. {
  16489. if (scope_element::e_variable == se.type)
  16490. {
  16491. se.active = true;
  16492. lodge_symbol(symbol,e_st_local_variable);
  16493. if (!post_variable_process(symbol))
  16494. return error_node();
  16495. next_token();
  16496. return se.var_node;
  16497. }
  16498. else if (scope_element::e_vector == se.type)
  16499. {
  16500. return parse_vector();
  16501. }
  16502. }
  16503. }
  16504. #ifndef exprtk_disable_string_capabilities
  16505. // Are we dealing with a string variable?
  16506. if (symbol_table_.is_stringvar(symbol))
  16507. {
  16508. return parse_string();
  16509. }
  16510. #endif
  16511. {
  16512. // Are we dealing with a function?
  16513. ifunction<T>* function = symbol_table_.get_function(symbol);
  16514. if (function)
  16515. {
  16516. lodge_symbol(symbol,e_st_function);
  16517. expression_node_ptr func_node =
  16518. parse_function_invocation(function,symbol);
  16519. if (func_node)
  16520. return func_node;
  16521. else
  16522. {
  16523. set_error(
  16524. make_error(parser_error::e_syntax,
  16525. current_token_,
  16526. "ERR156 - Failed to generate node for function: '" + symbol + "'"));
  16527. return error_node();
  16528. }
  16529. }
  16530. }
  16531. {
  16532. // Are we dealing with a vararg function?
  16533. ivararg_function<T>* vararg_function = symbol_table_.get_vararg_function(symbol);
  16534. if (vararg_function)
  16535. {
  16536. lodge_symbol(symbol,e_st_function);
  16537. expression_node_ptr vararg_func_node =
  16538. parse_vararg_function_call(vararg_function,symbol);
  16539. if (vararg_func_node)
  16540. return vararg_func_node;
  16541. else
  16542. {
  16543. set_error(
  16544. make_error(parser_error::e_syntax,
  16545. current_token_,
  16546. "ERR157 - Failed to generate node for vararg function: '" + symbol + "'"));
  16547. return error_node();
  16548. }
  16549. }
  16550. }
  16551. {
  16552. // Are we dealing with a vararg generic function?
  16553. igeneric_function<T>* generic_function = symbol_table_.get_generic_function(symbol);
  16554. if (generic_function)
  16555. {
  16556. lodge_symbol(symbol,e_st_function);
  16557. expression_node_ptr genericfunc_node =
  16558. parse_generic_function_call(generic_function,symbol);
  16559. if (genericfunc_node)
  16560. return genericfunc_node;
  16561. else
  16562. {
  16563. set_error(
  16564. make_error(parser_error::e_syntax,
  16565. current_token_,
  16566. "ERR158 - Failed to generate node for generic function: '" + symbol + "'"));
  16567. return error_node();
  16568. }
  16569. }
  16570. }
  16571. {
  16572. // Are we dealing with a vararg string returing function?
  16573. igeneric_function<T>* string_function = symbol_table_.get_string_function(symbol);
  16574. if (string_function)
  16575. {
  16576. lodge_symbol(symbol,e_st_function);
  16577. expression_node_ptr stringfunc_node =
  16578. parse_string_function_call(string_function,symbol);
  16579. if (stringfunc_node)
  16580. return stringfunc_node;
  16581. else
  16582. {
  16583. set_error(
  16584. make_error(parser_error::e_syntax,
  16585. current_token_,
  16586. "ERR159 - Failed to generate node for string function: '" + symbol + "'"));
  16587. return error_node();
  16588. }
  16589. }
  16590. }
  16591. // Are we dealing with a vector element?
  16592. if (symbol_table_.is_vector(symbol))
  16593. {
  16594. lodge_symbol(symbol,e_st_vector);
  16595. return parse_vector();
  16596. }
  16597. if (details::is_reserved_symbol(symbol))
  16598. {
  16599. set_error(
  16600. make_error(parser_error::e_syntax,
  16601. current_token_,
  16602. "ERR160 - Invalid use of reserved symbol '" + symbol + "'"));
  16603. return error_node();
  16604. }
  16605. // Should we handle unknown symbols?
  16606. if (resolve_unknown_symbol_ && unknown_symbol_resolver_)
  16607. {
  16608. T default_value = T(0);
  16609. std::string error_message;
  16610. typename unknown_symbol_resolver::usr_symbol_type usr_symbol_type;
  16611. if (unknown_symbol_resolver_->process(symbol,usr_symbol_type,default_value,error_message))
  16612. {
  16613. bool create_result = false;
  16614. switch (usr_symbol_type)
  16615. {
  16616. case unknown_symbol_resolver::e_usr_variable_type : create_result = symbol_table_.create_variable(symbol,default_value);
  16617. break;
  16618. case unknown_symbol_resolver::e_usr_constant_type : create_result = symbol_table_.add_constant(symbol,default_value);
  16619. break;
  16620. default : create_result = false;
  16621. }
  16622. if (create_result)
  16623. {
  16624. expression_node_ptr var = symbol_table_.get_variable(symbol);
  16625. if (var)
  16626. {
  16627. if (symbol_table_.is_constant_node(symbol))
  16628. {
  16629. var = expression_generator_(var->value());
  16630. }
  16631. lodge_symbol(symbol,e_st_variable);
  16632. if (!post_variable_process(symbol))
  16633. return error_node();
  16634. next_token();
  16635. return var;
  16636. }
  16637. }
  16638. set_error(
  16639. make_error(parser_error::e_symtab,
  16640. current_token_,
  16641. "ERR161 - Failed to create variable: '" + symbol + "'"));
  16642. return error_node();
  16643. }
  16644. }
  16645. set_error(
  16646. make_error(parser_error::e_syntax,
  16647. current_token_,
  16648. "ERR162 - Undefined symbol: '" + symbol + "'"));
  16649. return error_node();
  16650. }
  16651. inline expression_node_ptr parse_symbol()
  16652. {
  16653. static const std::string symbol_if = "if" ;
  16654. static const std::string symbol_while = "while" ;
  16655. static const std::string symbol_repeat = "repeat" ;
  16656. static const std::string symbol_for = "for" ;
  16657. static const std::string symbol_switch = "switch" ;
  16658. static const std::string symbol_null = "null" ;
  16659. static const std::string symbol_break = "break" ;
  16660. static const std::string symbol_continue = "continue";
  16661. static const std::string symbol_var = "var" ;
  16662. static const std::string symbol_swap = "swap" ;
  16663. if (valid_vararg_operation(current_token_.value))
  16664. {
  16665. return parse_vararg_function();
  16666. }
  16667. else if (valid_base_operation(current_token_.value))
  16668. {
  16669. return parse_base_operation();
  16670. }
  16671. else if (details::imatch(current_token_.value,symbol_if))
  16672. {
  16673. return parse_conditional_statement();
  16674. }
  16675. else if (details::imatch(current_token_.value,symbol_while))
  16676. {
  16677. return parse_while_loop();
  16678. }
  16679. else if (details::imatch(current_token_.value,symbol_repeat))
  16680. {
  16681. return parse_repeat_until_loop();
  16682. }
  16683. else if (details::imatch(current_token_.value,symbol_for))
  16684. {
  16685. return parse_for_loop();
  16686. }
  16687. else if (details::imatch(current_token_.value,symbol_switch))
  16688. {
  16689. return parse_switch_statement();
  16690. }
  16691. else if (details::is_valid_sf_symbol(current_token_.value))
  16692. {
  16693. return parse_special_function();
  16694. }
  16695. else if (details::imatch(current_token_.value,symbol_null))
  16696. {
  16697. return parse_null_statement();
  16698. }
  16699. #ifndef exprtk_disable_break_continue
  16700. else if (details::imatch(current_token_.value,symbol_break))
  16701. {
  16702. return parse_break_statement();
  16703. }
  16704. else if (details::imatch(current_token_.value,symbol_continue))
  16705. {
  16706. return parse_continue_statement();
  16707. }
  16708. #endif
  16709. else if (details::imatch(current_token_.value,symbol_var))
  16710. {
  16711. return parse_define_var_statement();
  16712. }
  16713. else if (details::imatch(current_token_.value,symbol_swap))
  16714. {
  16715. return parse_swap_statement();
  16716. }
  16717. else if (symbol_table_.valid() || !sem_.empty())
  16718. {
  16719. return parse_symtab_symbol();
  16720. }
  16721. else
  16722. {
  16723. set_error(
  16724. make_error(parser_error::e_symtab,
  16725. current_token_,
  16726. "ERR163 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value));
  16727. return error_node();
  16728. }
  16729. }
  16730. inline expression_node_ptr parse_branch(precedence_level precedence = e_level00)
  16731. {
  16732. expression_node_ptr branch = error_node();
  16733. if (token_t::e_number == current_token_.type)
  16734. {
  16735. T numeric_value = T(0);
  16736. if (details::string_to_real(current_token_.value,numeric_value))
  16737. {
  16738. expression_node_ptr literal_exp = expression_generator_(numeric_value);
  16739. next_token();
  16740. branch = literal_exp;
  16741. }
  16742. else
  16743. {
  16744. set_error(
  16745. make_error(parser_error::e_numeric,
  16746. current_token_,
  16747. "ERR164 - Failed to convert '" + current_token_.value + "' to a number"));
  16748. return error_node();
  16749. }
  16750. }
  16751. else if (token_t::e_symbol == current_token_.type)
  16752. {
  16753. branch = parse_symbol();
  16754. }
  16755. #ifndef exprtk_disable_string_capabilities
  16756. else if (token_t::e_string == current_token_.type)
  16757. {
  16758. branch = parse_const_string();
  16759. }
  16760. #endif
  16761. else if (token_t::e_lbracket == current_token_.type)
  16762. {
  16763. next_token();
  16764. if (0 == (branch = parse_expression()))
  16765. return error_node();
  16766. else if (!token_is(token_t::e_rbracket))
  16767. {
  16768. set_error(
  16769. make_error(parser_error::e_syntax,
  16770. current_token_,
  16771. "ERR165 - Expected ')' instead of: '" + current_token_.value + "'"));
  16772. free_node(node_allocator_,branch);
  16773. return error_node();
  16774. }
  16775. else if (!post_bracket_process(token_t::e_lbracket,branch))
  16776. {
  16777. free_node(node_allocator_,branch);
  16778. return error_node();
  16779. }
  16780. }
  16781. else if (token_t::e_lsqrbracket == current_token_.type)
  16782. {
  16783. next_token();
  16784. if (0 == (branch = parse_expression()))
  16785. return error_node();
  16786. else if (!token_is(token_t::e_rsqrbracket))
  16787. {
  16788. set_error(
  16789. make_error(parser_error::e_syntax,
  16790. current_token_,
  16791. "ERR166 - Expected ']' instead of: '" + current_token_.value + "'"));
  16792. free_node(node_allocator_,branch);
  16793. return error_node();
  16794. }
  16795. else if (!post_bracket_process(token_t::e_lsqrbracket,branch))
  16796. {
  16797. free_node(node_allocator_,branch);
  16798. return error_node();
  16799. }
  16800. }
  16801. else if (token_t::e_lcrlbracket == current_token_.type)
  16802. {
  16803. next_token();
  16804. if (0 == (branch = parse_expression()))
  16805. return error_node();
  16806. else if (!token_is(token_t::e_rcrlbracket))
  16807. {
  16808. set_error(
  16809. make_error(parser_error::e_syntax,
  16810. current_token_,
  16811. "ERR167 - Expected '}' instead of: '" + current_token_.value + "'"));
  16812. free_node(node_allocator_,branch);
  16813. return error_node();
  16814. }
  16815. else if (!post_bracket_process(token_t::e_lcrlbracket,branch))
  16816. {
  16817. free_node(node_allocator_,branch);
  16818. return error_node();
  16819. }
  16820. }
  16821. else if (token_t::e_sub == current_token_.type)
  16822. {
  16823. next_token();
  16824. branch = parse_expression(e_level11);
  16825. if (
  16826. branch &&
  16827. !(
  16828. details::is_neg_unary_node (branch) &&
  16829. simplify_unary_negation_branch(branch)
  16830. )
  16831. )
  16832. {
  16833. branch = expression_generator_(details::e_neg,branch);
  16834. }
  16835. }
  16836. else if (token_t::e_add == current_token_.type)
  16837. {
  16838. next_token();
  16839. branch = parse_expression(e_level13);
  16840. }
  16841. else if (token_t::e_eof == current_token_.type)
  16842. {
  16843. set_error(
  16844. make_error(parser_error::e_syntax,
  16845. current_token_,
  16846. "ERR168 - Premature end of expression[1]"));
  16847. return error_node();
  16848. }
  16849. else
  16850. {
  16851. set_error(
  16852. make_error(parser_error::e_syntax,
  16853. current_token_,
  16854. "ERR169 - Premature end of expression[2]"));
  16855. return error_node();
  16856. }
  16857. if (
  16858. branch &&
  16859. (e_level00 == precedence) &&
  16860. token_is(token_t::e_ternary,false)
  16861. )
  16862. {
  16863. branch = parse_ternary_conditional_statement(branch);
  16864. }
  16865. parse_pending_string_rangesize(branch);
  16866. return branch;
  16867. }
  16868. inline bool token_is(const typename token_t::token_type& ttype, const bool advance_token = true)
  16869. {
  16870. if (current_token_.type != ttype)
  16871. {
  16872. return false;
  16873. }
  16874. if (advance_token)
  16875. {
  16876. next_token();
  16877. }
  16878. return true;
  16879. }
  16880. inline bool peek_token_is(const typename token_t::token_type& ttype)
  16881. {
  16882. return (lexer_.peek_next_token().type == ttype);
  16883. }
  16884. inline bool peek_token_is(const std::string& s)
  16885. {
  16886. return (details::imatch(lexer_.peek_next_token().value,s));
  16887. }
  16888. template <typename Type>
  16889. class expression_generator
  16890. {
  16891. public:
  16892. typedef details::expression_node<Type>* expression_node_ptr;
  16893. typedef expression_node_ptr (*synthesize_functor_t)(expression_generator<T>&, const details::operator_type& operation, expression_node_ptr (&branch)[2]);
  16894. typedef std::map<std::string,synthesize_functor_t> synthesize_map_t;
  16895. typedef typename exprtk::parser<Type> parser_t;
  16896. typedef const Type& vtype;
  16897. typedef const Type ctype;
  16898. inline void init_synthesize_map()
  16899. {
  16900. #ifndef exprtk_disable_enhanced_features
  16901. synthesize_map_["(v)o(v)"] = synthesize_vov_expression::process;
  16902. synthesize_map_["(c)o(v)"] = synthesize_cov_expression::process;
  16903. synthesize_map_["(v)o(c)"] = synthesize_voc_expression::process;
  16904. #define register_synthezier(S) \
  16905. synthesize_map_[S ::node_type::id()] = S ::process; \
  16906. register_synthezier(synthesize_vovov_expression0)
  16907. register_synthezier(synthesize_vovov_expression1)
  16908. register_synthezier(synthesize_vovoc_expression0)
  16909. register_synthezier(synthesize_vovoc_expression1)
  16910. register_synthezier(synthesize_vocov_expression0)
  16911. register_synthezier(synthesize_vocov_expression1)
  16912. register_synthezier(synthesize_covov_expression0)
  16913. register_synthezier(synthesize_covov_expression1)
  16914. register_synthezier(synthesize_covoc_expression0)
  16915. register_synthezier(synthesize_covoc_expression1)
  16916. register_synthezier(synthesize_cocov_expression1)
  16917. register_synthezier(synthesize_vococ_expression0)
  16918. register_synthezier(synthesize_vovovov_expression0)
  16919. register_synthezier(synthesize_vovovoc_expression0)
  16920. register_synthezier(synthesize_vovocov_expression0)
  16921. register_synthezier(synthesize_vocovov_expression0)
  16922. register_synthezier(synthesize_covovov_expression0)
  16923. register_synthezier(synthesize_covocov_expression0)
  16924. register_synthezier(synthesize_vocovoc_expression0)
  16925. register_synthezier(synthesize_covovoc_expression0)
  16926. register_synthezier(synthesize_vococov_expression0)
  16927. register_synthezier(synthesize_vovovov_expression1)
  16928. register_synthezier(synthesize_vovovoc_expression1)
  16929. register_synthezier(synthesize_vovocov_expression1)
  16930. register_synthezier(synthesize_vocovov_expression1)
  16931. register_synthezier(synthesize_covovov_expression1)
  16932. register_synthezier(synthesize_covocov_expression1)
  16933. register_synthezier(synthesize_vocovoc_expression1)
  16934. register_synthezier(synthesize_covovoc_expression1)
  16935. register_synthezier(synthesize_vococov_expression1)
  16936. register_synthezier(synthesize_vovovov_expression2)
  16937. register_synthezier(synthesize_vovovoc_expression2)
  16938. register_synthezier(synthesize_vovocov_expression2)
  16939. register_synthezier(synthesize_vocovov_expression2)
  16940. register_synthezier(synthesize_covovov_expression2)
  16941. register_synthezier(synthesize_covocov_expression2)
  16942. register_synthezier(synthesize_vocovoc_expression2)
  16943. register_synthezier(synthesize_covovoc_expression2)
  16944. register_synthezier(synthesize_vovovov_expression3)
  16945. register_synthezier(synthesize_vovovoc_expression3)
  16946. register_synthezier(synthesize_vovocov_expression3)
  16947. register_synthezier(synthesize_vocovov_expression3)
  16948. register_synthezier(synthesize_covovov_expression3)
  16949. register_synthezier(synthesize_covocov_expression3)
  16950. register_synthezier(synthesize_vocovoc_expression3)
  16951. register_synthezier(synthesize_covovoc_expression3)
  16952. register_synthezier(synthesize_vococov_expression3)
  16953. register_synthezier(synthesize_vovovov_expression4)
  16954. register_synthezier(synthesize_vovovoc_expression4)
  16955. register_synthezier(synthesize_vovocov_expression4)
  16956. register_synthezier(synthesize_vocovov_expression4)
  16957. register_synthezier(synthesize_covovov_expression4)
  16958. register_synthezier(synthesize_covocov_expression4)
  16959. register_synthezier(synthesize_vocovoc_expression4)
  16960. register_synthezier(synthesize_covovoc_expression4)
  16961. #endif
  16962. }
  16963. inline void set_parser(parser_t& p)
  16964. {
  16965. parser_ = &p;
  16966. }
  16967. inline void set_uom(unary_op_map_t& unary_op_map)
  16968. {
  16969. unary_op_map_ = &unary_op_map;
  16970. }
  16971. inline void set_bom(binary_op_map_t& binary_op_map)
  16972. {
  16973. binary_op_map_ = &binary_op_map;
  16974. }
  16975. inline void set_ibom(inv_binary_op_map_t& inv_binary_op_map)
  16976. {
  16977. inv_binary_op_map_ = &inv_binary_op_map;
  16978. }
  16979. inline void set_sf3m(sf3_map_t& sf3_map)
  16980. {
  16981. sf3_map_ = &sf3_map;
  16982. }
  16983. inline void set_sf4m(sf4_map_t& sf4_map)
  16984. {
  16985. sf4_map_ = &sf4_map;
  16986. }
  16987. inline void set_allocator(details::node_allocator& na)
  16988. {
  16989. node_allocator_ = &na;
  16990. }
  16991. inline void set_strength_reduction_state(const bool enabled)
  16992. {
  16993. strength_reduction_enabled_ = enabled;
  16994. }
  16995. inline bool strength_reduction_enabled() const
  16996. {
  16997. return strength_reduction_enabled_;
  16998. }
  16999. inline bool valid_operator(const details::operator_type& operation, binary_functor_t& bop)
  17000. {
  17001. typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation);
  17002. if ((*binary_op_map_).end() == bop_itr)
  17003. return false;
  17004. bop = bop_itr->second;
  17005. return true;
  17006. }
  17007. inline bool valid_operator(const details::operator_type& operation, unary_functor_t& uop)
  17008. {
  17009. typename unary_op_map_t::iterator uop_itr = unary_op_map_->find(operation);
  17010. if ((*unary_op_map_).end() == uop_itr)
  17011. return false;
  17012. uop = uop_itr->second;
  17013. return true;
  17014. }
  17015. inline details::operator_type get_operator(const binary_functor_t& bop)
  17016. {
  17017. return (*inv_binary_op_map_).find(bop)->second;
  17018. }
  17019. inline expression_node_ptr operator()(const Type& v) const
  17020. {
  17021. return node_allocator_->allocate<literal_node_t>(v);
  17022. }
  17023. inline expression_node_ptr operator()(const std::string& s) const
  17024. {
  17025. return node_allocator_->allocate<string_literal_node_t>(s);
  17026. }
  17027. inline expression_node_ptr operator()(std::string& s, range_t& rp) const
  17028. {
  17029. return node_allocator_->allocate_rr<string_range_node_t>(s,rp);
  17030. }
  17031. inline expression_node_ptr operator()(const std::string& s, range_t& rp) const
  17032. {
  17033. return node_allocator_->allocate_tt<const_string_range_node_t>(s,rp);
  17034. }
  17035. inline expression_node_ptr operator()(expression_node_ptr branch, range_t& rp) const
  17036. {
  17037. if (is_generally_string_node(branch))
  17038. return node_allocator_->allocate_tt<generic_string_range_node_t>(branch,rp);
  17039. else
  17040. return error_node();
  17041. }
  17042. inline bool unary_optimizable(const details::operator_type& operation) const
  17043. {
  17044. return (details::e_abs == operation) || (details::e_acos == operation) ||
  17045. (details::e_acosh == operation) || (details::e_asin == operation) ||
  17046. (details::e_asinh == operation) || (details::e_atan == operation) ||
  17047. (details::e_atanh == operation) || (details::e_ceil == operation) ||
  17048. (details::e_cos == operation) || (details::e_cosh == operation) ||
  17049. (details::e_exp == operation) || (details::e_expm1 == operation) ||
  17050. (details::e_floor == operation) || (details::e_log == operation) ||
  17051. (details::e_log10 == operation) || (details::e_log2 == operation) ||
  17052. (details::e_log1p == operation) || (details::e_neg == operation) ||
  17053. (details::e_pos == operation) || (details::e_round == operation) ||
  17054. (details::e_sin == operation) || (details::e_sinc == operation) ||
  17055. (details::e_sinh == operation) || (details::e_sqrt == operation) ||
  17056. (details::e_tan == operation) || (details::e_tanh == operation) ||
  17057. (details::e_cot == operation) || (details::e_sec == operation) ||
  17058. (details::e_csc == operation) || (details::e_r2d == operation) ||
  17059. (details::e_d2r == operation) || (details::e_d2g == operation) ||
  17060. (details::e_g2d == operation) || (details::e_notl == operation) ||
  17061. (details::e_sgn == operation) || (details::e_erf == operation) ||
  17062. (details::e_erfc == operation) || (details::e_ncdf == operation) ||
  17063. (details::e_frac == operation) || (details::e_trunc == operation);
  17064. }
  17065. inline bool sf3_optimizable(const std::string& sf3id, trinary_functor_t& tfunc)
  17066. {
  17067. typename sf3_map_t::iterator itr = sf3_map_->find(sf3id);
  17068. if (sf3_map_->end() == itr)
  17069. return false;
  17070. else
  17071. tfunc = itr->second.first;
  17072. return true;
  17073. }
  17074. inline bool sf4_optimizable(const std::string& sf4id, quaternary_functor_t& qfunc)
  17075. {
  17076. typename sf4_map_t::iterator itr = sf4_map_->find(sf4id);
  17077. if (sf4_map_->end() == itr)
  17078. return false;
  17079. else
  17080. qfunc = itr->second.first;
  17081. return true;
  17082. }
  17083. inline bool sf3_optimizable(const std::string& sf3id, details::operator_type& operation)
  17084. {
  17085. typename sf3_map_t::iterator itr = sf3_map_->find(sf3id);
  17086. if (sf3_map_->end() == itr)
  17087. return false;
  17088. else
  17089. operation = itr->second.second;
  17090. return true;
  17091. }
  17092. inline bool sf4_optimizable(const std::string& sf4id, details::operator_type& operation)
  17093. {
  17094. typename sf4_map_t::iterator itr = sf4_map_->find(sf4id);
  17095. if (sf4_map_->end() == itr)
  17096. return false;
  17097. else
  17098. operation = itr->second.second;
  17099. return true;
  17100. }
  17101. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[1])
  17102. {
  17103. if (0 == branch[0])
  17104. return error_node();
  17105. else if (details::is_null_node(branch[0]))
  17106. return branch[0];
  17107. else if (details::is_break_node(branch[0]))
  17108. return error_node();
  17109. else if (details::is_continue_node(branch[0]))
  17110. return error_node();
  17111. else if (details::is_constant_node(branch[0]))
  17112. return synthesize_expression<unary_node_t,1>(operation,branch);
  17113. else if (unary_optimizable(operation) && details::is_variable_node(branch[0]))
  17114. return synthesize_uv_expression(operation,branch);
  17115. else if (unary_optimizable(operation) && details::is_ivector_node(branch[0]))
  17116. return synthesize_uvec_expression(operation,branch);
  17117. else
  17118. return synthesize_unary_expression(operation,branch);
  17119. }
  17120. inline bool is_assignment_operation(const details::operator_type& operation) const
  17121. {
  17122. return (details::e_addass == operation) ||
  17123. (details::e_subass == operation) ||
  17124. (details::e_mulass == operation) ||
  17125. (details::e_divass == operation) ||
  17126. (details::e_modass == operation) ;
  17127. }
  17128. #ifndef exprtk_disable_string_capabilities
  17129. inline bool valid_string_operation(const details::operator_type& operation) const
  17130. {
  17131. return (details::e_add == operation) ||
  17132. (details::e_lt == operation) ||
  17133. (details::e_lte == operation) ||
  17134. (details::e_gt == operation) ||
  17135. (details::e_gte == operation) ||
  17136. (details::e_eq == operation) ||
  17137. (details::e_ne == operation) ||
  17138. (details::e_in == operation) ||
  17139. (details::e_like == operation) ||
  17140. (details::e_ilike == operation) ||
  17141. (details::e_assign == operation) ||
  17142. (details::e_addass == operation) ||
  17143. (details::e_swap == operation) ;
  17144. }
  17145. #else
  17146. inline bool valid_string_operation(const details::operator_type&) const
  17147. {
  17148. return false;
  17149. }
  17150. #endif
  17151. inline std::string to_str(const details::operator_type& operation) const
  17152. {
  17153. switch (operation)
  17154. {
  17155. case details::e_add : return "+";
  17156. case details::e_sub : return "-";
  17157. case details::e_mul : return "*";
  17158. case details::e_div : return "/";
  17159. case details::e_mod : return "%";
  17160. case details::e_pow : return "^";
  17161. case details::e_lt : return "<";
  17162. case details::e_lte : return "<=";
  17163. case details::e_gt : return ">";
  17164. case details::e_gte : return ">=";
  17165. case details::e_eq : return "==";
  17166. case details::e_ne : return "!=";
  17167. case details::e_and : return "and";
  17168. case details::e_nand : return "nand";
  17169. case details::e_or : return "or";
  17170. case details::e_nor : return "nor";
  17171. case details::e_xor : return "xor";
  17172. case details::e_xnor : return "xnor";
  17173. default : return "UNKNOWN";
  17174. }
  17175. }
  17176. inline bool operation_optimizable(const details::operator_type& operation) const
  17177. {
  17178. return (details::e_add == operation) ||
  17179. (details::e_sub == operation) ||
  17180. (details::e_mul == operation) ||
  17181. (details::e_div == operation) ||
  17182. (details::e_mod == operation) ||
  17183. (details::e_pow == operation) ||
  17184. (details::e_lt == operation) ||
  17185. (details::e_lte == operation) ||
  17186. (details::e_gt == operation) ||
  17187. (details::e_gte == operation) ||
  17188. (details::e_eq == operation) ||
  17189. (details::e_ne == operation) ||
  17190. (details::e_and == operation) ||
  17191. (details::e_nand == operation) ||
  17192. (details::e_or == operation) ||
  17193. (details::e_nor == operation) ||
  17194. (details::e_xor == operation) ||
  17195. (details::e_xnor == operation) ;
  17196. }
  17197. inline std::string branch_to_id(expression_node_ptr branch)
  17198. {
  17199. static const std::string null_str ("(null)" );
  17200. static const std::string const_str ("(c)" );
  17201. static const std::string var_str ("(v)" );
  17202. static const std::string vov_str ("(vov)" );
  17203. static const std::string cov_str ("(cov)" );
  17204. static const std::string voc_str ("(voc)" );
  17205. static const std::string str_str ("(s)" );
  17206. static const std::string strrng_str ("(rngs)" );
  17207. static const std::string cs_str ("(cs)" );
  17208. static const std::string cstrrng_str("(crngs)");
  17209. if (details::is_null_node(branch))
  17210. return null_str;
  17211. else if (details::is_constant_node(branch))
  17212. return const_str;
  17213. else if (details::is_variable_node(branch))
  17214. return var_str;
  17215. else if (details::is_vov_node(branch))
  17216. return vov_str;
  17217. else if (details::is_cov_node(branch))
  17218. return cov_str;
  17219. else if (details::is_voc_node(branch))
  17220. return voc_str;
  17221. else if (details::is_string_node(branch))
  17222. return str_str;
  17223. else if (details::is_const_string_node(branch))
  17224. return cs_str;
  17225. else if (details::is_string_range_node(branch))
  17226. return strrng_str;
  17227. else if (details::is_const_string_range_node(branch))
  17228. return cstrrng_str;
  17229. else if (details::is_t0ot1ot2_node(branch))
  17230. return "(" + dynamic_cast<details::T0oT1oT2_base_node<T>*>(branch)->type_id() + ")";
  17231. else if (details::is_t0ot1ot2ot3_node(branch))
  17232. return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node<T>*>(branch)->type_id() + ")";
  17233. else
  17234. return "ERROR";
  17235. }
  17236. inline std::string branch_to_id(expression_node_ptr (&branch)[2])
  17237. {
  17238. return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]);
  17239. }
  17240. inline bool cov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17241. {
  17242. if (!operation_optimizable(operation))
  17243. return false;
  17244. else
  17245. return (details::is_constant_node(branch[0]) && details::is_variable_node(branch[1]));
  17246. }
  17247. inline bool voc_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17248. {
  17249. if (!operation_optimizable(operation))
  17250. return false;
  17251. else
  17252. return (details::is_variable_node(branch[0]) && details::is_constant_node(branch[1]));
  17253. }
  17254. inline bool vov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17255. {
  17256. if (!operation_optimizable(operation))
  17257. return false;
  17258. else
  17259. return (details::is_variable_node(branch[0]) && details::is_variable_node(branch[1]));
  17260. }
  17261. inline bool cob_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17262. {
  17263. if (!operation_optimizable(operation))
  17264. return false;
  17265. else
  17266. return (details::is_constant_node(branch[0]) && !details::is_constant_node(branch[1]));
  17267. }
  17268. inline bool boc_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17269. {
  17270. if (!operation_optimizable(operation))
  17271. return false;
  17272. else
  17273. return (!details::is_constant_node(branch[0]) && details::is_constant_node(branch[1]));
  17274. }
  17275. inline bool cocob_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17276. {
  17277. if (
  17278. (details::e_add == operation) ||
  17279. (details::e_sub == operation) ||
  17280. (details::e_mul == operation) ||
  17281. (details::e_div == operation)
  17282. )
  17283. {
  17284. return (details::is_constant_node(branch[0]) && details::is_cob_node(branch[1])) ||
  17285. (details::is_constant_node(branch[1]) && details::is_cob_node(branch[0]));
  17286. }
  17287. else
  17288. return false;
  17289. }
  17290. inline bool coboc_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17291. {
  17292. if (
  17293. (details::e_add == operation) ||
  17294. (details::e_sub == operation) ||
  17295. (details::e_mul == operation) ||
  17296. (details::e_div == operation)
  17297. )
  17298. {
  17299. return (details::is_constant_node(branch[0]) && details::is_boc_node(branch[1])) ||
  17300. (details::is_constant_node(branch[1]) && details::is_boc_node(branch[0]));
  17301. }
  17302. else
  17303. return false;
  17304. }
  17305. inline bool uvouv_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17306. {
  17307. if (!operation_optimizable(operation))
  17308. return false;
  17309. else
  17310. return (details::is_uv_node(branch[0]) && details::is_uv_node(branch[1]));
  17311. }
  17312. inline bool vob_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17313. {
  17314. if (!operation_optimizable(operation))
  17315. return false;
  17316. else
  17317. return (details::is_variable_node(branch[0]) && !details::is_variable_node(branch[1]));
  17318. }
  17319. inline bool bov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17320. {
  17321. if (!operation_optimizable(operation))
  17322. return false;
  17323. else
  17324. return (!details::is_variable_node(branch[0]) && details::is_variable_node(branch[1]));
  17325. }
  17326. inline bool binext_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  17327. {
  17328. if (!operation_optimizable(operation))
  17329. return false;
  17330. else
  17331. return (!details::is_constant_node(branch[0]) || !details::is_constant_node(branch[1]));
  17332. }
  17333. inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  17334. {
  17335. if (is_assignment_operation(operation))
  17336. {
  17337. const bool b1_is_genstring = details::is_generally_string_node(branch[1]);
  17338. if (details::is_string_node(branch[0]))
  17339. return !b1_is_genstring;
  17340. else
  17341. return (
  17342. !details::is_variable_node (branch[0]) &&
  17343. !details::is_vector_elem_node(branch[0]) &&
  17344. !details::is_vector_node (branch[0])
  17345. )
  17346. || b1_is_genstring;
  17347. }
  17348. else
  17349. return false;
  17350. }
  17351. inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2])
  17352. {
  17353. return (
  17354. details::is_break_node (branch[0]) ||
  17355. details::is_break_node (branch[1]) ||
  17356. details::is_continue_node(branch[0]) ||
  17357. details::is_continue_node(branch[1])
  17358. );
  17359. }
  17360. inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  17361. {
  17362. const bool b0_string = is_generally_string_node(branch[0]);
  17363. const bool b1_string = is_generally_string_node(branch[1]);
  17364. bool result = false;
  17365. if (b0_string ^ b1_string)
  17366. result = true;
  17367. else if (!valid_string_operation(operation) && b0_string && b1_string)
  17368. result = true;
  17369. if (result)
  17370. {
  17371. parser_->set_synthesis_error("Invalid string operation");
  17372. }
  17373. return result;
  17374. }
  17375. inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  17376. {
  17377. const bool b0_string = is_generally_string_node(branch[0]);
  17378. const bool b1_string = is_generally_string_node(branch[1]);
  17379. const bool b2_string = is_generally_string_node(branch[2]);
  17380. bool result = false;
  17381. if ((b0_string ^ b1_string) || (b1_string ^ b2_string))
  17382. result = true;
  17383. else if ((details::e_inrange != operation) && b0_string && b1_string && b2_string)
  17384. result = true;
  17385. if (result)
  17386. {
  17387. parser_->set_synthesis_error("Invalid string operation");
  17388. }
  17389. return result;
  17390. }
  17391. inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  17392. {
  17393. const bool b0_string = is_generally_string_node(branch[0]);
  17394. const bool b1_string = is_generally_string_node(branch[1]);
  17395. return (b0_string && b1_string && valid_string_operation(operation));
  17396. }
  17397. inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  17398. {
  17399. const bool b0_string = is_generally_string_node(branch[0]);
  17400. const bool b1_string = is_generally_string_node(branch[1]);
  17401. const bool b2_string = is_generally_string_node(branch[2]);
  17402. return (b0_string && b1_string && b2_string && (details::e_inrange == operation));
  17403. }
  17404. #ifndef exprtk_disable_sc_andor
  17405. inline bool is_shortcircuit_expression(const details::operator_type& operation)
  17406. {
  17407. return (
  17408. (details::e_scand == operation) ||
  17409. (details::e_scor == operation)
  17410. );
  17411. }
  17412. #else
  17413. inline bool is_shortcircuit_expression(const details::operator_type&)
  17414. {
  17415. return false;
  17416. }
  17417. #endif
  17418. inline bool is_null_present(expression_node_ptr (&branch)[2])
  17419. {
  17420. return (
  17421. details::is_null_node(branch[0]) ||
  17422. details::is_null_node(branch[1])
  17423. );
  17424. }
  17425. inline bool is_vector_eqineq_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  17426. {
  17427. if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
  17428. return false;
  17429. else
  17430. return (
  17431. (details::e_lt == operation) ||
  17432. (details::e_lte == operation) ||
  17433. (details::e_gt == operation) ||
  17434. (details::e_gte == operation) ||
  17435. (details::e_eq == operation) ||
  17436. (details::e_ne == operation)
  17437. );
  17438. }
  17439. inline bool is_vector_arithmetic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  17440. {
  17441. if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
  17442. return false;
  17443. else
  17444. return (
  17445. (details::e_add == operation) ||
  17446. (details::e_sub == operation) ||
  17447. (details::e_mul == operation) ||
  17448. (details::e_div == operation) ||
  17449. (details::e_pow == operation)
  17450. );
  17451. }
  17452. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  17453. {
  17454. if ((0 == branch[0]) || (0 == branch[1]))
  17455. return error_node();
  17456. else if (is_invalid_string_op(operation,branch))
  17457. return error_node();
  17458. else if (is_invalid_assignment_op(operation,branch))
  17459. return error_node();
  17460. else if (is_invalid_break_continue_op(branch))
  17461. return error_node();
  17462. else if (details::e_assign == operation)
  17463. return synthesize_assignment_expression(operation,branch);
  17464. else if (details::e_swap == operation)
  17465. return synthesize_swap_expression(branch);
  17466. else if (is_assignment_operation(operation))
  17467. return synthesize_assignment_operation_expression(operation,branch);
  17468. else if (is_vector_eqineq_operation(operation,branch))
  17469. return synthesize_veceqineq_operation_expression(operation,branch);
  17470. else if (is_vector_arithmetic_operation(operation,branch))
  17471. return synthesize_vecarithmetic_operation_expression(operation,branch);
  17472. else if (is_shortcircuit_expression(operation))
  17473. return synthesize_shortcircuit_expression(operation,branch);
  17474. else if (is_string_operation(operation,branch))
  17475. return synthesize_string_expression(operation,branch);
  17476. else if (is_null_present(branch))
  17477. return synthesize_null_expression(operation,branch);
  17478. expression_node_ptr result = error_node();
  17479. #ifndef exprtk_disable_enhanced_features
  17480. if (synthesize_expression(operation,branch,result))
  17481. return result;
  17482. else
  17483. #endif
  17484. {
  17485. /*
  17486. Possible reductions:
  17487. 1. c o cob -> cob
  17488. 2. cob o c -> cob
  17489. 3. c o boc -> boc
  17490. 4. boc o c -> boc
  17491. */
  17492. result = error_node();
  17493. if (cocob_optimizable(operation,branch))
  17494. result = synthesize_cocob_expression::process(*this,operation,branch);
  17495. else if (coboc_optimizable(operation,branch) && (0 == result))
  17496. result = synthesize_coboc_expression::process(*this,operation,branch);
  17497. if (result)
  17498. return result;
  17499. }
  17500. if (uvouv_optimizable(operation,branch))
  17501. return synthesize_uvouv_expression(operation,branch);
  17502. else if (vob_optimizable(operation,branch))
  17503. return synthesize_vob_expression::process(*this,operation,branch);
  17504. else if (bov_optimizable(operation,branch))
  17505. return synthesize_bov_expression::process(*this,operation,branch);
  17506. else if (cob_optimizable(operation,branch))
  17507. return synthesize_cob_expression::process(*this,operation,branch);
  17508. else if (boc_optimizable(operation,branch))
  17509. return synthesize_boc_expression::process(*this,operation,branch);
  17510. #ifndef exprtk_disable_enhanced_features
  17511. else if (cov_optimizable(operation,branch))
  17512. return synthesize_cov_expression::process(*this,operation,branch);
  17513. #endif
  17514. else if (binext_optimizable(operation,branch))
  17515. return synthesize_binary_ext_expression::process(*this,operation,branch);
  17516. else
  17517. return synthesize_expression<binary_node_t,2>(operation,branch);
  17518. }
  17519. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  17520. {
  17521. if (
  17522. (0 == branch[0]) ||
  17523. (0 == branch[1]) ||
  17524. (0 == branch[2])
  17525. )
  17526. {
  17527. details::free_all_nodes(*node_allocator_,branch);
  17528. return error_node();
  17529. }
  17530. else if (is_invalid_string_op(operation,branch))
  17531. return error_node();
  17532. else if (is_string_operation(operation,branch))
  17533. return synthesize_string_expression(operation,branch);
  17534. else
  17535. return synthesize_expression<trinary_node_t,3>(operation,branch);
  17536. }
  17537. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  17538. {
  17539. return synthesize_expression<quaternary_node_t,4>(operation,branch);
  17540. }
  17541. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[5])
  17542. {
  17543. return synthesize_expression<quinary_node_t,5>(operation,branch);
  17544. }
  17545. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[6])
  17546. {
  17547. return synthesize_expression<senary_node_t,6>(operation,branch);
  17548. }
  17549. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr b0)
  17550. {
  17551. expression_node_ptr branch[1] = { b0 };
  17552. return (*this)(operation,branch);
  17553. }
  17554. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr b0, expression_node_ptr b1)
  17555. {
  17556. if ((0 == b0) || (0 == b1))
  17557. return error_node();
  17558. else
  17559. {
  17560. expression_node_ptr branch[2] = { b0, b1 };
  17561. return expression_generator<Type>::operator()(operation,branch);
  17562. }
  17563. }
  17564. inline expression_node_ptr conditional(expression_node_ptr condition,
  17565. expression_node_ptr consequent,
  17566. expression_node_ptr alternative) const
  17567. {
  17568. if ((0 == condition) || (0 == consequent))
  17569. {
  17570. free_node(*node_allocator_,condition );
  17571. free_node(*node_allocator_,consequent );
  17572. free_node(*node_allocator_,alternative);
  17573. return error_node();
  17574. }
  17575. // Can the condition be immediately evaluated? if so optimize.
  17576. else if (details::is_constant_node(condition))
  17577. {
  17578. // True branch
  17579. if (details::is_true(condition))
  17580. {
  17581. free_node(*node_allocator_,condition );
  17582. free_node(*node_allocator_,alternative);
  17583. return consequent;
  17584. }
  17585. // False branch
  17586. else
  17587. {
  17588. free_node(*node_allocator_,condition);
  17589. free_node(*node_allocator_,consequent);
  17590. if (alternative)
  17591. return alternative;
  17592. else
  17593. return node_allocator_->allocate<details::null_node<T> >();
  17594. }
  17595. }
  17596. else if ((0 != consequent) && (0 != alternative))
  17597. {
  17598. return node_allocator_->allocate<conditional_node_t>(condition,consequent,alternative);
  17599. }
  17600. else
  17601. return node_allocator_->allocate<cons_conditional_node_t>(condition,consequent);
  17602. }
  17603. inline expression_node_ptr while_loop(expression_node_ptr& condition,
  17604. expression_node_ptr& branch,
  17605. const bool brkcont = false) const
  17606. {
  17607. if (!brkcont && details::is_constant_node(condition))
  17608. {
  17609. expression_node_ptr result = error_node();
  17610. if (details::is_true(condition))
  17611. // Infinite loops are not allowed.
  17612. result = error_node();
  17613. else
  17614. result = node_allocator_->allocate<details::null_node<Type> >();
  17615. free_node(*node_allocator_, condition);
  17616. free_node(*node_allocator_, branch );
  17617. return result;
  17618. }
  17619. else if (details::is_null_node(condition))
  17620. {
  17621. free_node(*node_allocator_,condition);
  17622. return branch;
  17623. }
  17624. else if (!brkcont)
  17625. return node_allocator_->allocate<while_loop_node_t>(condition,branch);
  17626. #ifndef exprtk_disable_break_continue
  17627. else
  17628. return node_allocator_->allocate<while_loop_bc_node_t>(condition,branch);
  17629. #else
  17630. return error_node();
  17631. #endif
  17632. }
  17633. inline expression_node_ptr repeat_until_loop(expression_node_ptr& condition,
  17634. expression_node_ptr& branch,
  17635. const bool brkcont = false) const
  17636. {
  17637. if (!brkcont && details::is_constant_node(condition))
  17638. {
  17639. if (details::is_true(condition) && details::is_constant_node(branch))
  17640. {
  17641. free_node(*node_allocator_,condition);
  17642. return branch;
  17643. }
  17644. free_node(*node_allocator_, condition);
  17645. free_node(*node_allocator_, branch );
  17646. return error_node();
  17647. }
  17648. else if (details::is_null_node(condition))
  17649. {
  17650. free_node(*node_allocator_,condition);
  17651. return branch;
  17652. }
  17653. else if (!brkcont)
  17654. return node_allocator_->allocate<repeat_until_loop_node_t>(condition,branch);
  17655. #ifndef exprtk_disable_break_continue
  17656. else
  17657. return node_allocator_->allocate<repeat_until_loop_bc_node_t>(condition,branch);
  17658. #else
  17659. return error_node();
  17660. #endif
  17661. }
  17662. inline expression_node_ptr for_loop(expression_node_ptr& initialiser,
  17663. expression_node_ptr& condition,
  17664. expression_node_ptr& incrementor,
  17665. expression_node_ptr& loop_body,
  17666. bool brkcont = false) const
  17667. {
  17668. if (!brkcont && details::is_constant_node(condition))
  17669. {
  17670. expression_node_ptr result = error_node();
  17671. if (details::is_true(condition))
  17672. // Infinite loops are not allowed.
  17673. result = error_node();
  17674. else
  17675. result = node_allocator_->allocate<details::null_node<Type> >();
  17676. free_node(*node_allocator_,initialiser);
  17677. free_node(*node_allocator_,condition );
  17678. free_node(*node_allocator_,incrementor);
  17679. free_node(*node_allocator_,loop_body );
  17680. return result;
  17681. }
  17682. else if (details::is_null_node(condition))
  17683. {
  17684. free_node(*node_allocator_,initialiser);
  17685. free_node(*node_allocator_,condition );
  17686. free_node(*node_allocator_,incrementor);
  17687. return loop_body;
  17688. }
  17689. else if (!brkcont)
  17690. return node_allocator_->allocate<for_loop_node_t>(initialiser,
  17691. condition,
  17692. incrementor,
  17693. loop_body);
  17694. #ifndef exprtk_disable_break_continue
  17695. else
  17696. return node_allocator_->allocate<for_loop_bc_node_t>(initialiser,
  17697. condition,
  17698. incrementor,
  17699. loop_body);
  17700. #else
  17701. return error_node();
  17702. #endif
  17703. }
  17704. template <typename Allocator,
  17705. template <typename,typename> class Sequence>
  17706. inline expression_node_ptr const_optimize_switch(Sequence<expression_node_ptr,Allocator>& arg_list)
  17707. {
  17708. expression_node_ptr result = error_node();
  17709. for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
  17710. {
  17711. expression_node_ptr condition = arg_list[(2 * i) ];
  17712. expression_node_ptr consequent = arg_list[(2 * i) + 1];
  17713. if ((0 == result) && details::is_true(condition))
  17714. {
  17715. result = consequent;
  17716. break;
  17717. }
  17718. }
  17719. if (0 == result)
  17720. {
  17721. result = arg_list.back();
  17722. }
  17723. for (std::size_t i = 0; i < arg_list.size(); ++i)
  17724. {
  17725. expression_node_ptr current_expr = arg_list[i];
  17726. if (current_expr && (current_expr != result))
  17727. {
  17728. free_node(*node_allocator_,current_expr);
  17729. }
  17730. }
  17731. return result;
  17732. }
  17733. template <typename Allocator,
  17734. template <typename,typename> class Sequence>
  17735. inline expression_node_ptr const_optimize_mswitch(Sequence<expression_node_ptr,Allocator>& arg_list)
  17736. {
  17737. expression_node_ptr result = error_node();
  17738. for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
  17739. {
  17740. expression_node_ptr condition = arg_list[(2 * i) ];
  17741. expression_node_ptr consequent = arg_list[(2 * i) + 1];
  17742. if (details::is_true(condition))
  17743. {
  17744. result = consequent;
  17745. }
  17746. }
  17747. if (0 == result)
  17748. {
  17749. T zero = T(0);
  17750. result = node_allocator_->allocate<literal_node_t>(zero);
  17751. }
  17752. for (std::size_t i = 0; i < arg_list.size(); ++i)
  17753. {
  17754. expression_node_ptr& current_expr = arg_list[i];
  17755. if (current_expr && (current_expr != result))
  17756. {
  17757. free_node(*node_allocator_,current_expr);
  17758. }
  17759. }
  17760. return result;
  17761. }
  17762. template <typename Allocator,
  17763. template <typename,typename> class Sequence>
  17764. inline expression_node_ptr switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list)
  17765. {
  17766. if (!all_nodes_valid(arg_list))
  17767. {
  17768. details::free_all_nodes(*node_allocator_,arg_list);
  17769. return error_node();
  17770. }
  17771. else if (is_constant_foldable(arg_list))
  17772. return const_optimize_switch(arg_list);
  17773. else
  17774. return node_allocator_->allocate<details::switch_node<Type> >(arg_list);
  17775. }
  17776. template <typename Allocator,
  17777. template <typename,typename> class Sequence>
  17778. inline expression_node_ptr multi_switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list)
  17779. {
  17780. if (!all_nodes_valid(arg_list))
  17781. {
  17782. details::free_all_nodes(*node_allocator_,arg_list);
  17783. return error_node();
  17784. }
  17785. else if (is_constant_foldable(arg_list))
  17786. return const_optimize_mswitch(arg_list);
  17787. else
  17788. return node_allocator_->allocate<details::multi_switch_node<Type> >(arg_list);
  17789. }
  17790. #define unary_opr_switch_statements \
  17791. case_stmt(details:: e_abs,details:: abs_op) \
  17792. case_stmt(details:: e_acos,details:: acos_op) \
  17793. case_stmt(details::e_acosh,details::acosh_op) \
  17794. case_stmt(details:: e_asin,details:: asin_op) \
  17795. case_stmt(details::e_asinh,details::asinh_op) \
  17796. case_stmt(details:: e_atan,details:: atan_op) \
  17797. case_stmt(details::e_atanh,details::atanh_op) \
  17798. case_stmt(details:: e_ceil,details:: ceil_op) \
  17799. case_stmt(details:: e_cos,details:: cos_op) \
  17800. case_stmt(details:: e_cosh,details:: cosh_op) \
  17801. case_stmt(details:: e_exp,details:: exp_op) \
  17802. case_stmt(details::e_expm1,details::expm1_op) \
  17803. case_stmt(details::e_floor,details::floor_op) \
  17804. case_stmt(details:: e_log,details:: log_op) \
  17805. case_stmt(details::e_log10,details::log10_op) \
  17806. case_stmt(details:: e_log2,details:: log2_op) \
  17807. case_stmt(details::e_log1p,details::log1p_op) \
  17808. case_stmt(details:: e_neg,details:: neg_op) \
  17809. case_stmt(details:: e_pos,details:: pos_op) \
  17810. case_stmt(details::e_round,details::round_op) \
  17811. case_stmt(details:: e_sin,details:: sin_op) \
  17812. case_stmt(details:: e_sinc,details:: sinc_op) \
  17813. case_stmt(details:: e_sinh,details:: sinh_op) \
  17814. case_stmt(details:: e_sqrt,details:: sqrt_op) \
  17815. case_stmt(details:: e_tan,details:: tan_op) \
  17816. case_stmt(details:: e_tanh,details:: tanh_op) \
  17817. case_stmt(details:: e_cot,details:: cot_op) \
  17818. case_stmt(details:: e_sec,details:: sec_op) \
  17819. case_stmt(details:: e_csc,details:: csc_op) \
  17820. case_stmt(details:: e_r2d,details:: r2d_op) \
  17821. case_stmt(details:: e_d2r,details:: d2r_op) \
  17822. case_stmt(details:: e_d2g,details:: d2g_op) \
  17823. case_stmt(details:: e_g2d,details:: g2d_op) \
  17824. case_stmt(details:: e_notl,details:: notl_op) \
  17825. case_stmt(details:: e_sgn,details:: sgn_op) \
  17826. case_stmt(details:: e_erf,details:: erf_op) \
  17827. case_stmt(details:: e_erfc,details:: erfc_op) \
  17828. case_stmt(details:: e_ncdf,details:: ncdf_op) \
  17829. case_stmt(details:: e_frac,details:: frac_op) \
  17830. case_stmt(details::e_trunc,details::trunc_op) \
  17831. inline expression_node_ptr synthesize_uv_expression(const details::operator_type& operation,
  17832. expression_node_ptr (&branch)[1])
  17833. {
  17834. T& v = static_cast<details::variable_node<T>*>(branch[0])->ref();
  17835. switch (operation)
  17836. {
  17837. #define case_stmt(op0,op1) \
  17838. case op0 : return node_allocator_-> \
  17839. allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \
  17840. unary_opr_switch_statements
  17841. #undef case_stmt
  17842. default : return error_node();
  17843. }
  17844. }
  17845. inline expression_node_ptr synthesize_uvec_expression(const details::operator_type& operation,
  17846. expression_node_ptr (&branch)[1])
  17847. {
  17848. switch (operation)
  17849. {
  17850. #define case_stmt(op0,op1) \
  17851. case op0 : return node_allocator_-> \
  17852. allocate<typename details::unary_vector_node<Type,op1<Type> > > \
  17853. (operation,branch[0]); \
  17854. unary_opr_switch_statements
  17855. #undef case_stmt
  17856. default : return error_node();
  17857. }
  17858. }
  17859. inline expression_node_ptr synthesize_unary_expression(const details::operator_type& operation,
  17860. expression_node_ptr (&branch)[1])
  17861. {
  17862. switch (operation)
  17863. {
  17864. #define case_stmt(op0,op1) \
  17865. case op0 : return node_allocator_-> \
  17866. allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \
  17867. unary_opr_switch_statements
  17868. #undef case_stmt
  17869. default : return error_node();
  17870. }
  17871. }
  17872. inline expression_node_ptr const_optimize_sf3(const details::operator_type& operation,
  17873. expression_node_ptr (&branch)[3])
  17874. {
  17875. expression_node_ptr temp_node = error_node();
  17876. switch (operation)
  17877. {
  17878. #define case_stmt(op0,op1) \
  17879. case op0 : temp_node = node_allocator_-> \
  17880. allocate<details::sf3_node<Type,op1<Type> > > \
  17881. (operation,branch); \
  17882. break; \
  17883. case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
  17884. case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
  17885. case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
  17886. case_stmt(details::e_sf06,details::sf06_op) case_stmt(details::e_sf07,details::sf07_op)
  17887. case_stmt(details::e_sf08,details::sf08_op) case_stmt(details::e_sf09,details::sf09_op)
  17888. case_stmt(details::e_sf10,details::sf10_op) case_stmt(details::e_sf11,details::sf11_op)
  17889. case_stmt(details::e_sf12,details::sf12_op) case_stmt(details::e_sf13,details::sf13_op)
  17890. case_stmt(details::e_sf14,details::sf14_op) case_stmt(details::e_sf15,details::sf15_op)
  17891. case_stmt(details::e_sf16,details::sf16_op) case_stmt(details::e_sf17,details::sf17_op)
  17892. case_stmt(details::e_sf18,details::sf18_op) case_stmt(details::e_sf19,details::sf19_op)
  17893. case_stmt(details::e_sf20,details::sf20_op) case_stmt(details::e_sf21,details::sf21_op)
  17894. case_stmt(details::e_sf22,details::sf22_op) case_stmt(details::e_sf23,details::sf23_op)
  17895. case_stmt(details::e_sf24,details::sf24_op) case_stmt(details::e_sf25,details::sf25_op)
  17896. case_stmt(details::e_sf26,details::sf26_op) case_stmt(details::e_sf27,details::sf27_op)
  17897. case_stmt(details::e_sf28,details::sf28_op) case_stmt(details::e_sf29,details::sf29_op)
  17898. case_stmt(details::e_sf30,details::sf30_op) case_stmt(details::e_sf31,details::sf31_op)
  17899. case_stmt(details::e_sf32,details::sf32_op) case_stmt(details::e_sf33,details::sf33_op)
  17900. case_stmt(details::e_sf34,details::sf34_op) case_stmt(details::e_sf35,details::sf35_op)
  17901. case_stmt(details::e_sf36,details::sf36_op) case_stmt(details::e_sf37,details::sf37_op)
  17902. case_stmt(details::e_sf38,details::sf38_op) case_stmt(details::e_sf39,details::sf39_op)
  17903. case_stmt(details::e_sf40,details::sf40_op) case_stmt(details::e_sf41,details::sf41_op)
  17904. case_stmt(details::e_sf42,details::sf42_op) case_stmt(details::e_sf43,details::sf43_op)
  17905. case_stmt(details::e_sf44,details::sf44_op) case_stmt(details::e_sf45,details::sf45_op)
  17906. case_stmt(details::e_sf46,details::sf46_op) case_stmt(details::e_sf47,details::sf47_op)
  17907. #undef case_stmt
  17908. default : return error_node();
  17909. }
  17910. T v = temp_node->value();
  17911. node_allocator_->free(temp_node);
  17912. details::free_node(*node_allocator_,temp_node);
  17913. return node_allocator_->allocate<literal_node_t>(v);
  17914. }
  17915. inline expression_node_ptr varnode_optimize_sf3(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  17916. {
  17917. typedef details::variable_node<Type>* variable_ptr;
  17918. const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
  17919. const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
  17920. const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
  17921. switch (operation)
  17922. {
  17923. #define case_stmt(op0,op1) \
  17924. case op0 : return node_allocator_-> \
  17925. allocate_rrr<details::sf3_var_node<Type,op1<Type> > > \
  17926. (v0,v1,v2); \
  17927. case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
  17928. case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
  17929. case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
  17930. case_stmt(details::e_sf06,details::sf06_op) case_stmt(details::e_sf07,details::sf07_op)
  17931. case_stmt(details::e_sf08,details::sf08_op) case_stmt(details::e_sf09,details::sf09_op)
  17932. case_stmt(details::e_sf10,details::sf10_op) case_stmt(details::e_sf11,details::sf11_op)
  17933. case_stmt(details::e_sf12,details::sf12_op) case_stmt(details::e_sf13,details::sf13_op)
  17934. case_stmt(details::e_sf14,details::sf14_op) case_stmt(details::e_sf15,details::sf15_op)
  17935. case_stmt(details::e_sf16,details::sf16_op) case_stmt(details::e_sf17,details::sf17_op)
  17936. case_stmt(details::e_sf18,details::sf18_op) case_stmt(details::e_sf19,details::sf19_op)
  17937. case_stmt(details::e_sf20,details::sf20_op) case_stmt(details::e_sf21,details::sf21_op)
  17938. case_stmt(details::e_sf22,details::sf22_op) case_stmt(details::e_sf23,details::sf23_op)
  17939. case_stmt(details::e_sf24,details::sf24_op) case_stmt(details::e_sf25,details::sf25_op)
  17940. case_stmt(details::e_sf26,details::sf26_op) case_stmt(details::e_sf27,details::sf27_op)
  17941. case_stmt(details::e_sf28,details::sf28_op) case_stmt(details::e_sf29,details::sf29_op)
  17942. case_stmt(details::e_sf30,details::sf30_op) case_stmt(details::e_sf31,details::sf31_op)
  17943. case_stmt(details::e_sf32,details::sf32_op) case_stmt(details::e_sf33,details::sf33_op)
  17944. case_stmt(details::e_sf34,details::sf34_op) case_stmt(details::e_sf35,details::sf35_op)
  17945. case_stmt(details::e_sf36,details::sf36_op) case_stmt(details::e_sf37,details::sf37_op)
  17946. case_stmt(details::e_sf38,details::sf38_op) case_stmt(details::e_sf39,details::sf39_op)
  17947. case_stmt(details::e_sf40,details::sf40_op) case_stmt(details::e_sf41,details::sf41_op)
  17948. case_stmt(details::e_sf42,details::sf42_op) case_stmt(details::e_sf43,details::sf43_op)
  17949. case_stmt(details::e_sf44,details::sf44_op) case_stmt(details::e_sf45,details::sf45_op)
  17950. case_stmt(details::e_sf46,details::sf46_op) case_stmt(details::e_sf47,details::sf47_op)
  17951. #undef case_stmt
  17952. default : return error_node();
  17953. }
  17954. }
  17955. inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  17956. {
  17957. if (!all_nodes_valid(branch))
  17958. return error_node();
  17959. else if (is_constant_foldable(branch))
  17960. return const_optimize_sf3(operation,branch);
  17961. else if (all_nodes_variables(branch))
  17962. return varnode_optimize_sf3(operation,branch);
  17963. else
  17964. {
  17965. switch (operation)
  17966. {
  17967. #define case_stmt(op0,op1) \
  17968. case op0 : return node_allocator_-> \
  17969. allocate<details::sf3_node<Type,op1<Type> > >(operation,branch); \
  17970. case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
  17971. case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
  17972. case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
  17973. case_stmt(details::e_sf06,details::sf06_op) case_stmt(details::e_sf07,details::sf07_op)
  17974. case_stmt(details::e_sf08,details::sf08_op) case_stmt(details::e_sf09,details::sf09_op)
  17975. case_stmt(details::e_sf10,details::sf10_op) case_stmt(details::e_sf11,details::sf11_op)
  17976. case_stmt(details::e_sf12,details::sf12_op) case_stmt(details::e_sf13,details::sf13_op)
  17977. case_stmt(details::e_sf14,details::sf14_op) case_stmt(details::e_sf15,details::sf15_op)
  17978. case_stmt(details::e_sf16,details::sf16_op) case_stmt(details::e_sf17,details::sf17_op)
  17979. case_stmt(details::e_sf18,details::sf18_op) case_stmt(details::e_sf19,details::sf19_op)
  17980. case_stmt(details::e_sf20,details::sf20_op) case_stmt(details::e_sf21,details::sf21_op)
  17981. case_stmt(details::e_sf22,details::sf22_op) case_stmt(details::e_sf23,details::sf23_op)
  17982. case_stmt(details::e_sf24,details::sf24_op) case_stmt(details::e_sf25,details::sf25_op)
  17983. case_stmt(details::e_sf26,details::sf26_op) case_stmt(details::e_sf27,details::sf27_op)
  17984. case_stmt(details::e_sf28,details::sf28_op) case_stmt(details::e_sf29,details::sf29_op)
  17985. case_stmt(details::e_sf30,details::sf30_op) case_stmt(details::e_sf31,details::sf31_op)
  17986. case_stmt(details::e_sf32,details::sf32_op) case_stmt(details::e_sf33,details::sf33_op)
  17987. case_stmt(details::e_sf34,details::sf34_op) case_stmt(details::e_sf35,details::sf35_op)
  17988. case_stmt(details::e_sf36,details::sf36_op) case_stmt(details::e_sf37,details::sf37_op)
  17989. case_stmt(details::e_sf38,details::sf38_op) case_stmt(details::e_sf39,details::sf39_op)
  17990. case_stmt(details::e_sf40,details::sf40_op) case_stmt(details::e_sf41,details::sf41_op)
  17991. case_stmt(details::e_sf42,details::sf42_op) case_stmt(details::e_sf43,details::sf43_op)
  17992. case_stmt(details::e_sf44,details::sf44_op) case_stmt(details::e_sf45,details::sf45_op)
  17993. case_stmt(details::e_sf46,details::sf46_op) case_stmt(details::e_sf47,details::sf47_op)
  17994. #undef case_stmt
  17995. default : return error_node();
  17996. }
  17997. }
  17998. }
  17999. inline expression_node_ptr const_optimize_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  18000. {
  18001. expression_node_ptr temp_node = error_node();
  18002. switch (operation)
  18003. {
  18004. #define case_stmt(op0,op1) \
  18005. case op0 : temp_node = node_allocator_-> \
  18006. allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); \
  18007. break; \
  18008. case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf49,details::sf49_op)
  18009. case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf51,details::sf51_op)
  18010. case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf53,details::sf53_op)
  18011. case_stmt(details::e_sf54,details::sf54_op) case_stmt(details::e_sf55,details::sf55_op)
  18012. case_stmt(details::e_sf56,details::sf56_op) case_stmt(details::e_sf57,details::sf57_op)
  18013. case_stmt(details::e_sf58,details::sf58_op) case_stmt(details::e_sf59,details::sf59_op)
  18014. case_stmt(details::e_sf60,details::sf60_op) case_stmt(details::e_sf61,details::sf61_op)
  18015. case_stmt(details::e_sf62,details::sf62_op) case_stmt(details::e_sf63,details::sf63_op)
  18016. case_stmt(details::e_sf64,details::sf64_op) case_stmt(details::e_sf65,details::sf65_op)
  18017. case_stmt(details::e_sf66,details::sf66_op) case_stmt(details::e_sf67,details::sf67_op)
  18018. case_stmt(details::e_sf68,details::sf68_op) case_stmt(details::e_sf69,details::sf69_op)
  18019. case_stmt(details::e_sf70,details::sf70_op) case_stmt(details::e_sf71,details::sf71_op)
  18020. case_stmt(details::e_sf72,details::sf72_op) case_stmt(details::e_sf73,details::sf73_op)
  18021. case_stmt(details::e_sf74,details::sf74_op) case_stmt(details::e_sf75,details::sf75_op)
  18022. case_stmt(details::e_sf76,details::sf76_op) case_stmt(details::e_sf77,details::sf77_op)
  18023. case_stmt(details::e_sf78,details::sf78_op) case_stmt(details::e_sf79,details::sf79_op)
  18024. case_stmt(details::e_sf80,details::sf80_op) case_stmt(details::e_sf81,details::sf81_op)
  18025. case_stmt(details::e_sf82,details::sf82_op) case_stmt(details::e_sf83,details::sf83_op)
  18026. case_stmt(details::e_sf84,details::sf84_op) case_stmt(details::e_sf85,details::sf85_op)
  18027. case_stmt(details::e_sf86,details::sf86_op) case_stmt(details::e_sf87,details::sf87_op)
  18028. case_stmt(details::e_sf88,details::sf88_op) case_stmt(details::e_sf89,details::sf89_op)
  18029. case_stmt(details::e_sf90,details::sf90_op) case_stmt(details::e_sf91,details::sf91_op)
  18030. case_stmt(details::e_sf92,details::sf92_op) case_stmt(details::e_sf93,details::sf93_op)
  18031. case_stmt(details::e_sf94,details::sf94_op) case_stmt(details::e_sf95,details::sf95_op)
  18032. case_stmt(details::e_sf96,details::sf96_op) case_stmt(details::e_sf97,details::sf97_op)
  18033. case_stmt(details::e_sf98,details::sf98_op) case_stmt(details::e_sf99,details::sf99_op)
  18034. #undef case_stmt
  18035. default : return error_node();
  18036. }
  18037. T v = temp_node->value();
  18038. details::free_node(*node_allocator_,temp_node);
  18039. return node_allocator_->allocate<literal_node_t>(v);
  18040. }
  18041. inline expression_node_ptr varnode_optimize_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  18042. {
  18043. typedef details::variable_node<Type>* variable_ptr;
  18044. const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
  18045. const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
  18046. const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
  18047. const Type& v3 = static_cast<variable_ptr>(branch[3])->ref();
  18048. switch (operation)
  18049. {
  18050. #define case_stmt(op0,op1) \
  18051. case op0 : return node_allocator_-> \
  18052. allocate_rrrr<details::sf4_var_node<Type,op1<Type> > >(v0,v1,v2,v3); \
  18053. case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf49,details::sf49_op)
  18054. case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf51,details::sf51_op)
  18055. case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf53,details::sf53_op)
  18056. case_stmt(details::e_sf54,details::sf54_op) case_stmt(details::e_sf55,details::sf55_op)
  18057. case_stmt(details::e_sf56,details::sf56_op) case_stmt(details::e_sf57,details::sf57_op)
  18058. case_stmt(details::e_sf58,details::sf58_op) case_stmt(details::e_sf59,details::sf59_op)
  18059. case_stmt(details::e_sf60,details::sf60_op) case_stmt(details::e_sf61,details::sf61_op)
  18060. case_stmt(details::e_sf62,details::sf62_op) case_stmt(details::e_sf63,details::sf63_op)
  18061. case_stmt(details::e_sf64,details::sf64_op) case_stmt(details::e_sf65,details::sf65_op)
  18062. case_stmt(details::e_sf66,details::sf66_op) case_stmt(details::e_sf67,details::sf67_op)
  18063. case_stmt(details::e_sf68,details::sf68_op) case_stmt(details::e_sf69,details::sf69_op)
  18064. case_stmt(details::e_sf70,details::sf70_op) case_stmt(details::e_sf71,details::sf71_op)
  18065. case_stmt(details::e_sf72,details::sf72_op) case_stmt(details::e_sf73,details::sf73_op)
  18066. case_stmt(details::e_sf74,details::sf74_op) case_stmt(details::e_sf75,details::sf75_op)
  18067. case_stmt(details::e_sf76,details::sf76_op) case_stmt(details::e_sf77,details::sf77_op)
  18068. case_stmt(details::e_sf78,details::sf78_op) case_stmt(details::e_sf79,details::sf79_op)
  18069. case_stmt(details::e_sf80,details::sf80_op) case_stmt(details::e_sf81,details::sf81_op)
  18070. case_stmt(details::e_sf82,details::sf82_op) case_stmt(details::e_sf83,details::sf83_op)
  18071. case_stmt(details::e_sf84,details::sf84_op) case_stmt(details::e_sf85,details::sf85_op)
  18072. case_stmt(details::e_sf86,details::sf86_op) case_stmt(details::e_sf87,details::sf87_op)
  18073. case_stmt(details::e_sf88,details::sf88_op) case_stmt(details::e_sf89,details::sf89_op)
  18074. case_stmt(details::e_sf90,details::sf90_op) case_stmt(details::e_sf91,details::sf91_op)
  18075. case_stmt(details::e_sf92,details::sf92_op) case_stmt(details::e_sf93,details::sf93_op)
  18076. case_stmt(details::e_sf94,details::sf94_op) case_stmt(details::e_sf95,details::sf95_op)
  18077. case_stmt(details::e_sf96,details::sf96_op) case_stmt(details::e_sf97,details::sf97_op)
  18078. case_stmt(details::e_sf98,details::sf98_op) case_stmt(details::e_sf99,details::sf99_op)
  18079. #undef case_stmt
  18080. default : return error_node();
  18081. }
  18082. }
  18083. inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  18084. {
  18085. if (!all_nodes_valid(branch))
  18086. return error_node();
  18087. else if (is_constant_foldable(branch))
  18088. return const_optimize_sf4(operation,branch);
  18089. else if (all_nodes_variables(branch))
  18090. return varnode_optimize_sf4(operation,branch);
  18091. switch (operation)
  18092. {
  18093. #define case_stmt(op0,op1) \
  18094. case op0 : return node_allocator_-> \
  18095. allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); \
  18096. case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf49,details::sf49_op)
  18097. case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf51,details::sf51_op)
  18098. case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf53,details::sf53_op)
  18099. case_stmt(details::e_sf54,details::sf54_op) case_stmt(details::e_sf55,details::sf55_op)
  18100. case_stmt(details::e_sf56,details::sf56_op) case_stmt(details::e_sf57,details::sf57_op)
  18101. case_stmt(details::e_sf58,details::sf58_op) case_stmt(details::e_sf59,details::sf59_op)
  18102. case_stmt(details::e_sf60,details::sf60_op) case_stmt(details::e_sf61,details::sf61_op)
  18103. case_stmt(details::e_sf62,details::sf62_op) case_stmt(details::e_sf63,details::sf63_op)
  18104. case_stmt(details::e_sf64,details::sf64_op) case_stmt(details::e_sf65,details::sf65_op)
  18105. case_stmt(details::e_sf66,details::sf66_op) case_stmt(details::e_sf67,details::sf67_op)
  18106. case_stmt(details::e_sf68,details::sf68_op) case_stmt(details::e_sf69,details::sf69_op)
  18107. case_stmt(details::e_sf70,details::sf70_op) case_stmt(details::e_sf71,details::sf71_op)
  18108. case_stmt(details::e_sf72,details::sf72_op) case_stmt(details::e_sf73,details::sf73_op)
  18109. case_stmt(details::e_sf74,details::sf74_op) case_stmt(details::e_sf75,details::sf75_op)
  18110. case_stmt(details::e_sf76,details::sf76_op) case_stmt(details::e_sf77,details::sf77_op)
  18111. case_stmt(details::e_sf78,details::sf78_op) case_stmt(details::e_sf79,details::sf79_op)
  18112. case_stmt(details::e_sf80,details::sf80_op) case_stmt(details::e_sf81,details::sf81_op)
  18113. case_stmt(details::e_sf82,details::sf82_op) case_stmt(details::e_sf83,details::sf83_op)
  18114. case_stmt(details::e_sf84,details::sf84_op) case_stmt(details::e_sf85,details::sf85_op)
  18115. case_stmt(details::e_sf86,details::sf86_op) case_stmt(details::e_sf87,details::sf87_op)
  18116. case_stmt(details::e_sf88,details::sf88_op) case_stmt(details::e_sf89,details::sf89_op)
  18117. case_stmt(details::e_sf90,details::sf90_op) case_stmt(details::e_sf91,details::sf91_op)
  18118. case_stmt(details::e_sf92,details::sf92_op) case_stmt(details::e_sf93,details::sf93_op)
  18119. case_stmt(details::e_sf94,details::sf94_op) case_stmt(details::e_sf95,details::sf95_op)
  18120. case_stmt(details::e_sf96,details::sf96_op) case_stmt(details::e_sf97,details::sf97_op)
  18121. case_stmt(details::e_sf98,details::sf98_op) case_stmt(details::e_sf99,details::sf99_op)
  18122. #undef case_stmt
  18123. default : return error_node();
  18124. }
  18125. }
  18126. template <typename Allocator,
  18127. template <typename,typename> class Sequence>
  18128. inline expression_node_ptr const_optimize_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
  18129. {
  18130. expression_node_ptr temp_node = error_node();
  18131. switch (operation)
  18132. {
  18133. #define case_stmt(op0,op1) \
  18134. case op0 : temp_node = node_allocator_-> \
  18135. allocate<details::vararg_node<Type,op1<Type> > > \
  18136. (arg_list); \
  18137. break; \
  18138. case_stmt(details::e_sum, details::vararg_add_op )
  18139. case_stmt(details::e_prod, details::vararg_mul_op )
  18140. case_stmt(details::e_avg, details::vararg_avg_op )
  18141. case_stmt(details::e_min, details::vararg_min_op )
  18142. case_stmt(details::e_max, details::vararg_max_op )
  18143. case_stmt(details::e_mand, details::vararg_mand_op )
  18144. case_stmt(details::e_mor, details::vararg_mor_op )
  18145. case_stmt(details::e_multi,details::vararg_multi_op)
  18146. #undef case_stmt
  18147. default : return error_node();
  18148. }
  18149. T v = temp_node->value();
  18150. details::free_node(*node_allocator_,temp_node);
  18151. return node_allocator_->allocate<literal_node_t>(v);
  18152. }
  18153. inline bool special_one_parameter_vararg(const details::operator_type& operation)
  18154. {
  18155. return (
  18156. (details::e_sum == operation) ||
  18157. (details::e_prod == operation) ||
  18158. (details::e_avg == operation) ||
  18159. (details::e_min == operation) ||
  18160. (details::e_max == operation)
  18161. );
  18162. }
  18163. template <typename Allocator,
  18164. template <typename,typename> class Sequence>
  18165. inline expression_node_ptr varnode_optimize_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
  18166. {
  18167. switch (operation)
  18168. {
  18169. #define case_stmt(op0,op1) \
  18170. case op0 : return node_allocator_-> \
  18171. allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \
  18172. case_stmt(details::e_sum, details::vararg_add_op )
  18173. case_stmt(details::e_prod, details::vararg_mul_op )
  18174. case_stmt(details::e_avg, details::vararg_avg_op )
  18175. case_stmt(details::e_min, details::vararg_min_op )
  18176. case_stmt(details::e_max, details::vararg_max_op )
  18177. case_stmt(details::e_mand, details::vararg_mand_op )
  18178. case_stmt(details::e_mor, details::vararg_mor_op )
  18179. case_stmt(details::e_multi,details::vararg_multi_op)
  18180. #undef case_stmt
  18181. default : return error_node();
  18182. }
  18183. }
  18184. template <typename Allocator,
  18185. template <typename,typename> class Sequence>
  18186. inline expression_node_ptr vectorize_func(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
  18187. {
  18188. if (1 == arg_list.size())
  18189. {
  18190. switch (operation)
  18191. {
  18192. #define case_stmt(op0,op1) \
  18193. case op0 : return node_allocator_-> \
  18194. allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \
  18195. case_stmt(details::e_sum, details::vec_add_op)
  18196. case_stmt(details::e_prod, details::vec_mul_op)
  18197. case_stmt(details::e_avg, details::vec_avg_op)
  18198. case_stmt(details::e_min, details::vec_min_op)
  18199. case_stmt(details::e_max, details::vec_max_op)
  18200. #undef case_stmt
  18201. default : return error_node();
  18202. }
  18203. }
  18204. else
  18205. return error_node();
  18206. }
  18207. template <typename Allocator,
  18208. template <typename,typename> class Sequence>
  18209. inline expression_node_ptr vararg_function(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
  18210. {
  18211. if (!all_nodes_valid(arg_list))
  18212. {
  18213. details::free_all_nodes(*node_allocator_,arg_list);
  18214. return error_node();
  18215. }
  18216. else if (is_constant_foldable(arg_list))
  18217. return const_optimize_varargfunc(operation,arg_list);
  18218. else if ((arg_list.size() == 1) && details::is_ivector_node(arg_list[0]))
  18219. return vectorize_func(operation,arg_list);
  18220. else if ((arg_list.size() == 1) && special_one_parameter_vararg(operation))
  18221. return arg_list[0];
  18222. else if (all_nodes_variables(arg_list))
  18223. return varnode_optimize_varargfunc(operation,arg_list);
  18224. switch (operation)
  18225. {
  18226. #define case_stmt(op0,op1) \
  18227. case op0 : return node_allocator_-> \
  18228. allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
  18229. case_stmt(details::e_sum, details::vararg_add_op )
  18230. case_stmt(details::e_prod, details::vararg_mul_op )
  18231. case_stmt(details::e_avg, details::vararg_avg_op )
  18232. case_stmt(details::e_min, details::vararg_min_op )
  18233. case_stmt(details::e_max, details::vararg_max_op )
  18234. case_stmt(details::e_mand, details::vararg_mand_op )
  18235. case_stmt(details::e_mor, details::vararg_mor_op )
  18236. case_stmt(details::e_multi,details::vararg_multi_op)
  18237. #undef case_stmt
  18238. default : return error_node();
  18239. }
  18240. }
  18241. template <std::size_t N>
  18242. inline expression_node_ptr function(ifunction_t* f, expression_node_ptr (&b)[N])
  18243. {
  18244. typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
  18245. expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b);
  18246. if (0 == result)
  18247. return error_node();
  18248. else
  18249. {
  18250. // Can the function call be completely optimized?
  18251. if (details::is_constant_node(result))
  18252. return result;
  18253. else if (!all_nodes_valid(b))
  18254. return error_node();
  18255. else if (N != f->param_count)
  18256. {
  18257. details::free_all_nodes(*node_allocator_,b);
  18258. return error_node();
  18259. }
  18260. function_N_node_t* func_node_ptr = static_cast<function_N_node_t*>(result);
  18261. if (func_node_ptr->init_branches(b))
  18262. return result;
  18263. else
  18264. {
  18265. details::free_all_nodes(*node_allocator_,b);
  18266. return error_node();
  18267. }
  18268. }
  18269. }
  18270. inline expression_node_ptr function(ifunction_t* f)
  18271. {
  18272. typedef typename details::function_N_node<Type,ifunction_t,0> function_N_node_t;
  18273. return node_allocator_->allocate<function_N_node_t>(f);
  18274. }
  18275. inline expression_node_ptr vararg_function_call(ivararg_function_t* vaf,
  18276. std::vector<expression_node_ptr>& arg_list)
  18277. {
  18278. if (!all_nodes_valid(arg_list))
  18279. {
  18280. details::free_all_nodes(*node_allocator_,arg_list);
  18281. return error_node();
  18282. }
  18283. typedef details::vararg_function_node<Type,ivararg_function_t> alloc_type;
  18284. expression_node_ptr result = node_allocator_->allocate<alloc_type>(vaf,arg_list);
  18285. if (
  18286. !arg_list.empty() &&
  18287. !vaf->has_side_effects &&
  18288. is_constant_foldable(arg_list)
  18289. )
  18290. {
  18291. Type v = result->value();
  18292. details::free_node(*node_allocator_,result);
  18293. result = node_allocator_->allocate<literal_node_t>(v);
  18294. }
  18295. return result;
  18296. }
  18297. inline expression_node_ptr generic_function_call(igeneric_function_t* gf,
  18298. std::vector<expression_node_ptr>& arg_list,
  18299. const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
  18300. {
  18301. if (!all_nodes_valid(arg_list))
  18302. {
  18303. details::free_all_nodes(*node_allocator_,arg_list);
  18304. return error_node();
  18305. }
  18306. typedef details::generic_function_node <Type,igeneric_function_t> alloc_type1;
  18307. typedef details::multimode_genfunction_node<Type,igeneric_function_t> alloc_type2;
  18308. const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
  18309. expression_node_ptr result = error_node();
  18310. if (no_psi == param_seq_index)
  18311. result = node_allocator_->allocate<alloc_type1>(gf,arg_list);
  18312. else
  18313. result = node_allocator_->allocate<alloc_type2>(gf,param_seq_index,arg_list);
  18314. alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result);
  18315. if (
  18316. !arg_list.empty() &&
  18317. !gf->has_side_effects &&
  18318. is_constant_foldable(arg_list)
  18319. )
  18320. {
  18321. genfunc_node_ptr->init_branches();
  18322. Type v = result->value();
  18323. details::free_node(*node_allocator_,result);
  18324. return node_allocator_->allocate<literal_node_t>(v);
  18325. }
  18326. else if (genfunc_node_ptr->init_branches())
  18327. return result;
  18328. else
  18329. {
  18330. details::free_node(*node_allocator_,result);
  18331. details::free_all_nodes(*node_allocator_,arg_list);
  18332. return error_node();
  18333. }
  18334. }
  18335. inline expression_node_ptr string_function_call(igeneric_function_t* gf,
  18336. std::vector<expression_node_ptr>& arg_list,
  18337. const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
  18338. {
  18339. if (!all_nodes_valid(arg_list))
  18340. {
  18341. details::free_all_nodes(*node_allocator_,arg_list);
  18342. return error_node();
  18343. }
  18344. typedef details::string_function_node <Type,igeneric_function_t> alloc_type1;
  18345. typedef details::multimode_strfunction_node<Type,igeneric_function_t> alloc_type2;
  18346. const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
  18347. expression_node_ptr result = error_node();
  18348. if (no_psi == param_seq_index)
  18349. result = node_allocator_->allocate<alloc_type1>(gf,arg_list);
  18350. else
  18351. result = node_allocator_->allocate<alloc_type2>(gf,param_seq_index,arg_list);
  18352. alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result);
  18353. if (
  18354. !arg_list.empty() &&
  18355. !gf->has_side_effects &&
  18356. is_constant_foldable(arg_list)
  18357. )
  18358. {
  18359. strfunc_node_ptr->init_branches();
  18360. Type v = result->value();
  18361. details::free_node(*node_allocator_,result);
  18362. return node_allocator_->allocate<literal_node_t>(v);
  18363. }
  18364. else if (strfunc_node_ptr->init_branches())
  18365. return result;
  18366. else
  18367. {
  18368. details::free_node(*node_allocator_,result);
  18369. details::free_all_nodes(*node_allocator_,arg_list);
  18370. return error_node();
  18371. }
  18372. }
  18373. inline expression_node_ptr vector_element(const std::string& symbol,
  18374. vector_holder_ptr vector_base,
  18375. expression_node_ptr index)
  18376. {
  18377. expression_node_ptr result = error_node();
  18378. if (details::is_constant_node(index))
  18379. {
  18380. std::size_t i = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
  18381. details::free_node(*node_allocator_,index);
  18382. Type* v = (*vector_base)[i];
  18383. scope_element& se = parser_->sem_.get_element(symbol,i);
  18384. if (se.index == i)
  18385. {
  18386. result = se.var_node;
  18387. }
  18388. else
  18389. {
  18390. scope_element nse;
  18391. nse.name = symbol;
  18392. nse.type = scope_element::e_vecelem;
  18393. nse.index = i;
  18394. nse.depth = parser_->scope_depth_;
  18395. nse.data = 0;
  18396. nse.var_node = new variable_node_t((*v));
  18397. if (!parser_->sem_.add_element(nse))
  18398. {
  18399. parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]");
  18400. result = error_node();
  18401. }
  18402. else
  18403. exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse.name.c_str()));
  18404. result = nse.var_node;
  18405. }
  18406. }
  18407. else
  18408. result = node_allocator_->allocate<details::vector_elem_node<Type> >(index,(*vector_base)[0]);
  18409. return result;
  18410. }
  18411. private:
  18412. template <std::size_t N, typename NodePtr>
  18413. inline bool is_constant_foldable(NodePtr (&b)[N]) const
  18414. {
  18415. for (std::size_t i = 0; i < N; ++i)
  18416. {
  18417. if (0 == b[i])
  18418. return false;
  18419. else if (!details::is_constant_node(b[i]))
  18420. return false;
  18421. }
  18422. return true;
  18423. }
  18424. template <typename NodePtr,
  18425. typename Allocator,
  18426. template <typename,typename> class Sequence>
  18427. inline bool is_constant_foldable(const Sequence<NodePtr,Allocator>& b) const
  18428. {
  18429. for (std::size_t i = 0; i < b.size(); ++i)
  18430. {
  18431. if (0 == b[i])
  18432. return false;
  18433. else if (!details::is_constant_node(b[i]))
  18434. return false;
  18435. }
  18436. return true;
  18437. }
  18438. void lodge_assignment(symbol_type cst, expression_node_ptr node)
  18439. {
  18440. if (!parser_->dec_.collect_assignments())
  18441. return;
  18442. std::string symbol_name;
  18443. switch (cst)
  18444. {
  18445. case e_st_variable : symbol_name = parser_->symbol_table_
  18446. .get_variable_name(node);
  18447. break;
  18448. case e_st_string : symbol_name = parser_->symbol_table_
  18449. .get_stringvar_name(node);
  18450. break;
  18451. case e_st_vector : {
  18452. typedef details::vector_holder<T> vector_holder_t;
  18453. vector_holder_t& vh = static_cast<vector_node_t*>(node)->ref();
  18454. symbol_name = parser_->symbol_table_.get_vector_name(&vh);
  18455. }
  18456. break;
  18457. default : return;
  18458. }
  18459. parser_->dec_.add_assignment(symbol_name,cst);
  18460. }
  18461. inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  18462. {
  18463. if (details::is_variable_node(branch[0]))
  18464. {
  18465. lodge_assignment(e_st_variable,branch[0]);
  18466. return synthesize_expression<assignment_node_t,2>(operation,branch);
  18467. }
  18468. else if (details::is_vector_elem_node(branch[0]))
  18469. return synthesize_expression<assignment_vec_elem_node_t,2>(operation,branch);
  18470. else if (details::is_string_node(branch[0]))
  18471. {
  18472. lodge_assignment(e_st_string,branch[0]);
  18473. return synthesize_expression<assignment_string_node_t,2>(operation,branch);
  18474. }
  18475. else if (details::is_string_range_node(branch[0]))
  18476. {
  18477. lodge_assignment(e_st_string,branch[0]);
  18478. return synthesize_expression<assignment_string_range_node_t,2>(operation,branch);
  18479. }
  18480. else if (details::is_vector_node(branch[0]))
  18481. {
  18482. lodge_assignment(e_st_vector,branch[0]);
  18483. if (details::is_ivector_node(branch[1]))
  18484. return synthesize_expression<assignment_vecvec_node_t,2>(operation,branch);
  18485. else
  18486. return synthesize_expression<assignment_vec_node_t,2>(operation,branch);
  18487. }
  18488. else
  18489. {
  18490. parser_->set_synthesis_error("Invalid assignment operation.[1]");
  18491. return error_node();
  18492. }
  18493. }
  18494. inline expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type& operation,
  18495. expression_node_ptr (&branch)[2])
  18496. {
  18497. if (details::is_variable_node(branch[0]))
  18498. {
  18499. lodge_assignment(e_st_variable,branch[0]);
  18500. switch (operation)
  18501. {
  18502. #define case_stmt(op0,op1) \
  18503. case op0 : return node_allocator_-> \
  18504. template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
  18505. (operation,branch[0],branch[1]); \
  18506. case_stmt(details::e_addass,details::add_op)
  18507. case_stmt(details::e_subass,details::sub_op)
  18508. case_stmt(details::e_mulass,details::mul_op)
  18509. case_stmt(details::e_divass,details::div_op)
  18510. case_stmt(details::e_modass,details::mod_op)
  18511. #undef case_stmt
  18512. default : return error_node();
  18513. }
  18514. }
  18515. else if (details::is_vector_elem_node(branch[0]))
  18516. {
  18517. switch (operation)
  18518. {
  18519. #define case_stmt(op0,op1) \
  18520. case op0 : return node_allocator_-> \
  18521. template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
  18522. (operation,branch[0],branch[1]); \
  18523. case_stmt(details::e_addass,details::add_op)
  18524. case_stmt(details::e_subass,details::sub_op)
  18525. case_stmt(details::e_mulass,details::mul_op)
  18526. case_stmt(details::e_divass,details::div_op)
  18527. case_stmt(details::e_modass,details::mod_op)
  18528. #undef case_stmt
  18529. default : return error_node();
  18530. }
  18531. }
  18532. else if (details::is_vector_node(branch[0]))
  18533. {
  18534. lodge_assignment(e_st_vector,branch[0]);
  18535. if (details::is_ivector_node(branch[1]))
  18536. {
  18537. switch (operation)
  18538. {
  18539. #define case_stmt(op0,op1) \
  18540. case op0 : return node_allocator_-> \
  18541. template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
  18542. (operation,branch[0],branch[1]); \
  18543. case_stmt(details::e_addass,details::add_op)
  18544. case_stmt(details::e_subass,details::sub_op)
  18545. case_stmt(details::e_mulass,details::mul_op)
  18546. case_stmt(details::e_divass,details::div_op)
  18547. case_stmt(details::e_modass,details::mod_op)
  18548. #undef case_stmt
  18549. default : return error_node();
  18550. }
  18551. }
  18552. else
  18553. {
  18554. switch (operation)
  18555. {
  18556. #define case_stmt(op0,op1) \
  18557. case op0 : return node_allocator_-> \
  18558. template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
  18559. (operation,branch[0],branch[1]); \
  18560. case_stmt(details::e_addass,details::add_op)
  18561. case_stmt(details::e_subass,details::sub_op)
  18562. case_stmt(details::e_mulass,details::mul_op)
  18563. case_stmt(details::e_divass,details::div_op)
  18564. case_stmt(details::e_modass,details::mod_op)
  18565. #undef case_stmt
  18566. default : return error_node();
  18567. }
  18568. }
  18569. }
  18570. else if (
  18571. (details::e_addass == operation) &&
  18572. details::is_string_node(branch[0])
  18573. )
  18574. {
  18575. typedef details::assignment_string_node<T,details::asn_addassignment> addass_t;
  18576. lodge_assignment(e_st_string,branch[0]);
  18577. return synthesize_expression<addass_t,2>(operation,branch);
  18578. }
  18579. else
  18580. {
  18581. parser_->set_synthesis_error("Invalid assignment operation[2]");
  18582. return error_node();
  18583. }
  18584. }
  18585. inline expression_node_ptr synthesize_veceqineq_operation_expression(const details::operator_type& operation,
  18586. expression_node_ptr (&branch)[2])
  18587. {
  18588. const bool is_b0_ivec = details::is_ivector_node(branch[0]);
  18589. const bool is_b1_ivec = details::is_ivector_node(branch[1]);
  18590. if (is_b0_ivec && is_b1_ivec)
  18591. {
  18592. switch (operation)
  18593. {
  18594. #define case_stmt(op0,op1) \
  18595. case op0 : return node_allocator_-> \
  18596. template allocate_rrr<typename details::eqineq_vecvec_node<Type,op1<Type> > > \
  18597. (operation,branch[0],branch[1]); \
  18598. case_stmt(details:: e_lt,details:: lt_op)
  18599. case_stmt(details:: e_lte,details:: lte_op)
  18600. case_stmt(details:: e_gt,details:: gt_op)
  18601. case_stmt(details:: e_gte,details:: gte_op)
  18602. case_stmt(details:: e_eq,details:: eq_op)
  18603. case_stmt(details:: e_ne,details:: ne_op)
  18604. #undef case_stmt
  18605. default : return error_node();
  18606. }
  18607. }
  18608. else if (is_b0_ivec && !is_b1_ivec)
  18609. {
  18610. switch (operation)
  18611. {
  18612. #define case_stmt(op0,op1) \
  18613. case op0 : return node_allocator_-> \
  18614. template allocate_rrr<typename details::eqineq_vecval_node<Type,op1<Type> > > \
  18615. (operation,branch[0],branch[1]); \
  18616. case_stmt(details:: e_lt,details:: lt_op)
  18617. case_stmt(details:: e_lte,details:: lte_op)
  18618. case_stmt(details:: e_gt,details:: gt_op)
  18619. case_stmt(details:: e_gte,details:: gte_op)
  18620. case_stmt(details:: e_eq,details:: eq_op)
  18621. case_stmt(details:: e_ne,details:: ne_op)
  18622. #undef case_stmt
  18623. default : return error_node();
  18624. }
  18625. }
  18626. else if (!is_b0_ivec && is_b1_ivec)
  18627. {
  18628. switch (operation)
  18629. {
  18630. #define case_stmt(op0,op1) \
  18631. case op0 : return node_allocator_-> \
  18632. template allocate_rrr<typename details::eqineq_valvec_node<Type,op1<Type> > > \
  18633. (operation,branch[0],branch[1]); \
  18634. case_stmt(details:: e_lt,details:: lt_op)
  18635. case_stmt(details:: e_lte,details:: lte_op)
  18636. case_stmt(details:: e_gt,details:: gt_op)
  18637. case_stmt(details:: e_gte,details:: gte_op)
  18638. case_stmt(details:: e_eq,details:: eq_op)
  18639. case_stmt(details:: e_ne,details:: ne_op)
  18640. #undef case_stmt
  18641. default : return error_node();
  18642. }
  18643. }
  18644. else
  18645. return error_node();
  18646. }
  18647. inline expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type& operation,
  18648. expression_node_ptr (&branch)[2])
  18649. {
  18650. const bool is_b0_ivec = details::is_ivector_node(branch[0]);
  18651. const bool is_b1_ivec = details::is_ivector_node(branch[1]);
  18652. #define vector_ops \
  18653. case_stmt(details::e_add,details::add_op) \
  18654. case_stmt(details::e_sub,details::sub_op) \
  18655. case_stmt(details::e_mul,details::mul_op) \
  18656. case_stmt(details::e_div,details::div_op) \
  18657. case_stmt(details::e_mod,details::mod_op) \
  18658. if (is_b0_ivec && is_b1_ivec)
  18659. {
  18660. switch (operation)
  18661. {
  18662. #define case_stmt(op0,op1) \
  18663. case op0 : return node_allocator_-> \
  18664. template allocate_rrr<typename details::vecarith_vecvec_node<Type,op1<Type> > > \
  18665. (operation,branch[0],branch[1]); \
  18666. vector_ops
  18667. case_stmt(details::e_pow,details:: pow_op)
  18668. #undef case_stmt
  18669. default : return error_node();
  18670. }
  18671. }
  18672. else if (is_b0_ivec && !is_b1_ivec)
  18673. {
  18674. switch (operation)
  18675. {
  18676. #define case_stmt(op0,op1) \
  18677. case op0 : return node_allocator_-> \
  18678. template allocate_rrr<typename details::vecarith_vecval_node<Type,op1<Type> > > \
  18679. (operation,branch[0],branch[1]); \
  18680. vector_ops
  18681. case_stmt(details::e_pow,details:: pow_op)
  18682. #undef case_stmt
  18683. default : return error_node();
  18684. }
  18685. }
  18686. else if (!is_b0_ivec && is_b1_ivec)
  18687. {
  18688. switch (operation)
  18689. {
  18690. #define case_stmt(op0,op1) \
  18691. case op0 : return node_allocator_-> \
  18692. template allocate_rrr<typename details::vecarith_valvec_node<Type,op1<Type> > > \
  18693. (operation,branch[0],branch[1]); \
  18694. vector_ops
  18695. #undef case_stmt
  18696. default : return error_node();
  18697. }
  18698. }
  18699. else
  18700. return error_node();
  18701. #undef vector_ops
  18702. }
  18703. inline expression_node_ptr synthesize_swap_expression(expression_node_ptr (&branch)[2])
  18704. {
  18705. const bool v0_is_ivar = details::is_ivariable_node(branch[0]);
  18706. const bool v1_is_ivar = details::is_ivariable_node(branch[1]);
  18707. const bool v0_is_ivec = details::is_ivector_node(branch[0]);
  18708. const bool v1_is_ivec = details::is_ivector_node(branch[1]);
  18709. const bool v0_is_str = details::is_generally_string_node(branch[0]);
  18710. const bool v1_is_str = details::is_generally_string_node(branch[1]);
  18711. if (v0_is_ivar && v1_is_ivar)
  18712. {
  18713. typedef details::variable_node<T>* variable_node_ptr;
  18714. variable_node_ptr v0 = variable_node_ptr(0);
  18715. variable_node_ptr v1 = variable_node_ptr(0);
  18716. if (
  18717. (0 != (v0 = dynamic_cast<variable_node_ptr>(branch[0]))) &&
  18718. (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1])))
  18719. )
  18720. {
  18721. return node_allocator_->allocate<details::swap_node<T> >(v0,v1);
  18722. }
  18723. else
  18724. return node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
  18725. }
  18726. else if (v0_is_ivec && v1_is_ivec)
  18727. {
  18728. return node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
  18729. }
  18730. else if (v0_is_str && v1_is_str)
  18731. {
  18732. return node_allocator_->allocate<details::swap_string_node<T> >(branch[0],branch[1]);
  18733. }
  18734. else
  18735. {
  18736. parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped");
  18737. return error_node();
  18738. }
  18739. }
  18740. #ifndef exprtk_disable_sc_andor
  18741. inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  18742. {
  18743. expression_node_ptr result = error_node();
  18744. if (details::is_constant_node(branch[0]))
  18745. {
  18746. if (
  18747. (details::e_scand == operation) &&
  18748. std::equal_to<T>()(T(0),branch[0]->value())
  18749. )
  18750. result = node_allocator_->allocate_c<literal_node_t>(T(0));
  18751. else if (
  18752. (details::e_scor == operation) &&
  18753. std::not_equal_to<T>()(T(0),branch[0]->value())
  18754. )
  18755. result = node_allocator_->allocate_c<literal_node_t>(T(1));
  18756. }
  18757. if (details::is_constant_node(branch[1]) && (0 == result))
  18758. {
  18759. if (
  18760. (details::e_scand == operation) &&
  18761. std::equal_to<T>()(T(0),branch[1]->value())
  18762. )
  18763. result = node_allocator_->allocate_c<literal_node_t>(T(0));
  18764. else if (
  18765. (details::e_scor == operation) &&
  18766. std::not_equal_to<T>()(T(0),branch[1]->value())
  18767. )
  18768. result = node_allocator_->allocate_c<literal_node_t>(T(1));
  18769. }
  18770. if (result)
  18771. {
  18772. free_node(*node_allocator_,branch[0]);
  18773. free_node(*node_allocator_,branch[1]);
  18774. return result;
  18775. }
  18776. else if (details::e_scand == operation)
  18777. return synthesize_expression<scand_node_t,2>(operation,branch);
  18778. else if (details::e_scor == operation)
  18779. return synthesize_expression<scor_node_t,2>(operation,branch);
  18780. else
  18781. return error_node();
  18782. }
  18783. #else
  18784. inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type&, expression_node_ptr (&)[2])
  18785. {
  18786. return error_node();
  18787. }
  18788. #endif
  18789. #define basic_opr_switch_statements \
  18790. case_stmt(details::e_add,details::add_op) \
  18791. case_stmt(details::e_sub,details::sub_op) \
  18792. case_stmt(details::e_mul,details::mul_op) \
  18793. case_stmt(details::e_div,details::div_op) \
  18794. case_stmt(details::e_mod,details::mod_op) \
  18795. case_stmt(details::e_pow,details::pow_op) \
  18796. #define extended_opr_switch_statements \
  18797. case_stmt(details:: e_lt,details:: lt_op) \
  18798. case_stmt(details:: e_lte,details:: lte_op) \
  18799. case_stmt(details:: e_gt,details:: gt_op) \
  18800. case_stmt(details:: e_gte,details:: gte_op) \
  18801. case_stmt(details:: e_eq,details:: eq_op) \
  18802. case_stmt(details:: e_ne,details:: ne_op) \
  18803. case_stmt(details:: e_and,details:: and_op) \
  18804. case_stmt(details::e_nand,details::nand_op) \
  18805. case_stmt(details:: e_or,details:: or_op) \
  18806. case_stmt(details:: e_nor,details:: nor_op) \
  18807. case_stmt(details:: e_xor,details:: xor_op) \
  18808. case_stmt(details::e_xnor,details::xnor_op) \
  18809. #ifndef exprtk_disable_cardinal_pow_optimisation
  18810. template <template <typename,typename> class IPowNode>
  18811. inline expression_node_ptr cardinal_pow_optimization_impl(const T& v, const unsigned int& p)
  18812. {
  18813. switch (p)
  18814. {
  18815. #define case_stmt(cp) \
  18816. case cp : return node_allocator_-> \
  18817. allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
  18818. case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
  18819. case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
  18820. case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
  18821. case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
  18822. case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
  18823. case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
  18824. case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
  18825. case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
  18826. case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
  18827. case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
  18828. case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
  18829. case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
  18830. case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
  18831. case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
  18832. case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
  18833. #undef case_stmt
  18834. default : return error_node();
  18835. }
  18836. }
  18837. inline expression_node_ptr cardinal_pow_optimization(const T& v, const T& c)
  18838. {
  18839. const bool not_recipricol = (c >= T(0));
  18840. const int p = details::numeric::to_int32(details::numeric::abs(c));
  18841. if (0 == p)
  18842. return node_allocator_->allocate_c<literal_node_t>(T(1));
  18843. else if (std::equal_to<T>()(T(2),c))
  18844. {
  18845. return node_allocator_->
  18846. template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
  18847. }
  18848. else
  18849. {
  18850. if (not_recipricol)
  18851. return cardinal_pow_optimization_impl<details::ipow_node>(v,p);
  18852. else
  18853. return cardinal_pow_optimization_impl<details::ipowinv_node>(v,p);
  18854. }
  18855. }
  18856. inline bool cardinal_pow_optimizable(const details::operator_type& operation, const T& c)
  18857. {
  18858. return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
  18859. }
  18860. #else
  18861. inline expression_node_ptr cardinal_pow_optimization(T&, const T&)
  18862. {
  18863. return error_node();
  18864. }
  18865. inline bool cardinal_pow_optimizable(const details::operator_type&, const T&)
  18866. {
  18867. return false;
  18868. }
  18869. #endif
  18870. struct synthesize_binary_ext_expression
  18871. {
  18872. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  18873. const details::operator_type& operation,
  18874. expression_node_ptr (&branch)[2])
  18875. {
  18876. const bool left_neg = is_neg_unary_node(branch[0]);
  18877. const bool right_neg = is_neg_unary_node(branch[1]);
  18878. if (left_neg && right_neg)
  18879. {
  18880. if (
  18881. (details::e_add == operation) ||
  18882. (details::e_sub == operation) ||
  18883. (details::e_mul == operation) ||
  18884. (details::e_div == operation)
  18885. )
  18886. {
  18887. if (
  18888. !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
  18889. !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
  18890. )
  18891. {
  18892. details::free_all_nodes(*expr_gen.node_allocator_,branch);
  18893. return error_node();
  18894. }
  18895. }
  18896. switch (operation)
  18897. {
  18898. // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1))
  18899. case details::e_add : return expr_gen(details::e_neg,
  18900. expr_gen.node_allocator_->
  18901. template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
  18902. (branch[0],branch[1]));
  18903. // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1)
  18904. case details::e_sub : return expr_gen.node_allocator_->
  18905. template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
  18906. (branch[1],branch[0]);
  18907. default : break;
  18908. }
  18909. }
  18910. else if (left_neg && !right_neg)
  18911. {
  18912. if (
  18913. (details::e_add == operation) ||
  18914. (details::e_sub == operation) ||
  18915. (details::e_mul == operation) ||
  18916. (details::e_div == operation)
  18917. )
  18918. {
  18919. if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
  18920. {
  18921. details::free_all_nodes(*expr_gen.node_allocator_,branch);
  18922. return error_node();
  18923. }
  18924. switch (operation)
  18925. {
  18926. // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1)
  18927. case details::e_add : return expr_gen.node_allocator_->
  18928. template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
  18929. (branch[1],branch[0]);
  18930. // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1))
  18931. case details::e_sub : return expr_gen(details::e_neg,
  18932. expr_gen.node_allocator_->
  18933. template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
  18934. (branch[0],branch[1]));
  18935. // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1))
  18936. case details::e_mul : return expr_gen(details::e_neg,
  18937. expr_gen.node_allocator_->
  18938. template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
  18939. (branch[0],branch[1]));
  18940. // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1))
  18941. case details::e_div : return expr_gen(details::e_neg,
  18942. expr_gen.node_allocator_->
  18943. template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
  18944. (branch[0],branch[1]));
  18945. default : return error_node();
  18946. }
  18947. }
  18948. }
  18949. else if (!left_neg && right_neg)
  18950. {
  18951. if (
  18952. (details::e_add == operation) ||
  18953. (details::e_sub == operation) ||
  18954. (details::e_mul == operation) ||
  18955. (details::e_div == operation)
  18956. )
  18957. {
  18958. if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
  18959. {
  18960. details::free_all_nodes(*expr_gen.node_allocator_,branch);
  18961. return error_node();
  18962. }
  18963. switch (operation)
  18964. {
  18965. // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1)
  18966. case details::e_add : return expr_gen.node_allocator_->
  18967. template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
  18968. (branch[0],branch[1]);
  18969. // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1)
  18970. case details::e_sub : return expr_gen.node_allocator_->
  18971. template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
  18972. (branch[0],branch[1]);
  18973. // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1))
  18974. case details::e_mul : return expr_gen(details::e_neg,
  18975. expr_gen.node_allocator_->
  18976. template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
  18977. (branch[0],branch[1]));
  18978. // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1))
  18979. case details::e_div : return expr_gen(details::e_neg,
  18980. expr_gen.node_allocator_->
  18981. template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
  18982. (branch[0],branch[1]));
  18983. default : return error_node();
  18984. }
  18985. }
  18986. }
  18987. switch (operation)
  18988. {
  18989. #define case_stmt(op0,op1) \
  18990. case op0 : return expr_gen.node_allocator_-> \
  18991. template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
  18992. (branch[0],branch[1]); \
  18993. basic_opr_switch_statements
  18994. extended_opr_switch_statements
  18995. #undef case_stmt
  18996. default : return error_node();
  18997. }
  18998. }
  18999. };
  19000. struct synthesize_vob_expression
  19001. {
  19002. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19003. const details::operator_type& operation,
  19004. expression_node_ptr (&branch)[2])
  19005. {
  19006. const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  19007. #ifndef exprtk_disable_enhanced_features
  19008. if (details::is_sf3ext_node(branch[1]))
  19009. {
  19010. expression_node_ptr result = error_node();
  19011. if (synthesize_sf4ext_expression::template compile_right<vtype>(expr_gen,v,operation,branch[1],result))
  19012. {
  19013. free_node(*expr_gen.node_allocator_,branch[1]);
  19014. return result;
  19015. }
  19016. }
  19017. #endif
  19018. if (
  19019. (details::e_mul == operation) ||
  19020. (details::e_div == operation)
  19021. )
  19022. {
  19023. if (details::is_uv_node(branch[1]))
  19024. {
  19025. details::operator_type o = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
  19026. if (details::e_neg == o)
  19027. {
  19028. const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
  19029. free_node(*expr_gen.node_allocator_,branch[1]);
  19030. switch (operation)
  19031. {
  19032. case details::e_mul : return expr_gen(details::e_neg,
  19033. expr_gen.node_allocator_->
  19034. template allocate_rr<typename details::
  19035. vov_node<Type,details::mul_op<Type> > >(v,v1));
  19036. case details::e_div : return expr_gen(details::e_neg,
  19037. expr_gen.node_allocator_->
  19038. template allocate_rr<typename details::
  19039. vov_node<Type,details::div_op<Type> > >(v,v1));
  19040. default : break;
  19041. }
  19042. }
  19043. }
  19044. }
  19045. switch (operation)
  19046. {
  19047. #define case_stmt(op0,op1) \
  19048. case op0 : return expr_gen.node_allocator_-> \
  19049. template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
  19050. (v,branch[1]); \
  19051. basic_opr_switch_statements
  19052. extended_opr_switch_statements
  19053. #undef case_stmt
  19054. default : return error_node();
  19055. }
  19056. }
  19057. };
  19058. struct synthesize_bov_expression
  19059. {
  19060. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19061. const details::operator_type& operation,
  19062. expression_node_ptr (&branch)[2])
  19063. {
  19064. const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  19065. #ifndef exprtk_disable_enhanced_features
  19066. if (details::is_sf3ext_node(branch[0]))
  19067. {
  19068. expression_node_ptr result = error_node();
  19069. if (synthesize_sf4ext_expression::template compile_left<vtype>(expr_gen,v,operation,branch[0],result))
  19070. {
  19071. free_node(*expr_gen.node_allocator_,branch[0]);
  19072. return result;
  19073. }
  19074. }
  19075. #endif
  19076. if (
  19077. (details::e_add == operation) ||
  19078. (details::e_sub == operation) ||
  19079. (details::e_mul == operation) ||
  19080. (details::e_div == operation)
  19081. )
  19082. {
  19083. if (details::is_uv_node(branch[0]))
  19084. {
  19085. details::operator_type o = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
  19086. if (details::e_neg == o)
  19087. {
  19088. const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
  19089. free_node(*expr_gen.node_allocator_,branch[0]);
  19090. switch (operation)
  19091. {
  19092. case details::e_add : return expr_gen.node_allocator_->
  19093. template allocate_rr<typename details::
  19094. vov_node<Type,details::sub_op<Type> > >(v,v0);
  19095. case details::e_sub : return expr_gen(details::e_neg,
  19096. expr_gen.node_allocator_->
  19097. template allocate_rr<typename details::
  19098. vov_node<Type,details::add_op<Type> > >(v0,v));
  19099. case details::e_mul : return expr_gen(details::e_neg,
  19100. expr_gen.node_allocator_->
  19101. template allocate_rr<typename details::
  19102. vov_node<Type,details::mul_op<Type> > >(v0,v));
  19103. case details::e_div : return expr_gen(details::e_neg,
  19104. expr_gen.node_allocator_->
  19105. template allocate_rr<typename details::
  19106. vov_node<Type,details::div_op<Type> > >(v0,v));
  19107. default : break;
  19108. }
  19109. }
  19110. }
  19111. }
  19112. switch (operation)
  19113. {
  19114. #define case_stmt(op0,op1) \
  19115. case op0 : return expr_gen.node_allocator_-> \
  19116. template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
  19117. (branch[0],v); \
  19118. basic_opr_switch_statements
  19119. extended_opr_switch_statements
  19120. #undef case_stmt
  19121. default : return error_node();
  19122. }
  19123. }
  19124. };
  19125. struct synthesize_cob_expression
  19126. {
  19127. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19128. const details::operator_type& operation,
  19129. expression_node_ptr (&branch)[2])
  19130. {
  19131. const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
  19132. free_node(*expr_gen.node_allocator_,branch[0]);
  19133. if (details::is_cob_node(branch[1]))
  19134. {
  19135. // Simplify expressions of the form:
  19136. // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
  19137. // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
  19138. if (
  19139. (operation == details::e_mul) ||
  19140. (operation == details::e_add)
  19141. )
  19142. {
  19143. details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
  19144. if (operation == cobnode->operation())
  19145. {
  19146. switch (operation)
  19147. {
  19148. case details::e_add : cobnode->set_c(c + cobnode->c()); break;
  19149. case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
  19150. default : return error_node();
  19151. }
  19152. return cobnode;
  19153. }
  19154. }
  19155. if (operation == details::e_mul)
  19156. {
  19157. details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
  19158. details::operator_type cob_opr = cobnode->operation();
  19159. if (
  19160. (details::e_div == cob_opr) ||
  19161. (details::e_mul == cob_opr)
  19162. )
  19163. {
  19164. switch (cob_opr)
  19165. {
  19166. case details::e_div : cobnode->set_c(c * cobnode->c()); break;
  19167. case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
  19168. default : return error_node();
  19169. }
  19170. return cobnode;
  19171. }
  19172. }
  19173. else if (operation == details::e_div)
  19174. {
  19175. details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
  19176. details::operator_type cob_opr = cobnode->operation();
  19177. if (
  19178. (details::e_div == cob_opr) ||
  19179. (details::e_mul == cob_opr)
  19180. )
  19181. {
  19182. details::expression_node<Type>* new_cobnode = error_node();
  19183. switch (cob_opr)
  19184. {
  19185. case details::e_div : new_cobnode = expr_gen.node_allocator_->
  19186. template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
  19187. (c / cobnode->c(),cobnode->move_branch(0));
  19188. break;
  19189. case details::e_mul : new_cobnode = expr_gen.node_allocator_->
  19190. template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
  19191. (c / cobnode->c(),cobnode->move_branch(0));
  19192. break;
  19193. default : return error_node();
  19194. }
  19195. free_node(*expr_gen.node_allocator_,branch[1]);
  19196. return new_cobnode;
  19197. }
  19198. }
  19199. }
  19200. #ifndef exprtk_disable_enhanced_features
  19201. else if (details::is_sf3ext_node(branch[1]))
  19202. {
  19203. expression_node_ptr result = error_node();
  19204. if (synthesize_sf4ext_expression::template compile_right<ctype>(expr_gen,c,operation,branch[1],result))
  19205. {
  19206. free_node(*expr_gen.node_allocator_,branch[1]);
  19207. return result;
  19208. }
  19209. }
  19210. #endif
  19211. switch (operation)
  19212. {
  19213. #define case_stmt(op0,op1) \
  19214. case op0 : return expr_gen.node_allocator_-> \
  19215. template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
  19216. (c,branch[1]); \
  19217. basic_opr_switch_statements
  19218. extended_opr_switch_statements
  19219. #undef case_stmt
  19220. default : return error_node();
  19221. }
  19222. }
  19223. };
  19224. struct synthesize_boc_expression
  19225. {
  19226. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19227. const details::operator_type& operation,
  19228. expression_node_ptr (&branch)[2])
  19229. {
  19230. const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
  19231. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  19232. if (details::is_boc_node(branch[0]))
  19233. {
  19234. // Simplify expressions of the form:
  19235. // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
  19236. // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
  19237. if (
  19238. (operation == details::e_mul) ||
  19239. (operation == details::e_add)
  19240. )
  19241. {
  19242. details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
  19243. if (operation == bocnode->operation())
  19244. {
  19245. switch (operation)
  19246. {
  19247. case details::e_add : bocnode->set_c(c + bocnode->c()); break;
  19248. case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
  19249. default : return error_node();
  19250. }
  19251. return bocnode;
  19252. }
  19253. }
  19254. else if (operation == details::e_div)
  19255. {
  19256. details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
  19257. details::operator_type boc_opr = bocnode->operation();
  19258. if (
  19259. (details::e_div == boc_opr) ||
  19260. (details::e_mul == boc_opr)
  19261. )
  19262. {
  19263. switch (boc_opr)
  19264. {
  19265. case details::e_div : bocnode->set_c(c * bocnode->c()); break;
  19266. case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
  19267. default : return error_node();
  19268. }
  19269. return bocnode;
  19270. }
  19271. }
  19272. }
  19273. #ifndef exprtk_disable_enhanced_features
  19274. if (details::is_sf3ext_node(branch[0]))
  19275. {
  19276. expression_node_ptr result = error_node();
  19277. if (synthesize_sf4ext_expression::template compile_left<ctype>(expr_gen,c,operation,branch[0],result))
  19278. {
  19279. free_node(*expr_gen.node_allocator_,branch[0]);
  19280. return result;
  19281. }
  19282. }
  19283. #endif
  19284. switch (operation)
  19285. {
  19286. #define case_stmt(op0,op1) \
  19287. case op0 : return expr_gen.node_allocator_-> \
  19288. template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
  19289. (branch[0],c); \
  19290. basic_opr_switch_statements
  19291. extended_opr_switch_statements
  19292. #undef case_stmt
  19293. default : return error_node();
  19294. }
  19295. }
  19296. };
  19297. struct synthesize_cocob_expression
  19298. {
  19299. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19300. const details::operator_type& operation,
  19301. expression_node_ptr (&branch)[2])
  19302. {
  19303. expression_node_ptr result = error_node();
  19304. // (cob) o c --> cob
  19305. if (details::is_cob_node(branch[0]))
  19306. {
  19307. details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
  19308. const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
  19309. bool op_addsub = (details::e_add == cobnode->operation()) ||
  19310. (details::e_sub == cobnode->operation());
  19311. if (op_addsub)
  19312. {
  19313. switch (operation)
  19314. {
  19315. case details::e_add : cobnode->set_c(cobnode->c() + c); break;
  19316. case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
  19317. default : return error_node();
  19318. }
  19319. result = cobnode;
  19320. }
  19321. else if (details::e_mul == cobnode->operation())
  19322. {
  19323. switch (operation)
  19324. {
  19325. case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
  19326. case details::e_div : cobnode->set_c(cobnode->c() / c); break;
  19327. default : return error_node();
  19328. }
  19329. result = cobnode;
  19330. }
  19331. else if (details::e_div == cobnode->operation())
  19332. {
  19333. if (details::e_mul == operation)
  19334. {
  19335. cobnode->set_c(cobnode->c() * c);
  19336. result = cobnode;
  19337. }
  19338. else if (details::e_div == operation)
  19339. {
  19340. result = expr_gen.node_allocator_->
  19341. template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
  19342. (cobnode->c() / c,cobnode->move_branch(0));
  19343. free_node(*expr_gen.node_allocator_,branch[0]);
  19344. }
  19345. }
  19346. if (result)
  19347. {
  19348. free_node(*expr_gen.node_allocator_,branch[1]);
  19349. }
  19350. }
  19351. // c o (cob) --> cob
  19352. else if (details::is_cob_node(branch[1]))
  19353. {
  19354. details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
  19355. const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
  19356. if (details::e_add == cobnode->operation())
  19357. {
  19358. if (details::e_add == operation)
  19359. {
  19360. cobnode->set_c(c + cobnode->c());
  19361. result = cobnode;
  19362. }
  19363. else if (details::e_sub == operation)
  19364. {
  19365. result = expr_gen.node_allocator_->
  19366. template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
  19367. (c - cobnode->c(),cobnode->move_branch(0));
  19368. free_node(*expr_gen.node_allocator_,branch[1]);
  19369. }
  19370. }
  19371. else if (details::e_sub == cobnode->operation())
  19372. {
  19373. if (details::e_add == operation)
  19374. {
  19375. cobnode->set_c(c + cobnode->c());
  19376. result = cobnode;
  19377. }
  19378. else if (details::e_sub == operation)
  19379. {
  19380. result = expr_gen.node_allocator_->
  19381. template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
  19382. (c - cobnode->c(),cobnode->move_branch(0));
  19383. free_node(*expr_gen.node_allocator_,branch[1]);
  19384. }
  19385. }
  19386. else if (details::e_mul == cobnode->operation())
  19387. {
  19388. if (details::e_mul == operation)
  19389. {
  19390. cobnode->set_c(c * cobnode->c());
  19391. result = cobnode;
  19392. }
  19393. else if (details::e_div == operation)
  19394. {
  19395. result = expr_gen.node_allocator_->
  19396. template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
  19397. (c / cobnode->c(),cobnode->move_branch(0));
  19398. free_node(*expr_gen.node_allocator_,branch[1]);
  19399. }
  19400. }
  19401. else if (details::e_div == cobnode->operation())
  19402. {
  19403. if (details::e_mul == operation)
  19404. {
  19405. cobnode->set_c(c * cobnode->c());
  19406. result = cobnode;
  19407. }
  19408. else if (details::e_div == operation)
  19409. {
  19410. result = expr_gen.node_allocator_->
  19411. template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
  19412. (c / cobnode->c(),cobnode->move_branch(0));
  19413. free_node(*expr_gen.node_allocator_,branch[1]);
  19414. }
  19415. }
  19416. if (result)
  19417. {
  19418. free_node(*expr_gen.node_allocator_,branch[0]);
  19419. }
  19420. }
  19421. return result;
  19422. }
  19423. };
  19424. struct synthesize_coboc_expression
  19425. {
  19426. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19427. const details::operator_type& operation,
  19428. expression_node_ptr (&branch)[2])
  19429. {
  19430. expression_node_ptr result = error_node();
  19431. // (boc) o c --> boc
  19432. if (details::is_boc_node(branch[0]))
  19433. {
  19434. details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
  19435. const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
  19436. if (details::e_add == bocnode->operation())
  19437. {
  19438. switch (operation)
  19439. {
  19440. case details::e_add : bocnode->set_c(bocnode->c() + c); break;
  19441. case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
  19442. default : return error_node();
  19443. }
  19444. result = bocnode;
  19445. }
  19446. else if (details::e_mul == bocnode->operation())
  19447. {
  19448. switch (operation)
  19449. {
  19450. case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
  19451. case details::e_div : bocnode->set_c(bocnode->c() / c); break;
  19452. default : return error_node();
  19453. }
  19454. result = bocnode;
  19455. }
  19456. else if (details::e_sub == bocnode->operation())
  19457. {
  19458. if (details::e_add == operation)
  19459. {
  19460. result = expr_gen.node_allocator_->
  19461. template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
  19462. (bocnode->move_branch(0),c - bocnode->c());
  19463. free_node(*expr_gen.node_allocator_,branch[0]);
  19464. }
  19465. else if (details::e_sub == operation)
  19466. {
  19467. bocnode->set_c(bocnode->c() + c);
  19468. result = bocnode;
  19469. }
  19470. }
  19471. else if (details::e_div == bocnode->operation())
  19472. {
  19473. switch (operation)
  19474. {
  19475. case details::e_div : bocnode->set_c(bocnode->c() * c); break;
  19476. case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
  19477. default : return error_node();
  19478. }
  19479. result = bocnode;
  19480. }
  19481. if (result)
  19482. {
  19483. free_node(*expr_gen.node_allocator_,branch[1]);
  19484. }
  19485. }
  19486. // c o (boc) --> boc
  19487. else if (details::is_boc_node(branch[1]))
  19488. {
  19489. details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
  19490. const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
  19491. if (details::e_add == bocnode->operation())
  19492. {
  19493. if (details::e_add == operation)
  19494. {
  19495. bocnode->set_c(c + bocnode->c());
  19496. result = bocnode;
  19497. }
  19498. else if (details::e_sub == operation)
  19499. {
  19500. result = expr_gen.node_allocator_->
  19501. template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
  19502. (c - bocnode->c(),bocnode->move_branch(0));
  19503. free_node(*expr_gen.node_allocator_,branch[1]);
  19504. }
  19505. }
  19506. else if (details::e_sub == bocnode->operation())
  19507. {
  19508. if (details::e_add == operation)
  19509. {
  19510. result = expr_gen.node_allocator_->
  19511. template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
  19512. (bocnode->move_branch(0),c - bocnode->c());
  19513. free_node(*expr_gen.node_allocator_,branch[1]);
  19514. }
  19515. else if (details::e_sub == operation)
  19516. {
  19517. result = expr_gen.node_allocator_->
  19518. template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
  19519. (c + bocnode->c(),bocnode->move_branch(0));
  19520. free_node(*expr_gen.node_allocator_,branch[1]);
  19521. }
  19522. }
  19523. else if (details::e_mul == bocnode->operation())
  19524. {
  19525. if (details::e_mul == operation)
  19526. {
  19527. bocnode->set_c(c * bocnode->c());
  19528. result = bocnode;
  19529. }
  19530. else if (details::e_div == operation)
  19531. {
  19532. result = expr_gen.node_allocator_->
  19533. template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
  19534. (c / bocnode->c(),bocnode->move_branch(0));
  19535. free_node(*expr_gen.node_allocator_,branch[1]);
  19536. }
  19537. }
  19538. else if (details::e_div == bocnode->operation())
  19539. {
  19540. if (details::e_mul == operation)
  19541. {
  19542. bocnode->set_c(bocnode->c() / c);
  19543. result = bocnode;
  19544. }
  19545. else if (details::e_div == operation)
  19546. {
  19547. result = expr_gen.node_allocator_->
  19548. template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
  19549. (c * bocnode->c(),bocnode->move_branch(0));
  19550. free_node(*expr_gen.node_allocator_,branch[1]);
  19551. }
  19552. }
  19553. if (result)
  19554. {
  19555. free_node(*expr_gen.node_allocator_,branch[0]);
  19556. }
  19557. }
  19558. return result;
  19559. }
  19560. };
  19561. #ifndef exprtk_disable_enhanced_features
  19562. inline bool synthesize_expression(const details::operator_type& operation,
  19563. expression_node_ptr (&branch)[2],
  19564. expression_node_ptr& result)
  19565. {
  19566. result = error_node();
  19567. if (!operation_optimizable(operation))
  19568. return false;
  19569. const std::string node_id = branch_to_id(branch);
  19570. typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
  19571. if (synthesize_map_.end() != itr)
  19572. {
  19573. result = itr->second(*this,operation,branch);
  19574. return true;
  19575. }
  19576. else
  19577. return false;
  19578. }
  19579. struct synthesize_vov_expression
  19580. {
  19581. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19582. const details::operator_type& operation,
  19583. expression_node_ptr (&branch)[2])
  19584. {
  19585. const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  19586. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  19587. switch (operation)
  19588. {
  19589. #define case_stmt(op0,op1) \
  19590. case op0 : return expr_gen.node_allocator_-> \
  19591. template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
  19592. (v1,v2); \
  19593. basic_opr_switch_statements
  19594. extended_opr_switch_statements
  19595. #undef case_stmt
  19596. default : return error_node();
  19597. }
  19598. }
  19599. };
  19600. struct synthesize_cov_expression
  19601. {
  19602. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19603. const details::operator_type& operation,
  19604. expression_node_ptr (&branch)[2])
  19605. {
  19606. const Type c = static_cast<details::literal_node<Type>*> (branch[0])->value();
  19607. const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  19608. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  19609. switch (operation)
  19610. {
  19611. #define case_stmt(op0,op1) \
  19612. case op0 : return expr_gen.node_allocator_-> \
  19613. template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
  19614. (c,v); \
  19615. basic_opr_switch_statements
  19616. extended_opr_switch_statements
  19617. #undef case_stmt
  19618. default : return error_node();
  19619. }
  19620. }
  19621. };
  19622. struct synthesize_voc_expression
  19623. {
  19624. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19625. const details::operator_type& operation,
  19626. expression_node_ptr (&branch)[2])
  19627. {
  19628. const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  19629. const Type c = static_cast<details::literal_node<Type>*> (branch[1])->value();
  19630. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  19631. if (expr_gen.cardinal_pow_optimizable(operation,c))
  19632. {
  19633. if (std::equal_to<T>()(T(1),c))
  19634. return branch[0];
  19635. else
  19636. return expr_gen.cardinal_pow_optimization(v,c);
  19637. }
  19638. switch (operation)
  19639. {
  19640. #define case_stmt(op0,op1) \
  19641. case op0 : return expr_gen.node_allocator_-> \
  19642. template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
  19643. (v,c); \
  19644. basic_opr_switch_statements
  19645. extended_opr_switch_statements
  19646. #undef case_stmt
  19647. default : return error_node();
  19648. }
  19649. }
  19650. };
  19651. struct synthesize_sf3ext_expression
  19652. {
  19653. template <typename T0, typename T1, typename T2>
  19654. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19655. const details::operator_type& sf3opr,
  19656. T0 t0, T1 t1, T2 t2)
  19657. {
  19658. switch (sf3opr)
  19659. {
  19660. #define case_stmt(op0,op1) \
  19661. case op0 : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,op1<Type> >:: \
  19662. allocate(*(expr_gen.node_allocator_),t0,t1,t2); \
  19663. case_stmt(details::e_sf00,details::sf00_op) case_stmt(details::e_sf01,details::sf01_op)
  19664. case_stmt(details::e_sf02,details::sf02_op) case_stmt(details::e_sf03,details::sf03_op)
  19665. case_stmt(details::e_sf04,details::sf04_op) case_stmt(details::e_sf05,details::sf05_op)
  19666. case_stmt(details::e_sf06,details::sf06_op) case_stmt(details::e_sf07,details::sf07_op)
  19667. case_stmt(details::e_sf08,details::sf08_op) case_stmt(details::e_sf09,details::sf09_op)
  19668. case_stmt(details::e_sf10,details::sf10_op) case_stmt(details::e_sf11,details::sf11_op)
  19669. case_stmt(details::e_sf12,details::sf12_op) case_stmt(details::e_sf13,details::sf13_op)
  19670. case_stmt(details::e_sf14,details::sf14_op) case_stmt(details::e_sf15,details::sf15_op)
  19671. case_stmt(details::e_sf16,details::sf16_op) case_stmt(details::e_sf17,details::sf17_op)
  19672. case_stmt(details::e_sf18,details::sf18_op) case_stmt(details::e_sf19,details::sf19_op)
  19673. case_stmt(details::e_sf20,details::sf20_op) case_stmt(details::e_sf21,details::sf21_op)
  19674. case_stmt(details::e_sf22,details::sf22_op) case_stmt(details::e_sf23,details::sf23_op)
  19675. case_stmt(details::e_sf24,details::sf24_op) case_stmt(details::e_sf25,details::sf25_op)
  19676. case_stmt(details::e_sf26,details::sf26_op) case_stmt(details::e_sf27,details::sf27_op)
  19677. case_stmt(details::e_sf28,details::sf28_op) case_stmt(details::e_sf29,details::sf29_op)
  19678. case_stmt(details::e_sf30,details::sf30_op)
  19679. #undef case_stmt
  19680. default : return error_node();
  19681. }
  19682. }
  19683. template <typename T0, typename T1, typename T2>
  19684. static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
  19685. T0 t0, T1 t1, T2 t2,
  19686. expression_node_ptr& result)
  19687. {
  19688. details::operator_type sf3opr;
  19689. if (!expr_gen.sf3_optimizable(id,sf3opr))
  19690. return false;
  19691. else
  19692. result = synthesize_sf3ext_expression::template process<T0,T1,T2>(expr_gen,sf3opr,t0,t1,t2);
  19693. return true;
  19694. }
  19695. };
  19696. struct synthesize_sf4ext_expression
  19697. {
  19698. template <typename T0, typename T1, typename T2, typename T3>
  19699. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19700. const details::operator_type& sf4opr,
  19701. T0 t0, T1 t1, T2 t2, T3 t3)
  19702. {
  19703. switch (sf4opr)
  19704. {
  19705. #define case_stmt(op0,op1) \
  19706. case op0 : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,op1<Type> >:: \
  19707. allocate(*(expr_gen.node_allocator_),t0,t1,t2,t3); \
  19708. case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf49,details::sf49_op)
  19709. case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf51,details::sf51_op)
  19710. case_stmt(details::e_sf52,details::sf52_op) case_stmt(details::e_sf53,details::sf53_op)
  19711. case_stmt(details::e_sf54,details::sf54_op) case_stmt(details::e_sf55,details::sf55_op)
  19712. case_stmt(details::e_sf56,details::sf56_op) case_stmt(details::e_sf57,details::sf57_op)
  19713. case_stmt(details::e_sf58,details::sf58_op) case_stmt(details::e_sf59,details::sf59_op)
  19714. case_stmt(details::e_sf60,details::sf60_op) case_stmt(details::e_sf61,details::sf61_op)
  19715. case_stmt(details::e_sf62,details::sf62_op) case_stmt(details::e_sf63,details::sf63_op)
  19716. case_stmt(details::e_sf64,details::sf64_op) case_stmt(details::e_sf65,details::sf65_op)
  19717. case_stmt(details::e_sf66,details::sf66_op) case_stmt(details::e_sf67,details::sf67_op)
  19718. case_stmt(details::e_sf68,details::sf68_op) case_stmt(details::e_sf69,details::sf69_op)
  19719. case_stmt(details::e_sf70,details::sf70_op) case_stmt(details::e_sf71,details::sf71_op)
  19720. case_stmt(details::e_sf72,details::sf72_op) case_stmt(details::e_sf73,details::sf73_op)
  19721. case_stmt(details::e_sf74,details::sf74_op) case_stmt(details::e_sf75,details::sf75_op)
  19722. case_stmt(details::e_sf76,details::sf76_op) case_stmt(details::e_sf77,details::sf77_op)
  19723. case_stmt(details::e_sf78,details::sf78_op) case_stmt(details::e_sf79,details::sf79_op)
  19724. case_stmt(details::e_sf80,details::sf80_op) case_stmt(details::e_sf81,details::sf81_op)
  19725. case_stmt(details::e_sf82,details::sf82_op) case_stmt(details::e_sf83,details::sf83_op)
  19726. case_stmt(details::e_sf4ext00,details::sfext00_op) case_stmt(details::e_sf4ext01,details::sfext01_op)
  19727. case_stmt(details::e_sf4ext02,details::sfext02_op) case_stmt(details::e_sf4ext03,details::sfext03_op)
  19728. case_stmt(details::e_sf4ext04,details::sfext04_op) case_stmt(details::e_sf4ext05,details::sfext05_op)
  19729. case_stmt(details::e_sf4ext06,details::sfext06_op) case_stmt(details::e_sf4ext07,details::sfext07_op)
  19730. case_stmt(details::e_sf4ext08,details::sfext08_op) case_stmt(details::e_sf4ext09,details::sfext09_op)
  19731. case_stmt(details::e_sf4ext10,details::sfext10_op) case_stmt(details::e_sf4ext11,details::sfext11_op)
  19732. case_stmt(details::e_sf4ext12,details::sfext12_op) case_stmt(details::e_sf4ext13,details::sfext13_op)
  19733. case_stmt(details::e_sf4ext14,details::sfext14_op) case_stmt(details::e_sf4ext15,details::sfext15_op)
  19734. case_stmt(details::e_sf4ext16,details::sfext16_op) case_stmt(details::e_sf4ext17,details::sfext17_op)
  19735. case_stmt(details::e_sf4ext18,details::sfext18_op) case_stmt(details::e_sf4ext19,details::sfext19_op)
  19736. case_stmt(details::e_sf4ext20,details::sfext20_op) case_stmt(details::e_sf4ext21,details::sfext21_op)
  19737. case_stmt(details::e_sf4ext22,details::sfext22_op) case_stmt(details::e_sf4ext23,details::sfext23_op)
  19738. case_stmt(details::e_sf4ext24,details::sfext24_op) case_stmt(details::e_sf4ext25,details::sfext25_op)
  19739. case_stmt(details::e_sf4ext26,details::sfext26_op) case_stmt(details::e_sf4ext27,details::sfext27_op)
  19740. case_stmt(details::e_sf4ext28,details::sfext28_op) case_stmt(details::e_sf4ext29,details::sfext29_op)
  19741. case_stmt(details::e_sf4ext30,details::sfext30_op) case_stmt(details::e_sf4ext31,details::sfext31_op)
  19742. case_stmt(details::e_sf4ext32,details::sfext32_op) case_stmt(details::e_sf4ext33,details::sfext33_op)
  19743. case_stmt(details::e_sf4ext34,details::sfext34_op) case_stmt(details::e_sf4ext35,details::sfext35_op)
  19744. case_stmt(details::e_sf4ext36,details::sfext36_op) case_stmt(details::e_sf4ext37,details::sfext37_op)
  19745. case_stmt(details::e_sf4ext38,details::sfext38_op) case_stmt(details::e_sf4ext39,details::sfext39_op)
  19746. case_stmt(details::e_sf4ext40,details::sfext40_op) case_stmt(details::e_sf4ext41,details::sfext41_op)
  19747. case_stmt(details::e_sf4ext42,details::sfext42_op) case_stmt(details::e_sf4ext43,details::sfext43_op)
  19748. case_stmt(details::e_sf4ext44,details::sfext44_op) case_stmt(details::e_sf4ext45,details::sfext45_op)
  19749. case_stmt(details::e_sf4ext46,details::sfext46_op) case_stmt(details::e_sf4ext47,details::sfext47_op)
  19750. case_stmt(details::e_sf4ext48,details::sfext48_op) case_stmt(details::e_sf4ext49,details::sfext49_op)
  19751. case_stmt(details::e_sf4ext50,details::sfext50_op) case_stmt(details::e_sf4ext51,details::sfext51_op)
  19752. case_stmt(details::e_sf4ext52,details::sfext52_op) case_stmt(details::e_sf4ext53,details::sfext53_op)
  19753. case_stmt(details::e_sf4ext54,details::sfext54_op) case_stmt(details::e_sf4ext55,details::sfext55_op)
  19754. case_stmt(details::e_sf4ext56,details::sfext56_op) case_stmt(details::e_sf4ext57,details::sfext57_op)
  19755. case_stmt(details::e_sf4ext58,details::sfext58_op) case_stmt(details::e_sf4ext59,details::sfext59_op)
  19756. #undef case_stmt
  19757. default : return error_node();
  19758. }
  19759. }
  19760. template <typename T0, typename T1, typename T2, typename T3>
  19761. static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
  19762. T0 t0, T1 t1, T2 t2, T3 t3,
  19763. expression_node_ptr& result)
  19764. {
  19765. details::operator_type sf4opr;
  19766. if (!expr_gen.sf4_optimizable(id,sf4opr))
  19767. return false;
  19768. else
  19769. result = synthesize_sf4ext_expression::template process<T0,T1,T2,T3>(expr_gen,sf4opr,t0,t1,t2,t3);
  19770. return true;
  19771. }
  19772. // T o (sf3ext)
  19773. template <typename ExternalType>
  19774. static inline bool compile_right(expression_generator<Type>& expr_gen,
  19775. ExternalType t,
  19776. const details::operator_type& operation,
  19777. expression_node_ptr& sf3node,
  19778. expression_node_ptr& result)
  19779. {
  19780. if (!details::is_sf3ext_node(sf3node))
  19781. return false;
  19782. typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
  19783. sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
  19784. std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
  19785. switch (n->type())
  19786. {
  19787. case details::expression_node<Type>::e_covoc : return compile_right_impl
  19788. <typename covoc_t::sf3_type_node,ExternalType,ctype,vtype,ctype>
  19789. (expr_gen,id,t,sf3node,result);
  19790. case details::expression_node<Type>::e_covov : return compile_right_impl
  19791. <typename covov_t::sf3_type_node,ExternalType,ctype,vtype,vtype>
  19792. (expr_gen,id,t,sf3node,result);
  19793. case details::expression_node<Type>::e_vocov : return compile_right_impl
  19794. <typename vocov_t::sf3_type_node,ExternalType,vtype,ctype,vtype>
  19795. (expr_gen,id,t,sf3node,result);
  19796. case details::expression_node<Type>::e_vovoc : return compile_right_impl
  19797. <typename vovoc_t::sf3_type_node,ExternalType,vtype,vtype,ctype>
  19798. (expr_gen,id,t,sf3node,result);
  19799. case details::expression_node<Type>::e_vovov : return compile_right_impl
  19800. <typename vovov_t::sf3_type_node,ExternalType,vtype,vtype,vtype>
  19801. (expr_gen,id,t,sf3node,result);
  19802. default : return false;
  19803. }
  19804. }
  19805. // (sf3ext) o T
  19806. template <typename ExternalType>
  19807. static inline bool compile_left(expression_generator<Type>& expr_gen,
  19808. ExternalType t,
  19809. const details::operator_type& operation,
  19810. expression_node_ptr& sf3node,
  19811. expression_node_ptr& result)
  19812. {
  19813. if (!details::is_sf3ext_node(sf3node))
  19814. return false;
  19815. typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
  19816. sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
  19817. std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
  19818. switch (n->type())
  19819. {
  19820. case details::expression_node<Type>::e_covoc : return compile_left_impl
  19821. <typename covoc_t::sf3_type_node,ExternalType,ctype,vtype,ctype>
  19822. (expr_gen,id,t,sf3node,result);
  19823. case details::expression_node<Type>::e_covov : return compile_left_impl
  19824. <typename covov_t::sf3_type_node,ExternalType,ctype,vtype,vtype>
  19825. (expr_gen,id,t,sf3node,result);
  19826. case details::expression_node<Type>::e_vocov : return compile_left_impl
  19827. <typename vocov_t::sf3_type_node,ExternalType,vtype,ctype,vtype>
  19828. (expr_gen,id,t,sf3node,result);
  19829. case details::expression_node<Type>::e_vovoc : return compile_left_impl
  19830. <typename vovoc_t::sf3_type_node,ExternalType,vtype,vtype,ctype>
  19831. (expr_gen,id,t,sf3node,result);
  19832. case details::expression_node<Type>::e_vovov : return compile_left_impl
  19833. <typename vovov_t::sf3_type_node,ExternalType,vtype,vtype,vtype>
  19834. (expr_gen,id,t,sf3node,result);
  19835. default : return false;
  19836. }
  19837. }
  19838. template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
  19839. static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
  19840. const std::string& id,
  19841. ExternalType t,
  19842. expression_node_ptr& node,
  19843. expression_node_ptr& result)
  19844. {
  19845. SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
  19846. if (n)
  19847. {
  19848. T0 t0 = n->t0();
  19849. T1 t1 = n->t1();
  19850. T2 t2 = n->t2();
  19851. return synthesize_sf4ext_expression::
  19852. template compile<ExternalType,T0,T1,T2>(expr_gen,id,t,t0,t1,t2,result);
  19853. }
  19854. else
  19855. return false;
  19856. }
  19857. template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
  19858. static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
  19859. const std::string& id,
  19860. ExternalType t,
  19861. expression_node_ptr& node,
  19862. expression_node_ptr& result)
  19863. {
  19864. SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
  19865. if (n)
  19866. {
  19867. T0 t0 = n->t0();
  19868. T1 t1 = n->t1();
  19869. T2 t2 = n->t2();
  19870. return synthesize_sf4ext_expression::
  19871. template compile<T0,T1,T2,ExternalType>(expr_gen,id,t0,t1,t2,t,result);
  19872. }
  19873. else
  19874. return false;
  19875. }
  19876. };
  19877. struct synthesize_vovov_expression0
  19878. {
  19879. typedef typename vovov_t::type0 node_type;
  19880. typedef typename vovov_t::sf3_type sf3_type;
  19881. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19882. const details::operator_type& operation,
  19883. expression_node_ptr (&branch)[2])
  19884. {
  19885. // (v0 o0 v1) o1 (v2)
  19886. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
  19887. const Type& v0 = vov->v0();
  19888. const Type& v1 = vov->v1();
  19889. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  19890. const details::operator_type o0 = vov->operation();
  19891. const details::operator_type o1 = operation;
  19892. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  19893. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  19894. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  19895. expression_node_ptr result = error_node();
  19896. if (expr_gen.strength_reduction_enabled())
  19897. {
  19898. // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)
  19899. if ((details::e_div == o0) && (details::e_div == o1))
  19900. {
  19901. const bool synthesis_result =
  19902. synthesize_sf3ext_expression::
  19903. template compile<vtype,vtype,vtype>(expr_gen,"t/(t*t)",v0,v1,v2,result);
  19904. exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
  19905. return (synthesis_result) ? result : error_node();
  19906. }
  19907. }
  19908. if (synthesize_sf3ext_expression::template compile<vtype,vtype,vtype>(expr_gen,id(expr_gen,o0,o1),v0,v1,v2,result))
  19909. return result;
  19910. else if (!expr_gen.valid_operator(o0,f0))
  19911. return error_node();
  19912. else if (!expr_gen.valid_operator(o1,f1))
  19913. return error_node();
  19914. else
  19915. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,f0,f1);
  19916. }
  19917. static inline std::string id(expression_generator<Type>& expr_gen,
  19918. const details::operator_type o0, const details::operator_type o1)
  19919. {
  19920. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
  19921. }
  19922. };
  19923. struct synthesize_vovov_expression1
  19924. {
  19925. typedef typename vovov_t::type1 node_type;
  19926. typedef typename vovov_t::sf3_type sf3_type;
  19927. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19928. const details::operator_type& operation,
  19929. expression_node_ptr (&branch)[2])
  19930. {
  19931. // (v0) o0 (v1 o1 v2)
  19932. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
  19933. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  19934. const Type& v1 = vov->v0();
  19935. const Type& v2 = vov->v1();
  19936. const details::operator_type o0 = operation;
  19937. const details::operator_type o1 = vov->operation();
  19938. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  19939. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  19940. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  19941. expression_node_ptr result = error_node();
  19942. if (expr_gen.strength_reduction_enabled())
  19943. {
  19944. // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1
  19945. if ((details::e_div == o0) && (details::e_div == o1))
  19946. {
  19947. const bool synthesis_result =
  19948. synthesize_sf3ext_expression::
  19949. template compile<vtype,vtype,vtype>(expr_gen,"(t*t)/t",v0,v2,v1,result);
  19950. exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
  19951. return (synthesis_result) ? result : error_node();
  19952. }
  19953. }
  19954. if (synthesize_sf3ext_expression::template compile<vtype,vtype,vtype>(expr_gen,id(expr_gen,o0,o1),v0,v1,v2,result))
  19955. return result;
  19956. else if (!expr_gen.valid_operator(o0,f0))
  19957. return error_node();
  19958. else if (!expr_gen.valid_operator(o1,f1))
  19959. return error_node();
  19960. else
  19961. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,f0,f1);
  19962. }
  19963. static inline std::string id(expression_generator<Type>& expr_gen,
  19964. const details::operator_type o0, const details::operator_type o1)
  19965. {
  19966. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
  19967. }
  19968. };
  19969. struct synthesize_vovoc_expression0
  19970. {
  19971. typedef typename vovoc_t::type0 node_type;
  19972. typedef typename vovoc_t::sf3_type sf3_type;
  19973. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  19974. const details::operator_type& operation,
  19975. expression_node_ptr (&branch)[2])
  19976. {
  19977. // (v0 o0 v1) o1 (c)
  19978. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
  19979. const Type& v0 = vov->v0();
  19980. const Type& v1 = vov->v1();
  19981. const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
  19982. const details::operator_type o0 = vov->operation();
  19983. const details::operator_type o1 = operation;
  19984. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  19985. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  19986. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  19987. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  19988. expression_node_ptr result = error_node();
  19989. if (expr_gen.strength_reduction_enabled())
  19990. {
  19991. // (v0 / v1) / c --> (vovoc) v0 / (v1 * c)
  19992. if ((details::e_div == o0) && (details::e_div == o1))
  19993. {
  19994. const bool synthesis_result =
  19995. synthesize_sf3ext_expression::
  19996. template compile<vtype,vtype,ctype>(expr_gen,"t/(t*t)",v0,v1,c,result);
  19997. exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
  19998. return (synthesis_result) ? result : error_node();
  19999. }
  20000. }
  20001. if (synthesize_sf3ext_expression::template compile<vtype,vtype,ctype>(expr_gen,id(expr_gen,o0,o1),v0,v1,c,result))
  20002. return result;
  20003. else if (!expr_gen.valid_operator(o0,f0))
  20004. return error_node();
  20005. else if (!expr_gen.valid_operator(o1,f1))
  20006. return error_node();
  20007. else
  20008. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,f0,f1);
  20009. }
  20010. static inline std::string id(expression_generator<Type>& expr_gen,
  20011. const details::operator_type o0, const details::operator_type o1)
  20012. {
  20013. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
  20014. }
  20015. };
  20016. struct synthesize_vovoc_expression1
  20017. {
  20018. typedef typename vovoc_t::type1 node_type;
  20019. typedef typename vovoc_t::sf3_type sf3_type;
  20020. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20021. const details::operator_type& operation,
  20022. expression_node_ptr (&branch)[2])
  20023. {
  20024. // (v0) o0 (v1 o1 c)
  20025. const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
  20026. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  20027. const Type& v1 = voc->v();
  20028. const Type c = voc->c();
  20029. const details::operator_type o0 = operation;
  20030. const details::operator_type o1 = voc->operation();
  20031. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20032. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20033. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20034. expression_node_ptr result = error_node();
  20035. if (expr_gen.strength_reduction_enabled())
  20036. {
  20037. // v0 / (v1 / c) --> (vocov) (v0 * c) / v1
  20038. if ((details::e_div == o0) && (details::e_div == o1))
  20039. {
  20040. const bool synthesis_result =
  20041. synthesize_sf3ext_expression::
  20042. template compile<vtype,ctype,vtype>(expr_gen,"(t*t)/t",v0,c,v1,result);
  20043. exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
  20044. return (synthesis_result) ? result : error_node();
  20045. }
  20046. }
  20047. if (synthesize_sf3ext_expression::template compile<vtype,vtype,ctype>(expr_gen,id(expr_gen,o0,o1),v0,v1,c,result))
  20048. return result;
  20049. else if (!expr_gen.valid_operator(o0,f0))
  20050. return error_node();
  20051. else if (!expr_gen.valid_operator(o1,f1))
  20052. return error_node();
  20053. else
  20054. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,f0,f1);
  20055. }
  20056. static inline std::string id(expression_generator<Type>& expr_gen,
  20057. const details::operator_type o0, const details::operator_type o1)
  20058. {
  20059. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
  20060. }
  20061. };
  20062. struct synthesize_vocov_expression0
  20063. {
  20064. typedef typename vocov_t::type0 node_type;
  20065. typedef typename vocov_t::sf3_type sf3_type;
  20066. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20067. const details::operator_type& operation,
  20068. expression_node_ptr (&branch)[2])
  20069. {
  20070. // (v0 o0 c) o1 (v1)
  20071. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
  20072. const Type& v0 = voc->v();
  20073. const Type c = voc->c();
  20074. const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  20075. const details::operator_type o0 = voc->operation();
  20076. const details::operator_type o1 = operation;
  20077. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20078. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20079. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20080. expression_node_ptr result = error_node();
  20081. if (expr_gen.strength_reduction_enabled())
  20082. {
  20083. // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c)
  20084. if ((details::e_div == o0) && (details::e_div == o1))
  20085. {
  20086. const bool synthesis_result =
  20087. synthesize_sf3ext_expression::
  20088. template compile<vtype,vtype,ctype>(expr_gen,"t/(t*t)",v0,v1,c,result);
  20089. exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
  20090. return (synthesis_result) ? result : error_node();
  20091. }
  20092. }
  20093. if (synthesize_sf3ext_expression::template compile<vtype,ctype,vtype>(expr_gen,id(expr_gen,o0,o1),v0,c,v1,result))
  20094. return result;
  20095. else if (!expr_gen.valid_operator(o0,f0))
  20096. return error_node();
  20097. else if (!expr_gen.valid_operator(o1,f1))
  20098. return error_node();
  20099. else
  20100. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,f0,f1);
  20101. }
  20102. static inline std::string id(expression_generator<Type>& expr_gen,
  20103. const details::operator_type o0, const details::operator_type o1)
  20104. {
  20105. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
  20106. }
  20107. };
  20108. struct synthesize_vocov_expression1
  20109. {
  20110. typedef typename vocov_t::type1 node_type;
  20111. typedef typename vocov_t::sf3_type sf3_type;
  20112. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20113. const details::operator_type& operation,
  20114. expression_node_ptr (&branch)[2])
  20115. {
  20116. // (v0) o0 (c o1 v1)
  20117. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
  20118. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  20119. const Type c = cov->c();
  20120. const Type& v1 = cov->v();
  20121. const details::operator_type o0 = operation;
  20122. const details::operator_type o1 = cov->operation();
  20123. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20124. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20125. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20126. expression_node_ptr result = error_node();
  20127. if (expr_gen.strength_reduction_enabled())
  20128. {
  20129. // v0 / (c / v1) --> (vovoc) (v0 * v1) / c
  20130. if ((details::e_div == o0) && (details::e_div == o1))
  20131. {
  20132. const bool synthesis_result =
  20133. synthesize_sf3ext_expression::
  20134. template compile<vtype,vtype,ctype>(expr_gen,"(t*t)/t",v0,v1,c,result);
  20135. exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
  20136. return (synthesis_result) ? result : error_node();
  20137. }
  20138. }
  20139. if (synthesize_sf3ext_expression::template compile<vtype,ctype,vtype>(expr_gen,id(expr_gen,o0,o1),v0,c,v1,result))
  20140. return result;
  20141. else if (!expr_gen.valid_operator(o0,f0))
  20142. return error_node();
  20143. else if (!expr_gen.valid_operator(o1,f1))
  20144. return error_node();
  20145. else
  20146. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,f0,f1);
  20147. }
  20148. static inline std::string id(expression_generator<Type>& expr_gen,
  20149. const details::operator_type o0, const details::operator_type o1)
  20150. {
  20151. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
  20152. }
  20153. };
  20154. struct synthesize_covov_expression0
  20155. {
  20156. typedef typename covov_t::type0 node_type;
  20157. typedef typename covov_t::sf3_type sf3_type;
  20158. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20159. const details::operator_type& operation,
  20160. expression_node_ptr (&branch)[2])
  20161. {
  20162. // (c o0 v0) o1 (v1)
  20163. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
  20164. const Type c = cov->c();
  20165. const Type& v0 = cov->v();
  20166. const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  20167. const details::operator_type o0 = cov->operation();
  20168. const details::operator_type o1 = operation;
  20169. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20170. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20171. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20172. expression_node_ptr result = error_node();
  20173. if (expr_gen.strength_reduction_enabled())
  20174. {
  20175. // (c / v0) / v1 --> (covov) c / (v0 * v1)
  20176. if ((details::e_div == o0) && (details::e_div == o1))
  20177. {
  20178. const bool synthesis_result =
  20179. synthesize_sf3ext_expression::
  20180. template compile<ctype,vtype,vtype>(expr_gen,"t/(t*t)",c,v0,v1,result);
  20181. exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
  20182. return (synthesis_result) ? result : error_node();
  20183. }
  20184. }
  20185. if (synthesize_sf3ext_expression::template compile<ctype,vtype,vtype>(expr_gen,id(expr_gen,o0,o1),c,v0,v1,result))
  20186. return result;
  20187. else if (!expr_gen.valid_operator(o0,f0))
  20188. return error_node();
  20189. else if (!expr_gen.valid_operator(o1,f1))
  20190. return error_node();
  20191. else
  20192. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,f0,f1);
  20193. }
  20194. static inline std::string id(expression_generator<Type>& expr_gen,
  20195. const details::operator_type o0, const details::operator_type o1)
  20196. {
  20197. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
  20198. }
  20199. };
  20200. struct synthesize_covov_expression1
  20201. {
  20202. typedef typename covov_t::type1 node_type;
  20203. typedef typename covov_t::sf3_type sf3_type;
  20204. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20205. const details::operator_type& operation,
  20206. expression_node_ptr (&branch)[2])
  20207. {
  20208. // (c) o0 (v0 o1 v1)
  20209. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
  20210. const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
  20211. const Type& v0 = vov->v0();
  20212. const Type& v1 = vov->v1();
  20213. const details::operator_type o0 = operation;
  20214. const details::operator_type o1 = vov->operation();
  20215. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20216. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20217. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20218. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20219. expression_node_ptr result = error_node();
  20220. if (expr_gen.strength_reduction_enabled())
  20221. {
  20222. // c / (v0 / v1) --> (covov) (c * v1) / v0
  20223. if ((details::e_div == o0) && (details::e_div == o1))
  20224. {
  20225. const bool synthesis_result =
  20226. synthesize_sf3ext_expression::
  20227. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",c,v1,v0,result);
  20228. exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
  20229. return (synthesis_result) ? result : error_node();
  20230. }
  20231. }
  20232. if (synthesize_sf3ext_expression::template compile<ctype,vtype,vtype>(expr_gen,id(expr_gen,o0,o1),c,v0,v1,result))
  20233. return result;
  20234. else if (!expr_gen.valid_operator(o0,f0))
  20235. return error_node();
  20236. else if (!expr_gen.valid_operator(o1,f1))
  20237. return error_node();
  20238. else
  20239. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,f0,f1);
  20240. }
  20241. static inline std::string id(expression_generator<Type>& expr_gen, const details::operator_type o0, const details::operator_type o1)
  20242. {
  20243. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
  20244. }
  20245. };
  20246. struct synthesize_covoc_expression0
  20247. {
  20248. typedef typename covoc_t::type0 node_type;
  20249. typedef typename covoc_t::sf3_type sf3_type;
  20250. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20251. const details::operator_type& operation,
  20252. expression_node_ptr (&branch)[2])
  20253. {
  20254. // (c0 o0 v) o1 (c1)
  20255. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
  20256. const Type c0 = cov->c();
  20257. const Type& v = cov->v();
  20258. const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
  20259. const details::operator_type o0 = cov->operation();
  20260. const details::operator_type o1 = operation;
  20261. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20262. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20263. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20264. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20265. expression_node_ptr result = error_node();
  20266. if (expr_gen.strength_reduction_enabled())
  20267. {
  20268. // (c0 + v) + c1 --> (cov) (c0 + c1) + v
  20269. if ((details::e_add == o0) && (details::e_add == o1))
  20270. {
  20271. exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
  20272. return expr_gen.node_allocator_->
  20273. template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1,v);
  20274. }
  20275. // (c0 + v) - c1 --> (cov) (c0 - c1) + v
  20276. else if ((details::e_add == o0) && (details::e_sub == o1))
  20277. {
  20278. exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
  20279. return expr_gen.node_allocator_->
  20280. template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1,v);
  20281. }
  20282. // (c0 - v) + c1 --> (cov) (c0 + c1) - v
  20283. else if ((details::e_sub == o0) && (details::e_add == o1))
  20284. {
  20285. exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
  20286. return expr_gen.node_allocator_->
  20287. template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1,v);
  20288. }
  20289. // (c0 - v) - c1 --> (cov) (c0 - c1) - v
  20290. else if ((details::e_sub == o0) && (details::e_sub == o1))
  20291. {
  20292. exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
  20293. return expr_gen.node_allocator_->
  20294. template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1,v);
  20295. }
  20296. // (c0 * v) * c1 --> (cov) (c0 * c1) * v
  20297. else if ((details::e_mul == o0) && (details::e_mul == o1))
  20298. {
  20299. exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
  20300. return expr_gen.node_allocator_->
  20301. template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1,v);
  20302. }
  20303. // (c0 * v) / c1 --> (cov) (c0 / c1) * v
  20304. else if ((details::e_mul == o0) && (details::e_div == o1))
  20305. {
  20306. exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
  20307. return expr_gen.node_allocator_->
  20308. template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1,v);
  20309. }
  20310. // (c0 / v) * c1 --> (cov) (c0 * c1) / v
  20311. else if ((details::e_div == o0) && (details::e_mul == o1))
  20312. {
  20313. exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
  20314. return expr_gen.node_allocator_->
  20315. template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1,v);
  20316. }
  20317. // (c0 / v) / c1 --> (cov) (c0 / c1) / v
  20318. else if ((details::e_div == o0) && (details::e_div == o1))
  20319. {
  20320. exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
  20321. return expr_gen.node_allocator_->
  20322. template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1,v);
  20323. }
  20324. }
  20325. if (synthesize_sf3ext_expression::template compile<ctype,vtype,ctype>(expr_gen,id(expr_gen,o0,o1),c0,v,c1,result))
  20326. return result;
  20327. else if (!expr_gen.valid_operator(o0,f0))
  20328. return error_node();
  20329. else if (!expr_gen.valid_operator(o1,f1))
  20330. return error_node();
  20331. else
  20332. return node_type::allocate(*(expr_gen.node_allocator_),c0,v,c1,f0,f1);
  20333. }
  20334. static inline std::string id(expression_generator<Type>& expr_gen,
  20335. const details::operator_type o0, const details::operator_type o1)
  20336. {
  20337. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
  20338. }
  20339. };
  20340. struct synthesize_covoc_expression1
  20341. {
  20342. typedef typename covoc_t::type1 node_type;
  20343. typedef typename covoc_t::sf3_type sf3_type;
  20344. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20345. const details::operator_type& operation,
  20346. expression_node_ptr (&branch)[2])
  20347. {
  20348. // (c0) o0 (v o1 c1)
  20349. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
  20350. const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
  20351. const Type& v = voc->v();
  20352. const Type c1 = voc->c();
  20353. const details::operator_type o0 = operation;
  20354. const details::operator_type o1 = voc->operation();
  20355. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20356. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20357. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20358. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20359. expression_node_ptr result = error_node();
  20360. if (expr_gen.strength_reduction_enabled())
  20361. {
  20362. // (c0) + (v + c1) --> (cov) (c0 + c1) + v
  20363. if ((details::e_add == o0) && (details::e_add == o1))
  20364. {
  20365. exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
  20366. return expr_gen.node_allocator_->
  20367. template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1,v);
  20368. }
  20369. // (c0) + (v - c1) --> (cov) (c0 - c1) + v
  20370. else if ((details::e_add == o0) && (details::e_sub == o1))
  20371. {
  20372. exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
  20373. return expr_gen.node_allocator_->
  20374. template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1,v);
  20375. }
  20376. // (c0) - (v + c1) --> (cov) (c0 - c1) - v
  20377. else if ((details::e_sub == o0) && (details::e_add == o1))
  20378. {
  20379. exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
  20380. return expr_gen.node_allocator_->
  20381. template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1,v);
  20382. }
  20383. // (c0) - (v - c1) --> (cov) (c0 + c1) - v
  20384. else if ((details::e_sub == o0) && (details::e_sub == o1))
  20385. {
  20386. exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
  20387. return expr_gen.node_allocator_->
  20388. template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1,v);
  20389. }
  20390. // (c0) * (v * c1) --> (voc) v * (c0 * c1)
  20391. else if ((details::e_mul == o0) && (details::e_mul == o1))
  20392. {
  20393. exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
  20394. return expr_gen.node_allocator_->
  20395. template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1,v);
  20396. }
  20397. // (c0) * (v / c1) --> (cov) (c0 / c1) * v
  20398. else if ((details::e_mul == o0) && (details::e_div == o1))
  20399. {
  20400. exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
  20401. return expr_gen.node_allocator_->
  20402. template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1,v);
  20403. }
  20404. // (c0) / (v * c1) --> (cov) (c0 / c1) / v
  20405. else if ((details::e_div == o0) && (details::e_mul == o1))
  20406. {
  20407. exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
  20408. return expr_gen.node_allocator_->
  20409. template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1,v);
  20410. }
  20411. // (c0) / (v / c1) --> (cov) (c0 * c1) / v
  20412. else if ((details::e_div == o0) && (details::e_div == o1))
  20413. {
  20414. exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
  20415. return expr_gen.node_allocator_->
  20416. template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1,v);
  20417. }
  20418. }
  20419. if (synthesize_sf3ext_expression::template compile<ctype,vtype,ctype>(expr_gen,id(expr_gen,o0,o1),c0,v,c1,result))
  20420. return result;
  20421. else if (!expr_gen.valid_operator(o0,f0))
  20422. return error_node();
  20423. else if (!expr_gen.valid_operator(o1,f1))
  20424. return error_node();
  20425. else
  20426. return node_type::allocate(*(expr_gen.node_allocator_),c0,v,c1,f0,f1);
  20427. }
  20428. static inline std::string id(expression_generator<Type>& expr_gen,
  20429. const details::operator_type o0, const details::operator_type o1)
  20430. {
  20431. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
  20432. }
  20433. };
  20434. struct synthesize_cocov_expression0
  20435. {
  20436. typedef typename cocov_t::type0 node_type;
  20437. static inline expression_node_ptr process(expression_generator<Type>&, const details::operator_type&, expression_node_ptr (&)[2])
  20438. {
  20439. // (c0 o0 c1) o1 (v) - Not possible.
  20440. return error_node();
  20441. }
  20442. };
  20443. struct synthesize_cocov_expression1
  20444. {
  20445. typedef typename cocov_t::type1 node_type;
  20446. typedef typename cocov_t::sf3_type sf3_type;
  20447. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20448. const details::operator_type& operation,
  20449. expression_node_ptr (&branch)[2])
  20450. {
  20451. // (c0) o0 (c1 o1 v)
  20452. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
  20453. const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
  20454. const Type c1 = cov->c();
  20455. const Type& v = cov->v();
  20456. const details::operator_type o0 = operation;
  20457. const details::operator_type o1 = cov->operation();
  20458. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20459. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20460. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20461. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20462. expression_node_ptr result = error_node();
  20463. if (expr_gen.strength_reduction_enabled())
  20464. {
  20465. // (c0) + (c1 + v) --> (cov) (c0 + c1) + v
  20466. if ((details::e_add == o0) && (details::e_add == o1))
  20467. {
  20468. exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
  20469. return expr_gen.node_allocator_->
  20470. template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1,v);
  20471. }
  20472. // (c0) + (c1 - v) --> (cov) (c0 + c1) - v
  20473. else if ((details::e_add == o0) && (details::e_sub == o1))
  20474. {
  20475. exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
  20476. return expr_gen.node_allocator_->
  20477. template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1,v);
  20478. }
  20479. // (c0) - (c1 + v) --> (cov) (c0 - c1) - v
  20480. else if ((details::e_sub == o0) && (details::e_add == o1))
  20481. {
  20482. exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
  20483. return expr_gen.node_allocator_->
  20484. template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1,v);
  20485. }
  20486. // (c0) - (c1 - v) --> (cov) (c0 - c1) + v
  20487. else if ((details::e_sub == o0) && (details::e_sub == o1))
  20488. {
  20489. exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
  20490. return expr_gen.node_allocator_->
  20491. template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1,v);
  20492. }
  20493. // (c0) * (c1 * v) --> (cov) (c0 * c1) * v
  20494. else if ((details::e_mul == o0) && (details::e_mul == o1))
  20495. {
  20496. exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
  20497. return expr_gen.node_allocator_->
  20498. template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1,v);
  20499. }
  20500. // (c0) * (c1 / v) --> (cov) (c0 * c1) / v
  20501. else if ((details::e_mul == o0) && (details::e_div == o1))
  20502. {
  20503. exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
  20504. return expr_gen.node_allocator_->
  20505. template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1,v);
  20506. }
  20507. // (c0) / (c1 * v) --> (cov) (c0 / c1) / v
  20508. else if ((details::e_div == o0) && (details::e_mul == o1))
  20509. {
  20510. exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
  20511. return expr_gen.node_allocator_->
  20512. template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1,v);
  20513. }
  20514. // (c0) / (c1 / v) --> (cov) (c0 / c1) * v
  20515. else if ((details::e_div == o0) && (details::e_div == o1))
  20516. {
  20517. exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
  20518. return expr_gen.node_allocator_->
  20519. template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1,v);
  20520. }
  20521. }
  20522. if (synthesize_sf3ext_expression::template compile<ctype,ctype,vtype>(expr_gen,id(expr_gen,o0,o1),c0,c1,v,result))
  20523. return result;
  20524. else if (!expr_gen.valid_operator(o0,f0))
  20525. return error_node();
  20526. else if (!expr_gen.valid_operator(o1,f1))
  20527. return error_node();
  20528. else
  20529. return node_type::allocate(*(expr_gen.node_allocator_),c0,c1,v,f0,f1);
  20530. }
  20531. static inline std::string id(expression_generator<Type>& expr_gen, const details::operator_type o0, const details::operator_type o1)
  20532. {
  20533. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
  20534. }
  20535. };
  20536. struct synthesize_vococ_expression0
  20537. {
  20538. typedef typename vococ_t::type0 node_type;
  20539. typedef typename vococ_t::sf3_type sf3_type;
  20540. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20541. const details::operator_type& operation,
  20542. expression_node_ptr (&branch)[2])
  20543. {
  20544. // (v o0 c0) o1 (c1)
  20545. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
  20546. const Type& v = voc->v();
  20547. const Type& c0 = voc->c();
  20548. const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
  20549. const details::operator_type o0 = voc->operation();
  20550. const details::operator_type o1 = operation;
  20551. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20552. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20553. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20554. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20555. expression_node_ptr result = error_node();
  20556. if (expr_gen.strength_reduction_enabled())
  20557. {
  20558. // (v + c0) + c1 --> (voc) v + (c0 + c1)
  20559. if ((details::e_add == o0) && (details::e_add == o1))
  20560. {
  20561. exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
  20562. return expr_gen.node_allocator_->
  20563. template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v,c0 + c1);
  20564. }
  20565. // (v + c0) - c1 --> (voc) v + (c0 - c1)
  20566. else if ((details::e_add == o0) && (details::e_sub == o1))
  20567. {
  20568. exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
  20569. return expr_gen.node_allocator_->
  20570. template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v,c0 - c1);
  20571. }
  20572. // (v - c0) + c1 --> (voc) v - (c0 + c1)
  20573. else if ((details::e_sub == o0) && (details::e_add == o1))
  20574. {
  20575. exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
  20576. return expr_gen.node_allocator_->
  20577. template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v,c1 - c0);
  20578. }
  20579. // (v - c0) - c1 --> (voc) v - (c0 + c1)
  20580. else if ((details::e_sub == o0) && (details::e_sub == o1))
  20581. {
  20582. exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
  20583. return expr_gen.node_allocator_->
  20584. template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v,c0 + c1);
  20585. }
  20586. // (v * c0) * c1 --> (voc) v * (c0 * c1)
  20587. else if ((details::e_mul == o0) && (details::e_mul == o1))
  20588. {
  20589. exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
  20590. return expr_gen.node_allocator_->
  20591. template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v,c0 * c1);
  20592. }
  20593. // (v * c0) / c1 --> (voc) v * (c0 / c1)
  20594. else if ((details::e_mul == o0) && (details::e_div == o1))
  20595. {
  20596. exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
  20597. return expr_gen.node_allocator_->
  20598. template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v,c0 / c1);
  20599. }
  20600. // (v / c0) * c1 --> (voc) v * (c1 / c0)
  20601. else if ((details::e_div == o0) && (details::e_mul == o1))
  20602. {
  20603. exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
  20604. return expr_gen.node_allocator_->
  20605. template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v,c1 / c0);
  20606. }
  20607. // (v / c0) / c1 --> (voc) v / (c0 * c1)
  20608. else if ((details::e_div == o0) && (details::e_div == o1))
  20609. {
  20610. exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
  20611. return expr_gen.node_allocator_->
  20612. template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v,c0 * c1);
  20613. }
  20614. }
  20615. if (synthesize_sf3ext_expression::template compile<vtype,ctype,ctype>(expr_gen,id(expr_gen,o0,o1),v,c0,c1,result))
  20616. return result;
  20617. else if (!expr_gen.valid_operator(o0,f0))
  20618. return error_node();
  20619. else if (!expr_gen.valid_operator(o1,f1))
  20620. return error_node();
  20621. else
  20622. return node_type::allocate(*(expr_gen.node_allocator_),v,c0,c1,f0,f1);
  20623. }
  20624. static inline std::string id(expression_generator<Type>& expr_gen,
  20625. const details::operator_type o0, const details::operator_type o1)
  20626. {
  20627. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
  20628. }
  20629. };
  20630. struct synthesize_vococ_expression1
  20631. {
  20632. typedef typename vococ_t::type0 node_type;
  20633. static inline expression_node_ptr process(expression_generator<Type>&, const details::operator_type&, expression_node_ptr (&)[2])
  20634. {
  20635. // (v) o0 (c0 o1 c1) - Not possible.
  20636. exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n"));
  20637. return error_node();
  20638. }
  20639. };
  20640. struct synthesize_vovovov_expression0
  20641. {
  20642. typedef typename vovovov_t::type0 node_type;
  20643. typedef typename vovovov_t::sf4_type sf4_type;
  20644. typedef typename node_type::T0 T0;
  20645. typedef typename node_type::T1 T1;
  20646. typedef typename node_type::T2 T2;
  20647. typedef typename node_type::T3 T3;
  20648. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20649. const details::operator_type& operation,
  20650. expression_node_ptr (&branch)[2])
  20651. {
  20652. // (v0 o0 v1) o1 (v2 o2 v3)
  20653. const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
  20654. const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
  20655. const Type& v0 = vov0->v0();
  20656. const Type& v1 = vov0->v1();
  20657. const Type& v2 = vov1->v0();
  20658. const Type& v3 = vov1->v1();
  20659. const details::operator_type o0 = vov0->operation();
  20660. const details::operator_type o1 = operation;
  20661. const details::operator_type o2 = vov1->operation();
  20662. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20663. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20664. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  20665. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20666. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20667. expression_node_ptr result = error_node();
  20668. if (expr_gen.strength_reduction_enabled())
  20669. {
  20670. // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)
  20671. if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  20672. {
  20673. const bool synthesis_result =
  20674. synthesize_sf4ext_expression::
  20675. template compile<vtype,vtype,vtype,vtype>(expr_gen,"(t*t)/(t*t)",v0,v2,v1,v3,result);
  20676. exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
  20677. return (synthesis_result) ? result : error_node();
  20678. }
  20679. // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)
  20680. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  20681. {
  20682. const bool synthesis_result =
  20683. synthesize_sf4ext_expression::
  20684. template compile<vtype,vtype,vtype,vtype>(expr_gen,"(t*t)/(t*t)",v0,v3,v1,v2,result);
  20685. exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
  20686. return (synthesis_result) ? result : error_node();
  20687. }
  20688. }
  20689. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
  20690. return result;
  20691. else if (!expr_gen.valid_operator(o0,f0))
  20692. return error_node();
  20693. else if (!expr_gen.valid_operator(o1,f1))
  20694. return error_node();
  20695. else if (!expr_gen.valid_operator(o2,f2))
  20696. return error_node();
  20697. else
  20698. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,v3,f0,f1,f2);
  20699. }
  20700. static inline std::string id(expression_generator<Type>& expr_gen,
  20701. const details::operator_type o0,
  20702. const details::operator_type o1,
  20703. const details::operator_type o2)
  20704. {
  20705. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  20706. }
  20707. };
  20708. struct synthesize_vovovoc_expression0
  20709. {
  20710. typedef typename vovovoc_t::type0 node_type;
  20711. typedef typename vovovoc_t::sf4_type sf4_type;
  20712. typedef typename node_type::T0 T0;
  20713. typedef typename node_type::T1 T1;
  20714. typedef typename node_type::T2 T2;
  20715. typedef typename node_type::T3 T3;
  20716. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20717. const details::operator_type& operation,
  20718. expression_node_ptr (&branch)[2])
  20719. {
  20720. // (v0 o0 v1) o1 (v2 o2 c)
  20721. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
  20722. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
  20723. const Type& v0 = vov->v0();
  20724. const Type& v1 = vov->v1();
  20725. const Type& v2 = voc->v ();
  20726. const Type c = voc->c ();
  20727. const details::operator_type o0 = vov->operation();
  20728. const details::operator_type o1 = operation;
  20729. const details::operator_type o2 = voc->operation();
  20730. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20731. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20732. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  20733. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20734. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20735. expression_node_ptr result = error_node();
  20736. if (expr_gen.strength_reduction_enabled())
  20737. {
  20738. // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)
  20739. if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  20740. {
  20741. const bool synthesis_result =
  20742. synthesize_sf4ext_expression::
  20743. template compile<vtype,vtype,vtype,ctype>(expr_gen,"(t*t)/(t*t)",v0,v2,v1,c,result);
  20744. exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
  20745. return (synthesis_result) ? result : error_node();
  20746. }
  20747. // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)
  20748. if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  20749. {
  20750. const bool synthesis_result =
  20751. synthesize_sf4ext_expression::
  20752. template compile<vtype,ctype,vtype,vtype>(expr_gen,"(t*t)/(t*t)",v0,c,v1,v2,result);
  20753. exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
  20754. return (synthesis_result) ? result : error_node();
  20755. }
  20756. }
  20757. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,c,result))
  20758. return result;
  20759. else if (!expr_gen.valid_operator(o0,f0))
  20760. return error_node();
  20761. else if (!expr_gen.valid_operator(o1,f1))
  20762. return error_node();
  20763. else if (!expr_gen.valid_operator(o2,f2))
  20764. return error_node();
  20765. else
  20766. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,c,f0,f1,f2);
  20767. }
  20768. static inline std::string id(expression_generator<Type>& expr_gen,
  20769. const details::operator_type o0,
  20770. const details::operator_type o1,
  20771. const details::operator_type o2)
  20772. {
  20773. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  20774. }
  20775. };
  20776. struct synthesize_vovocov_expression0
  20777. {
  20778. typedef typename vovocov_t::type0 node_type;
  20779. typedef typename vovocov_t::sf4_type sf4_type;
  20780. typedef typename node_type::T0 T0;
  20781. typedef typename node_type::T1 T1;
  20782. typedef typename node_type::T2 T2;
  20783. typedef typename node_type::T3 T3;
  20784. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20785. const details::operator_type& operation,
  20786. expression_node_ptr (&branch)[2])
  20787. {
  20788. // (v0 o0 v1) o1 (c o2 v2)
  20789. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
  20790. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
  20791. const Type& v0 = vov->v0();
  20792. const Type& v1 = vov->v1();
  20793. const Type& v2 = cov->v ();
  20794. const Type c = cov->c ();
  20795. const details::operator_type o0 = vov->operation();
  20796. const details::operator_type o1 = operation;
  20797. const details::operator_type o2 = cov->operation();
  20798. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20799. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20800. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  20801. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20802. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20803. expression_node_ptr result = error_node();
  20804. if (expr_gen.strength_reduction_enabled())
  20805. {
  20806. // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)
  20807. if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  20808. {
  20809. const bool synthesis_result =
  20810. synthesize_sf4ext_expression::
  20811. template compile<vtype,ctype,vtype,vtype>(expr_gen,"(t*t)/(t*t)",v0,c,v1,v2,result);
  20812. exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
  20813. return (synthesis_result) ? result : error_node();
  20814. }
  20815. // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)
  20816. if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  20817. {
  20818. const bool synthesis_result =
  20819. synthesize_sf4ext_expression::
  20820. template compile<vtype,vtype,vtype,ctype>(expr_gen,"(t*t)/(t*t)",v0,v2,v1,c,result);
  20821. exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
  20822. return (synthesis_result) ? result : error_node();
  20823. }
  20824. }
  20825. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,c,v2,result))
  20826. return result;
  20827. else if (!expr_gen.valid_operator(o0,f0))
  20828. return error_node();
  20829. else if (!expr_gen.valid_operator(o1,f1))
  20830. return error_node();
  20831. else if (!expr_gen.valid_operator(o2,f2))
  20832. return error_node();
  20833. else
  20834. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,v2,f0,f1,f2);
  20835. }
  20836. static inline std::string id(expression_generator<Type>& expr_gen,
  20837. const details::operator_type o0,
  20838. const details::operator_type o1,
  20839. const details::operator_type o2)
  20840. {
  20841. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  20842. }
  20843. };
  20844. struct synthesize_vocovov_expression0
  20845. {
  20846. typedef typename vocovov_t::type0 node_type;
  20847. typedef typename vocovov_t::sf4_type sf4_type;
  20848. typedef typename node_type::T0 T0;
  20849. typedef typename node_type::T1 T1;
  20850. typedef typename node_type::T2 T2;
  20851. typedef typename node_type::T3 T3;
  20852. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20853. const details::operator_type& operation,
  20854. expression_node_ptr (&branch)[2])
  20855. {
  20856. // (v0 o0 c) o1 (v1 o2 v2)
  20857. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
  20858. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
  20859. const Type c = voc->c ();
  20860. const Type& v0 = voc->v ();
  20861. const Type& v1 = vov->v0();
  20862. const Type& v2 = vov->v1();
  20863. const details::operator_type o0 = voc->operation();
  20864. const details::operator_type o1 = operation;
  20865. const details::operator_type o2 = vov->operation();
  20866. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20867. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20868. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  20869. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20870. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20871. expression_node_ptr result = error_node();
  20872. if (expr_gen.strength_reduction_enabled())
  20873. {
  20874. // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)
  20875. if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  20876. {
  20877. const bool synthesis_result =
  20878. synthesize_sf4ext_expression::
  20879. template compile<vtype,vtype,ctype,vtype>(expr_gen,"(t*t)/(t*t)",v0,v1,c,v2,result);
  20880. exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
  20881. return (synthesis_result) ? result : error_node();
  20882. }
  20883. // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)
  20884. if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  20885. {
  20886. const bool synthesis_result =
  20887. synthesize_sf4ext_expression::
  20888. template compile<vtype,vtype,ctype,vtype>(expr_gen,"(t*t)/(t*t)",v0,v2,c,v1,result);
  20889. exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
  20890. return (synthesis_result) ? result : error_node();
  20891. }
  20892. }
  20893. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c,v1,v2,result))
  20894. return result;
  20895. else if (!expr_gen.valid_operator(o0,f0))
  20896. return error_node();
  20897. else if (!expr_gen.valid_operator(o1,f1))
  20898. return error_node();
  20899. else if (!expr_gen.valid_operator(o2,f2))
  20900. return error_node();
  20901. else
  20902. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,v2,f0,f1,f2);
  20903. }
  20904. static inline std::string id(expression_generator<Type>& expr_gen,
  20905. const details::operator_type o0,
  20906. const details::operator_type o1,
  20907. const details::operator_type o2)
  20908. {
  20909. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  20910. }
  20911. };
  20912. struct synthesize_covovov_expression0
  20913. {
  20914. typedef typename covovov_t::type0 node_type;
  20915. typedef typename covovov_t::sf4_type sf4_type;
  20916. typedef typename node_type::T0 T0;
  20917. typedef typename node_type::T1 T1;
  20918. typedef typename node_type::T2 T2;
  20919. typedef typename node_type::T3 T3;
  20920. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20921. const details::operator_type& operation,
  20922. expression_node_ptr (&branch)[2])
  20923. {
  20924. // (c o0 v0) o1 (v1 o2 v2)
  20925. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
  20926. const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
  20927. const Type c = cov->c ();
  20928. const Type& v0 = cov->v ();
  20929. const Type& v1 = vov->v0();
  20930. const Type& v2 = vov->v1();
  20931. const details::operator_type o0 = cov->operation();
  20932. const details::operator_type o1 = operation;
  20933. const details::operator_type o2 = vov->operation();
  20934. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  20935. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  20936. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  20937. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  20938. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  20939. expression_node_ptr result = error_node();
  20940. if (expr_gen.strength_reduction_enabled())
  20941. {
  20942. // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)
  20943. if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  20944. {
  20945. const bool synthesis_result =
  20946. synthesize_sf4ext_expression::
  20947. template compile<ctype,vtype,vtype,vtype>(expr_gen,"(t*t)/(t*t)",c,v1,v0,v2,result);
  20948. exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
  20949. return (synthesis_result) ? result : error_node();
  20950. }
  20951. // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)
  20952. if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  20953. {
  20954. const bool synthesis_result =
  20955. synthesize_sf4ext_expression::
  20956. template compile<ctype,vtype,vtype,vtype>(expr_gen,"(t*t)/(t*t)",c,v2,v0,v1,result);
  20957. exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
  20958. return (synthesis_result) ? result : error_node();
  20959. }
  20960. }
  20961. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c,v0,v1,v2,result))
  20962. return result;
  20963. else if (!expr_gen.valid_operator(o0,f0))
  20964. return error_node();
  20965. else if (!expr_gen.valid_operator(o1,f1))
  20966. return error_node();
  20967. else if (!expr_gen.valid_operator(o2,f2))
  20968. return error_node();
  20969. else
  20970. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,v2,f0,f1,f2);
  20971. }
  20972. static inline std::string id(expression_generator<Type>& expr_gen,
  20973. const details::operator_type o0,
  20974. const details::operator_type o1,
  20975. const details::operator_type o2)
  20976. {
  20977. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  20978. }
  20979. };
  20980. struct synthesize_covocov_expression0
  20981. {
  20982. typedef typename covocov_t::type0 node_type;
  20983. typedef typename covocov_t::sf4_type sf4_type;
  20984. typedef typename node_type::T0 T0;
  20985. typedef typename node_type::T1 T1;
  20986. typedef typename node_type::T2 T2;
  20987. typedef typename node_type::T3 T3;
  20988. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  20989. const details::operator_type& operation,
  20990. expression_node_ptr (&branch)[2])
  20991. {
  20992. // (c0 o0 v0) o1 (c1 o2 v1)
  20993. const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
  20994. const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
  20995. const Type c0 = cov0->c();
  20996. const Type& v0 = cov0->v();
  20997. const Type c1 = cov1->c();
  20998. const Type& v1 = cov1->v();
  20999. const details::operator_type o0 = cov0->operation();
  21000. const details::operator_type o1 = operation;
  21001. const details::operator_type o2 = cov1->operation();
  21002. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21003. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  21004. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  21005. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21006. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21007. expression_node_ptr result = error_node();
  21008. if (expr_gen.strength_reduction_enabled())
  21009. {
  21010. // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
  21011. if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
  21012. {
  21013. const bool synthesis_result =
  21014. synthesize_sf3ext_expression::
  21015. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)+t",(c0 + c1),v0,v1,result);
  21016. exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
  21017. return (synthesis_result) ? result : error_node();
  21018. }
  21019. // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
  21020. else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
  21021. {
  21022. const bool synthesis_result =
  21023. synthesize_sf3ext_expression::
  21024. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)-t",(c0 - c1),v0,v1,result);
  21025. exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
  21026. return (synthesis_result) ? result : error_node();
  21027. }
  21028. // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1
  21029. else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
  21030. {
  21031. const bool synthesis_result =
  21032. synthesize_sf3ext_expression::
  21033. template compile<ctype,vtype,vtype>(expr_gen,"(t-t)+t",(c0 - c1),v0,v1,result);
  21034. exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
  21035. return (synthesis_result) ? result : error_node();
  21036. }
  21037. // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
  21038. else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
  21039. {
  21040. const bool synthesis_result =
  21041. synthesize_sf3ext_expression::
  21042. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)*t",(c0 * c1),v0,v1,result);
  21043. exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
  21044. return (synthesis_result) ? result : error_node();
  21045. }
  21046. // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)
  21047. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21048. {
  21049. const bool synthesis_result =
  21050. synthesize_sf3ext_expression::
  21051. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c0 / c1),v0,v1,result);
  21052. exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
  21053. return (synthesis_result) ? result : error_node();
  21054. }
  21055. // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)
  21056. else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  21057. {
  21058. const bool synthesis_result =
  21059. synthesize_sf3ext_expression::
  21060. template compile<ctype,vtype,vtype>(expr_gen,"t/(t*t)",(c0 * c1),v0,v1,result);
  21061. exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
  21062. return (synthesis_result) ? result : error_node();
  21063. }
  21064. // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0
  21065. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  21066. {
  21067. const bool synthesis_result =
  21068. synthesize_sf3ext_expression::
  21069. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c0 / c1),v1,v0,result);
  21070. exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
  21071. return (synthesis_result) ? result : error_node();
  21072. }
  21073. // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
  21074. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
  21075. {
  21076. const bool synthesis_result =
  21077. synthesize_sf3ext_expression::
  21078. template compile<ctype,vtype,vtype>(expr_gen,"t*(t*t)",(c0 / c1),v0,v1,result);
  21079. exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
  21080. return (synthesis_result) ? result : error_node();
  21081. }
  21082. // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)
  21083. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21084. {
  21085. const bool synthesis_result =
  21086. synthesize_sf3ext_expression::
  21087. template compile<ctype,vtype,vtype>(expr_gen,"t/(t*t)",(c0 / c1),v0,v1,result);
  21088. exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
  21089. return (synthesis_result) ? result : error_node();
  21090. }
  21091. // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)
  21092. else if (
  21093. (std::equal_to<T>()(c0,c1)) &&
  21094. (details::e_mul == o0) &&
  21095. (details::e_mul == o2) &&
  21096. (
  21097. (details::e_add == o1) ||
  21098. (details::e_sub == o1)
  21099. )
  21100. )
  21101. {
  21102. std::string specfunc;
  21103. switch (o1)
  21104. {
  21105. case details::e_add : specfunc = "t*(t+t)"; break;
  21106. case details::e_sub : specfunc = "t*(t-t)"; break;
  21107. default : return error_node();
  21108. }
  21109. const bool synthesis_result =
  21110. synthesize_sf3ext_expression::
  21111. template compile<ctype,vtype,vtype>(expr_gen,specfunc,c0,v0,v1,result);
  21112. exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
  21113. return (synthesis_result) ? result : error_node();
  21114. }
  21115. }
  21116. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,c1,v1,result))
  21117. return result;
  21118. else if (!expr_gen.valid_operator(o0,f0))
  21119. return error_node();
  21120. else if (!expr_gen.valid_operator(o1,f1))
  21121. return error_node();
  21122. else if (!expr_gen.valid_operator(o2,f2))
  21123. return error_node();
  21124. else
  21125. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,c1,v1,f0,f1,f2);
  21126. }
  21127. static inline std::string id(expression_generator<Type>& expr_gen,
  21128. const details::operator_type o0,
  21129. const details::operator_type o1,
  21130. const details::operator_type o2)
  21131. {
  21132. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  21133. }
  21134. };
  21135. struct synthesize_vocovoc_expression0
  21136. {
  21137. typedef typename vocovoc_t::type0 node_type;
  21138. typedef typename vocovoc_t::sf4_type sf4_type;
  21139. typedef typename node_type::T0 T0;
  21140. typedef typename node_type::T1 T1;
  21141. typedef typename node_type::T2 T2;
  21142. typedef typename node_type::T3 T3;
  21143. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21144. const details::operator_type& operation,
  21145. expression_node_ptr (&branch)[2])
  21146. {
  21147. // (v0 o0 c0) o1 (v1 o2 c1)
  21148. const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
  21149. const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
  21150. const Type c0 = voc0->c();
  21151. const Type& v0 = voc0->v();
  21152. const Type c1 = voc1->c();
  21153. const Type& v1 = voc1->v();
  21154. const details::operator_type o0 = voc0->operation();
  21155. const details::operator_type o1 = operation;
  21156. const details::operator_type o2 = voc1->operation();
  21157. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21158. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  21159. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  21160. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21161. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21162. expression_node_ptr result = error_node();
  21163. if (expr_gen.strength_reduction_enabled())
  21164. {
  21165. // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
  21166. if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
  21167. {
  21168. const bool synthesis_result =
  21169. synthesize_sf3ext_expression::
  21170. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)+t",(c0 + c1),v0,v1,result);
  21171. exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
  21172. return (synthesis_result) ? result : error_node();
  21173. }
  21174. // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
  21175. else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
  21176. {
  21177. const bool synthesis_result =
  21178. synthesize_sf3ext_expression::
  21179. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)-t",(c0 - c1),v0,v1,result);
  21180. exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
  21181. return (synthesis_result) ? result : error_node();
  21182. }
  21183. // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1
  21184. else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
  21185. {
  21186. const bool synthesis_result =
  21187. synthesize_sf3ext_expression::
  21188. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)-t",(c1 - c0),v0,v1,result);
  21189. exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
  21190. return (synthesis_result) ? result : error_node();
  21191. }
  21192. // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
  21193. else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
  21194. {
  21195. const bool synthesis_result =
  21196. synthesize_sf3ext_expression::
  21197. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)*t",(c0 * c1),v0,v1,result);
  21198. exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
  21199. return (synthesis_result) ? result : error_node();
  21200. }
  21201. // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
  21202. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21203. {
  21204. const bool synthesis_result =
  21205. synthesize_sf3ext_expression::
  21206. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c0 / c1),v0,v1,result);
  21207. exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
  21208. return (synthesis_result) ? result : error_node();
  21209. }
  21210. // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1
  21211. else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  21212. {
  21213. const bool synthesis_result =
  21214. synthesize_sf3ext_expression::
  21215. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)*t",Type(1) / (c0 * c1),v0,v1,result);
  21216. exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
  21217. return (synthesis_result) ? result : error_node();
  21218. }
  21219. // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1
  21220. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  21221. {
  21222. const bool synthesis_result =
  21223. synthesize_sf3ext_expression::
  21224. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c1 / c0),v0,v1,result);
  21225. exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
  21226. return (synthesis_result) ? result : error_node();
  21227. }
  21228. // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
  21229. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
  21230. {
  21231. const bool synthesis_result =
  21232. synthesize_sf3ext_expression::
  21233. template compile<ctype,vtype,vtype>(expr_gen,"t*(t/t)",(c0 * c1),v0,v1,result);
  21234. exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
  21235. return (synthesis_result) ? result : error_node();
  21236. }
  21237. // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1
  21238. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21239. {
  21240. const bool synthesis_result =
  21241. synthesize_sf3ext_expression::
  21242. template compile<ctype,vtype,vtype>(expr_gen,"t*(t/t)",Type(1) / (c0 * c1),v0,v1,result);
  21243. exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
  21244. return (synthesis_result) ? result : error_node();
  21245. }
  21246. // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)
  21247. else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
  21248. {
  21249. const bool synthesis_result =
  21250. synthesize_sf4ext_expression::
  21251. template compile<vtype,ctype,vtype,ctype>(expr_gen,"(t*t)*(t+t)",v0,T(1) / c0,v1,c1,result);
  21252. exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
  21253. return (synthesis_result) ? result : error_node();
  21254. }
  21255. // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)
  21256. else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
  21257. {
  21258. const bool synthesis_result =
  21259. synthesize_sf4ext_expression::
  21260. template compile<vtype,ctype,vtype,ctype>(expr_gen,"(t*t)*(t-t)",v0,T(1) / c0,v1,c1,result);
  21261. exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
  21262. return (synthesis_result) ? result : error_node();
  21263. }
  21264. // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
  21265. else if (
  21266. (std::equal_to<T>()(c0,c1)) &&
  21267. (details::e_mul == o0) &&
  21268. (details::e_mul == o2) &&
  21269. (
  21270. (details::e_add == o1) ||
  21271. (details::e_sub == o1)
  21272. )
  21273. )
  21274. {
  21275. std::string specfunc;
  21276. switch (o1)
  21277. {
  21278. case details::e_add : specfunc = "t*(t+t)"; break;
  21279. case details::e_sub : specfunc = "t*(t-t)"; break;
  21280. default : return error_node();
  21281. }
  21282. const bool synthesis_result =
  21283. synthesize_sf3ext_expression::
  21284. template compile<ctype,vtype,vtype>(expr_gen,specfunc,c0,v0,v1,result);
  21285. exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
  21286. return (synthesis_result) ? result : error_node();
  21287. }
  21288. // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c
  21289. else if (
  21290. (std::equal_to<T>()(c0,c1)) &&
  21291. (details::e_div == o0) &&
  21292. (details::e_div == o2) &&
  21293. (
  21294. (details::e_add == o1) ||
  21295. (details::e_sub == o1)
  21296. )
  21297. )
  21298. {
  21299. std::string specfunc;
  21300. switch (o1)
  21301. {
  21302. case details::e_add : specfunc = "(t+t)/t"; break;
  21303. case details::e_sub : specfunc = "(t-t)/t"; break;
  21304. default : return error_node();
  21305. }
  21306. const bool synthesis_result =
  21307. synthesize_sf3ext_expression::
  21308. template compile<ctype,vtype,vtype>(expr_gen,specfunc,c0,v0,v1,result);
  21309. exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
  21310. return (synthesis_result) ? result : error_node();
  21311. }
  21312. }
  21313. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,v1,c1,result))
  21314. return result;
  21315. else if (!expr_gen.valid_operator(o0,f0))
  21316. return error_node();
  21317. else if (!expr_gen.valid_operator(o1,f1))
  21318. return error_node();
  21319. else if (!expr_gen.valid_operator(o2,f2))
  21320. return error_node();
  21321. else
  21322. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,v1,c1,f0,f1,f2);
  21323. }
  21324. static inline std::string id(expression_generator<Type>& expr_gen,
  21325. const details::operator_type o0,
  21326. const details::operator_type o1,
  21327. const details::operator_type o2)
  21328. {
  21329. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  21330. }
  21331. };
  21332. struct synthesize_covovoc_expression0
  21333. {
  21334. typedef typename covovoc_t::type0 node_type;
  21335. typedef typename covovoc_t::sf4_type sf4_type;
  21336. typedef typename node_type::T0 T0;
  21337. typedef typename node_type::T1 T1;
  21338. typedef typename node_type::T2 T2;
  21339. typedef typename node_type::T3 T3;
  21340. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21341. const details::operator_type& operation,
  21342. expression_node_ptr (&branch)[2])
  21343. {
  21344. // (c0 o0 v0) o1 (v1 o2 c1)
  21345. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
  21346. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
  21347. const Type c0 = cov->c();
  21348. const Type& v0 = cov->v();
  21349. const Type c1 = voc->c();
  21350. const Type& v1 = voc->v();
  21351. const details::operator_type o0 = cov->operation();
  21352. const details::operator_type o1 = operation;
  21353. const details::operator_type o2 = voc->operation();
  21354. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21355. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  21356. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  21357. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21358. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21359. expression_node_ptr result = error_node();
  21360. if (expr_gen.strength_reduction_enabled())
  21361. {
  21362. // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
  21363. if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
  21364. {
  21365. const bool synthesis_result =
  21366. synthesize_sf3ext_expression::
  21367. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)+t",(c0 + c1),v0,v1,result);
  21368. exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
  21369. return (synthesis_result) ? result : error_node();
  21370. }
  21371. // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
  21372. else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
  21373. {
  21374. const bool synthesis_result =
  21375. synthesize_sf3ext_expression::
  21376. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)-t",(c0 - c1),v0,v1,result);
  21377. exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
  21378. return (synthesis_result) ? result : error_node();
  21379. }
  21380. // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1
  21381. else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
  21382. {
  21383. const bool synthesis_result =
  21384. synthesize_sf3ext_expression::
  21385. template compile<ctype,vtype,vtype>(expr_gen,"t-(t+t)",(c0 + c1),v0,v1,result);
  21386. exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
  21387. return (synthesis_result) ? result : error_node();
  21388. }
  21389. // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
  21390. else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
  21391. {
  21392. const bool synthesis_result =
  21393. synthesize_sf3ext_expression::
  21394. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)*t",(c0 * c1),v0,v1,result);
  21395. exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
  21396. return (synthesis_result) ? result : error_node();
  21397. }
  21398. // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
  21399. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21400. {
  21401. const bool synthesis_result =
  21402. synthesize_sf3ext_expression::
  21403. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c0 / c1),v0,v1,result);
  21404. exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
  21405. return (synthesis_result) ? result : error_node();
  21406. }
  21407. // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)
  21408. else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  21409. {
  21410. const bool synthesis_result =
  21411. synthesize_sf3ext_expression::
  21412. template compile<ctype,vtype,vtype>(expr_gen,"t*(t/t)",(c0 / c1),v1,v0,result);
  21413. exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
  21414. return (synthesis_result) ? result : error_node();
  21415. }
  21416. // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)
  21417. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  21418. {
  21419. const bool synthesis_result =
  21420. synthesize_sf3ext_expression::
  21421. template compile<ctype,vtype,vtype>(expr_gen,"t/(t*t)",(c0 * c1),v0,v1,result);
  21422. exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
  21423. return (synthesis_result) ? result : error_node();
  21424. }
  21425. // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
  21426. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
  21427. {
  21428. const bool synthesis_result =
  21429. synthesize_sf3ext_expression::
  21430. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c0 * c1),v0,v1,result);
  21431. exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
  21432. return (synthesis_result) ? result : error_node();
  21433. }
  21434. // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)
  21435. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21436. {
  21437. const bool synthesis_result =
  21438. synthesize_sf3ext_expression::
  21439. template compile<ctype,vtype,vtype>(expr_gen,"t/(t*t)",(c0 / c1),v0,v1,result);
  21440. exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
  21441. return (synthesis_result) ? result : error_node();
  21442. }
  21443. // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
  21444. else if (
  21445. (std::equal_to<T>()(c0,c1)) &&
  21446. (details::e_mul == o0) &&
  21447. (details::e_mul == o2) &&
  21448. (
  21449. (details::e_add == o1) ||
  21450. (details::e_sub == o1)
  21451. )
  21452. )
  21453. {
  21454. std::string specfunc;
  21455. switch (o1)
  21456. {
  21457. case details::e_add : specfunc = "t*(t+t)"; break;
  21458. case details::e_sub : specfunc = "t*(t-t)"; break;
  21459. default : return error_node();
  21460. }
  21461. const bool synthesis_result =
  21462. synthesize_sf3ext_expression::
  21463. template compile<ctype,vtype,vtype>(expr_gen,specfunc,c0,v0,v1,result);
  21464. exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
  21465. return (synthesis_result) ? result : error_node();
  21466. }
  21467. }
  21468. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,v1,c1,result))
  21469. return result;
  21470. else if (!expr_gen.valid_operator(o0,f0))
  21471. return error_node();
  21472. else if (!expr_gen.valid_operator(o1,f1))
  21473. return error_node();
  21474. else if (!expr_gen.valid_operator(o2,f2))
  21475. return error_node();
  21476. else
  21477. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,v1,c1,f0,f1,f2);
  21478. }
  21479. static inline std::string id(expression_generator<Type>& expr_gen,
  21480. const details::operator_type o0,
  21481. const details::operator_type o1,
  21482. const details::operator_type o2)
  21483. {
  21484. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  21485. }
  21486. };
  21487. struct synthesize_vococov_expression0
  21488. {
  21489. typedef typename vococov_t::type0 node_type;
  21490. typedef typename vococov_t::sf4_type sf4_type;
  21491. typedef typename node_type::T0 T0;
  21492. typedef typename node_type::T1 T1;
  21493. typedef typename node_type::T2 T2;
  21494. typedef typename node_type::T3 T3;
  21495. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21496. const details::operator_type& operation,
  21497. expression_node_ptr (&branch)[2])
  21498. {
  21499. // (v0 o0 c0) o1 (c1 o2 v1)
  21500. const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
  21501. const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
  21502. const Type c0 = voc->c();
  21503. const Type& v0 = voc->v();
  21504. const Type c1 = cov->c();
  21505. const Type& v1 = cov->v();
  21506. const details::operator_type o0 = voc->operation();
  21507. const details::operator_type o1 = operation;
  21508. const details::operator_type o2 = cov->operation();
  21509. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21510. binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
  21511. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  21512. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21513. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21514. expression_node_ptr result = error_node();
  21515. if (expr_gen.strength_reduction_enabled())
  21516. {
  21517. // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
  21518. if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
  21519. {
  21520. const bool synthesis_result =
  21521. synthesize_sf3ext_expression::
  21522. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)+t",(c0 + c1),v0,v1,result);
  21523. exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
  21524. return (synthesis_result) ? result : error_node();
  21525. }
  21526. // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
  21527. else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
  21528. {
  21529. const bool synthesis_result =
  21530. synthesize_sf3ext_expression::
  21531. template compile<ctype,vtype,vtype>(expr_gen,"(t+t)-t",(c0 - c1),v0,v1,result);
  21532. exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
  21533. return (synthesis_result) ? result : error_node();
  21534. }
  21535. // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)
  21536. else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
  21537. {
  21538. const bool synthesis_result =
  21539. synthesize_sf3ext_expression::
  21540. template compile<vtype,vtype,ctype>(expr_gen,"(t+t)-t",v0,v1,(c1 + c0),result);
  21541. exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
  21542. return (synthesis_result) ? result : error_node();
  21543. }
  21544. // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
  21545. else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
  21546. {
  21547. const bool synthesis_result =
  21548. synthesize_sf3ext_expression::
  21549. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)*t",(c0 * c1),v0,v1,result);
  21550. exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
  21551. return (synthesis_result) ? result : error_node();
  21552. }
  21553. // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)
  21554. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21555. {
  21556. const bool synthesis_result =
  21557. synthesize_sf3ext_expression::
  21558. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c0 / c1),v0,v1,result);
  21559. exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
  21560. return (synthesis_result) ? result : error_node();
  21561. }
  21562. // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)
  21563. else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
  21564. {
  21565. const bool synthesis_result =
  21566. synthesize_sf3ext_expression::
  21567. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",(c1 / c0),v0,v1,result);
  21568. exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
  21569. return (synthesis_result) ? result : error_node();
  21570. }
  21571. // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
  21572. else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
  21573. {
  21574. const bool synthesis_result =
  21575. synthesize_sf3ext_expression::
  21576. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)*t",(c0 / c1),v0,v1,result);
  21577. exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
  21578. return (synthesis_result) ? result : error_node();
  21579. }
  21580. // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)
  21581. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
  21582. {
  21583. const bool synthesis_result =
  21584. synthesize_sf3ext_expression::
  21585. template compile<ctype,vtype,vtype>(expr_gen,"(t*t)/t",Type(1) / (c0 * c1),v0,v1,result);
  21586. exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
  21587. return (synthesis_result) ? result : error_node();
  21588. }
  21589. // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))
  21590. else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
  21591. {
  21592. const bool synthesis_result =
  21593. synthesize_sf3ext_expression::
  21594. template compile<vtype,vtype,ctype>(expr_gen,"(t*t)*t",v0,v1,Type(1) / (c0 * c1),result);
  21595. exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
  21596. return (synthesis_result) ? result : error_node();
  21597. }
  21598. // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)
  21599. else if (
  21600. (std::equal_to<T>()(c0,c1)) &&
  21601. (details::e_mul == o0) &&
  21602. (details::e_mul == o2) &&
  21603. (
  21604. (details::e_add == o1) || (details::e_sub == o1)
  21605. )
  21606. )
  21607. {
  21608. std::string specfunc;
  21609. switch (o1)
  21610. {
  21611. case details::e_add : specfunc = "t*(t+t)"; break;
  21612. case details::e_sub : specfunc = "t*(t-t)"; break;
  21613. default : return error_node();
  21614. }
  21615. const bool synthesis_result =
  21616. synthesize_sf3ext_expression::
  21617. template compile<ctype,vtype,vtype>(expr_gen,specfunc,c0,v0,v1,result);
  21618. exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
  21619. return (synthesis_result) ? result : error_node();
  21620. }
  21621. }
  21622. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,c1,v1,result))
  21623. return result;
  21624. else if (!expr_gen.valid_operator(o0,f0))
  21625. return error_node();
  21626. else if (!expr_gen.valid_operator(o1,f1))
  21627. return error_node();
  21628. else if (!expr_gen.valid_operator(o2,f2))
  21629. return error_node();
  21630. else
  21631. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,c1,v1,f0,f1,f2);
  21632. }
  21633. static inline std::string id(expression_generator<Type>& expr_gen,
  21634. const details::operator_type o0,
  21635. const details::operator_type o1,
  21636. const details::operator_type o2)
  21637. {
  21638. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
  21639. }
  21640. };
  21641. struct synthesize_vovovov_expression1
  21642. {
  21643. typedef typename vovovov_t::type1 node_type;
  21644. typedef typename vovovov_t::sf4_type sf4_type;
  21645. typedef typename node_type::T0 T0;
  21646. typedef typename node_type::T1 T1;
  21647. typedef typename node_type::T2 T2;
  21648. typedef typename node_type::T3 T3;
  21649. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21650. const details::operator_type& operation,
  21651. expression_node_ptr (&branch)[2])
  21652. {
  21653. // v0 o0 (v1 o1 (v2 o2 v3))
  21654. typedef typename synthesize_vovov_expression1::node_type vovov_t;
  21655. const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
  21656. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  21657. const Type& v1 = vovov->t0();
  21658. const Type& v2 = vovov->t1();
  21659. const Type& v3 = vovov->t2();
  21660. const details::operator_type o0 = operation;
  21661. const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
  21662. const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
  21663. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21664. binary_functor_t f1 = vovov->f0();
  21665. binary_functor_t f2 = vovov->f1();
  21666. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21667. expression_node_ptr result = error_node();
  21668. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
  21669. return result;
  21670. else if (!expr_gen.valid_operator(o0,f0))
  21671. return error_node();
  21672. exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n"));
  21673. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,v3,f0,f1,f2);
  21674. }
  21675. static inline std::string id(expression_generator<Type>& expr_gen,
  21676. const details::operator_type o0,
  21677. const details::operator_type o1,
  21678. const details::operator_type o2)
  21679. {
  21680. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21681. }
  21682. };
  21683. struct synthesize_vovovoc_expression1
  21684. {
  21685. typedef typename vovovoc_t::type1 node_type;
  21686. typedef typename vovovoc_t::sf4_type sf4_type;
  21687. typedef typename node_type::T0 T0;
  21688. typedef typename node_type::T1 T1;
  21689. typedef typename node_type::T2 T2;
  21690. typedef typename node_type::T3 T3;
  21691. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21692. const details::operator_type& operation,
  21693. expression_node_ptr (&branch)[2])
  21694. {
  21695. // v0 o0 (v1 o1 (v2 o2 c))
  21696. typedef typename synthesize_vovoc_expression1::node_type vovoc_t;
  21697. const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
  21698. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  21699. const Type& v1 = vovoc->t0();
  21700. const Type& v2 = vovoc->t1();
  21701. const Type c = vovoc->t2();
  21702. const details::operator_type o0 = operation;
  21703. const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
  21704. const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
  21705. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21706. binary_functor_t f1 = vovoc->f0();
  21707. binary_functor_t f2 = vovoc->f1();
  21708. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21709. expression_node_ptr result = error_node();
  21710. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,c,result))
  21711. return result;
  21712. else if (!expr_gen.valid_operator(o0,f0))
  21713. return error_node();
  21714. exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n"));
  21715. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,c,f0,f1,f2);
  21716. }
  21717. static inline std::string id(expression_generator<Type>& expr_gen,
  21718. const details::operator_type o0,
  21719. const details::operator_type o1,
  21720. const details::operator_type o2)
  21721. {
  21722. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21723. }
  21724. };
  21725. struct synthesize_vovocov_expression1
  21726. {
  21727. typedef typename vovocov_t::type1 node_type;
  21728. typedef typename vovocov_t::sf4_type sf4_type;
  21729. typedef typename node_type::T0 T0;
  21730. typedef typename node_type::T1 T1;
  21731. typedef typename node_type::T2 T2;
  21732. typedef typename node_type::T3 T3;
  21733. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21734. const details::operator_type& operation,
  21735. expression_node_ptr (&branch)[2])
  21736. {
  21737. // v0 o0 (v1 o1 (c o2 v2))
  21738. typedef typename synthesize_vocov_expression1::node_type vocov_t;
  21739. const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
  21740. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  21741. const Type& v1 = vocov->t0();
  21742. const Type c = vocov->t1();
  21743. const Type& v2 = vocov->t2();
  21744. const details::operator_type o0 = operation;
  21745. const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
  21746. const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
  21747. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21748. binary_functor_t f1 = vocov->f0();
  21749. binary_functor_t f2 = vocov->f1();
  21750. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21751. expression_node_ptr result = error_node();
  21752. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,c,v2,result))
  21753. return result;
  21754. if (!expr_gen.valid_operator(o0,f0))
  21755. return error_node();
  21756. exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n"));
  21757. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,v2,f0,f1,f2);
  21758. }
  21759. static inline std::string id(expression_generator<Type>& expr_gen,
  21760. const details::operator_type o0,
  21761. const details::operator_type o1,
  21762. const details::operator_type o2)
  21763. {
  21764. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21765. }
  21766. };
  21767. struct synthesize_vocovov_expression1
  21768. {
  21769. typedef typename vocovov_t::type1 node_type;
  21770. typedef typename vocovov_t::sf4_type sf4_type;
  21771. typedef typename node_type::T0 T0;
  21772. typedef typename node_type::T1 T1;
  21773. typedef typename node_type::T2 T2;
  21774. typedef typename node_type::T3 T3;
  21775. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21776. const details::operator_type& operation,
  21777. expression_node_ptr (&branch)[2])
  21778. {
  21779. // v0 o0 (c o1 (v1 o2 v2))
  21780. typedef typename synthesize_covov_expression1::node_type covov_t;
  21781. const covov_t* covov = static_cast<const covov_t*>(branch[1]);
  21782. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  21783. const Type c = covov->t0();
  21784. const Type& v1 = covov->t1();
  21785. const Type& v2 = covov->t2();
  21786. const details::operator_type o0 = operation;
  21787. const details::operator_type o1 = expr_gen.get_operator(covov->f0());
  21788. const details::operator_type o2 = expr_gen.get_operator(covov->f1());
  21789. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21790. binary_functor_t f1 = covov->f0();
  21791. binary_functor_t f2 = covov->f1();
  21792. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21793. expression_node_ptr result = error_node();
  21794. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c,v1,v2,result))
  21795. return result;
  21796. else if (!expr_gen.valid_operator(o0,f0))
  21797. return error_node();
  21798. exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n"));
  21799. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,v2,f0,f1,f2);
  21800. }
  21801. static inline std::string id(expression_generator<Type>& expr_gen,
  21802. const details::operator_type o0,
  21803. const details::operator_type o1,
  21804. const details::operator_type o2)
  21805. {
  21806. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21807. }
  21808. };
  21809. struct synthesize_covovov_expression1
  21810. {
  21811. typedef typename covovov_t::type1 node_type;
  21812. typedef typename covovov_t::sf4_type sf4_type;
  21813. typedef typename node_type::T0 T0;
  21814. typedef typename node_type::T1 T1;
  21815. typedef typename node_type::T2 T2;
  21816. typedef typename node_type::T3 T3;
  21817. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21818. const details::operator_type& operation,
  21819. expression_node_ptr (&branch)[2])
  21820. {
  21821. // c o0 (v0 o1 (v1 o2 v2))
  21822. typedef typename synthesize_vovov_expression1::node_type vovov_t;
  21823. const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
  21824. const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
  21825. const Type& v0 = vovov->t0();
  21826. const Type& v1 = vovov->t1();
  21827. const Type& v2 = vovov->t2();
  21828. const details::operator_type o0 = operation;
  21829. const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
  21830. const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
  21831. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21832. binary_functor_t f1 = vovov->f0();
  21833. binary_functor_t f2 = vovov->f1();
  21834. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21835. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21836. expression_node_ptr result = error_node();
  21837. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c,v0,v1,v2,result))
  21838. return result;
  21839. if (!expr_gen.valid_operator(o0,f0))
  21840. return error_node();
  21841. exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n"));
  21842. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,v2,f0,f1,f2);
  21843. }
  21844. static inline std::string id(expression_generator<Type>& expr_gen,
  21845. const details::operator_type o0,
  21846. const details::operator_type o1,
  21847. const details::operator_type o2)
  21848. {
  21849. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21850. }
  21851. };
  21852. struct synthesize_covocov_expression1
  21853. {
  21854. typedef typename covocov_t::type1 node_type;
  21855. typedef typename covocov_t::sf4_type sf4_type;
  21856. typedef typename node_type::T0 T0;
  21857. typedef typename node_type::T1 T1;
  21858. typedef typename node_type::T2 T2;
  21859. typedef typename node_type::T3 T3;
  21860. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21861. const details::operator_type& operation,
  21862. expression_node_ptr (&branch)[2])
  21863. {
  21864. // c0 o0 (v0 o1 (c1 o2 v1))
  21865. typedef typename synthesize_vocov_expression1::node_type vocov_t;
  21866. const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
  21867. const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
  21868. const Type& v0 = vocov->t0();
  21869. const Type c1 = vocov->t1();
  21870. const Type& v1 = vocov->t2();
  21871. const details::operator_type o0 = operation;
  21872. const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
  21873. const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
  21874. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21875. binary_functor_t f1 = vocov->f0();
  21876. binary_functor_t f2 = vocov->f1();
  21877. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21878. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21879. expression_node_ptr result = error_node();
  21880. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,c1,v1,result))
  21881. return result;
  21882. else if (!expr_gen.valid_operator(o0,f0))
  21883. return error_node();
  21884. exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n"));
  21885. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,c1,v1,f0,f1,f2);
  21886. }
  21887. static inline std::string id(expression_generator<Type>& expr_gen,
  21888. const details::operator_type o0,
  21889. const details::operator_type o1,
  21890. const details::operator_type o2)
  21891. {
  21892. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21893. }
  21894. };
  21895. struct synthesize_vocovoc_expression1
  21896. {
  21897. typedef typename vocovoc_t::type1 node_type;
  21898. typedef typename vocovoc_t::sf4_type sf4_type;
  21899. typedef typename node_type::T0 T0;
  21900. typedef typename node_type::T1 T1;
  21901. typedef typename node_type::T2 T2;
  21902. typedef typename node_type::T3 T3;
  21903. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21904. const details::operator_type& operation,
  21905. expression_node_ptr (&branch)[2])
  21906. {
  21907. // v0 o0 (c0 o1 (v1 o2 c2))
  21908. typedef typename synthesize_covoc_expression1::node_type covoc_t;
  21909. const covoc_t* covoc = static_cast<const covoc_t*>(branch[1]);
  21910. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  21911. const Type c0 = covoc->t0();
  21912. const Type& v1 = covoc->t1();
  21913. const Type c1 = covoc->t2();
  21914. const details::operator_type o0 = operation;
  21915. const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
  21916. const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
  21917. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21918. binary_functor_t f1 = covoc->f0();
  21919. binary_functor_t f2 = covoc->f1();
  21920. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21921. expression_node_ptr result = error_node();
  21922. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,v1,c1,result))
  21923. return result;
  21924. else if (!expr_gen.valid_operator(o0,f0))
  21925. return error_node();
  21926. exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n"));
  21927. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,v1,c1,f0,f1,f2);
  21928. }
  21929. static inline std::string id(expression_generator<Type>& expr_gen,
  21930. const details::operator_type o0,
  21931. const details::operator_type o1,
  21932. const details::operator_type o2)
  21933. {
  21934. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21935. }
  21936. };
  21937. struct synthesize_covovoc_expression1
  21938. {
  21939. typedef typename covovoc_t::type1 node_type;
  21940. typedef typename covovoc_t::sf4_type sf4_type;
  21941. typedef typename node_type::T0 T0;
  21942. typedef typename node_type::T1 T1;
  21943. typedef typename node_type::T2 T2;
  21944. typedef typename node_type::T3 T3;
  21945. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21946. const details::operator_type& operation,
  21947. expression_node_ptr (&branch)[2])
  21948. {
  21949. // c0 o0 (v0 o1 (v1 o2 c1))
  21950. typedef typename synthesize_vovoc_expression1::node_type vovoc_t;
  21951. const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
  21952. const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
  21953. const Type& v0 = vovoc->t0();
  21954. const Type& v1 = vovoc->t1();
  21955. const Type c1 = vovoc->t2();
  21956. const details::operator_type o0 = operation;
  21957. const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
  21958. const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
  21959. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  21960. binary_functor_t f1 = vovoc->f0();
  21961. binary_functor_t f2 = vovoc->f1();
  21962. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  21963. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  21964. expression_node_ptr result = error_node();
  21965. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,v1,c1,result))
  21966. return result;
  21967. else if (!expr_gen.valid_operator(o0,f0))
  21968. return error_node();
  21969. exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n"));
  21970. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,v1,c1,f0,f1,f2);
  21971. }
  21972. static inline std::string id(expression_generator<Type>& expr_gen,
  21973. const details::operator_type o0,
  21974. const details::operator_type o1,
  21975. const details::operator_type o2)
  21976. {
  21977. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  21978. }
  21979. };
  21980. struct synthesize_vococov_expression1
  21981. {
  21982. typedef typename vococov_t::type1 node_type;
  21983. typedef typename vococov_t::sf4_type sf4_type;
  21984. typedef typename node_type::T0 T0;
  21985. typedef typename node_type::T1 T1;
  21986. typedef typename node_type::T2 T2;
  21987. typedef typename node_type::T3 T3;
  21988. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  21989. const details::operator_type& operation,
  21990. expression_node_ptr (&branch)[2])
  21991. {
  21992. // v0 o0 (c0 o1 (c1 o2 v1))
  21993. typedef typename synthesize_cocov_expression1::node_type cocov_t;
  21994. const cocov_t* cocov = static_cast<const cocov_t*>(branch[1]);
  21995. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  21996. const Type c0 = cocov->t0();
  21997. const Type c1 = cocov->t1();
  21998. const Type& v1 = cocov->t2();
  21999. const details::operator_type o0 = operation;
  22000. const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
  22001. const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
  22002. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22003. binary_functor_t f1 = cocov->f0();
  22004. binary_functor_t f2 = cocov->f1();
  22005. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22006. expression_node_ptr result = error_node();
  22007. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,c1,v1,result))
  22008. return result;
  22009. else if (!expr_gen.valid_operator(o0,f0))
  22010. return error_node();
  22011. exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n"));
  22012. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,c1,v1,f0,f1,f2);
  22013. }
  22014. static inline std::string id(expression_generator<Type>& expr_gen,
  22015. const details::operator_type o0,
  22016. const details::operator_type o1,
  22017. const details::operator_type o2)
  22018. {
  22019. return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
  22020. }
  22021. };
  22022. struct synthesize_vovovov_expression2
  22023. {
  22024. typedef typename vovovov_t::type2 node_type;
  22025. typedef typename vovovov_t::sf4_type sf4_type;
  22026. typedef typename node_type::T0 T0;
  22027. typedef typename node_type::T1 T1;
  22028. typedef typename node_type::T2 T2;
  22029. typedef typename node_type::T3 T3;
  22030. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22031. const details::operator_type& operation,
  22032. expression_node_ptr (&branch)[2])
  22033. {
  22034. // v0 o0 ((v1 o1 v2) o2 v3)
  22035. typedef typename synthesize_vovov_expression0::node_type vovov_t;
  22036. const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
  22037. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  22038. const Type& v1 = vovov->t0();
  22039. const Type& v2 = vovov->t1();
  22040. const Type& v3 = vovov->t2();
  22041. const details::operator_type o0 = operation;
  22042. const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
  22043. const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
  22044. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22045. binary_functor_t f1 = vovov->f0();
  22046. binary_functor_t f2 = vovov->f1();
  22047. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22048. expression_node_ptr result = error_node();
  22049. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
  22050. return result;
  22051. else if (!expr_gen.valid_operator(o0,f0))
  22052. return error_node();
  22053. exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n"));
  22054. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,v3,f0,f1,f2);
  22055. }
  22056. static inline std::string id(expression_generator<Type>& expr_gen,
  22057. const details::operator_type o0,
  22058. const details::operator_type o1,
  22059. const details::operator_type o2)
  22060. {
  22061. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22062. }
  22063. };
  22064. struct synthesize_vovovoc_expression2
  22065. {
  22066. typedef typename vovovoc_t::type2 node_type;
  22067. typedef typename vovovoc_t::sf4_type sf4_type;
  22068. typedef typename node_type::T0 T0;
  22069. typedef typename node_type::T1 T1;
  22070. typedef typename node_type::T2 T2;
  22071. typedef typename node_type::T3 T3;
  22072. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22073. const details::operator_type& operation,
  22074. expression_node_ptr (&branch)[2])
  22075. {
  22076. // v0 o0 ((v1 o1 v2) o2 c)
  22077. typedef typename synthesize_vovoc_expression0::node_type vovoc_t;
  22078. const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
  22079. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  22080. const Type& v1 = vovoc->t0();
  22081. const Type& v2 = vovoc->t1();
  22082. const Type c = vovoc->t2();
  22083. const details::operator_type o0 = operation;
  22084. const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
  22085. const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
  22086. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22087. binary_functor_t f1 = vovoc->f0();
  22088. binary_functor_t f2 = vovoc->f1();
  22089. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22090. expression_node_ptr result = error_node();
  22091. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,c,result))
  22092. return result;
  22093. else if (!expr_gen.valid_operator(o0,f0))
  22094. return error_node();
  22095. exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n"));
  22096. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,c,f0,f1,f2);
  22097. }
  22098. static inline std::string id(expression_generator<Type>& expr_gen,
  22099. const details::operator_type o0,
  22100. const details::operator_type o1,
  22101. const details::operator_type o2)
  22102. {
  22103. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22104. }
  22105. };
  22106. struct synthesize_vovocov_expression2
  22107. {
  22108. typedef typename vovocov_t::type2 node_type;
  22109. typedef typename vovocov_t::sf4_type sf4_type;
  22110. typedef typename node_type::T0 T0;
  22111. typedef typename node_type::T1 T1;
  22112. typedef typename node_type::T2 T2;
  22113. typedef typename node_type::T3 T3;
  22114. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22115. const details::operator_type& operation,
  22116. expression_node_ptr (&branch)[2])
  22117. {
  22118. // v0 o0 ((v1 o1 c) o2 v2)
  22119. typedef typename synthesize_vocov_expression0::node_type vocov_t;
  22120. const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
  22121. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  22122. const Type& v1 = vocov->t0();
  22123. const Type c = vocov->t1();
  22124. const Type& v2 = vocov->t2();
  22125. const details::operator_type o0 = operation;
  22126. const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
  22127. const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
  22128. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22129. binary_functor_t f1 = vocov->f0();
  22130. binary_functor_t f2 = vocov->f1();
  22131. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22132. expression_node_ptr result = error_node();
  22133. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,c,v2,result))
  22134. return result;
  22135. else if (!expr_gen.valid_operator(o0,f0))
  22136. return error_node();
  22137. exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n"));
  22138. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,v2,f0,f1,f2);
  22139. }
  22140. static inline std::string id(expression_generator<Type>& expr_gen,
  22141. const details::operator_type o0,
  22142. const details::operator_type o1,
  22143. const details::operator_type o2)
  22144. {
  22145. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22146. }
  22147. };
  22148. struct synthesize_vocovov_expression2
  22149. {
  22150. typedef typename vocovov_t::type2 node_type;
  22151. typedef typename vocovov_t::sf4_type sf4_type;
  22152. typedef typename node_type::T0 T0;
  22153. typedef typename node_type::T1 T1;
  22154. typedef typename node_type::T2 T2;
  22155. typedef typename node_type::T3 T3;
  22156. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22157. const details::operator_type& operation,
  22158. expression_node_ptr (&branch)[2])
  22159. {
  22160. // v0 o0 ((c o1 v1) o2 v2)
  22161. typedef typename synthesize_covov_expression0::node_type covov_t;
  22162. const covov_t* covov = static_cast<const covov_t*>(branch[1]);
  22163. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  22164. const Type c = covov->t0();
  22165. const Type& v1 = covov->t1();
  22166. const Type& v2 = covov->t2();
  22167. const details::operator_type o0 = operation;
  22168. const details::operator_type o1 = expr_gen.get_operator(covov->f0());
  22169. const details::operator_type o2 = expr_gen.get_operator(covov->f1());
  22170. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22171. binary_functor_t f1 = covov->f0();
  22172. binary_functor_t f2 = covov->f1();
  22173. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22174. expression_node_ptr result = error_node();
  22175. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c,v1,v2,result))
  22176. return result;
  22177. else if (!expr_gen.valid_operator(o0,f0))
  22178. return error_node();
  22179. exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n"));
  22180. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,v2,f0,f1,f2);
  22181. }
  22182. static inline std::string id(expression_generator<Type>& expr_gen,
  22183. const details::operator_type o0,
  22184. const details::operator_type o1,
  22185. const details::operator_type o2)
  22186. {
  22187. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22188. }
  22189. };
  22190. struct synthesize_covovov_expression2
  22191. {
  22192. typedef typename covovov_t::type2 node_type;
  22193. typedef typename covovov_t::sf4_type sf4_type;
  22194. typedef typename node_type::T0 T0;
  22195. typedef typename node_type::T1 T1;
  22196. typedef typename node_type::T2 T2;
  22197. typedef typename node_type::T3 T3;
  22198. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22199. const details::operator_type& operation,
  22200. expression_node_ptr (&branch)[2])
  22201. {
  22202. // c o0 ((v1 o1 v2) o2 v3)
  22203. typedef typename synthesize_vovov_expression0::node_type vovov_t;
  22204. const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
  22205. const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
  22206. const Type& v0 = vovov->t0();
  22207. const Type& v1 = vovov->t1();
  22208. const Type& v2 = vovov->t2();
  22209. const details::operator_type o0 = operation;
  22210. const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
  22211. const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
  22212. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22213. binary_functor_t f1 = vovov->f0();
  22214. binary_functor_t f2 = vovov->f1();
  22215. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22216. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22217. expression_node_ptr result = error_node();
  22218. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c,v0,v1,v2,result))
  22219. return result;
  22220. else if (!expr_gen.valid_operator(o0,f0))
  22221. return error_node();
  22222. exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n"));
  22223. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,v2,f0,f1,f2);
  22224. }
  22225. static inline std::string id(expression_generator<Type>& expr_gen,
  22226. const details::operator_type o0,
  22227. const details::operator_type o1,
  22228. const details::operator_type o2)
  22229. {
  22230. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22231. }
  22232. };
  22233. struct synthesize_covocov_expression2
  22234. {
  22235. typedef typename covocov_t::type2 node_type;
  22236. typedef typename covocov_t::sf4_type sf4_type;
  22237. typedef typename node_type::T0 T0;
  22238. typedef typename node_type::T1 T1;
  22239. typedef typename node_type::T2 T2;
  22240. typedef typename node_type::T3 T3;
  22241. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22242. const details::operator_type& operation,
  22243. expression_node_ptr (&branch)[2])
  22244. {
  22245. // c0 o0 ((v0 o1 c1) o2 v1)
  22246. typedef typename synthesize_vocov_expression0::node_type vocov_t;
  22247. const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
  22248. const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
  22249. const Type& v0 = vocov->t0();
  22250. const Type c1 = vocov->t1();
  22251. const Type& v1 = vocov->t2();
  22252. const details::operator_type o0 = operation;
  22253. const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
  22254. const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
  22255. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22256. binary_functor_t f1 = vocov->f0();
  22257. binary_functor_t f2 = vocov->f1();
  22258. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22259. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22260. expression_node_ptr result = error_node();
  22261. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,c1,v1,result))
  22262. return result;
  22263. else if (!expr_gen.valid_operator(o0,f0))
  22264. return error_node();
  22265. exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n"));
  22266. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,c1,v1,f0,f1,f2);
  22267. }
  22268. static inline std::string id(expression_generator<Type>& expr_gen,
  22269. const details::operator_type o0,
  22270. const details::operator_type o1,
  22271. const details::operator_type o2)
  22272. {
  22273. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22274. }
  22275. };
  22276. struct synthesize_vocovoc_expression2
  22277. {
  22278. typedef typename vocovoc_t::type2 node_type;
  22279. typedef typename vocovoc_t::sf4_type sf4_type;
  22280. typedef typename node_type::T0 T0;
  22281. typedef typename node_type::T1 T1;
  22282. typedef typename node_type::T2 T2;
  22283. typedef typename node_type::T3 T3;
  22284. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22285. const details::operator_type& operation,
  22286. expression_node_ptr (&branch)[2])
  22287. {
  22288. // v0 o0 ((c0 o1 v1) o2 c1)
  22289. typedef typename synthesize_covoc_expression0::node_type covoc_t;
  22290. const covoc_t* covoc = static_cast<const covoc_t*>(branch[1]);
  22291. const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
  22292. const Type c0 = covoc->t0();
  22293. const Type& v1 = covoc->t1();
  22294. const Type c1 = covoc->t2();
  22295. const details::operator_type o0 = operation;
  22296. const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
  22297. const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
  22298. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22299. binary_functor_t f1 = covoc->f0();
  22300. binary_functor_t f2 = covoc->f1();
  22301. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22302. expression_node_ptr result = error_node();
  22303. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,v1,c1,result))
  22304. return result;
  22305. else if (!expr_gen.valid_operator(o0,f0))
  22306. return error_node();
  22307. exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n"));
  22308. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,v1,c1,f0,f1,f2);
  22309. }
  22310. static inline std::string id(expression_generator<Type>& expr_gen,
  22311. const details::operator_type o0,
  22312. const details::operator_type o1,
  22313. const details::operator_type o2)
  22314. {
  22315. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22316. }
  22317. };
  22318. struct synthesize_covovoc_expression2
  22319. {
  22320. typedef typename covovoc_t::type2 node_type;
  22321. typedef typename covovoc_t::sf4_type sf4_type;
  22322. typedef typename node_type::T0 T0;
  22323. typedef typename node_type::T1 T1;
  22324. typedef typename node_type::T2 T2;
  22325. typedef typename node_type::T3 T3;
  22326. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22327. const details::operator_type& operation,
  22328. expression_node_ptr (&branch)[2])
  22329. {
  22330. // c0 o0 ((v0 o1 v1) o2 c1)
  22331. typedef typename synthesize_vovoc_expression0::node_type vovoc_t;
  22332. const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
  22333. const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
  22334. const Type& v0 = vovoc->t0();
  22335. const Type& v1 = vovoc->t1();
  22336. const Type c1 = vovoc->t2();
  22337. const details::operator_type o0 = operation;
  22338. const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
  22339. const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
  22340. binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
  22341. binary_functor_t f1 = vovoc->f0();
  22342. binary_functor_t f2 = vovoc->f1();
  22343. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22344. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22345. expression_node_ptr result = error_node();
  22346. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,v1,c1,result))
  22347. return result;
  22348. else if (!expr_gen.valid_operator(o0,f0))
  22349. return error_node();
  22350. exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n"));
  22351. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,v1,c1,f0,f1,f2);
  22352. }
  22353. static inline std::string id(expression_generator<Type>& expr_gen,
  22354. const details::operator_type o0,
  22355. const details::operator_type o1,
  22356. const details::operator_type o2)
  22357. {
  22358. return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
  22359. }
  22360. };
  22361. struct synthesize_vococov_expression2
  22362. {
  22363. typedef typename vococov_t::type2 node_type;
  22364. static inline expression_node_ptr process(expression_generator<Type>&, const details::operator_type&, expression_node_ptr (&)[2])
  22365. {
  22366. // v0 o0 ((c0 o1 c1) o2 v1) - Not possible
  22367. exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
  22368. return error_node();
  22369. }
  22370. static inline std::string id(expression_generator<Type>&,
  22371. const details::operator_type, const details::operator_type, const details::operator_type)
  22372. {
  22373. return "INVALID";
  22374. }
  22375. };
  22376. struct synthesize_vovovov_expression3
  22377. {
  22378. typedef typename vovovov_t::type3 node_type;
  22379. typedef typename vovovov_t::sf4_type sf4_type;
  22380. typedef typename node_type::T0 T0;
  22381. typedef typename node_type::T1 T1;
  22382. typedef typename node_type::T2 T2;
  22383. typedef typename node_type::T3 T3;
  22384. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22385. const details::operator_type& operation,
  22386. expression_node_ptr (&branch)[2])
  22387. {
  22388. // ((v0 o0 v1) o1 v2) o2 v3
  22389. typedef typename synthesize_vovov_expression0::node_type vovov_t;
  22390. const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
  22391. const Type& v0 = vovov->t0();
  22392. const Type& v1 = vovov->t1();
  22393. const Type& v2 = vovov->t2();
  22394. const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22395. const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
  22396. const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
  22397. const details::operator_type o2 = operation;
  22398. binary_functor_t f0 = vovov->f0();
  22399. binary_functor_t f1 = vovov->f1();
  22400. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22401. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22402. expression_node_ptr result = error_node();
  22403. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
  22404. return result;
  22405. else if (!expr_gen.valid_operator(o2,f2))
  22406. return error_node();
  22407. exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n"));
  22408. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,v3,f0,f1,f2);
  22409. }
  22410. static inline std::string id(expression_generator<Type>& expr_gen,
  22411. const details::operator_type o0,
  22412. const details::operator_type o1,
  22413. const details::operator_type o2)
  22414. {
  22415. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22416. }
  22417. };
  22418. struct synthesize_vovovoc_expression3
  22419. {
  22420. typedef typename vovovoc_t::type3 node_type;
  22421. typedef typename vovovoc_t::sf4_type sf4_type;
  22422. typedef typename node_type::T0 T0;
  22423. typedef typename node_type::T1 T1;
  22424. typedef typename node_type::T2 T2;
  22425. typedef typename node_type::T3 T3;
  22426. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22427. const details::operator_type& operation,
  22428. expression_node_ptr (&branch)[2])
  22429. {
  22430. // ((v0 o0 v1) o1 v2) o2 c
  22431. typedef typename synthesize_vovov_expression0::node_type vovov_t;
  22432. const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
  22433. const Type& v0 = vovov->t0();
  22434. const Type& v1 = vovov->t1();
  22435. const Type& v2 = vovov->t2();
  22436. const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
  22437. const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
  22438. const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
  22439. const details::operator_type o2 = operation;
  22440. binary_functor_t f0 = vovov->f0();
  22441. binary_functor_t f1 = vovov->f1();
  22442. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22443. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22444. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22445. expression_node_ptr result = error_node();
  22446. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,c,result))
  22447. return result;
  22448. else if (!expr_gen.valid_operator(o2,f2))
  22449. return error_node();
  22450. exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n"));
  22451. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,c,f0,f1,f2);
  22452. }
  22453. static inline std::string id(expression_generator<Type>& expr_gen,
  22454. const details::operator_type o0,
  22455. const details::operator_type o1,
  22456. const details::operator_type o2)
  22457. {
  22458. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22459. }
  22460. };
  22461. struct synthesize_vovocov_expression3
  22462. {
  22463. typedef typename vovocov_t::type3 node_type;
  22464. typedef typename vovocov_t::sf4_type sf4_type;
  22465. typedef typename node_type::T0 T0;
  22466. typedef typename node_type::T1 T1;
  22467. typedef typename node_type::T2 T2;
  22468. typedef typename node_type::T3 T3;
  22469. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22470. const details::operator_type& operation,
  22471. expression_node_ptr (&branch)[2])
  22472. {
  22473. // ((v0 o0 v1) o1 c) o2 v2
  22474. typedef typename synthesize_vovoc_expression0::node_type vovoc_t;
  22475. const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[0]);
  22476. const Type& v0 = vovoc->t0();
  22477. const Type& v1 = vovoc->t1();
  22478. const Type c = vovoc->t2();
  22479. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22480. const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
  22481. const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
  22482. const details::operator_type o2 = operation;
  22483. binary_functor_t f0 = vovoc->f0();
  22484. binary_functor_t f1 = vovoc->f1();
  22485. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22486. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22487. expression_node_ptr result = error_node();
  22488. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,c,v2,result))
  22489. return result;
  22490. else if (!expr_gen.valid_operator(o2,f2))
  22491. return error_node();
  22492. exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n"));
  22493. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,v2,f0,f1,f2);
  22494. }
  22495. static inline std::string id(expression_generator<Type>& expr_gen,
  22496. const details::operator_type o0,
  22497. const details::operator_type o1,
  22498. const details::operator_type o2)
  22499. {
  22500. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22501. }
  22502. };
  22503. struct synthesize_vocovov_expression3
  22504. {
  22505. typedef typename vocovov_t::type3 node_type;
  22506. typedef typename vocovov_t::sf4_type sf4_type;
  22507. typedef typename node_type::T0 T0;
  22508. typedef typename node_type::T1 T1;
  22509. typedef typename node_type::T2 T2;
  22510. typedef typename node_type::T3 T3;
  22511. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22512. const details::operator_type& operation,
  22513. expression_node_ptr (&branch)[2])
  22514. {
  22515. // ((v0 o0 c) o1 v1) o2 v2
  22516. typedef typename synthesize_vocov_expression0::node_type vocov_t;
  22517. const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
  22518. const Type& v0 = vocov->t0();
  22519. const Type c = vocov->t1();
  22520. const Type& v1 = vocov->t2();
  22521. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22522. const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
  22523. const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
  22524. const details::operator_type o2 = operation;
  22525. binary_functor_t f0 = vocov->f0();
  22526. binary_functor_t f1 = vocov->f1();
  22527. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22528. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22529. expression_node_ptr result = error_node();
  22530. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c,v1,v2,result))
  22531. return result;
  22532. else if (!expr_gen.valid_operator(o2,f2))
  22533. return error_node();
  22534. exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n"));
  22535. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,v2,f0,f1,f2);
  22536. }
  22537. static inline std::string id(expression_generator<Type>& expr_gen,
  22538. const details::operator_type o0,
  22539. const details::operator_type o1,
  22540. const details::operator_type o2)
  22541. {
  22542. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22543. }
  22544. };
  22545. struct synthesize_covovov_expression3
  22546. {
  22547. typedef typename covovov_t::type3 node_type;
  22548. typedef typename covovov_t::sf4_type sf4_type;
  22549. typedef typename node_type::T0 T0;
  22550. typedef typename node_type::T1 T1;
  22551. typedef typename node_type::T2 T2;
  22552. typedef typename node_type::T3 T3;
  22553. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22554. const details::operator_type& operation,
  22555. expression_node_ptr (&branch)[2])
  22556. {
  22557. // ((c o0 v0) o1 v1) o2 v2
  22558. typedef typename synthesize_covov_expression0::node_type covov_t;
  22559. const covov_t* covov = static_cast<const covov_t*>(branch[0]);
  22560. const Type c = covov->t0();
  22561. const Type& v0 = covov->t1();
  22562. const Type& v1 = covov->t2();
  22563. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22564. const details::operator_type o0 = expr_gen.get_operator(covov->f0());
  22565. const details::operator_type o1 = expr_gen.get_operator(covov->f1());
  22566. const details::operator_type o2 = operation;
  22567. binary_functor_t f0 = covov->f0();
  22568. binary_functor_t f1 = covov->f1();
  22569. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22570. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22571. expression_node_ptr result = error_node();
  22572. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c,v0,v1,v2,result))
  22573. return result;
  22574. else if (!expr_gen.valid_operator(o2,f2))
  22575. return error_node();
  22576. exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n"));
  22577. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,v2,f0,f1,f2);
  22578. }
  22579. static inline std::string id(expression_generator<Type>& expr_gen,
  22580. const details::operator_type o0,
  22581. const details::operator_type o1,
  22582. const details::operator_type o2)
  22583. {
  22584. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22585. }
  22586. };
  22587. struct synthesize_covocov_expression3
  22588. {
  22589. typedef typename covocov_t::type3 node_type;
  22590. typedef typename covocov_t::sf4_type sf4_type;
  22591. typedef typename node_type::T0 T0;
  22592. typedef typename node_type::T1 T1;
  22593. typedef typename node_type::T2 T2;
  22594. typedef typename node_type::T3 T3;
  22595. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22596. const details::operator_type& operation,
  22597. expression_node_ptr (&branch)[2])
  22598. {
  22599. // ((c0 o0 v0) o1 c1) o2 v1
  22600. typedef typename synthesize_covoc_expression0::node_type covoc_t;
  22601. const covoc_t* covoc = static_cast<const covoc_t*>(branch[0]);
  22602. const Type c0 = covoc->t0();
  22603. const Type& v0 = covoc->t1();
  22604. const Type c1 = covoc->t2();
  22605. const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22606. const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
  22607. const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
  22608. const details::operator_type o2 = operation;
  22609. binary_functor_t f0 = covoc->f0();
  22610. binary_functor_t f1 = covoc->f1();
  22611. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22612. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22613. expression_node_ptr result = error_node();
  22614. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,c1,v1,result))
  22615. return result;
  22616. else if (!expr_gen.valid_operator(o2,f2))
  22617. return error_node();
  22618. exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n"));
  22619. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,c1,v1,f0,f1,f2);
  22620. }
  22621. static inline std::string id(expression_generator<Type>& expr_gen,
  22622. const details::operator_type o0,
  22623. const details::operator_type o1,
  22624. const details::operator_type o2)
  22625. {
  22626. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22627. }
  22628. };
  22629. struct synthesize_vocovoc_expression3
  22630. {
  22631. typedef typename vocovoc_t::type3 node_type;
  22632. typedef typename vocovoc_t::sf4_type sf4_type;
  22633. typedef typename node_type::T0 T0;
  22634. typedef typename node_type::T1 T1;
  22635. typedef typename node_type::T2 T2;
  22636. typedef typename node_type::T3 T3;
  22637. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22638. const details::operator_type& operation,
  22639. expression_node_ptr (&branch)[2])
  22640. {
  22641. // ((v0 o0 c0) o1 v1) o2 c1
  22642. typedef typename synthesize_vocov_expression0::node_type vocov_t;
  22643. const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
  22644. const Type& v0 = vocov->t0();
  22645. const Type c0 = vocov->t1();
  22646. const Type& v1 = vocov->t2();
  22647. const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
  22648. const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
  22649. const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
  22650. const details::operator_type o2 = operation;
  22651. binary_functor_t f0 = vocov->f0();
  22652. binary_functor_t f1 = vocov->f1();
  22653. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22654. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22655. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22656. expression_node_ptr result = error_node();
  22657. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,v1,c1,result))
  22658. return result;
  22659. else if (!expr_gen.valid_operator(o2,f2))
  22660. return error_node();
  22661. exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n"));
  22662. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,v1,c1,f0,f1,f2);
  22663. }
  22664. static inline std::string id(expression_generator<Type>& expr_gen,
  22665. const details::operator_type o0,
  22666. const details::operator_type o1,
  22667. const details::operator_type o2)
  22668. {
  22669. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22670. }
  22671. };
  22672. struct synthesize_covovoc_expression3
  22673. {
  22674. typedef typename covovoc_t::type3 node_type;
  22675. typedef typename covovoc_t::sf4_type sf4_type;
  22676. typedef typename node_type::T0 T0;
  22677. typedef typename node_type::T1 T1;
  22678. typedef typename node_type::T2 T2;
  22679. typedef typename node_type::T3 T3;
  22680. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22681. const details::operator_type& operation,
  22682. expression_node_ptr (&branch)[2])
  22683. {
  22684. // ((c0 o0 v0) o1 v1) o2 c1
  22685. typedef typename synthesize_covov_expression0::node_type covov_t;
  22686. const covov_t* covov = static_cast<const covov_t*>(branch[0]);
  22687. const Type c0 = covov->t0();
  22688. const Type& v0 = covov->t1();
  22689. const Type& v1 = covov->t2();
  22690. const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
  22691. const details::operator_type o0 = expr_gen.get_operator(covov->f0());
  22692. const details::operator_type o1 = expr_gen.get_operator(covov->f1());
  22693. const details::operator_type o2 = operation;
  22694. binary_functor_t f0 = covov->f0();
  22695. binary_functor_t f1 = covov->f1();
  22696. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22697. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22698. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22699. expression_node_ptr result = error_node();
  22700. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,v1,c1,result))
  22701. return result;
  22702. else if (!expr_gen.valid_operator(o2,f2))
  22703. return error_node();
  22704. exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n"));
  22705. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,v1,c1,f0,f1,f2);
  22706. }
  22707. static inline std::string id(expression_generator<Type>& expr_gen,
  22708. const details::operator_type o0,
  22709. const details::operator_type o1,
  22710. const details::operator_type o2)
  22711. {
  22712. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22713. }
  22714. };
  22715. struct synthesize_vococov_expression3
  22716. {
  22717. typedef typename vococov_t::type3 node_type;
  22718. typedef typename vococov_t::sf4_type sf4_type;
  22719. typedef typename node_type::T0 T0;
  22720. typedef typename node_type::T1 T1;
  22721. typedef typename node_type::T2 T2;
  22722. typedef typename node_type::T3 T3;
  22723. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22724. const details::operator_type& operation,
  22725. expression_node_ptr (&branch)[2])
  22726. {
  22727. // ((v0 o0 c0) o1 c1) o2 v1
  22728. typedef typename synthesize_vococ_expression0::node_type vococ_t;
  22729. const vococ_t* vococ = static_cast<const vococ_t*>(branch[0]);
  22730. const Type& v0 = vococ->t0();
  22731. const Type c0 = vococ->t1();
  22732. const Type c1 = vococ->t2();
  22733. const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22734. const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
  22735. const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
  22736. const details::operator_type o2 = operation;
  22737. binary_functor_t f0 = vococ->f0();
  22738. binary_functor_t f1 = vococ->f1();
  22739. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22740. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22741. expression_node_ptr result = error_node();
  22742. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,c1,v1,result))
  22743. return result;
  22744. else if (!expr_gen.valid_operator(o2,f2))
  22745. return error_node();
  22746. exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n"));
  22747. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,c1,v1,f0,f1,f2);
  22748. }
  22749. static inline std::string id(expression_generator<Type>& expr_gen,
  22750. const details::operator_type o0,
  22751. const details::operator_type o1,
  22752. const details::operator_type o2)
  22753. {
  22754. return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22755. }
  22756. };
  22757. struct synthesize_vovovov_expression4
  22758. {
  22759. typedef typename vovovov_t::type4 node_type;
  22760. typedef typename vovovov_t::sf4_type sf4_type;
  22761. typedef typename node_type::T0 T0;
  22762. typedef typename node_type::T1 T1;
  22763. typedef typename node_type::T2 T2;
  22764. typedef typename node_type::T3 T3;
  22765. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22766. const details::operator_type& operation,
  22767. expression_node_ptr (&branch)[2])
  22768. {
  22769. // (v0 o0 (v1 o1 v2)) o2 v3
  22770. typedef typename synthesize_vovov_expression1::node_type vovov_t;
  22771. const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
  22772. const Type& v0 = vovov->t0();
  22773. const Type& v1 = vovov->t1();
  22774. const Type& v2 = vovov->t2();
  22775. const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22776. const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
  22777. const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
  22778. const details::operator_type o2 = operation;
  22779. binary_functor_t f0 = vovov->f0();
  22780. binary_functor_t f1 = vovov->f1();
  22781. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22782. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22783. expression_node_ptr result = error_node();
  22784. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
  22785. return result;
  22786. else if (!expr_gen.valid_operator(o2,f2))
  22787. return error_node();
  22788. exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n"));
  22789. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,v3,f0,f1,f2);
  22790. }
  22791. static inline std::string id(expression_generator<Type>& expr_gen,
  22792. const details::operator_type o0,
  22793. const details::operator_type o1,
  22794. const details::operator_type o2)
  22795. {
  22796. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22797. }
  22798. };
  22799. struct synthesize_vovovoc_expression4
  22800. {
  22801. typedef typename vovovoc_t::type4 node_type;
  22802. typedef typename vovovoc_t::sf4_type sf4_type;
  22803. typedef typename node_type::T0 T0;
  22804. typedef typename node_type::T1 T1;
  22805. typedef typename node_type::T2 T2;
  22806. typedef typename node_type::T3 T3;
  22807. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22808. const details::operator_type& operation,
  22809. expression_node_ptr (&branch)[2])
  22810. {
  22811. // ((v0 o0 (v1 o1 v2)) o2 c)
  22812. typedef typename synthesize_vovov_expression1::node_type vovov_t;
  22813. const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
  22814. const Type& v0 = vovov->t0();
  22815. const Type& v1 = vovov->t1();
  22816. const Type& v2 = vovov->t2();
  22817. const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
  22818. const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
  22819. const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
  22820. const details::operator_type o2 = operation;
  22821. binary_functor_t f0 = vovov->f0();
  22822. binary_functor_t f1 = vovov->f1();
  22823. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22824. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22825. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  22826. expression_node_ptr result = error_node();
  22827. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,c,result))
  22828. return result;
  22829. else if (!expr_gen.valid_operator(o2,f2))
  22830. return error_node();
  22831. exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n"));
  22832. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,c,f0,f1,f2);
  22833. }
  22834. static inline std::string id(expression_generator<Type>& expr_gen,
  22835. const details::operator_type o0,
  22836. const details::operator_type o1,
  22837. const details::operator_type o2)
  22838. {
  22839. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22840. }
  22841. };
  22842. struct synthesize_vovocov_expression4
  22843. {
  22844. typedef typename vovocov_t::type4 node_type;
  22845. typedef typename vovocov_t::sf4_type sf4_type;
  22846. typedef typename node_type::T0 T0;
  22847. typedef typename node_type::T1 T1;
  22848. typedef typename node_type::T2 T2;
  22849. typedef typename node_type::T3 T3;
  22850. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22851. const details::operator_type& operation,
  22852. expression_node_ptr (&branch)[2])
  22853. {
  22854. // ((v0 o0 (v1 o1 c)) o2 v1)
  22855. typedef typename synthesize_vovoc_expression1::node_type vovoc_t;
  22856. const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[0]);
  22857. const Type& v0 = vovoc->t0();
  22858. const Type& v1 = vovoc->t1();
  22859. const Type c = vovoc->t2();
  22860. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22861. const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
  22862. const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
  22863. const details::operator_type o2 = operation;
  22864. binary_functor_t f0 = vovoc->f0();
  22865. binary_functor_t f1 = vovoc->f1();
  22866. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22867. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22868. expression_node_ptr result = error_node();
  22869. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,c,v2,result))
  22870. return result;
  22871. else if (!expr_gen.valid_operator(o2,f2))
  22872. return error_node();
  22873. exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n"));
  22874. return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,c,v2,f0,f1,f2);
  22875. }
  22876. static inline std::string id(expression_generator<Type>& expr_gen,
  22877. const details::operator_type o0,
  22878. const details::operator_type o1,
  22879. const details::operator_type o2)
  22880. {
  22881. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22882. }
  22883. };
  22884. struct synthesize_vocovov_expression4
  22885. {
  22886. typedef typename vocovov_t::type4 node_type;
  22887. typedef typename vocovov_t::sf4_type sf4_type;
  22888. typedef typename node_type::T0 T0;
  22889. typedef typename node_type::T1 T1;
  22890. typedef typename node_type::T2 T2;
  22891. typedef typename node_type::T3 T3;
  22892. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22893. const details::operator_type& operation,
  22894. expression_node_ptr (&branch)[2])
  22895. {
  22896. // ((v0 o0 (c o1 v1)) o2 v2)
  22897. typedef typename synthesize_vocov_expression1::node_type vocov_t;
  22898. const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
  22899. const Type& v0 = vocov->t0();
  22900. const Type c = vocov->t1();
  22901. const Type& v1 = vocov->t2();
  22902. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22903. const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
  22904. const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
  22905. const details::operator_type o2 = operation;
  22906. binary_functor_t f0 = vocov->f0();
  22907. binary_functor_t f1 = vocov->f1();
  22908. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22909. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22910. expression_node_ptr result = error_node();
  22911. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c,v1,v2,result))
  22912. return result;
  22913. else if (!expr_gen.valid_operator(o2,f2))
  22914. return error_node();
  22915. exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n"));
  22916. return node_type::allocate(*(expr_gen.node_allocator_),v0,c,v1,v2,f0,f1,f2);
  22917. }
  22918. static inline std::string id(expression_generator<Type>& expr_gen,
  22919. const details::operator_type o0,
  22920. const details::operator_type o1,
  22921. const details::operator_type o2)
  22922. {
  22923. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22924. }
  22925. };
  22926. struct synthesize_covovov_expression4
  22927. {
  22928. typedef typename covovov_t::type4 node_type;
  22929. typedef typename covovov_t::sf4_type sf4_type;
  22930. typedef typename node_type::T0 T0;
  22931. typedef typename node_type::T1 T1;
  22932. typedef typename node_type::T2 T2;
  22933. typedef typename node_type::T3 T3;
  22934. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22935. const details::operator_type& operation,
  22936. expression_node_ptr (&branch)[2])
  22937. {
  22938. // ((c o0 (v0 o1 v1)) o2 v2)
  22939. typedef typename synthesize_covov_expression1::node_type covov_t;
  22940. const covov_t* covov = static_cast<const covov_t*>(branch[0]);
  22941. const Type c = covov->t0();
  22942. const Type& v0 = covov->t1();
  22943. const Type& v1 = covov->t2();
  22944. const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22945. const details::operator_type o0 = expr_gen.get_operator(covov->f0());
  22946. const details::operator_type o1 = expr_gen.get_operator(covov->f1());
  22947. const details::operator_type o2 = operation;
  22948. binary_functor_t f0 = covov->f0();
  22949. binary_functor_t f1 = covov->f1();
  22950. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22951. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22952. expression_node_ptr result = error_node();
  22953. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c,v0,v1,v2,result))
  22954. return result;
  22955. else if (!expr_gen.valid_operator(o2,f2))
  22956. return error_node();
  22957. exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n"));
  22958. return node_type::allocate(*(expr_gen.node_allocator_),c,v0,v1,v2,f0,f1,f2);
  22959. }
  22960. static inline std::string id(expression_generator<Type>& expr_gen,
  22961. const details::operator_type o0,
  22962. const details::operator_type o1,
  22963. const details::operator_type o2)
  22964. {
  22965. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  22966. }
  22967. };
  22968. struct synthesize_covocov_expression4
  22969. {
  22970. typedef typename covocov_t::type4 node_type;
  22971. typedef typename covocov_t::sf4_type sf4_type;
  22972. typedef typename node_type::T0 T0;
  22973. typedef typename node_type::T1 T1;
  22974. typedef typename node_type::T2 T2;
  22975. typedef typename node_type::T3 T3;
  22976. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  22977. const details::operator_type& operation,
  22978. expression_node_ptr (&branch)[2])
  22979. {
  22980. // ((c0 o0 (v0 o1 c1)) o2 v1)
  22981. typedef typename synthesize_covoc_expression1::node_type covoc_t;
  22982. const covoc_t* covoc = static_cast<const covoc_t*>(branch[0]);
  22983. const Type c0 = covoc->t0();
  22984. const Type& v0 = covoc->t1();
  22985. const Type c1 = covoc->t2();
  22986. const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
  22987. const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
  22988. const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
  22989. const details::operator_type o2 = operation;
  22990. binary_functor_t f0 = covoc->f0();
  22991. binary_functor_t f1 = covoc->f1();
  22992. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  22993. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  22994. expression_node_ptr result = error_node();
  22995. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,c1,v1,result))
  22996. return result;
  22997. else if (!expr_gen.valid_operator(o2,f2))
  22998. return error_node();
  22999. exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n"));
  23000. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,c1,v1,f0,f1,f2);
  23001. }
  23002. static inline std::string id(expression_generator<Type>& expr_gen,
  23003. const details::operator_type o0,
  23004. const details::operator_type o1,
  23005. const details::operator_type o2)
  23006. {
  23007. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  23008. }
  23009. };
  23010. struct synthesize_vocovoc_expression4
  23011. {
  23012. typedef typename vocovoc_t::type4 node_type;
  23013. typedef typename vocovoc_t::sf4_type sf4_type;
  23014. typedef typename node_type::T0 T0;
  23015. typedef typename node_type::T1 T1;
  23016. typedef typename node_type::T2 T2;
  23017. typedef typename node_type::T3 T3;
  23018. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  23019. const details::operator_type& operation,
  23020. expression_node_ptr (&branch)[2])
  23021. {
  23022. // ((v0 o0 (c0 o1 v1)) o2 c1)
  23023. typedef typename synthesize_vocov_expression1::node_type vocov_t;
  23024. const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
  23025. const Type& v0 = vocov->t0();
  23026. const Type c0 = vocov->t1();
  23027. const Type& v1 = vocov->t2();
  23028. const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
  23029. const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
  23030. const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
  23031. const details::operator_type o2 = operation;
  23032. binary_functor_t f0 = vocov->f0();
  23033. binary_functor_t f1 = vocov->f1();
  23034. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  23035. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  23036. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  23037. expression_node_ptr result = error_node();
  23038. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,c0,v1,c1,result))
  23039. return result;
  23040. else if (!expr_gen.valid_operator(o2,f2))
  23041. return error_node();
  23042. exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n"));
  23043. return node_type::allocate(*(expr_gen.node_allocator_),v0,c0,v1,c1,f0,f1,f2);
  23044. }
  23045. static inline std::string id(expression_generator<Type>& expr_gen,
  23046. const details::operator_type o0,
  23047. const details::operator_type o1,
  23048. const details::operator_type o2)
  23049. {
  23050. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  23051. }
  23052. };
  23053. struct synthesize_covovoc_expression4
  23054. {
  23055. typedef typename covovoc_t::type4 node_type;
  23056. typedef typename covovoc_t::sf4_type sf4_type;
  23057. typedef typename node_type::T0 T0;
  23058. typedef typename node_type::T1 T1;
  23059. typedef typename node_type::T2 T2;
  23060. typedef typename node_type::T3 T3;
  23061. static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
  23062. const details::operator_type& operation,
  23063. expression_node_ptr (&branch)[2])
  23064. {
  23065. // ((c0 o0 (v0 o1 v1)) o2 c1)
  23066. typedef typename synthesize_covov_expression1::node_type covov_t;
  23067. const covov_t* covov = static_cast<const covov_t*>(branch[0]);
  23068. const Type c0 = covov->t0();
  23069. const Type& v0 = covov->t1();
  23070. const Type& v1 = covov->t2();
  23071. const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
  23072. const details::operator_type o0 = expr_gen.get_operator(covov->f0());
  23073. const details::operator_type o1 = expr_gen.get_operator(covov->f1());
  23074. const details::operator_type o2 = operation;
  23075. binary_functor_t f0 = covov->f0();
  23076. binary_functor_t f1 = covov->f1();
  23077. binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
  23078. details::free_node(*(expr_gen.node_allocator_),branch[0]);
  23079. details::free_node(*(expr_gen.node_allocator_),branch[1]);
  23080. expression_node_ptr result = error_node();
  23081. if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),c0,v0,v1,c1,result))
  23082. return result;
  23083. else if (!expr_gen.valid_operator(o2,f2))
  23084. return error_node();
  23085. exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n"));
  23086. return node_type::allocate(*(expr_gen.node_allocator_),c0,v0,v1,c1,f0,f1,f2);
  23087. }
  23088. static inline std::string id(expression_generator<Type>& expr_gen,
  23089. const details::operator_type o0,
  23090. const details::operator_type o1,
  23091. const details::operator_type o2)
  23092. {
  23093. return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
  23094. }
  23095. };
  23096. struct synthesize_vococov_expression4
  23097. {
  23098. typedef typename vococov_t::type4 node_type;
  23099. static inline expression_node_ptr process(expression_generator<Type>&, const details::operator_type&, expression_node_ptr (&)[2])
  23100. {
  23101. // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible
  23102. exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
  23103. return error_node();
  23104. }
  23105. static inline std::string id(expression_generator<Type>&,
  23106. const details::operator_type, const details::operator_type, const details::operator_type)
  23107. {
  23108. return "INVALID";
  23109. }
  23110. };
  23111. #endif
  23112. inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  23113. {
  23114. // Definition: uv o uv
  23115. details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
  23116. details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
  23117. const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
  23118. const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
  23119. unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
  23120. unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
  23121. binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
  23122. if (!valid_operator(o0,u0))
  23123. return error_node();
  23124. else if (!valid_operator(o1,u1))
  23125. return error_node();
  23126. else if (!valid_operator(operation,f))
  23127. return error_node();
  23128. expression_node_ptr result = error_node();
  23129. if (
  23130. (details::e_neg == o0) &&
  23131. (details::e_neg == o1)
  23132. )
  23133. {
  23134. switch (operation)
  23135. {
  23136. // (-v0 + -v1) --> -(v0 + v1)
  23137. case details::e_add : result = (*this)(details::e_neg,
  23138. node_allocator_->
  23139. allocate_rr<typename details::
  23140. vov_node<Type,details::add_op<Type> > >(v0,v1));
  23141. exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n"));
  23142. break;
  23143. // (-v0 - -v1) --> (v1 - v0)
  23144. case details::e_sub : result = node_allocator_->
  23145. allocate_rr<typename details::
  23146. vov_node<Type,details::sub_op<Type> > >(v1,v0);
  23147. exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n"));
  23148. break;
  23149. // (-v0 * -v1) --> (v0 * v1)
  23150. case details::e_mul : result = node_allocator_->
  23151. allocate_rr<typename details::
  23152. vov_node<Type,details::mul_op<Type> > >(v0,v1);
  23153. exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n"));
  23154. break;
  23155. // (-v0 / -v1) --> (v0 / v1)
  23156. case details::e_div : result = node_allocator_->
  23157. allocate_rr<typename details::
  23158. vov_node<Type,details::div_op<Type> > >(v0,v1);
  23159. exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n"));
  23160. break;
  23161. default : break;
  23162. }
  23163. }
  23164. if (0 == result)
  23165. {
  23166. result = node_allocator_->
  23167. allocate_rrrrr<typename details::uvouv_node<Type> >(v0,v1,u0,u1,f);
  23168. }
  23169. details::free_all_nodes(*node_allocator_,branch);
  23170. return result;
  23171. }
  23172. #undef basic_opr_switch_statements
  23173. #undef extended_opr_switch_statements
  23174. #undef unary_opr_switch_statements
  23175. #ifndef exprtk_disable_string_capabilities
  23176. #define string_opr_switch_statements \
  23177. case_stmt(details:: e_lt ,details:: lt_op) \
  23178. case_stmt(details:: e_lte ,details:: lte_op) \
  23179. case_stmt(details:: e_gt ,details:: gt_op) \
  23180. case_stmt(details:: e_gte ,details:: gte_op) \
  23181. case_stmt(details:: e_eq ,details:: eq_op) \
  23182. case_stmt(details:: e_ne ,details:: ne_op) \
  23183. case_stmt(details::e_in ,details:: in_op) \
  23184. case_stmt(details::e_like ,details:: like_op) \
  23185. case_stmt(details::e_ilike,details::ilike_op) \
  23186. template <typename T0, typename T1>
  23187. inline expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type& opr,
  23188. T0 s0, T1 s1,
  23189. range_t rp0)
  23190. {
  23191. switch (opr)
  23192. {
  23193. #define case_stmt(op0,op1) \
  23194. case op0 : return node_allocator_-> \
  23195. allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
  23196. (s0,s1,rp0); \
  23197. string_opr_switch_statements
  23198. #undef case_stmt
  23199. default : return error_node();
  23200. }
  23201. }
  23202. template <typename T0, typename T1>
  23203. inline expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type& opr,
  23204. T0 s0, T1 s1,
  23205. range_t rp1)
  23206. {
  23207. switch (opr)
  23208. {
  23209. #define case_stmt(op0,op1) \
  23210. case op0 : return node_allocator_-> \
  23211. allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
  23212. (s0,s1,rp1); \
  23213. string_opr_switch_statements
  23214. #undef case_stmt
  23215. default : return error_node();
  23216. }
  23217. }
  23218. template <typename T0, typename T1>
  23219. inline expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type& opr,
  23220. T0 s0, T1 s1,
  23221. range_t rp0, range_t rp1)
  23222. {
  23223. switch (opr)
  23224. {
  23225. #define case_stmt(op0,op1) \
  23226. case op0 : return node_allocator_-> \
  23227. allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
  23228. (s0,s1,rp0,rp1); \
  23229. string_opr_switch_statements
  23230. #undef case_stmt
  23231. default : return error_node();
  23232. }
  23233. }
  23234. template <typename T0, typename T1>
  23235. inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1)
  23236. {
  23237. switch (opr)
  23238. {
  23239. #define case_stmt(op0,op1) \
  23240. case op0 : return node_allocator_-> \
  23241. allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0,s1); \
  23242. string_opr_switch_statements
  23243. #undef case_stmt
  23244. default : return error_node();
  23245. }
  23246. }
  23247. inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23248. {
  23249. std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
  23250. std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
  23251. return synthesize_sos_expression_impl<std::string&,std::string&>(opr,s0,s1);
  23252. }
  23253. inline expression_node_ptr synthesize_sros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23254. {
  23255. std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
  23256. std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
  23257. range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
  23258. static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
  23259. free_node(*node_allocator_,branch[0]);
  23260. return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr,s0,s1,rp0);
  23261. }
  23262. inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23263. {
  23264. std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
  23265. std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
  23266. range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
  23267. static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
  23268. free_node(*node_allocator_,branch[1]);
  23269. return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr,s0,s1,rp1);
  23270. }
  23271. inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23272. {
  23273. std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
  23274. std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
  23275. range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
  23276. static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
  23277. free_node(*node_allocator_,branch[1]);
  23278. return synthesize_str_xoxr_expression_impl<std::string&,const std::string>(opr,s0,s1,rp1);
  23279. }
  23280. inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23281. {
  23282. std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
  23283. std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
  23284. range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
  23285. range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
  23286. static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
  23287. static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
  23288. details::free_node(*node_allocator_,branch[0]);
  23289. details::free_node(*node_allocator_,branch[1]);
  23290. return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr,s0,s1,rp0,rp1);
  23291. }
  23292. inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23293. {
  23294. std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
  23295. std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
  23296. details::free_node(*node_allocator_,branch[1]);
  23297. return synthesize_sos_expression_impl<std::string&,const std::string>(opr,s0,s1);
  23298. }
  23299. inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23300. {
  23301. std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
  23302. std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  23303. details::free_node(*node_allocator_,branch[0]);
  23304. return synthesize_sos_expression_impl<const std::string,std::string&>(opr,s0,s1);
  23305. }
  23306. inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23307. {
  23308. std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
  23309. std::string& s1 = static_cast<details::string_range_node<Type>*> (branch[1])->ref ();
  23310. range_t rp1 = static_cast<details::string_range_node<Type>*> (branch[1])->range();
  23311. static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
  23312. details::free_node(*node_allocator_,branch[0]);
  23313. details::free_node(*node_allocator_,branch[1]);
  23314. return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr,s0,s1,rp1);
  23315. }
  23316. inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23317. {
  23318. std::string& s0 = static_cast<details::string_range_node<Type>*> (branch[0])->ref ();
  23319. std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
  23320. range_t rp0 = static_cast<details::string_range_node<Type>*> (branch[0])->range();
  23321. static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
  23322. details::free_node(*node_allocator_,branch[0]);
  23323. details::free_node(*node_allocator_,branch[1]);
  23324. return synthesize_str_xrox_expression_impl<std::string&,const std::string>(opr,s0,s1,rp0);
  23325. }
  23326. inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23327. {
  23328. std::string& s0 = static_cast<details::string_range_node<Type>*> (branch[0])->ref ();
  23329. std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
  23330. range_t rp0 = static_cast<details::string_range_node<Type>*> (branch[0])->range();
  23331. range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
  23332. static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
  23333. static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
  23334. details::free_node(*node_allocator_,branch[0]);
  23335. details::free_node(*node_allocator_,branch[1]);
  23336. return synthesize_str_xroxr_expression_impl<std::string&,const std::string>(opr,s0,s1,rp0,rp1);
  23337. }
  23338. inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23339. {
  23340. const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
  23341. const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
  23342. expression_node_ptr result = error_node();
  23343. if (details::e_add == opr)
  23344. result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
  23345. else if (details::e_in == opr)
  23346. result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op<Type>::process(s0,s1));
  23347. else if (details::e_like == opr)
  23348. result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op<Type>::process(s0,s1));
  23349. else if (details::e_ilike == opr)
  23350. result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
  23351. else
  23352. {
  23353. expression_node_ptr temp = synthesize_sos_expression_impl<const std::string,const std::string>(opr,s0,s1);
  23354. Type v = temp->value();
  23355. details::free_node(*node_allocator_,temp);
  23356. result = node_allocator_->allocate<literal_node_t>(v);
  23357. }
  23358. details::free_all_nodes(*node_allocator_,branch);
  23359. return result;
  23360. }
  23361. inline expression_node_ptr synthesize_csocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23362. {
  23363. const std::string s0 = static_cast<details::string_literal_node<Type>*> (branch[0])->str ();
  23364. std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
  23365. range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
  23366. static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
  23367. free_node(*node_allocator_,branch[0]);
  23368. free_node(*node_allocator_,branch[1]);
  23369. return synthesize_str_xoxr_expression_impl<const std::string,const std::string>(opr,s0,s1,rp1);
  23370. }
  23371. inline expression_node_ptr synthesize_csros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23372. {
  23373. std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
  23374. std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
  23375. range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
  23376. static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
  23377. free_node(*node_allocator_,branch[0]);
  23378. return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr,s0,s1,rp0);
  23379. }
  23380. inline expression_node_ptr synthesize_csrosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23381. {
  23382. const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
  23383. std::string& s1 = static_cast<details::string_range_node<Type>*> (branch[1])->ref ();
  23384. range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
  23385. range_t rp1 = static_cast<details::string_range_node<Type>*> (branch[1])->range();
  23386. static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
  23387. static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
  23388. free_node(*node_allocator_,branch[0]);
  23389. free_node(*node_allocator_,branch[1]);
  23390. return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr,s0,s1,rp0,rp1);
  23391. }
  23392. inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23393. {
  23394. std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
  23395. const std::string s1 = static_cast<details::string_literal_node<Type>*> (branch[1])->str ();
  23396. range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
  23397. static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
  23398. details::free_all_nodes(*node_allocator_,branch);
  23399. return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr,s0,s1,rp0);
  23400. }
  23401. inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23402. {
  23403. std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
  23404. std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
  23405. range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
  23406. range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
  23407. static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
  23408. static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
  23409. details::free_all_nodes(*node_allocator_,branch);
  23410. return synthesize_str_xroxr_expression_impl<const std::string,const std::string>(opr,s0,s1,rp0,rp1);
  23411. }
  23412. inline expression_node_ptr synthesize_strogen_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23413. {
  23414. switch (opr)
  23415. {
  23416. #define case_stmt(op0,op1) \
  23417. case op0 : return node_allocator_-> \
  23418. allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
  23419. (opr,branch[0],branch[1]); \
  23420. string_opr_switch_statements
  23421. #undef case_stmt
  23422. default : return error_node();
  23423. }
  23424. }
  23425. #endif
  23426. #ifndef exprtk_disable_string_capabilities
  23427. inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  23428. {
  23429. if ((0 == branch[0]) || (0 == branch[1]))
  23430. {
  23431. details::free_all_nodes(*node_allocator_,branch);
  23432. return error_node();
  23433. }
  23434. const bool b0_is_s = details::is_string_node (branch[0]);
  23435. const bool b0_is_cs = details::is_const_string_node (branch[0]);
  23436. const bool b0_is_sr = details::is_string_range_node (branch[0]);
  23437. const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
  23438. const bool b1_is_s = details::is_string_node (branch[1]);
  23439. const bool b1_is_cs = details::is_const_string_node (branch[1]);
  23440. const bool b1_is_sr = details::is_string_range_node (branch[1]);
  23441. const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
  23442. const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
  23443. details::is_genricstring_range_node(branch[0]) ||
  23444. details::is_string_concat_node (branch[0]) ||
  23445. details::is_string_function_node (branch[0]) ;
  23446. const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
  23447. details::is_genricstring_range_node(branch[1]) ||
  23448. details::is_string_concat_node (branch[1]) ||
  23449. details::is_string_function_node (branch[1]) ;
  23450. if (details::e_add == opr)
  23451. {
  23452. if (!b0_is_cs || !b1_is_cs)
  23453. {
  23454. return synthesize_expression<string_concat_node_t,2>(opr,branch);
  23455. }
  23456. }
  23457. if (b0_is_gen || b1_is_gen)
  23458. {
  23459. return synthesize_strogen_expression(opr,branch);
  23460. }
  23461. else if (b0_is_s)
  23462. {
  23463. if (b1_is_s ) return synthesize_sos_expression (opr,branch);
  23464. else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
  23465. else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
  23466. else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
  23467. }
  23468. else if (b0_is_cs)
  23469. {
  23470. if (b1_is_s ) return synthesize_csos_expression (opr,branch);
  23471. else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
  23472. else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
  23473. else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
  23474. }
  23475. else if (b0_is_sr)
  23476. {
  23477. if (b1_is_s ) return synthesize_sros_expression (opr,branch);
  23478. else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
  23479. else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
  23480. else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
  23481. }
  23482. else if (b0_is_csr)
  23483. {
  23484. if (b1_is_s ) return synthesize_csros_expression (opr,branch);
  23485. else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
  23486. else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
  23487. else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
  23488. }
  23489. return error_node();
  23490. }
  23491. #else
  23492. inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2])
  23493. {
  23494. details::free_all_nodes(*node_allocator_,branch);
  23495. return error_node();
  23496. }
  23497. #endif
  23498. #ifndef exprtk_disable_string_capabilities
  23499. inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3])
  23500. {
  23501. if (details::e_inrange != opr)
  23502. return error_node();
  23503. else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
  23504. {
  23505. details::free_all_nodes(*node_allocator_,branch);
  23506. return error_node();
  23507. }
  23508. else if (
  23509. details::is_const_string_node(branch[0]) &&
  23510. details::is_const_string_node(branch[1]) &&
  23511. details::is_const_string_node(branch[2])
  23512. )
  23513. {
  23514. const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
  23515. const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
  23516. const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
  23517. Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
  23518. details::free_all_nodes(*node_allocator_,branch);
  23519. return node_allocator_->allocate_c<details::literal_node<Type> >(v);
  23520. }
  23521. else if (
  23522. details::is_string_node(branch[0]) &&
  23523. details::is_string_node(branch[1]) &&
  23524. details::is_string_node(branch[2])
  23525. )
  23526. {
  23527. std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
  23528. std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
  23529. std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
  23530. typedef typename details::sosos_node<Type,std::string&,std::string&,std::string&,details::inrange_op<Type> > inrange_t;
  23531. return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string&>(s0,s1,s2);
  23532. }
  23533. else if (
  23534. details::is_const_string_node(branch[0]) &&
  23535. details::is_string_node(branch[1]) &&
  23536. details::is_const_string_node(branch[2])
  23537. )
  23538. {
  23539. std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
  23540. std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  23541. std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
  23542. typedef typename details::sosos_node<Type,std::string,std::string&,std::string,details::inrange_op<Type> > inrange_t;
  23543. details::free_node(*node_allocator_,branch[0]);
  23544. details::free_node(*node_allocator_,branch[2]);
  23545. return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string>(s0,s1,s2);
  23546. }
  23547. else if (
  23548. details::is_string_node(branch[0]) &&
  23549. details::is_const_string_node(branch[1]) &&
  23550. details::is_string_node(branch[2])
  23551. )
  23552. {
  23553. std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
  23554. std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
  23555. std::string& s2 = static_cast< details::stringvar_node<Type>*>(branch[2])->ref();
  23556. typedef typename details::sosos_node<Type,std::string&,std::string,std::string&,details::inrange_op<Type> > inrange_t;
  23557. details::free_node(*node_allocator_,branch[1]);
  23558. return node_allocator_->allocate_type<inrange_t,std::string&,std::string,std::string&>(s0,s1,s2);
  23559. }
  23560. else if (
  23561. details::is_string_node(branch[0]) &&
  23562. details::is_string_node(branch[1]) &&
  23563. details::is_const_string_node(branch[2])
  23564. )
  23565. {
  23566. std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
  23567. std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  23568. std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
  23569. typedef typename details::sosos_node<Type,std::string&,std::string&,std::string,details::inrange_op<Type> > inrange_t;
  23570. details::free_node(*node_allocator_,branch[2]);
  23571. return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string>(s0,s1,s2);
  23572. }
  23573. else if (
  23574. details::is_const_string_node(branch[0]) &&
  23575. details:: is_string_node(branch[1]) &&
  23576. details:: is_string_node(branch[2])
  23577. )
  23578. {
  23579. std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
  23580. std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  23581. std::string& s2 = static_cast< details::stringvar_node<Type>*>(branch[2])->ref();
  23582. typedef typename details::sosos_node<Type,std::string,std::string&,std::string&,details::inrange_op<Type> > inrange_t;
  23583. details::free_node(*node_allocator_,branch[0]);
  23584. return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string&>(s0,s1,s2);
  23585. }
  23586. else
  23587. return error_node();
  23588. }
  23589. #else
  23590. inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3])
  23591. {
  23592. details::free_all_nodes(*node_allocator_,branch);
  23593. return error_node();
  23594. }
  23595. #endif
  23596. inline expression_node_ptr synthesize_null_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  23597. {
  23598. /*
  23599. Note: The following are the type promotion rules
  23600. that relate to operations that include 'null':
  23601. 0. null ==/!= null --> true false
  23602. 1. null operation null --> null
  23603. 2. x ==/!= null --> true/false
  23604. 3. null ==/!= x --> true/false
  23605. 4. x operation null --> x
  23606. 5. null operation x --> x
  23607. */
  23608. typedef typename details::null_eq_node<T> nulleq_node_t;
  23609. bool b0_null = details::is_null_node(branch[0]);
  23610. bool b1_null = details::is_null_node(branch[1]);
  23611. if (b0_null && b1_null)
  23612. {
  23613. expression_node_ptr result = error_node();
  23614. if (details::e_eq == operation)
  23615. result = node_allocator_->allocate_c<literal_node_t>(T(1));
  23616. else if (details::e_ne == operation)
  23617. result = node_allocator_->allocate_c<literal_node_t>(T(0));
  23618. if (result)
  23619. {
  23620. details::free_node(*node_allocator_,branch[0]);
  23621. details::free_node(*node_allocator_,branch[1]);
  23622. return result;
  23623. }
  23624. details::free_node(*node_allocator_,branch[1]);
  23625. return branch[0];
  23626. }
  23627. else if (details::e_eq == operation)
  23628. {
  23629. expression_node_ptr result = node_allocator_->
  23630. allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
  23631. details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
  23632. return result;
  23633. }
  23634. else if (details::e_ne == operation)
  23635. {
  23636. expression_node_ptr result = node_allocator_->
  23637. allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
  23638. details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
  23639. return result;
  23640. }
  23641. else if (b0_null)
  23642. {
  23643. details::free_node(*node_allocator_,branch[0]);
  23644. branch[0] = branch[1];
  23645. branch[1] = error_node();
  23646. }
  23647. else if (b1_null)
  23648. {
  23649. details::free_node(*node_allocator_,branch[1]);
  23650. branch[1] = error_node();
  23651. }
  23652. if (
  23653. (details::e_add == operation) || (details::e_sub == operation) ||
  23654. (details::e_mul == operation) || (details::e_div == operation) ||
  23655. (details::e_mod == operation) || (details::e_pow == operation)
  23656. )
  23657. {
  23658. return branch[0];
  23659. }
  23660. else if (
  23661. (details::e_lt == operation) || (details::e_lte == operation) ||
  23662. (details::e_gt == operation) || (details::e_gte == operation) ||
  23663. (details::e_and == operation) || (details::e_nand == operation) ||
  23664. (details::e_or == operation) || (details::e_nor == operation) ||
  23665. (details::e_xor == operation) || (details::e_xnor == operation) ||
  23666. (details::e_in == operation) || (details::e_like == operation) ||
  23667. (details::e_ilike == operation)
  23668. )
  23669. {
  23670. return node_allocator_->allocate_c<literal_node_t>(T(0));
  23671. }
  23672. details::free_node(*node_allocator_,branch[0]);
  23673. return node_allocator_->allocate<details::null_node<Type> >();
  23674. }
  23675. template <typename NodeType, std::size_t N>
  23676. inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N])
  23677. {
  23678. if (
  23679. (details::e_in == operation) ||
  23680. (details::e_like == operation) ||
  23681. (details::e_ilike == operation)
  23682. )
  23683. return error_node();
  23684. else if (!details::all_nodes_valid<N>(branch))
  23685. {
  23686. free_all_nodes(*node_allocator_,branch);
  23687. return error_node();
  23688. }
  23689. else if ((details::e_default != operation))
  23690. {
  23691. // Attempt simple constant folding optimization.
  23692. expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
  23693. if (is_constant_foldable<N>(branch))
  23694. {
  23695. Type v = expression_point->value();
  23696. details::free_node(*node_allocator_,expression_point);
  23697. return node_allocator_->allocate<literal_node_t>(v);
  23698. }
  23699. else
  23700. return expression_point;
  23701. }
  23702. else
  23703. return error_node();
  23704. }
  23705. template <typename NodeType, std::size_t N>
  23706. inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N])
  23707. {
  23708. if (!details::all_nodes_valid<N>(branch))
  23709. {
  23710. free_all_nodes(*node_allocator_,branch);
  23711. return error_node();
  23712. }
  23713. typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
  23714. // Attempt simple constant folding optimization.
  23715. expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
  23716. function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
  23717. if (0 == func_node_ptr)
  23718. {
  23719. free_all_nodes(*node_allocator_,branch);
  23720. return error_node();
  23721. }
  23722. else
  23723. func_node_ptr->init_branches(branch);
  23724. if (is_constant_foldable<N>(branch) && !f->has_side_effects)
  23725. {
  23726. Type v = expression_point->value();
  23727. details::free_node(*node_allocator_,expression_point);
  23728. return node_allocator_->allocate<literal_node_t>(v);
  23729. }
  23730. else
  23731. return expression_point;
  23732. }
  23733. bool strength_reduction_enabled_;
  23734. details::node_allocator* node_allocator_;
  23735. synthesize_map_t synthesize_map_;
  23736. unary_op_map_t* unary_op_map_;
  23737. binary_op_map_t* binary_op_map_;
  23738. inv_binary_op_map_t* inv_binary_op_map_;
  23739. sf3_map_t* sf3_map_;
  23740. sf4_map_t* sf4_map_;
  23741. parser_t* parser_;
  23742. };
  23743. inline void set_error(const parser_error::type& error_type)
  23744. {
  23745. error_list_.push_back(error_type);
  23746. }
  23747. inline void remove_last_error()
  23748. {
  23749. if (!error_list_.empty())
  23750. {
  23751. error_list_.pop_back();
  23752. }
  23753. }
  23754. inline void set_synthesis_error(const std::string& synthesis_error_message)
  23755. {
  23756. if (synthesis_error_.empty())
  23757. {
  23758. synthesis_error_ = synthesis_error_message;
  23759. }
  23760. }
  23761. inline void register_local_vars(expression<T>& e)
  23762. {
  23763. for (std::size_t i = 0; i < sem_.size(); ++i)
  23764. {
  23765. scope_element& se = sem_.get_element(i);
  23766. if (
  23767. (scope_element::e_variable == se.type) ||
  23768. (scope_element::e_vecelem == se.type)
  23769. )
  23770. {
  23771. if (se.var_node)
  23772. {
  23773. e.register_local_var(se.var_node);
  23774. }
  23775. if (se.data)
  23776. {
  23777. e.register_local_data(se.data,1);
  23778. }
  23779. }
  23780. else if (scope_element::e_vector == se.type)
  23781. {
  23782. if (se.vec_node)
  23783. {
  23784. e.register_local_var (se.vec_node);
  23785. }
  23786. if (se.data)
  23787. {
  23788. e.register_local_data(se.data,se.size,true);
  23789. }
  23790. }
  23791. se.var_node = 0;
  23792. se.vec_node = 0;
  23793. se.data = 0;
  23794. se.ref_count = 0;
  23795. se.active = false;
  23796. }
  23797. }
  23798. inline void load_unary_operations_map(unary_op_map_t& m)
  23799. {
  23800. #define register_unary_op(Op,UnaryFunctor) \
  23801. m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
  23802. register_unary_op(details:: e_abs,details:: abs_op)
  23803. register_unary_op(details:: e_acos,details:: acos_op)
  23804. register_unary_op(details::e_acosh,details::acosh_op)
  23805. register_unary_op(details:: e_asin,details:: asin_op)
  23806. register_unary_op(details::e_asinh,details::asinh_op)
  23807. register_unary_op(details::e_atanh,details::atanh_op)
  23808. register_unary_op(details:: e_ceil,details:: ceil_op)
  23809. register_unary_op(details:: e_cos,details:: cos_op)
  23810. register_unary_op(details:: e_cosh,details:: cosh_op)
  23811. register_unary_op(details:: e_exp,details:: exp_op)
  23812. register_unary_op(details::e_expm1,details::expm1_op)
  23813. register_unary_op(details::e_floor,details::floor_op)
  23814. register_unary_op(details:: e_log,details:: log_op)
  23815. register_unary_op(details::e_log10,details::log10_op)
  23816. register_unary_op(details:: e_log2,details:: log2_op)
  23817. register_unary_op(details::e_log1p,details::log1p_op)
  23818. register_unary_op(details:: e_neg,details:: neg_op)
  23819. register_unary_op(details:: e_pos,details:: pos_op)
  23820. register_unary_op(details::e_round,details::round_op)
  23821. register_unary_op(details:: e_sin,details:: sin_op)
  23822. register_unary_op(details:: e_sinc,details:: sinc_op)
  23823. register_unary_op(details:: e_sinh,details:: sinh_op)
  23824. register_unary_op(details:: e_sqrt,details:: sqrt_op)
  23825. register_unary_op(details:: e_tan,details:: tan_op)
  23826. register_unary_op(details:: e_tanh,details:: tanh_op)
  23827. register_unary_op(details:: e_cot,details:: cot_op)
  23828. register_unary_op(details:: e_sec,details:: sec_op)
  23829. register_unary_op(details:: e_csc,details:: csc_op)
  23830. register_unary_op(details:: e_r2d,details:: r2d_op)
  23831. register_unary_op(details:: e_d2r,details:: d2r_op)
  23832. register_unary_op(details:: e_d2g,details:: d2g_op)
  23833. register_unary_op(details:: e_g2d,details:: g2d_op)
  23834. register_unary_op(details:: e_notl,details:: notl_op)
  23835. register_unary_op(details:: e_sgn,details:: sgn_op)
  23836. register_unary_op(details:: e_erf,details:: erf_op)
  23837. register_unary_op(details:: e_erfc,details:: erfc_op)
  23838. register_unary_op(details:: e_ncdf,details:: ncdf_op)
  23839. register_unary_op(details:: e_frac,details:: frac_op)
  23840. register_unary_op(details::e_trunc,details::trunc_op)
  23841. #undef register_unary_op
  23842. }
  23843. inline void load_binary_operations_map(binary_op_map_t& m)
  23844. {
  23845. typedef typename binary_op_map_t::value_type value_type;
  23846. #define register_binary_op(Op,BinaryFunctor) \
  23847. m.insert(value_type(Op,BinaryFunctor<T>::process)); \
  23848. register_binary_op(details:: e_add,details:: add_op)
  23849. register_binary_op(details:: e_sub,details:: sub_op)
  23850. register_binary_op(details:: e_mul,details:: mul_op)
  23851. register_binary_op(details:: e_div,details:: div_op)
  23852. register_binary_op(details:: e_mod,details:: mod_op)
  23853. register_binary_op(details:: e_pow,details:: pow_op)
  23854. register_binary_op(details:: e_lt,details:: lt_op)
  23855. register_binary_op(details:: e_lte,details:: lte_op)
  23856. register_binary_op(details:: e_gt,details:: gt_op)
  23857. register_binary_op(details:: e_gte,details:: gte_op)
  23858. register_binary_op(details:: e_eq,details:: eq_op)
  23859. register_binary_op(details:: e_ne,details:: ne_op)
  23860. register_binary_op(details:: e_and,details:: and_op)
  23861. register_binary_op(details::e_nand,details::nand_op)
  23862. register_binary_op(details:: e_or,details:: or_op)
  23863. register_binary_op(details:: e_nor,details:: nor_op)
  23864. register_binary_op(details:: e_xor,details:: xor_op)
  23865. register_binary_op(details::e_xnor,details::xnor_op)
  23866. #undef register_binary_op
  23867. }
  23868. inline void load_inv_binary_operations_map(inv_binary_op_map_t& m)
  23869. {
  23870. typedef typename inv_binary_op_map_t::value_type value_type;
  23871. #define register_binary_op(Op,BinaryFunctor) \
  23872. m.insert(value_type(BinaryFunctor<T>::process,Op)); \
  23873. register_binary_op(details:: e_add,details:: add_op)
  23874. register_binary_op(details:: e_sub,details:: sub_op)
  23875. register_binary_op(details:: e_mul,details:: mul_op)
  23876. register_binary_op(details:: e_div,details:: div_op)
  23877. register_binary_op(details:: e_mod,details:: mod_op)
  23878. register_binary_op(details:: e_pow,details:: pow_op)
  23879. register_binary_op(details:: e_lt,details:: lt_op)
  23880. register_binary_op(details:: e_lte,details:: lte_op)
  23881. register_binary_op(details:: e_gt,details:: gt_op)
  23882. register_binary_op(details:: e_gte,details:: gte_op)
  23883. register_binary_op(details:: e_eq,details:: eq_op)
  23884. register_binary_op(details:: e_ne,details:: ne_op)
  23885. register_binary_op(details:: e_and,details:: and_op)
  23886. register_binary_op(details::e_nand,details::nand_op)
  23887. register_binary_op(details:: e_or,details:: or_op)
  23888. register_binary_op(details:: e_nor,details:: nor_op)
  23889. register_binary_op(details:: e_xor,details:: xor_op)
  23890. register_binary_op(details::e_xnor,details::xnor_op)
  23891. #undef register_binary_op
  23892. }
  23893. inline void load_sf3_map(sf3_map_t& sf3_map)
  23894. {
  23895. typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
  23896. #define register_sf3(Op) \
  23897. sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
  23898. register_sf3(00) register_sf3(01) register_sf3(02) register_sf3(03)
  23899. register_sf3(04) register_sf3(05) register_sf3(06) register_sf3(07)
  23900. register_sf3(08) register_sf3(09) register_sf3(10) register_sf3(11)
  23901. register_sf3(12) register_sf3(13) register_sf3(14) register_sf3(15)
  23902. register_sf3(16) register_sf3(17) register_sf3(18) register_sf3(19)
  23903. register_sf3(20) register_sf3(21) register_sf3(22) register_sf3(23)
  23904. register_sf3(24) register_sf3(25) register_sf3(26) register_sf3(27)
  23905. register_sf3(28) register_sf3(29) register_sf3(30)
  23906. #undef register_sf3
  23907. }
  23908. inline void load_sf4_map(sf4_map_t& sf4_map)
  23909. {
  23910. typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
  23911. #define register_sf4(Op) \
  23912. sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
  23913. register_sf4(48) register_sf4(49) register_sf4(50) register_sf4(51)
  23914. register_sf4(52) register_sf4(53) register_sf4(54) register_sf4(55)
  23915. register_sf4(56) register_sf4(57) register_sf4(58) register_sf4(59)
  23916. register_sf4(60) register_sf4(61) register_sf4(62) register_sf4(63)
  23917. register_sf4(64) register_sf4(65) register_sf4(66) register_sf4(67)
  23918. register_sf4(68) register_sf4(69) register_sf4(70) register_sf4(71)
  23919. register_sf4(72) register_sf4(73) register_sf4(74) register_sf4(75)
  23920. register_sf4(76) register_sf4(77) register_sf4(78) register_sf4(79)
  23921. register_sf4(80) register_sf4(81) register_sf4(82) register_sf4(83)
  23922. #undef register_sf4
  23923. #define register_sf4ext(Op) \
  23924. sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
  23925. register_sf4ext(00) register_sf4ext(01) register_sf4ext(02) register_sf4ext(03)
  23926. register_sf4ext(04) register_sf4ext(05) register_sf4ext(06) register_sf4ext(07)
  23927. register_sf4ext(08) register_sf4ext(09) register_sf4ext(10) register_sf4ext(11)
  23928. register_sf4ext(12) register_sf4ext(13) register_sf4ext(14) register_sf4ext(15)
  23929. register_sf4ext(16) register_sf4ext(17) register_sf4ext(18) register_sf4ext(19)
  23930. register_sf4ext(20) register_sf4ext(21) register_sf4ext(22) register_sf4ext(23)
  23931. register_sf4ext(24) register_sf4ext(25) register_sf4ext(26) register_sf4ext(27)
  23932. register_sf4ext(28) register_sf4ext(29) register_sf4ext(30) register_sf4ext(31)
  23933. register_sf4ext(32) register_sf4ext(33) register_sf4ext(34) register_sf4ext(35)
  23934. register_sf4ext(36) register_sf4ext(36) register_sf4ext(38) register_sf4ext(39)
  23935. register_sf4ext(40) register_sf4ext(41) register_sf4ext(42) register_sf4ext(43)
  23936. register_sf4ext(44) register_sf4ext(45) register_sf4ext(46) register_sf4ext(47)
  23937. register_sf4ext(48) register_sf4ext(49) register_sf4ext(50) register_sf4ext(51)
  23938. register_sf4ext(52) register_sf4ext(53) register_sf4ext(54) register_sf4ext(55)
  23939. register_sf4ext(56) register_sf4ext(57) register_sf4ext(58) register_sf4ext(59)
  23940. #undef register_sf4ext
  23941. }
  23942. private:
  23943. parser(const parser<T>&);
  23944. parser<T>& operator=(const parser<T>&);
  23945. lexer::generator lexer_;
  23946. lexer::token current_token_;
  23947. lexer::token store_current_token_;
  23948. expression_generator<T> expression_generator_;
  23949. details::node_allocator node_allocator_;
  23950. symbol_table_t symbol_table_;
  23951. dependent_entity_collector dec_;
  23952. std::size_t compile_options_;
  23953. std::deque<parser_error::type> error_list_;
  23954. std::deque<bool> brkcnt_list_;
  23955. bool resolve_unknown_symbol_;
  23956. bool vardef_disabled_;
  23957. std::size_t scope_depth_;
  23958. unknown_symbol_resolver* unknown_symbol_resolver_;
  23959. unknown_symbol_resolver default_usr_;
  23960. base_ops_map_t base_ops_map_;
  23961. unary_op_map_t unary_op_map_;
  23962. binary_op_map_t binary_op_map_;
  23963. inv_binary_op_map_t inv_binary_op_map_;
  23964. sf3_map_t sf3_map_;
  23965. sf4_map_t sf4_map_;
  23966. std::string synthesis_error_;
  23967. scope_element_manager sem_;
  23968. lexer::helper::helper_assembly helper_assembly_;
  23969. lexer::helper::commutative_inserter commutative_inserter_;
  23970. lexer::helper::operator_joiner operator_joiner_2_;
  23971. lexer::helper::operator_joiner operator_joiner_3_;
  23972. lexer::helper::symbol_replacer symbol_replacer_;
  23973. lexer::helper::bracket_checker bracket_checker_;
  23974. lexer::helper::numeric_checker numeric_checker_;
  23975. lexer::helper::sequence_validator sequence_validator_;
  23976. };
  23977. template <typename T>
  23978. inline T integrate(expression<T>& e,
  23979. T& x,
  23980. const T& r0, const T& r1,
  23981. const std::size_t number_of_intervals = 1000000)
  23982. {
  23983. if (r0 > r1)
  23984. return T(0);
  23985. T h = (r1 - r0) / (T(2) * number_of_intervals);
  23986. T total_area = T(0);
  23987. for (std::size_t i = 0; i < number_of_intervals; ++i)
  23988. {
  23989. x = r0 + T(2) * i * h;
  23990. T y0 = e.value(); x += h;
  23991. T y1 = e.value(); x += h;
  23992. T y2 = e.value(); x += h;
  23993. total_area += h * (y0 + T(4) * y1 + y2) / T(3);
  23994. }
  23995. return total_area;
  23996. }
  23997. template <typename T>
  23998. inline T integrate(expression<T>& e,
  23999. const std::string& variable_name,
  24000. const T& r0, const T& r1,
  24001. const std::size_t number_of_intervals = 1000000)
  24002. {
  24003. symbol_table<T>& sym_table = e.get_symbol_table();
  24004. if (!sym_table.valid())
  24005. return std::numeric_limits<T>::quiet_NaN();
  24006. details::variable_node<T>* var = sym_table.get_variable(variable_name);
  24007. if (var)
  24008. {
  24009. T& x = var->ref();
  24010. T x_original = x;
  24011. T result = integrate(e,x,r0,r1,number_of_intervals);
  24012. x = x_original;
  24013. return result;
  24014. }
  24015. else
  24016. return std::numeric_limits<T>::quiet_NaN();
  24017. }
  24018. template <typename T>
  24019. inline T derivative(expression<T>& e,
  24020. T& x,
  24021. const T& h = T(0.00000001))
  24022. {
  24023. T x_init = x;
  24024. x = x_init + T(2) * h;
  24025. T y0 = e.value();
  24026. x = x_init + h;
  24027. T y1 = e.value();
  24028. x = x_init - h;
  24029. T y2 = e.value();
  24030. x = x_init - T(2) * h;
  24031. T y3 = e.value();
  24032. x = x_init;
  24033. return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
  24034. }
  24035. template <typename T>
  24036. inline T second_derivative(expression<T>& e,
  24037. T& x,
  24038. const T& h = T(0.00001))
  24039. {
  24040. T y = e.value();
  24041. T x_init = x;
  24042. x = x_init + T(2) * h;
  24043. T y0 = e.value();
  24044. x = x_init + h;
  24045. T y1 = e.value();
  24046. x = x_init - h;
  24047. T y2 = e.value();
  24048. x = x_init - T(2) * h;
  24049. T y3 = e.value();
  24050. x = x_init;
  24051. return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
  24052. }
  24053. template <typename T>
  24054. inline T third_derivative(expression<T>& e,
  24055. T& x,
  24056. const T& h = T(0.0001))
  24057. {
  24058. T x_init = x;
  24059. x = x_init + T(2) * h;
  24060. T y0 = e.value();
  24061. x = x_init + h;
  24062. T y1 = e.value();
  24063. x = x_init - h;
  24064. T y2 = e.value();
  24065. x = x_init - T(2) * h;
  24066. T y3 = e.value();
  24067. x = x_init;
  24068. return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
  24069. }
  24070. template <typename T>
  24071. inline T derivative(expression<T>& e,
  24072. const std::string& variable_name,
  24073. const T& h = T(0.00000001))
  24074. {
  24075. symbol_table<T>& sym_table = e.get_symbol_table();
  24076. if (!sym_table.valid())
  24077. {
  24078. return std::numeric_limits<T>::quiet_NaN();
  24079. }
  24080. details::variable_node<T>* var = sym_table.get_variable(variable_name);
  24081. if (var)
  24082. {
  24083. T& x = var->ref();
  24084. T x_original = x;
  24085. T result = derivative(e,x,h);
  24086. x = x_original;
  24087. return result;
  24088. }
  24089. else
  24090. return std::numeric_limits<T>::quiet_NaN();
  24091. }
  24092. template <typename T>
  24093. inline T second_derivative(expression<T>& e,
  24094. const std::string& variable_name,
  24095. const T& h = T(0.00001))
  24096. {
  24097. symbol_table<T>& sym_table = e.get_symbol_table();
  24098. if (!sym_table.valid())
  24099. {
  24100. return std::numeric_limits<T>::quiet_NaN();
  24101. }
  24102. details::variable_node<T>* var = sym_table.get_variable(variable_name);
  24103. if (var)
  24104. {
  24105. T& x = var->ref();
  24106. T x_original = x;
  24107. T result = second_derivative(e,x,h);
  24108. x = x_original;
  24109. return result;
  24110. }
  24111. else
  24112. return std::numeric_limits<T>::quiet_NaN();
  24113. }
  24114. template <typename T>
  24115. inline T third_derivative(expression<T>& e,
  24116. const std::string& variable_name,
  24117. const T& h = T(0.0001))
  24118. {
  24119. symbol_table<T>& sym_table = e.get_symbol_table();
  24120. if (!sym_table.valid())
  24121. {
  24122. return std::numeric_limits<T>::quiet_NaN();
  24123. }
  24124. details::variable_node<T>* var = sym_table.get_variable(variable_name);
  24125. if (var)
  24126. {
  24127. T& x = var->ref();
  24128. T x_original = x;
  24129. T result = third_derivative(e,x,h);
  24130. x = x_original;
  24131. return result;
  24132. }
  24133. else
  24134. return std::numeric_limits<T>::quiet_NaN();
  24135. }
  24136. /*
  24137. Note: The following 'compute' routines are simple helpers,
  24138. for quickly setting up the required pieces of code in order
  24139. to evaluate an expression. By virtue of how they operate
  24140. there will be an overhead with regards to their setup and
  24141. teardown and hence should not be used in time critical
  24142. sections of code.
  24143. Furthermore they only assume a small sub set of variables - no
  24144. string variables or user defined functions.
  24145. */
  24146. template <typename T>
  24147. inline bool compute(const std::string& expression_string, T& result)
  24148. {
  24149. // No variables
  24150. symbol_table<T> symbol_table;
  24151. symbol_table.add_constants();
  24152. expression<T> expression;
  24153. parser<T> parser;
  24154. if (parser.compile(expression_string,expression))
  24155. {
  24156. result = expression.value();
  24157. return true;
  24158. }
  24159. else
  24160. return false;
  24161. }
  24162. template <typename T>
  24163. inline bool compute(const std::string& expression_string,
  24164. const T& x,
  24165. T& result)
  24166. {
  24167. // Only 'x'
  24168. static const std::string x_var("x");
  24169. symbol_table<T> symbol_table;
  24170. symbol_table.add_constants();
  24171. symbol_table.add_variable(x_var,x);
  24172. expression<T> expression;
  24173. parser<T> parser;
  24174. if (parser.compile(expression_string,expression))
  24175. {
  24176. result = expression.value();
  24177. return true;
  24178. }
  24179. else
  24180. return false;
  24181. }
  24182. template <typename T>
  24183. inline bool compute(const std::string& expression_string,
  24184. const T&x, const T& y,
  24185. T& result)
  24186. {
  24187. // Only 'x' and 'y'
  24188. static const std::string x_var("x");
  24189. static const std::string y_var("y");
  24190. symbol_table<T> symbol_table;
  24191. symbol_table.add_constants();
  24192. symbol_table.add_variable(x_var,x);
  24193. symbol_table.add_variable(y_var,y);
  24194. expression<T> expression;
  24195. parser<T> parser;
  24196. if (parser.compile(expression_string,expression))
  24197. {
  24198. result = expression.value();
  24199. return true;
  24200. }
  24201. else
  24202. return false;
  24203. }
  24204. template <typename T>
  24205. inline bool compute(const std::string& expression_string,
  24206. const T& x, const T& y, const T& z,
  24207. T& result)
  24208. {
  24209. // Only 'x', 'y' or 'z'
  24210. static const std::string x_var("x");
  24211. static const std::string y_var("y");
  24212. static const std::string z_var("z");
  24213. symbol_table<T> symbol_table;
  24214. symbol_table.add_constants();
  24215. symbol_table.add_variable(x_var,x);
  24216. symbol_table.add_variable(y_var,y);
  24217. symbol_table.add_variable(z_var,z);
  24218. expression<T> expression;
  24219. parser<T> parser;
  24220. if (parser.compile(expression_string,expression))
  24221. {
  24222. result = expression.value();
  24223. return true;
  24224. }
  24225. else
  24226. return false;
  24227. }
  24228. template <typename T, std::size_t N>
  24229. class polynomial : public ifunction<T>
  24230. {
  24231. private:
  24232. template <typename Type, std::size_t NumberOfCoefficients>
  24233. struct poly_impl { };
  24234. template <typename Type>
  24235. struct poly_impl <Type,12>
  24236. {
  24237. static inline T evaluate(const Type x,
  24238. const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
  24239. const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
  24240. const Type c2, const Type c1, const Type c0)
  24241. {
  24242. // 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
  24243. 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);
  24244. }
  24245. };
  24246. template <typename Type>
  24247. struct poly_impl <Type,11>
  24248. {
  24249. static inline T evaluate(const Type x,
  24250. const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
  24251. const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
  24252. const Type c1, const Type c0)
  24253. {
  24254. // 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
  24255. return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24256. }
  24257. };
  24258. template <typename Type>
  24259. struct poly_impl <Type,10>
  24260. {
  24261. static inline T evaluate(const Type x,
  24262. const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
  24263. const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
  24264. const Type c0)
  24265. {
  24266. // 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
  24267. return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24268. }
  24269. };
  24270. template <typename Type>
  24271. struct poly_impl <Type,9>
  24272. {
  24273. static inline T evaluate(const Type x,
  24274. const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
  24275. const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
  24276. {
  24277. // 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
  24278. return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24279. }
  24280. };
  24281. template <typename Type>
  24282. struct poly_impl <Type,8>
  24283. {
  24284. static inline T evaluate(const Type x,
  24285. const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
  24286. const Type c3, const Type c2, const Type c1, const Type c0)
  24287. {
  24288. // 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
  24289. return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24290. }
  24291. };
  24292. template <typename Type>
  24293. struct poly_impl <Type,7>
  24294. {
  24295. static inline T evaluate(const Type x,
  24296. const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
  24297. const Type c2, const Type c1, const Type c0)
  24298. {
  24299. // 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
  24300. return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24301. }
  24302. };
  24303. template <typename Type>
  24304. struct poly_impl <Type,6>
  24305. {
  24306. static inline T evaluate(const Type x,
  24307. const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
  24308. const Type c1, const Type c0)
  24309. {
  24310. // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  24311. return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24312. }
  24313. };
  24314. template <typename Type>
  24315. struct poly_impl <Type,5>
  24316. {
  24317. static inline T evaluate(const Type x,
  24318. const Type c5, const Type c4, const Type c3, const Type c2,
  24319. const Type c1, const Type c0)
  24320. {
  24321. // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  24322. return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  24323. }
  24324. };
  24325. template <typename Type>
  24326. struct poly_impl <Type,4>
  24327. {
  24328. static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
  24329. {
  24330. // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  24331. return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
  24332. }
  24333. };
  24334. template <typename Type>
  24335. struct poly_impl <Type,3>
  24336. {
  24337. static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
  24338. {
  24339. // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  24340. return (((c3 * x + c2) * x + c1) * x + c0);
  24341. }
  24342. };
  24343. template <typename Type>
  24344. struct poly_impl <Type,2>
  24345. {
  24346. static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
  24347. {
  24348. // p(x) = c_2x^2 + c_1x^1 + c_0x^0
  24349. return ((c2 * x + c1) * x + c0);
  24350. }
  24351. };
  24352. template <typename Type>
  24353. struct poly_impl <Type,1>
  24354. {
  24355. static inline T evaluate(const Type x, const Type c1, const Type c0)
  24356. {
  24357. // p(x) = c_1x^1 + c_0x^0
  24358. return (c1 * x + c0);
  24359. }
  24360. };
  24361. public:
  24362. polynomial()
  24363. : exprtk::ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max(),false)
  24364. {}
  24365. inline virtual T operator()(const T& x, const T& c1, const T& c0)
  24366. {
  24367. return ((1 == N) ? poly_impl<T,1>::evaluate(x,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24368. }
  24369. inline virtual T operator()(const T& x, const T& c2, const T& c1, const T& c0)
  24370. {
  24371. return ((2 == N) ? poly_impl<T,2>::evaluate(x,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24372. }
  24373. inline virtual T operator()(const T& x, const T& c3, const T& c2, const T& c1, const T& c0)
  24374. {
  24375. return ((3 == N) ? poly_impl<T,3>::evaluate(x,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24376. }
  24377. inline virtual T operator()(const T& x, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24378. {
  24379. return ((4 == N) ? poly_impl<T,4>::evaluate(x,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24380. }
  24381. inline virtual T operator()(const T& x, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24382. {
  24383. return ((5 == N) ? poly_impl<T,5>::evaluate(x,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24384. }
  24385. inline virtual T operator()(const T& x, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24386. {
  24387. return ((6 == N) ? poly_impl<T,6>::evaluate(x,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24388. }
  24389. inline virtual T operator()(const T& x, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24390. {
  24391. return ((7 == N) ? poly_impl<T,7>::evaluate(x,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24392. }
  24393. inline virtual T operator()(const T& x, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24394. {
  24395. return ((8 == N) ? poly_impl<T,8>::evaluate(x,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24396. }
  24397. inline virtual T operator()(const T& x, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24398. {
  24399. return ((9 == N) ? poly_impl<T,9>::evaluate(x,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24400. }
  24401. inline virtual T operator()(const T& x, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24402. {
  24403. return ((10 == N) ? poly_impl<T,10>::evaluate(x,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24404. }
  24405. inline virtual T operator()(const T& x, const T& c11, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24406. {
  24407. return ((11 == N) ? poly_impl<T,11>::evaluate(x,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24408. }
  24409. inline virtual T operator()(const T& x, const T& c12, const T& c11, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  24410. {
  24411. return ((12 == N) ? poly_impl<T,12>::evaluate(x,c12,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  24412. }
  24413. inline virtual T operator()()
  24414. {
  24415. return std::numeric_limits<T>::quiet_NaN();
  24416. }
  24417. inline virtual T operator()(const T&)
  24418. {
  24419. return std::numeric_limits<T>::quiet_NaN();
  24420. }
  24421. inline virtual T operator()(const T&, const T&)
  24422. {
  24423. return std::numeric_limits<T>::quiet_NaN();
  24424. }
  24425. };
  24426. template <typename T>
  24427. class function_compositor
  24428. {
  24429. public:
  24430. typedef exprtk::expression<T> expression_t;
  24431. typedef exprtk::symbol_table<T> symbol_table_t;
  24432. typedef exprtk::parser<T> parser_t;
  24433. struct function
  24434. {
  24435. function()
  24436. {}
  24437. function(const std::string& n)
  24438. : name_(n)
  24439. {}
  24440. inline function& name(const std::string& n)
  24441. {
  24442. name_ = n;
  24443. return (*this);
  24444. }
  24445. inline function& expression(const std::string& e)
  24446. {
  24447. expression_ = e;
  24448. return (*this);
  24449. }
  24450. inline function& var(const std::string& v)
  24451. {
  24452. v_.push_back(v);
  24453. return (*this);
  24454. }
  24455. std::string name_;
  24456. std::string expression_;
  24457. std::deque<std::string> v_;
  24458. };
  24459. private:
  24460. struct base_func : public exprtk::ifunction<T>
  24461. {
  24462. typedef const T& type;
  24463. typedef exprtk::ifunction<T> function_t;
  24464. typedef std::vector<T*> varref_t;
  24465. typedef std::vector<T> var_t;
  24466. typedef std::pair<T*,std::size_t> lvarref_t;
  24467. typedef std::vector<lvarref_t> lvr_vec_t;
  24468. base_func(const std::size_t& pc = 0)
  24469. : exprtk::ifunction<T>(pc),
  24470. local_var_stack_size(0),
  24471. stack_depth(0)
  24472. {
  24473. v.resize(pc);
  24474. }
  24475. virtual ~base_func()
  24476. {}
  24477. inline void update(const T& v0)
  24478. {
  24479. (*v[0]) = v0;
  24480. }
  24481. inline void update(const T& v0, const T& v1)
  24482. {
  24483. (*v[0]) = v0; (*v[1]) = v1;
  24484. }
  24485. inline void update(const T& v0, const T& v1, const T& v2)
  24486. {
  24487. (*v[0]) = v0; (*v[1]) = v1;
  24488. (*v[2]) = v2;
  24489. }
  24490. inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
  24491. {
  24492. (*v[0]) = v0; (*v[1]) = v1;
  24493. (*v[2]) = v2; (*v[3]) = v3;
  24494. }
  24495. inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
  24496. {
  24497. (*v[0]) = v0; (*v[1]) = v1;
  24498. (*v[2]) = v2; (*v[3]) = v3;
  24499. (*v[4]) = v4;
  24500. }
  24501. inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
  24502. {
  24503. (*v[0]) = v0; (*v[1]) = v1;
  24504. (*v[2]) = v2; (*v[3]) = v3;
  24505. (*v[4]) = v4; (*v[5]) = v5;
  24506. }
  24507. inline function_t& setup(expression_t& expr)
  24508. {
  24509. expression = expr;
  24510. typedef typename expression_t::expression_holder::local_data_list_t ldl_t;
  24511. ldl_t ldl = expr.local_data_list();
  24512. std::vector<std::size_t> index_list;
  24513. for (std::size_t i = 0; i < ldl.size(); ++i)
  24514. {
  24515. if (ldl[i].size)
  24516. {
  24517. index_list.push_back(i);
  24518. }
  24519. }
  24520. std::size_t input_param_count = 0;
  24521. for (std::size_t i = 0; i < index_list.size(); ++i)
  24522. {
  24523. const std::size_t index = index_list[i];
  24524. if (i < (index_list.size() - v.size()))
  24525. {
  24526. lv.push_back(
  24527. std::make_pair(
  24528. reinterpret_cast<T*>(ldl[index].pointer),
  24529. ldl[index].size));
  24530. local_var_stack_size += ldl[index].size;
  24531. }
  24532. else
  24533. v[input_param_count++] = reinterpret_cast<T*>(ldl[index].pointer);
  24534. }
  24535. clear_stack();
  24536. return (*this);
  24537. }
  24538. inline void pre()
  24539. {
  24540. if (stack_depth++)
  24541. {
  24542. if (!v.empty())
  24543. {
  24544. var_t var_stack(v.size(),T(0));
  24545. copy(v,var_stack);
  24546. param_stack.push_back(var_stack);
  24547. }
  24548. if (!lv.empty())
  24549. {
  24550. var_t local_var_stack(local_var_stack_size,T(0));
  24551. copy(lv,local_var_stack);
  24552. local_stack.push_back(local_var_stack);
  24553. }
  24554. }
  24555. }
  24556. inline void post()
  24557. {
  24558. if (--stack_depth)
  24559. {
  24560. if (!v.empty())
  24561. {
  24562. copy(param_stack.back(),v);
  24563. param_stack.pop_back();
  24564. }
  24565. if (!lv.empty())
  24566. {
  24567. copy(local_stack.back(),lv);
  24568. local_stack.pop_back();
  24569. }
  24570. }
  24571. }
  24572. void copy(const varref_t& src_v, var_t& dest_v)
  24573. {
  24574. for (std::size_t i = 0; i < src_v.size(); ++i)
  24575. {
  24576. dest_v[i] = (*src_v[i]);
  24577. }
  24578. }
  24579. void copy(const var_t& src_v, varref_t& dest_v)
  24580. {
  24581. for (std::size_t i = 0; i < src_v.size(); ++i)
  24582. {
  24583. (*dest_v[i]) = src_v[i];
  24584. }
  24585. }
  24586. void copy(const lvr_vec_t& src_v, var_t& dest_v)
  24587. {
  24588. typename var_t::iterator itr = dest_v.begin();
  24589. for (std::size_t i = 0; i < src_v.size(); ++i)
  24590. {
  24591. lvarref_t vr = src_v[i];
  24592. if (1 == vr.second)
  24593. *itr++ = (*vr.first);
  24594. else
  24595. {
  24596. std::copy(vr.first,vr.first + vr.second,itr);
  24597. itr += vr.second;
  24598. }
  24599. }
  24600. }
  24601. void copy(const var_t& src_v, lvr_vec_t& dest_v)
  24602. {
  24603. typename var_t::const_iterator itr = src_v.begin();
  24604. for (std::size_t i = 0; i < src_v.size(); ++i)
  24605. {
  24606. lvarref_t vr = dest_v[i];
  24607. if (1 == vr.second)
  24608. (*vr.first) = *itr++;
  24609. else
  24610. {
  24611. std::copy(itr,itr + vr.second,vr.first);
  24612. itr += vr.second;
  24613. }
  24614. }
  24615. }
  24616. inline void clear_stack()
  24617. {
  24618. for (std::size_t i = 0; i < v.size(); ++i)
  24619. {
  24620. (*v[i]) = 0;
  24621. }
  24622. }
  24623. expression_t expression;
  24624. varref_t v;
  24625. lvr_vec_t lv;
  24626. std::size_t local_var_stack_size;
  24627. std::size_t stack_depth;
  24628. std::deque<var_t> param_stack;
  24629. std::deque<var_t> local_stack;
  24630. };
  24631. typedef std::map<std::string,base_func*> funcparam_t;
  24632. struct func_0param : public base_func
  24633. {
  24634. func_0param() : base_func(0) {}
  24635. inline T operator()()
  24636. {
  24637. return base_func::expression.value();
  24638. }
  24639. };
  24640. typedef const T& type;
  24641. struct func_1param : public base_func
  24642. {
  24643. func_1param() : base_func(1) {}
  24644. inline T operator()(type v0)
  24645. {
  24646. base_func::pre();
  24647. base_func::update(v0);
  24648. T result = base_func::expression.value();
  24649. base_func::post();
  24650. return result;
  24651. }
  24652. };
  24653. struct func_2param : public base_func
  24654. {
  24655. func_2param() : base_func(2) {}
  24656. inline T operator()(type v0, type v1)
  24657. {
  24658. base_func::pre();
  24659. base_func::update(v0,v1);
  24660. T result = base_func::expression.value();
  24661. base_func::post();
  24662. return result;
  24663. }
  24664. };
  24665. struct func_3param : public base_func
  24666. {
  24667. func_3param() : base_func(3) {}
  24668. inline T operator()(type v0, type v1, type v2)
  24669. {
  24670. base_func::pre();
  24671. base_func::update(v0,v1,v2);
  24672. T result = base_func::expression.value();
  24673. base_func::post();
  24674. return result;
  24675. }
  24676. };
  24677. struct func_4param : public base_func
  24678. {
  24679. func_4param() : base_func(4) {}
  24680. inline T operator()(type v0, type v1, type v2, type v3)
  24681. {
  24682. base_func::pre();
  24683. base_func::update(v0,v1,v2,v3);
  24684. T result = base_func::expression.value();
  24685. base_func::post();
  24686. return result;
  24687. }
  24688. };
  24689. struct func_5param : public base_func
  24690. {
  24691. func_5param() : base_func(5) {}
  24692. inline T operator()(type v0, type v1, type v2, type v3, type v4)
  24693. {
  24694. base_func::pre();
  24695. base_func::update(v0,v1,v2,v3,v4);
  24696. T result = base_func::expression.value();
  24697. base_func::post();
  24698. return result;
  24699. }
  24700. };
  24701. struct func_6param : public base_func
  24702. {
  24703. func_6param() : base_func(6) {}
  24704. inline T operator()(type v0, type v1, type v2, type v3, type v4, type v5)
  24705. {
  24706. base_func::pre();
  24707. base_func::update(v0,v1,v2,v3,v4,v5);
  24708. T result = base_func::expression.value();
  24709. base_func::post();
  24710. return result;
  24711. }
  24712. };
  24713. template <typename Allocator,
  24714. template <typename,typename> class Sequence>
  24715. inline bool add(const std::string& name,
  24716. const std::string& expression,
  24717. const Sequence<std::string,Allocator>& var_list)
  24718. {
  24719. const std::size_t n = var_list.size();
  24720. if (expr_map_.end() != expr_map_.find(name))
  24721. return false;
  24722. else if (compile_expression(name,expression,var_list))
  24723. {
  24724. fp_map_[n][name]->setup(expr_map_[name]);
  24725. return true;
  24726. }
  24727. else
  24728. return false;
  24729. }
  24730. public:
  24731. function_compositor()
  24732. : fp_map_(7)
  24733. {}
  24734. function_compositor(const symbol_table_t& st)
  24735. : symbol_table_(st),
  24736. fp_map_(7)
  24737. {}
  24738. ~function_compositor()
  24739. {
  24740. clear();
  24741. }
  24742. inline symbol_table_t& symbol_table()
  24743. {
  24744. return symbol_table_;
  24745. }
  24746. void clear()
  24747. {
  24748. symbol_table_.clear();
  24749. expr_map_.clear();
  24750. for (std::size_t i = 0; i < fp_map_.size(); ++i)
  24751. {
  24752. typename funcparam_t::iterator itr = fp_map_[i].begin();
  24753. typename funcparam_t::iterator end = fp_map_[i].end ();
  24754. while (itr != end)
  24755. {
  24756. delete itr->second;
  24757. ++itr;
  24758. }
  24759. fp_map_[i].clear();
  24760. }
  24761. }
  24762. inline bool add(const function& f)
  24763. {
  24764. return add(f.name_,f.expression_,f.v_);
  24765. }
  24766. inline bool add(const std::string& name,
  24767. const std::string& expression)
  24768. {
  24769. const std::size_t n = 0;
  24770. std::vector<std::string> v(n);
  24771. return add(name,expression,v);
  24772. }
  24773. inline bool add(const std::string& name,
  24774. const std::string& expression,
  24775. const std::string& v0)
  24776. {
  24777. const std::size_t n = 1;
  24778. std::vector<std::string> v(n);
  24779. v[0] = v0;
  24780. return add(name,expression,v);
  24781. }
  24782. inline bool add(const std::string& name,
  24783. const std::string& expression,
  24784. const std::string& v0, const std::string& v1)
  24785. {
  24786. const std::size_t n = 2;
  24787. std::vector<std::string> v(n);
  24788. v[0] = v0; v[1] = v1;
  24789. return add(name,expression,v);
  24790. }
  24791. inline bool add(const std::string& name,
  24792. const std::string& expression,
  24793. const std::string& v0, const std::string& v1, const std::string& v2)
  24794. {
  24795. const std::size_t n = 3;
  24796. std::vector<std::string> v(n);
  24797. v[0] = v0; v[1] = v1; v[2] = v2;
  24798. return add(name,expression,v);
  24799. }
  24800. inline bool add(const std::string& name,
  24801. const std::string& expression,
  24802. const std::string& v0, const std::string& v1, const std::string& v2,
  24803. const std::string& v3)
  24804. {
  24805. const std::size_t n = 4;
  24806. std::vector<std::string> v(n);
  24807. v[0] = v0; v[1] = v1;
  24808. v[2] = v2; v[3] = v3;
  24809. return add(name,expression,v);
  24810. }
  24811. inline bool add(const std::string& name,
  24812. const std::string& expression,
  24813. const std::string& v0, const std::string& v1, const std::string& v2,
  24814. const std::string& v3, const std::string& v4)
  24815. {
  24816. const std::size_t n = 5;
  24817. std::vector<std::string> v(n);
  24818. v[0] = v0; v[1] = v1;
  24819. v[2] = v2; v[3] = v3;
  24820. v[4] = v4;
  24821. return add(name,expression,v);
  24822. }
  24823. inline bool add(const std::string& name,
  24824. const std::string& expression,
  24825. const std::string& v0, const std::string& v1, const std::string& v2,
  24826. const std::string& v3, const std::string& v4, const std::string& v5)
  24827. {
  24828. const std::size_t n = 5;
  24829. std::vector<std::string> v(n);
  24830. v[0] = v0; v[1] = v1;
  24831. v[2] = v2; v[3] = v3;
  24832. v[4] = v4; v[5] = v5;
  24833. return add(name,expression,v);
  24834. }
  24835. private:
  24836. template <typename Allocator,
  24837. template <typename,typename> class Sequence>
  24838. bool compile_expression(const std::string& name,
  24839. const std::string& expression,
  24840. const Sequence<std::string,Allocator>& input_var_list)
  24841. {
  24842. expression_t compiled_expression;
  24843. symbol_table_t local_symbol_table;
  24844. local_symbol_table.load_from(symbol_table_);
  24845. local_symbol_table.add_constants();
  24846. if (!forward(name,input_var_list.size(),local_symbol_table))
  24847. return false;
  24848. compiled_expression.register_symbol_table(local_symbol_table);
  24849. std::string mod_expression;
  24850. for (std::size_t i = 0; i < input_var_list.size(); ++i)
  24851. {
  24852. mod_expression += " var " + input_var_list[i] + "{};\n";
  24853. }
  24854. mod_expression += "~{" + expression + "};";
  24855. if (!parser_.compile(mod_expression,compiled_expression))
  24856. {
  24857. exprtk_debug(("Error: %s\n",parser_.error().c_str()));
  24858. return false;
  24859. }
  24860. expr_map_[name] = compiled_expression;
  24861. exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
  24862. return symbol_table_.add_function(name,ifunc);
  24863. }
  24864. inline bool symbol_used(const std::string& symbol)
  24865. {
  24866. return (
  24867. symbol_table_.is_variable (symbol) ||
  24868. symbol_table_.is_stringvar (symbol) ||
  24869. symbol_table_.is_function (symbol) ||
  24870. symbol_table_.is_vector (symbol) ||
  24871. symbol_table_.is_vararg_function(symbol)
  24872. );
  24873. }
  24874. inline bool forward(const std::string& name, const std::size_t& arg_count, symbol_table_t& sym_table)
  24875. {
  24876. if (arg_count > 6)
  24877. return false;
  24878. else if (symbol_used(name))
  24879. return false;
  24880. else
  24881. {
  24882. if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
  24883. return false;
  24884. switch (arg_count)
  24885. {
  24886. case 0 : (fp_map_[arg_count])[name] = new func_0param(); break;
  24887. case 1 : (fp_map_[arg_count])[name] = new func_1param(); break;
  24888. case 2 : (fp_map_[arg_count])[name] = new func_2param(); break;
  24889. case 3 : (fp_map_[arg_count])[name] = new func_3param(); break;
  24890. case 4 : (fp_map_[arg_count])[name] = new func_4param(); break;
  24891. case 5 : (fp_map_[arg_count])[name] = new func_5param(); break;
  24892. case 6 : (fp_map_[arg_count])[name] = new func_6param(); break;
  24893. }
  24894. exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
  24895. return sym_table.add_function(name,ifunc);
  24896. }
  24897. }
  24898. template <typename Allocator,
  24899. template <typename,typename> class Sequence>
  24900. inline void remove(const std::string& name, const Sequence<std::string,Allocator>& v)
  24901. {
  24902. symbol_table_.remove_function(name);
  24903. for (std::size_t i = 0; i < v.size(); ++i)
  24904. {
  24905. symbol_table_.remove_variable(v[i]);
  24906. }
  24907. remove(name,v.size());
  24908. }
  24909. inline void remove(const std::string& name, const std::size_t& arg_count)
  24910. {
  24911. if (arg_count > 6)
  24912. return;
  24913. typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
  24914. if (expr_map_.end() != em_itr)
  24915. {
  24916. expr_map_.erase(em_itr);
  24917. }
  24918. typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
  24919. if (fp_map_[arg_count].end() != fp_itr)
  24920. return;
  24921. else
  24922. delete fp_itr->second;
  24923. fp_map_[arg_count].erase(fp_itr);
  24924. }
  24925. private:
  24926. symbol_table_t symbol_table_;
  24927. parser_t parser_;
  24928. std::map<std::string,expression_t> expr_map_;
  24929. std::vector<funcparam_t> fp_map_;
  24930. };
  24931. template <typename T>
  24932. inline bool pgo_primer()
  24933. {
  24934. static const std::string expression_list[]
  24935. = {
  24936. "(y + x)",
  24937. "2 * (y + x)",
  24938. "(2 * y + 2 * x)",
  24939. "(y + x / y) * (x - y / x)",
  24940. "x / ((x + y) * (x - y)) / y",
  24941. "1 - ((x * y) + (y / x)) - 3",
  24942. "sin(2 * x) + cos(pi / y)",
  24943. "1 - sin(2 * x) + cos(pi / y)",
  24944. "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
  24945. "(x^2 / sin(2 * pi / y)) -x / 2",
  24946. "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
  24947. "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
  24948. "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
  24949. "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
  24950. "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
  24951. "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
  24952. "(yy + xx)",
  24953. "2 * (yy + xx)",
  24954. "(2 * yy + 2 * xx)",
  24955. "(yy + xx / yy) * (xx - yy / xx)",
  24956. "xx / ((xx + yy) * (xx - yy)) / yy",
  24957. "1 - ((xx * yy) + (yy / xx)) - 3",
  24958. "sin(2 * xx) + cos(pi / yy)",
  24959. "1 - sin(2 * xx) + cos(pi / yy)",
  24960. "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
  24961. "(xx^2 / sin(2 * pi / yy)) -xx / 2",
  24962. "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
  24963. "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
  24964. "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
  24965. "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
  24966. "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55",
  24967. "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))",
  24968. "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)",
  24969. "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)",
  24970. "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)",
  24971. "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)",
  24972. "(x + 2) * 3", "x + (2 * 3)",
  24973. "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)",
  24974. "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)",
  24975. "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))",
  24976. "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))",
  24977. "2 + (x * (y / 3))", "x + (2 * (3 / y))",
  24978. "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)",
  24979. "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)",
  24980. "x + ((2 * 3) / y)", "(((x + y) * z) / w)",
  24981. "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)",
  24982. "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)",
  24983. "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)",
  24984. "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)",
  24985. "((x + (2 * 3)) / y)",
  24986. "(xx + yy) * zz", "xx + (yy * zz)",
  24987. "(xx + yy) * 7", "xx + (yy * 7)",
  24988. "(xx + 7) * yy", "xx + (7 * yy)",
  24989. "(7 + xx) * yy", "7 + (xx * yy)",
  24990. "(2 + x) * 3", "2 + (x * 3)",
  24991. "(2 + 3) * x", "2 + (3 * x)",
  24992. "(x + 2) * 3", "x + (2 * 3)",
  24993. "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)",
  24994. "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)",
  24995. "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)",
  24996. "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)",
  24997. "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))",
  24998. "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))",
  24999. "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))",
  25000. "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))",
  25001. "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))",
  25002. "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)",
  25003. "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)",
  25004. "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)",
  25005. "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)",
  25006. "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)",
  25007. "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)",
  25008. "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)",
  25009. "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)",
  25010. "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)",
  25011. "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)",
  25012. "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)",
  25013. "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)",
  25014. "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)",
  25015. "((xx + (2 * 3)) / yy)"
  25016. };
  25017. static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
  25018. T x = T(0);
  25019. T y = T(0);
  25020. T z = T(0);
  25021. T w = T(0);
  25022. T xx = T(0);
  25023. T yy = T(0);
  25024. T zz = T(0);
  25025. T ww = T(0);
  25026. exprtk::symbol_table<T> symbol_table;
  25027. symbol_table.add_constants();
  25028. symbol_table.add_variable( "x", x);
  25029. symbol_table.add_variable( "y", y);
  25030. symbol_table.add_variable( "z", z);
  25031. symbol_table.add_variable( "w", w);
  25032. symbol_table.add_variable("xx",xx);
  25033. symbol_table.add_variable("yy",yy);
  25034. symbol_table.add_variable("zz",zz);
  25035. symbol_table.add_variable("ww",ww);
  25036. typedef typename std::deque<exprtk::expression<T> > expr_list_t;
  25037. expr_list_t expr_list;
  25038. const std::size_t rounds = 50;
  25039. {
  25040. for (std::size_t r = 0; r < rounds; ++r)
  25041. {
  25042. expr_list.clear();
  25043. exprtk::parser<T> parser;
  25044. for (std::size_t i = 0; i < expression_list_size; ++i)
  25045. {
  25046. exprtk::expression<T> expression;
  25047. expression.register_symbol_table(symbol_table);
  25048. if (!parser.compile(expression_list[i],expression))
  25049. {
  25050. return false;
  25051. }
  25052. expr_list.push_back(expression);
  25053. }
  25054. }
  25055. }
  25056. struct execute
  25057. {
  25058. static inline T process(T& x, T& y, expression<T>& expression)
  25059. {
  25060. static const T lower_bound = T(-20);
  25061. static const T upper_bound = T(+20);
  25062. T delta = T(0.1);
  25063. T total = T(0);
  25064. for (x = lower_bound; x <= upper_bound; x += delta)
  25065. {
  25066. for (y = lower_bound; y <= upper_bound; y += delta)
  25067. {
  25068. total += expression.value();
  25069. }
  25070. }
  25071. return total;
  25072. }
  25073. };
  25074. for (std::size_t i = 0; i < expr_list.size(); ++i)
  25075. {
  25076. execute::process( x, y,expr_list[i]);
  25077. execute::process(xx,yy,expr_list[i]);
  25078. }
  25079. {
  25080. for (std::size_t i = 0; i < 10000; ++i)
  25081. {
  25082. T v = T(123.456 + i);
  25083. if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 1>::result(v),details::numeric::pow(v,T( 1))))) return false;
  25084. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 2>::result(v),details::numeric::pow(v,T( 2))))) return false;
  25085. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 3>::result(v),details::numeric::pow(v,T( 3))))) return false;
  25086. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 4>::result(v),details::numeric::pow(v,T( 4))))) return false;
  25087. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 5>::result(v),details::numeric::pow(v,T( 5))))) return false;
  25088. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 6>::result(v),details::numeric::pow(v,T( 6))))) return false;
  25089. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 7>::result(v),details::numeric::pow(v,T( 7))))) return false;
  25090. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 8>::result(v),details::numeric::pow(v,T( 8))))) return false;
  25091. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 9>::result(v),details::numeric::pow(v,T( 9))))) return false;
  25092. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,10>::result(v),details::numeric::pow(v,T(10))))) return false;
  25093. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,11>::result(v),details::numeric::pow(v,T(11))))) return false;
  25094. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,12>::result(v),details::numeric::pow(v,T(12))))) return false;
  25095. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,13>::result(v),details::numeric::pow(v,T(13))))) return false;
  25096. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,14>::result(v),details::numeric::pow(v,T(14))))) return false;
  25097. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,15>::result(v),details::numeric::pow(v,T(15))))) return false;
  25098. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,16>::result(v),details::numeric::pow(v,T(16))))) return false;
  25099. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,17>::result(v),details::numeric::pow(v,T(17))))) return false;
  25100. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,18>::result(v),details::numeric::pow(v,T(18))))) return false;
  25101. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,19>::result(v),details::numeric::pow(v,T(19))))) return false;
  25102. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,20>::result(v),details::numeric::pow(v,T(20))))) return false;
  25103. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,21>::result(v),details::numeric::pow(v,T(21))))) return false;
  25104. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,22>::result(v),details::numeric::pow(v,T(22))))) return false;
  25105. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,23>::result(v),details::numeric::pow(v,T(23))))) return false;
  25106. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,24>::result(v),details::numeric::pow(v,T(24))))) return false;
  25107. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,25>::result(v),details::numeric::pow(v,T(25))))) return false;
  25108. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,26>::result(v),details::numeric::pow(v,T(26))))) return false;
  25109. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,27>::result(v),details::numeric::pow(v,T(27))))) return false;
  25110. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,28>::result(v),details::numeric::pow(v,T(28))))) return false;
  25111. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,29>::result(v),details::numeric::pow(v,T(29))))) return false;
  25112. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,30>::result(v),details::numeric::pow(v,T(30))))) return false;
  25113. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,31>::result(v),details::numeric::pow(v,T(31))))) return false;
  25114. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,32>::result(v),details::numeric::pow(v,T(32))))) return false;
  25115. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,33>::result(v),details::numeric::pow(v,T(33))))) return false;
  25116. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,34>::result(v),details::numeric::pow(v,T(34))))) return false;
  25117. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,35>::result(v),details::numeric::pow(v,T(35))))) return false;
  25118. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,36>::result(v),details::numeric::pow(v,T(36))))) return false;
  25119. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,37>::result(v),details::numeric::pow(v,T(37))))) return false;
  25120. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,38>::result(v),details::numeric::pow(v,T(38))))) return false;
  25121. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,39>::result(v),details::numeric::pow(v,T(39))))) return false;
  25122. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,40>::result(v),details::numeric::pow(v,T(40))))) return false;
  25123. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,41>::result(v),details::numeric::pow(v,T(41))))) return false;
  25124. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,42>::result(v),details::numeric::pow(v,T(42))))) return false;
  25125. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,43>::result(v),details::numeric::pow(v,T(43))))) return false;
  25126. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,44>::result(v),details::numeric::pow(v,T(44))))) return false;
  25127. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,45>::result(v),details::numeric::pow(v,T(45))))) return false;
  25128. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,46>::result(v),details::numeric::pow(v,T(46))))) return false;
  25129. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,47>::result(v),details::numeric::pow(v,T(47))))) return false;
  25130. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,48>::result(v),details::numeric::pow(v,T(48))))) return false;
  25131. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,49>::result(v),details::numeric::pow(v,T(49))))) return false;
  25132. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,50>::result(v),details::numeric::pow(v,T(50))))) return false;
  25133. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,51>::result(v),details::numeric::pow(v,T(51))))) return false;
  25134. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,52>::result(v),details::numeric::pow(v,T(52))))) return false;
  25135. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,53>::result(v),details::numeric::pow(v,T(53))))) return false;
  25136. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,54>::result(v),details::numeric::pow(v,T(54))))) return false;
  25137. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,55>::result(v),details::numeric::pow(v,T(55))))) return false;
  25138. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,56>::result(v),details::numeric::pow(v,T(56))))) return false;
  25139. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,57>::result(v),details::numeric::pow(v,T(57))))) return false;
  25140. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,58>::result(v),details::numeric::pow(v,T(58))))) return false;
  25141. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,59>::result(v),details::numeric::pow(v,T(59))))) return false;
  25142. else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,60>::result(v),details::numeric::pow(v,T(60))))) return false;
  25143. }
  25144. }
  25145. return true;
  25146. }
  25147. namespace helper
  25148. {
  25149. namespace details
  25150. {
  25151. template <typename T>
  25152. inline void print_type(const std::string& fmt, const T v, exprtk::details::numeric::details::real_type_tag)
  25153. {
  25154. printf(fmt.c_str(),v);
  25155. }
  25156. template <typename T>
  25157. struct print_impl
  25158. {
  25159. typedef typename igeneric_function<T>::generic_type generic_type;
  25160. typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
  25161. typedef typename generic_type::scalar_view scalar_t;
  25162. typedef typename generic_type::vector_view vector_t;
  25163. typedef typename generic_type::string_view string_t;
  25164. static void process(const std::string& scalar_format, parameter_list_t parameters)
  25165. {
  25166. for (std::size_t i = 0; i < parameters.size(); ++i)
  25167. {
  25168. generic_type& gt = parameters[i];
  25169. typename exprtk::details::numeric::details::number_type<T>::type num_type;
  25170. switch (gt.type)
  25171. {
  25172. case generic_type::e_scalar : print_type(scalar_format.c_str(),scalar_t(gt)(),num_type);
  25173. break;
  25174. case generic_type::e_vector : {
  25175. vector_t vector(gt);
  25176. for (std::size_t x = 0; x < vector.size(); ++x)
  25177. {
  25178. print_type(scalar_format.c_str(),vector[x],num_type);
  25179. if ((x + 1) < vector.size())
  25180. printf(" ");
  25181. }
  25182. }
  25183. break;
  25184. case generic_type::e_string : printf("%s",to_str(string_t(gt)).c_str());
  25185. break;
  25186. default : continue;
  25187. }
  25188. }
  25189. }
  25190. };
  25191. }
  25192. template <typename T>
  25193. struct print : public exprtk::igeneric_function<T>
  25194. {
  25195. typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
  25196. print(const std::string& scalar_format = "%10.5f")
  25197. : scalar_format_(scalar_format)
  25198. {}
  25199. inline T operator()(parameter_list_t parameters)
  25200. {
  25201. details::print_impl<T>::process(scalar_format_,parameters);
  25202. return T(0);
  25203. }
  25204. std::string scalar_format_;
  25205. };
  25206. template <typename T>
  25207. struct println : public exprtk::igeneric_function<T>
  25208. {
  25209. typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
  25210. println(const std::string& scalar_format = "%10.5f")
  25211. : scalar_format_(scalar_format)
  25212. {}
  25213. inline T operator()(parameter_list_t parameters)
  25214. {
  25215. details::print_impl<T>::process(scalar_format_,parameters);
  25216. printf("\n");
  25217. return T(0);
  25218. }
  25219. std::string scalar_format_;
  25220. };
  25221. }
  25222. }
  25223. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  25224. # ifndef NOMINMAX
  25225. # define NOMINMAX
  25226. # endif
  25227. # ifndef WIN32_LEAN_AND_MEAN
  25228. # define WIN32_LEAN_AND_MEAN
  25229. # endif
  25230. # include <windows.h>
  25231. # include <ctime>
  25232. #else
  25233. # include <ctime>
  25234. # include <sys/time.h>
  25235. # include <sys/types.h>
  25236. #endif
  25237. namespace exprtk
  25238. {
  25239. class timer
  25240. {
  25241. public:
  25242. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  25243. timer()
  25244. : in_use_(false)
  25245. {
  25246. QueryPerformanceFrequency(&clock_frequency_);
  25247. }
  25248. inline void start()
  25249. {
  25250. in_use_ = true;
  25251. QueryPerformanceCounter(&start_time_);
  25252. }
  25253. inline void stop()
  25254. {
  25255. QueryPerformanceCounter(&stop_time_);
  25256. in_use_ = false;
  25257. }
  25258. inline double time() const
  25259. {
  25260. return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
  25261. }
  25262. #else
  25263. timer()
  25264. : in_use_(false)
  25265. {
  25266. start_time_.tv_sec = 0;
  25267. start_time_.tv_usec = 0;
  25268. stop_time_.tv_sec = 0;
  25269. stop_time_.tv_usec = 0;
  25270. }
  25271. inline void start()
  25272. {
  25273. in_use_ = true;
  25274. gettimeofday(&start_time_,0);
  25275. }
  25276. inline void stop()
  25277. {
  25278. gettimeofday(&stop_time_, 0);
  25279. in_use_ = false;
  25280. }
  25281. inline unsigned long long int usec_time() const
  25282. {
  25283. if (!in_use_)
  25284. {
  25285. if (stop_time_.tv_sec >= start_time_.tv_sec)
  25286. {
  25287. return 1000000 * (stop_time_.tv_sec - start_time_.tv_sec ) +
  25288. (stop_time_.tv_usec - start_time_.tv_usec);
  25289. }
  25290. else
  25291. return std::numeric_limits<unsigned long long int>::max();
  25292. }
  25293. else
  25294. return std::numeric_limits<unsigned long long int>::max();
  25295. }
  25296. inline double time() const
  25297. {
  25298. return usec_time() * 0.000001;
  25299. }
  25300. #endif
  25301. inline bool in_use() const
  25302. {
  25303. return in_use_;
  25304. }
  25305. private:
  25306. bool in_use_;
  25307. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  25308. LARGE_INTEGER start_time_;
  25309. LARGE_INTEGER stop_time_;
  25310. LARGE_INTEGER clock_frequency_;
  25311. #else
  25312. struct timeval start_time_;
  25313. struct timeval stop_time_;
  25314. #endif
  25315. };
  25316. namespace information
  25317. {
  25318. static const char* library = "Mathematical Expression Toolkit";
  25319. static const char* version = "2.7182818284590452353602874713526624977572470936999595";
  25320. static const char* date = "20150111";
  25321. static inline std::string data()
  25322. {
  25323. static const std::string info_str = std::string(library) +
  25324. std::string(" v") + std::string(version) +
  25325. std::string(" (") + date + std::string(")");
  25326. return info_str;
  25327. }
  25328. } // namespace information
  25329. } // namespace exprtk
  25330. #endif