PageRenderTime 68ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 2ms

/exprtk.hpp

http://exprtk.codeplex.com
C++ Header | 10925 lines | 9219 code | 1577 blank | 129 comment | 1589 complexity | d77335b11214244e1477262350bde5de MD5 | raw file
  1. /*
  2. ****************************************************************
  3. * C++ Mathematical Expression Toolkit Library *
  4. * *
  5. * Author: Arash Partow (1999-2013) *
  6. * URL: http://www.partow.net/programming/exprtk/index.html *
  7. * *
  8. * Copyright notice: *
  9. * Free use of the C++ Mathematical Expression Toolkit Library *
  10. * is permitted under the guidelines and in accordance with the *
  11. * most 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) if(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) (12.34sin(x)cos(2y)7+1)==(12.34*sin(x)*cos(2*y)*7+1) *
  27. * (12) (x ilike 's*ri?g') and [y<(3z^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 <deque>
  37. #include <limits>
  38. #include <list>
  39. #include <map>
  40. #include <set>
  41. #include <stack>
  42. #include <stdexcept>
  43. #include <string>
  44. #ifndef exprtk_enable_all_optimizations
  45. # define exprtk_lean_and_mean
  46. # ifdef exprtk_lean_and_mean_numeric_only
  47. # ifndef exprtk_lean_and_mean
  48. # define exprtk_lean_and_mean
  49. # endif
  50. # ifndef exprtk_disable_string_capabilities
  51. # define exprtk_disable_string_capabilities
  52. # endif
  53. # endif
  54. # ifdef exprtk_lean_and_mean
  55. # ifndef exprtk_disable_extended_operator_optimizations
  56. # define exprtk_disable_extended_operator_optimizations
  57. # endif
  58. # ifndef exprtk_disable_extended_optimisations
  59. # define exprtk_disable_extended_optimisations
  60. # endif
  61. # endif
  62. #endif
  63. namespace exprtk
  64. {
  65. namespace details
  66. {
  67. inline bool is_whitespace(const char c)
  68. {
  69. return (' ' == c) || ('\n' == c) ||
  70. ('\r' == c) || ('\t' == c) ||
  71. ('\b' == c) || ('\v' == c) ||
  72. ('\f' == c) ;
  73. }
  74. inline bool is_operator_char(const char c)
  75. {
  76. return ('+' == c) || ('-' == c) ||
  77. ('*' == c) || ('/' == c) ||
  78. ('^' == c) || ('<' == c) ||
  79. ('>' == c) || ('=' == c) ||
  80. (',' == c) || ('!' == c) ||
  81. ('(' == c) || (')' == c) ||
  82. ('[' == c) || (']' == c) ||
  83. ('{' == c) || ('}' == c) ||
  84. ('%' == c) || (':' == c) ||
  85. ('?' == c);
  86. }
  87. inline bool is_letter(const char c)
  88. {
  89. return (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
  90. }
  91. inline bool is_digit(const char c)
  92. {
  93. return ('0' <= c) && (c <= '9');
  94. }
  95. inline bool is_letter_or_digit(const char c)
  96. {
  97. return is_letter(c) || is_digit(c);
  98. }
  99. inline bool is_left_bracket(const char c)
  100. {
  101. return ('(' == c) || ('[' == c) || ('{' == c);
  102. }
  103. inline bool is_right_bracket(const char c)
  104. {
  105. return (')' == c) || (']' == c) || ('}' == c);
  106. }
  107. inline bool is_bracket(const char c)
  108. {
  109. return is_left_bracket(c) || is_right_bracket(c);
  110. }
  111. inline bool is_sign(const char c)
  112. {
  113. return ('+' == c) || ('-' == c);
  114. }
  115. inline bool is_invalid(const char c)
  116. {
  117. return !is_whitespace(c) &&
  118. !is_operator_char(c) &&
  119. !is_letter(c) &&
  120. !is_digit(c) &&
  121. ('.' != c) &&
  122. ('_' != c) &&
  123. ('$' != c) &&
  124. ('\'' != c);
  125. }
  126. inline bool imatch(const char c1, const char c2)
  127. {
  128. return std::tolower(c1) == std::tolower(c2);
  129. }
  130. inline bool imatch(const std::string& s1, const std::string& s2)
  131. {
  132. if (s1.size() == s2.size())
  133. {
  134. for (std::size_t i = 0; i < s1.size(); ++i)
  135. {
  136. if (std::tolower(s1[i]) != std::tolower(s2[i]))
  137. {
  138. return false;
  139. }
  140. }
  141. return true;
  142. }
  143. return false;
  144. }
  145. inline bool is_valid_sf_symbol(const std::string& symbol)
  146. {
  147. //Special function: $f12 or $F34
  148. return (symbol.size() == 4) &&
  149. ('$' == symbol[0]) &&
  150. imatch('f',symbol[1]) &&
  151. is_digit(symbol[2]) &&
  152. is_digit(symbol[3]);
  153. }
  154. inline std::string to_str(int i)
  155. {
  156. if (0 == i)
  157. return std::string("0");
  158. std::string result;
  159. bool negative = (i < 0);
  160. if (negative) i *= -1;
  161. while (i)
  162. {
  163. char digit = '0' + char(i % 10);
  164. result = (digit + result);
  165. i /= 10;
  166. }
  167. if (negative)
  168. result = "-" + result;
  169. return result;
  170. }
  171. struct ilesscompare
  172. {
  173. inline bool operator()(const std::string& s1, const std::string& s2) const
  174. {
  175. const std::size_t length = std::min(s1.size(),s2.size());
  176. for (std::size_t i = 0; i < length; ++i)
  177. {
  178. if (std::tolower(s1[i]) > std::tolower(s2[i]))
  179. return false;
  180. else if (std::tolower(s1[i]) < std::tolower(s2[i]))
  181. return true;
  182. }
  183. return s1.size() < s2.size();
  184. }
  185. };
  186. static const std::string reserved_words[] =
  187. {
  188. "and", "false", "for", "if", "ilike", "in", "like", "nand", "nor", "not",
  189. "or", "shl", "shr", "true", "while", "xor"
  190. };
  191. static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
  192. static const std::string reserved_symbols[] =
  193. {
  194. "abs", "acos", "and", "asin", "atan", "atan2", "avg", "ceil", "clamp",
  195. "cos", "cosh", "cot", "csc", "deg2grad", "deg2rad", "equal", "erf", "erfc",
  196. "exp", "false", "floor", "for", "frac", "grad2deg", "hyp", "if", "ilike",
  197. "in", "inrange", "like", "log", "log10", "logn", "max", "min", "mod", "mul",
  198. "nand", "nor", "not", "not_equal", "or", "pow", "rad2deg", "root", "round",
  199. "roundn", "sec", "sgn", "shl", "shr", "sin", "sinh", "sqrt", "sum", "tan",
  200. "tanh", "true", "trunc", "while", "xor"
  201. };
  202. static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
  203. inline bool is_reserved_word(const std::string& symbol)
  204. {
  205. for (std::size_t i = 0; i < reserved_words_size; ++i)
  206. {
  207. if (imatch(symbol,reserved_words[i]))
  208. {
  209. return true;
  210. }
  211. }
  212. return false;
  213. }
  214. inline bool is_reserved_symbol(const std::string& symbol)
  215. {
  216. for (std::size_t i = 0; i < reserved_symbols_size; ++i)
  217. {
  218. if (imatch(symbol,reserved_symbols[i]))
  219. {
  220. return true;
  221. }
  222. }
  223. return false;
  224. }
  225. struct cs_match { static inline bool cmp(const char c0, const char c1) { return c0 == c1; } };
  226. struct cis_match { static inline bool cmp(const char c0, const char c1) { return std::tolower(c0) == std::tolower(c1); } };
  227. template <typename Iterator, typename Compare>
  228. inline bool match_impl(const Iterator pattern_begin,
  229. const Iterator pattern_end,
  230. const Iterator data_begin,
  231. const Iterator data_end,
  232. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  233. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  234. {
  235. if (0 == std::distance(data_begin,data_end)) return false;
  236. Iterator d_itr = data_begin;
  237. Iterator p_itr = pattern_begin;
  238. Iterator c_itr = data_begin;
  239. Iterator m_itr = data_begin;
  240. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  241. {
  242. if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr)))
  243. {
  244. return false;
  245. }
  246. ++p_itr;
  247. ++d_itr;
  248. }
  249. while (data_end != d_itr)
  250. {
  251. if (zero_or_more == (*p_itr))
  252. {
  253. if (pattern_end == (++p_itr))
  254. {
  255. return true;
  256. }
  257. m_itr = p_itr;
  258. c_itr = d_itr;
  259. ++c_itr;
  260. }
  261. else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr)))
  262. {
  263. ++p_itr;
  264. ++d_itr;
  265. }
  266. else
  267. {
  268. p_itr = m_itr;
  269. d_itr = c_itr++;
  270. }
  271. }
  272. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr;
  273. return (p_itr == pattern_end);
  274. }
  275. inline bool wc_match(const std::string& wild_card,
  276. const std::string& str)
  277. {
  278. return match_impl<const char*,cs_match>(wild_card.data(),
  279. wild_card.data() + wild_card.size(),
  280. str.data(),
  281. str.data() + str.size(),
  282. '*',
  283. '?');
  284. }
  285. inline bool wc_imatch(const std::string& wild_card,
  286. const std::string& str)
  287. {
  288. return match_impl<const char*,cis_match>(wild_card.data(),
  289. wild_card.data() + wild_card.size(),
  290. str.data(),
  291. str.data() + str.size(),
  292. '*',
  293. '?');
  294. }
  295. static const double pow10[] = {
  296. 1.0,
  297. 10.0,
  298. 100.0,
  299. 1000.0,
  300. 10000.0,
  301. 100000.0,
  302. 1000000.0,
  303. 10000000.0,
  304. 100000000.0,
  305. 1000000000.0,
  306. 10000000000.0,
  307. 100000000000.0,
  308. 1000000000000.0,
  309. 10000000000000.0,
  310. 100000000000000.0,
  311. 1000000000000000.0,
  312. 10000000000000000.0,
  313. };
  314. namespace numeric
  315. {
  316. namespace constant
  317. {
  318. static const double e = 2.718281828459045235360;
  319. static const double pi = 3.141592653589793238462;
  320. static const double pi_2 = 1.570796326794896619231;
  321. static const double pi_4 = 0.785398163397448309616;
  322. static const double pi_180 = 0.017453292519943295769;
  323. static const double _1_pi = 0.318309886183790671538;
  324. static const double _2_pi = 0.636619772367581343076;
  325. static const double _180_pi = 57.295779513082320876798;
  326. }
  327. namespace details
  328. {
  329. struct unknown_type_tag {};
  330. struct real_type_tag {};
  331. struct int_type_tag {};
  332. template <typename T>
  333. struct number_type { typedef unknown_type_tag type; };
  334. #define exprtk_register_real_type_tag(T)\
  335. template<> struct number_type<T> { typedef real_type_tag type; };
  336. #define exprtk_register_int_type_tag(T)\
  337. template<> struct number_type<T> { typedef int_type_tag type; };
  338. exprtk_register_real_type_tag(double)
  339. exprtk_register_real_type_tag(long double)
  340. exprtk_register_real_type_tag(float)
  341. exprtk_register_int_type_tag(short)
  342. exprtk_register_int_type_tag(int)
  343. exprtk_register_int_type_tag(long long int)
  344. exprtk_register_int_type_tag(unsigned short)
  345. exprtk_register_int_type_tag(unsigned int)
  346. exprtk_register_int_type_tag(unsigned long long int)
  347. #undef exprtk_register_real_type_tag
  348. #undef exprtk_register_int_type_tag
  349. template <typename T>
  350. inline T equal_impl(const T& v0, const T& v1, real_type_tag)
  351. {
  352. static const T epsilon = T(0.00000000001);
  353. return (std::abs(v0 - v1) <= (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? T(1) : T(0);
  354. }
  355. template <typename T>
  356. inline T equal_impl(const T& v0, const T& v1, int_type_tag)
  357. {
  358. return (v0 == v1) ? 1 : 0;
  359. }
  360. template <typename T>
  361. inline T nequal_impl(const T& v0, const T& v1, real_type_tag)
  362. {
  363. static const T epsilon = T(0.0000000001);
  364. return (std::abs(v0 - v1) > (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? T(1) : T(0);
  365. }
  366. template <typename T>
  367. inline T nequal_impl(const T& v0, const T& v1, int_type_tag)
  368. {
  369. return (v0 != v1) ? 1 : 0;
  370. }
  371. template <typename T>
  372. inline T modulus_impl(const T& v0, const T& v1, real_type_tag)
  373. {
  374. return std::fmod(v0,v1);
  375. }
  376. template <typename T>
  377. inline T modulus_impl(const T& v0, const T& v1, int_type_tag)
  378. {
  379. return v0 % v1;
  380. }
  381. template <typename T>
  382. inline T pow_impl(const T& v0, const T& v1, real_type_tag)
  383. {
  384. return std::pow(v0,v1);
  385. }
  386. template <typename T>
  387. inline T pow_impl(const T& v0, const T& v1, int_type_tag)
  388. {
  389. return std::pow(static_cast<double>(v0),static_cast<double>(v1));
  390. }
  391. template <typename T>
  392. inline T logn_impl(const T& v0, const T& v1, real_type_tag)
  393. {
  394. return std::log(v0) / std::log(v1);
  395. }
  396. template <typename T>
  397. inline T logn_impl(const T& v0, const T& v1, int_type_tag)
  398. {
  399. return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
  400. }
  401. template <typename T>
  402. inline T root_impl(const T& v0, const T& v1, real_type_tag)
  403. {
  404. return std::pow(v0,T(1)/v1);
  405. }
  406. template <typename T>
  407. inline T root_impl(const T& v0, const T& v1, int_type_tag)
  408. {
  409. return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
  410. }
  411. template <typename T>
  412. inline T roundn_impl(const T& v0, const T& v1, real_type_tag)
  413. {
  414. return T(std::floor((v0 * pow10[(int)std::floor(v1)]) + T(0.5)) / T(pow10[(int)std::floor(v1)]));
  415. }
  416. template <typename T>
  417. inline T roundn_impl(const T& v0, const T&, int_type_tag)
  418. {
  419. return v0;
  420. }
  421. template <typename T>
  422. inline T hyp_impl(const T& v0, const T& v1, real_type_tag)
  423. {
  424. return std::sqrt((v0 * v0) + (v1 * v1));
  425. }
  426. template <typename T>
  427. inline T hyp_impl(const T& v0, const T& v1, int_type_tag)
  428. {
  429. return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
  430. }
  431. template <typename T>
  432. inline T atan2_impl(const T& v0, const T& v1, real_type_tag)
  433. {
  434. return std::atan2(v0,v1);
  435. }
  436. template <typename T>
  437. inline T atan2_impl(const T&, const T&, int_type_tag)
  438. {
  439. return 0;
  440. }
  441. template <typename T>
  442. inline T shr_impl(const T& v0, const T& v1, real_type_tag)
  443. {
  444. return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
  445. }
  446. template <typename T>
  447. inline T shr_impl(const T& v0, const T& v1, int_type_tag)
  448. {
  449. return v0 >> v1;
  450. }
  451. template <typename T>
  452. inline T shl_impl(const T& v0, const T& v1, real_type_tag)
  453. {
  454. return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
  455. }
  456. template <typename T>
  457. inline T shl_impl(const T& v0, const T& v1, int_type_tag)
  458. {
  459. return v0 << v1;
  460. }
  461. template <typename T>
  462. inline T sgn_impl(const T& v, real_type_tag)
  463. {
  464. if (v > T(0.0)) return T(+1.0);
  465. else if (v < T(0.0)) return T(-1.0);
  466. else return T( 0.0);
  467. }
  468. template <typename T>
  469. inline T sgn_impl(const T& v, int_type_tag)
  470. {
  471. if (v > T(0)) return T(+1);
  472. else if (v < T(0)) return T(-1);
  473. else return T( 0);
  474. }
  475. template <typename T>
  476. inline T xor_impl(const T& v0, const T& v1, real_type_tag)
  477. {
  478. return v0 != v1;
  479. }
  480. template <typename T>
  481. inline T xor_impl(const T& v0, const T& v1, int_type_tag)
  482. {
  483. return v0 ^ v1;
  484. }
  485. template <typename T>
  486. inline T erf_impl(T v, real_type_tag)
  487. {
  488. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  489. //Note: This should not be required for mscv 11.+
  490. T a1 = T(+0.254829592);
  491. T a2 = T(-0.284496736);
  492. T a3 = T(+1.421413741);
  493. T a4 = T(-1.453152027);
  494. T a5 = T(+1.061405429);
  495. T p = T( 0.327591100);
  496. T sign = T(1.0);
  497. if (v < 0)
  498. {
  499. sign = -1;
  500. v = abs(v);
  501. }
  502. T t = T(1.0) / (T(1.0) + p * v);
  503. T y = T(1.0) - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * std::exp(-v * v);
  504. return sign * y;
  505. #else
  506. return ::erf(v);
  507. #endif
  508. }
  509. template <typename T>
  510. inline T erf_impl(T v, int_type_tag)
  511. {
  512. return erf_impl(static_cast<double>(v),real_type_tag());
  513. }
  514. template <typename T>
  515. inline T erfc_impl(T v, real_type_tag)
  516. {
  517. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  518. return T(1.0) - erf_impl(v,real_type_tag());
  519. #else
  520. return ::erfc(v);
  521. #endif
  522. }
  523. template <typename T>
  524. inline T erfc_impl(T v, int_type_tag)
  525. {
  526. return erfc_impl(static_cast<double>(v),real_type_tag());
  527. }
  528. template <typename T> inline T abs_impl(const T v, real_type_tag) { return std::abs (v); }
  529. template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
  530. template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
  531. template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
  532. template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
  533. template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
  534. template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
  535. template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
  536. template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
  537. template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
  538. template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
  539. template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
  540. template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
  541. template <typename T> inline T round_impl(const T v, real_type_tag) { return std::floor(v + T(0.5)); }
  542. template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
  543. template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
  544. template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
  545. template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
  546. template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
  547. template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
  548. template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
  549. template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
  550. template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
  551. template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
  552. template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); }
  553. template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); }
  554. template <typename T> inline T notl_impl(const T v, real_type_tag) { return (v != T(0) ? T(0) : T(1)); }
  555. template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
  556. template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
  557. template <typename T> inline T abs_impl(const T v, int_type_tag) { return std::abs (v); }
  558. template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
  559. template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
  560. template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
  561. template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
  562. template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
  563. template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
  564. template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
  565. template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
  566. template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
  567. template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
  568. template <typename T> inline T frac_impl(const T v, int_type_tag) { return T(0); }
  569. template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
  570. template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  571. template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  572. template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  573. template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  574. template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  575. template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  576. template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  577. template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  578. template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  579. template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  580. template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  581. template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  582. template <typename T>
  583. inline bool is_integer_impl(const T& v, real_type_tag)
  584. {
  585. return (T(0.0) == std::fmod(v,T(1.0)));
  586. }
  587. template <typename T>
  588. inline bool is_integer_impl(const T&, int_type_tag)
  589. {
  590. return true;
  591. }
  592. }
  593. template <typename Type>
  594. struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
  595. template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
  596. template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
  597. template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
  598. template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
  599. template <typename T>
  600. inline T equal(const T v0, const T v1)
  601. {
  602. typename details::number_type<T>::type num_type;
  603. return details::equal_impl(v0,v1,num_type);
  604. }
  605. template <typename T>
  606. inline T nequal(const T v0, const T v1)
  607. {
  608. typename details::number_type<T>::type num_type;
  609. return details::nequal_impl(v0,v1,num_type);
  610. }
  611. template <typename T>
  612. inline T modulus(const T v0, const T v1)
  613. {
  614. typename details::number_type<T>::type num_type;
  615. return details::modulus_impl(v0,v1,num_type);
  616. }
  617. template <typename T>
  618. inline T pow(const T v0, const T v1)
  619. {
  620. typename details::number_type<T>::type num_type;
  621. return details::pow_impl(v0,v1,num_type);
  622. }
  623. template <typename T>
  624. inline T logn(const T v0, const T v1)
  625. {
  626. typename details::number_type<T>::type num_type;
  627. return details::logn_impl(v0,v1,num_type);
  628. }
  629. template <typename T>
  630. inline T root(const T v0, const T v1)
  631. {
  632. typename details::number_type<T>::type num_type;
  633. return details::root_impl(v0,v1,num_type);
  634. }
  635. template <typename T>
  636. inline T roundn(const T v0, const T v1)
  637. {
  638. typename details::number_type<T>::type num_type;
  639. return details::roundn_impl(v0,v1,num_type);
  640. }
  641. template <typename T>
  642. inline T hyp(const T v0, const T v1)
  643. {
  644. typename details::number_type<T>::type num_type;
  645. return details::hyp_impl(v0,v1,num_type);
  646. }
  647. template <typename T>
  648. inline T atan2(const T v0, const T v1)
  649. {
  650. typename details::number_type<T>::type num_type;
  651. return details::atan2_impl(v0,v1,num_type);
  652. }
  653. template <typename T>
  654. inline T shr(const T v0, const T v1)
  655. {
  656. typename details::number_type<T>::type num_type;
  657. return details::shr_impl(v0,v1,num_type);
  658. }
  659. template <typename T>
  660. inline T shl(const T v0, const T v1)
  661. {
  662. typename details::number_type<T>::type num_type;
  663. return details::shl_impl(v0,v1,num_type);
  664. }
  665. template <typename T>
  666. inline T xor_opr(const T v0, const T v1)
  667. {
  668. typename details::number_type<T>::type num_type;
  669. return details::xor_impl(v0,v1,num_type);
  670. }
  671. template <typename T>
  672. inline bool is_integer(const T v)
  673. {
  674. typename details::number_type<T>::type num_type;
  675. return details::is_integer_impl(v,num_type);
  676. }
  677. template <typename T, unsigned int N>
  678. struct fast_exp
  679. {
  680. static inline T result(T v)
  681. {
  682. unsigned int k = N;
  683. T l = T(1);
  684. while (k)
  685. {
  686. if (k & 1)
  687. {
  688. l *= v;
  689. --k;
  690. }
  691. v *= v;
  692. k >>= 1;
  693. }
  694. return l;
  695. }
  696. };
  697. 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; } };
  698. template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
  699. 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; } };
  700. template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
  701. 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; } };
  702. template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
  703. template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
  704. template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
  705. template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v; } };
  706. template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } };
  707. template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } };
  708. #define exprtk_define_unary_function(FunctionName) \
  709. template <typename T> \
  710. inline T FunctionName (const T v) \
  711. { \
  712. typename details::number_type<T>::type num_type; \
  713. return details:: FunctionName##_impl(v,num_type); \
  714. }
  715. exprtk_define_unary_function(abs )
  716. exprtk_define_unary_function(acos )
  717. exprtk_define_unary_function(asin )
  718. exprtk_define_unary_function(atan )
  719. exprtk_define_unary_function(ceil )
  720. exprtk_define_unary_function(cos )
  721. exprtk_define_unary_function(cosh )
  722. exprtk_define_unary_function(exp )
  723. exprtk_define_unary_function(floor)
  724. exprtk_define_unary_function(log )
  725. exprtk_define_unary_function(log10)
  726. exprtk_define_unary_function(neg )
  727. exprtk_define_unary_function(pos )
  728. exprtk_define_unary_function(round)
  729. exprtk_define_unary_function(sin )
  730. exprtk_define_unary_function(sinh )
  731. exprtk_define_unary_function(sqrt )
  732. exprtk_define_unary_function(tan )
  733. exprtk_define_unary_function(tanh )
  734. exprtk_define_unary_function(cot )
  735. exprtk_define_unary_function(sec )
  736. exprtk_define_unary_function(csc )
  737. exprtk_define_unary_function(r2d )
  738. exprtk_define_unary_function(d2r )
  739. exprtk_define_unary_function(d2g )
  740. exprtk_define_unary_function(g2d )
  741. exprtk_define_unary_function(notl )
  742. exprtk_define_unary_function(sgn )
  743. exprtk_define_unary_function(erf )
  744. exprtk_define_unary_function(erfc )
  745. exprtk_define_unary_function(frac )
  746. exprtk_define_unary_function(trunc)
  747. #undef exprtk_define_unary_function
  748. }
  749. template <typename Iterator, typename Type>
  750. static inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, Type& result)
  751. {
  752. if (end == itr) return false;
  753. Type t = 0;
  754. bool negative = false;
  755. if ('+' == (*itr))
  756. ++itr;
  757. else if ('-' == (*itr))
  758. {
  759. ++itr;
  760. negative = true;
  761. }
  762. if (end == itr)
  763. return false;
  764. unsigned int digit_count = 0;
  765. while ((end != itr) && ('0' == (*itr))) ++itr;
  766. bool return_result = true;
  767. while (end != itr)
  768. {
  769. const unsigned char digit = (*itr - '0');
  770. if (digit > 9)
  771. {
  772. return_result = false;
  773. break;
  774. }
  775. if ((++digit_count) <= numeric::numeric_info<Type>::bound_length)
  776. {
  777. t *= 10;
  778. t += digit;
  779. }
  780. else
  781. {
  782. typedef unsigned long long int base_type;
  783. static const base_type max_limit = +std::numeric_limits<Type>::max();
  784. static const base_type min_limit = -std::numeric_limits<Type>::min();
  785. base_type tmp = static_cast<base_type>(t) * 10 + digit;
  786. if (negative && static_cast<base_type>(tmp) > min_limit)
  787. return_result = false;
  788. else if (static_cast<base_type>(tmp) > max_limit)
  789. return_result = false;
  790. t = static_cast<Type>(tmp);
  791. }
  792. ++itr;
  793. }
  794. result = static_cast<Type>((negative) ? -t : t);
  795. return return_result;
  796. }
  797. template <typename Iterator, typename T>
  798. static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
  799. {
  800. typedef typename std::iterator_traits<Iterator>::value_type type;
  801. static const std::size_t nan_length = 3;
  802. if (std::distance(itr,end) != static_cast<int>(nan_length))
  803. return false;
  804. if (static_cast<type>('n') == (*itr))
  805. {
  806. if ((static_cast<type>('a') != *(itr + 1)) || (static_cast<type>('n') != *(itr + 2)))
  807. {
  808. return false;
  809. }
  810. }
  811. else if ((static_cast<type>('A') != *(itr + 1)) || (static_cast<type>('N') != *(itr + 2)))
  812. {
  813. return false;
  814. }
  815. t = std::numeric_limits<T>::quiet_NaN();
  816. return true;
  817. }
  818. template <typename Iterator, typename T>
  819. static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
  820. {
  821. static const char inf_uc[] = "INFINITY";
  822. static const char inf_lc[] = "infinity";
  823. static const std::size_t inf_length = 8;
  824. const std::size_t length = std::distance(itr,end);
  825. if ((3 != length) && (inf_length != length))
  826. return false;
  827. const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
  828. while (end != itr)
  829. {
  830. if (*inf_itr == static_cast<char>(*itr))
  831. {
  832. ++itr;
  833. ++inf_itr;
  834. continue;
  835. }
  836. else
  837. return false;
  838. }
  839. if (negative)
  840. t = -std::numeric_limits<T>::infinity();
  841. else
  842. t = std::numeric_limits<T>::infinity();
  843. return true;
  844. }
  845. template <typename Iterator, typename T>
  846. inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t)
  847. {
  848. if (end == itr_external)
  849. return false;
  850. Iterator itr = itr_external;
  851. double d = 0.0;
  852. bool negative = false;
  853. if ('+' == (*itr))
  854. ++itr;
  855. else if ('-' == (*itr))
  856. {
  857. ++itr;
  858. negative = true;
  859. }
  860. if (end == itr)
  861. return false;
  862. if (('I' <= (*itr)) && ((*itr) <= 'n'))
  863. {
  864. if (('i' == (*itr)) || ('I' == (*itr)))
  865. {
  866. return parse_inf(itr,end,t,negative);
  867. }
  868. else if (('n' == (*itr)) || ('N' == (*itr)))
  869. {
  870. return parse_nan(itr,end,t);
  871. }
  872. else
  873. return false;
  874. }
  875. bool instate = false;
  876. int pre_decimal = 0;
  877. if ('.' != (*itr))
  878. {
  879. const Iterator curr = itr;
  880. while ((end != itr) && ('0' == (*itr))) ++itr;
  881. const Iterator post_zero_cull_itr = itr;
  882. unsigned char digit = 0;
  883. #define parse_digit_1 \
  884. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; if (end == ++itr) break; \
  885. #define parse_digit_2 \
  886. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; ++itr;\
  887. while (end != itr)
  888. {
  889. parse_digit_1
  890. parse_digit_1
  891. parse_digit_1
  892. parse_digit_1
  893. parse_digit_1
  894. parse_digit_1
  895. parse_digit_1
  896. parse_digit_2
  897. }
  898. #undef parse_digit_1
  899. #undef parse_digit_2
  900. if (curr != itr) instate = true;
  901. pre_decimal = static_cast<int>(std::distance(post_zero_cull_itr,itr));
  902. }
  903. int exponent = 0;
  904. if (end != itr)
  905. {
  906. if ('.' == (*itr))
  907. {
  908. ++itr;
  909. const Iterator curr = itr;
  910. unsigned char digit = 0;
  911. #define parse_digit_1 \
  912. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; if (end == ++itr) break; \
  913. #define parse_digit_2 \
  914. if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; ++itr;\
  915. while (end != itr)
  916. {
  917. parse_digit_1
  918. parse_digit_1
  919. parse_digit_1
  920. parse_digit_1
  921. parse_digit_1
  922. parse_digit_1
  923. parse_digit_1
  924. parse_digit_2
  925. }
  926. #undef parse_digit_1
  927. #undef parse_digit_2
  928. if (curr != itr) instate = true;
  929. exponent -= static_cast<int>(std::distance(curr,itr));
  930. }
  931. if (end != itr)
  932. {
  933. typename std::iterator_traits<Iterator>::value_type c = (*itr);
  934. if (('e' == c) || ('E' == c))
  935. {
  936. ++itr;
  937. int exp = 0;
  938. if (!string_to_type_converter_impl_ref(itr,end,exp))
  939. {
  940. if (end == itr)
  941. return false;
  942. else
  943. c = (*itr);
  944. }
  945. if (
  946. (exp < numeric::numeric_info<T>::min_exp) ||
  947. (numeric::numeric_info<T>::max_exp < exp)
  948. )
  949. return false;
  950. exponent += exp;
  951. }
  952. if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
  953. ++itr;
  954. else if ('#' == c)
  955. {
  956. ++itr;
  957. if (end == itr)
  958. return false;
  959. if ((10.0 != d) || (exponent != -1))
  960. return false;
  961. if (('I' <= (*itr)) && ((*itr) <= 'n'))
  962. {
  963. if (('i' == (*itr)) || ('I' == (*itr)))
  964. {
  965. return parse_inf(itr,end,t,negative);
  966. }
  967. else if (('n' == (*itr)) || ('N' == (*itr)))
  968. {
  969. return parse_nan(itr,end,t);
  970. }
  971. else
  972. return false;
  973. }
  974. return false;
  975. }
  976. }
  977. }
  978. if ((end != itr) || (!instate))
  979. return false;
  980. if (0 != exponent)
  981. {
  982. if (
  983. (std::numeric_limits<T>::max_exponent10 < (exponent + pre_decimal)) ||
  984. (std::numeric_limits<T>::min_exponent10 > (exponent + pre_decimal))
  985. )
  986. {
  987. return false;
  988. }
  989. const int e = std::abs(exponent);
  990. static const double fract10[] =
  991. {
  992. 0.0,
  993. 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,
  994. 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,
  995. 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,
  996. 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,
  997. 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,
  998. 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,
  999. 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,
  1000. 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,
  1001. 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,
  1002. 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,
  1003. 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,
  1004. 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,
  1005. 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,
  1006. 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,
  1007. 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,
  1008. 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,
  1009. 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,
  1010. 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,
  1011. 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,
  1012. 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,
  1013. 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,
  1014. 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,
  1015. 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,
  1016. 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,
  1017. 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,
  1018. 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,
  1019. 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,
  1020. 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,
  1021. 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
  1022. };
  1023. static const std::size_t fract10_size = sizeof(fract10) / sizeof(double);
  1024. if (d != 0.0)
  1025. {
  1026. if (static_cast<std::size_t>(e) < fract10_size)
  1027. {
  1028. if (exponent > 0)
  1029. d *= fract10[e];
  1030. else
  1031. d /= fract10[e];
  1032. }
  1033. else
  1034. d *= std::pow(10.0, 1.0 * exponent);
  1035. }
  1036. }
  1037. t = static_cast<T>((negative) ? -d : d);
  1038. return true;
  1039. }
  1040. template <typename T>
  1041. inline bool string_to_real(const std::string& s, T& t)
  1042. {
  1043. const char* begin = s.data();
  1044. const char* end = s.data() + s.size();
  1045. return string_to_real(begin,end,t);
  1046. }
  1047. } // namespace details
  1048. namespace lexer
  1049. {
  1050. struct token
  1051. {
  1052. enum token_type
  1053. {
  1054. e_none = 0,
  1055. e_error = 1,
  1056. e_err_symbol = 2,
  1057. e_err_number = 3,
  1058. e_err_string = 4,
  1059. e_err_sfunc = 5,
  1060. e_eof = 6,
  1061. e_number = 7,
  1062. e_symbol = 8,
  1063. e_string = 9,
  1064. e_assign = 10,
  1065. e_shr = 11,
  1066. e_shl = 12,
  1067. e_lte = 13,
  1068. e_ne = 14,
  1069. e_gte = 15,
  1070. e_lt = '<',
  1071. e_gt = '>',
  1072. e_eq = '=',
  1073. e_rbracket = ')',
  1074. e_lbracket = '(',
  1075. e_rsqrbracket = ']',
  1076. e_lsqrbracket = '[',
  1077. e_rcrlbracket = '}',
  1078. e_lcrlbracket = '{',
  1079. e_comma = ',',
  1080. e_add = '+',
  1081. e_sub = '-',
  1082. e_div = '/',
  1083. e_mul = '*',
  1084. e_mod = '%',
  1085. e_pow = '^',
  1086. e_colon = ':'
  1087. };
  1088. token()
  1089. : type(e_none),
  1090. value(""),
  1091. position(std::numeric_limits<std::size_t>::max())
  1092. {}
  1093. void clear()
  1094. {
  1095. type = e_none;
  1096. value = "";
  1097. position = std::numeric_limits<std::size_t>::max();
  1098. }
  1099. template <typename Iterator>
  1100. inline token& set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1101. {
  1102. type = tt;
  1103. value.assign(begin,end);
  1104. if (base_begin)
  1105. position = std::distance(base_begin,begin);
  1106. return *this;
  1107. }
  1108. template <typename Iterator>
  1109. inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1110. {
  1111. type = e_symbol;
  1112. value.assign(begin,end);
  1113. if (base_begin)
  1114. position = std::distance(base_begin,begin);
  1115. return *this;
  1116. }
  1117. template <typename Iterator>
  1118. inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1119. {
  1120. type = e_number;
  1121. value.assign(begin,end);
  1122. if (base_begin)
  1123. position = std::distance(base_begin,begin);
  1124. return *this;
  1125. }
  1126. template <typename Iterator>
  1127. inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1128. {
  1129. type = e_string;
  1130. value.assign(begin,end);
  1131. if (base_begin)
  1132. position = std::distance(base_begin,begin);
  1133. return *this;
  1134. }
  1135. template <typename Iterator>
  1136. inline token& set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1137. {
  1138. if (
  1139. (e_error == et) ||
  1140. (e_err_symbol == et) ||
  1141. (e_err_number == et) ||
  1142. (e_err_string == et) ||
  1143. (e_err_sfunc == et)
  1144. )
  1145. {
  1146. type = et;
  1147. }
  1148. else
  1149. type = e_error;
  1150. value.assign(begin,end);
  1151. if (base_begin)
  1152. position = std::distance(base_begin,begin);
  1153. return *this;
  1154. }
  1155. inline std::string to_str(token_type t) const
  1156. {
  1157. switch (t)
  1158. {
  1159. case e_none : return "NONE";
  1160. case e_error : return "ERROR";
  1161. case e_err_symbol : return "ERROR_SYMBOL";
  1162. case e_err_number : return "ERROR_NUMBER";
  1163. case e_err_string : return "ERROR_STRING";
  1164. case e_eof : return "EOF";
  1165. case e_number : return "NUMBER";
  1166. case e_symbol : return "SYMBOL";
  1167. case e_string : return "STRING";
  1168. case e_assign : return ":=";
  1169. case e_shr : return ">>";
  1170. case e_shl : return "<<";
  1171. case e_lte : return "<=";
  1172. case e_ne : return "!=";
  1173. case e_gte : return ">=";
  1174. case e_lt : return "<";
  1175. case e_gt : return ">";
  1176. case e_eq : return "=";
  1177. case e_rbracket : return ")";
  1178. case e_lbracket : return "(";
  1179. case e_rsqrbracket : return "]";
  1180. case e_lsqrbracket : return "[";
  1181. case e_rcrlbracket : return "}";
  1182. case e_lcrlbracket : return "{";
  1183. case e_comma : return ",";
  1184. case e_add : return "+";
  1185. case e_sub : return "-";
  1186. case e_div : return "/";
  1187. case e_mul : return "*";
  1188. case e_mod : return "%";
  1189. case e_pow : return "^";
  1190. case e_colon : return ":";
  1191. default : return "UNKNOWN";
  1192. }
  1193. }
  1194. inline bool is_error() const
  1195. {
  1196. return (
  1197. (e_error == type) ||
  1198. (e_err_symbol == type) ||
  1199. (e_err_number == type) ||
  1200. (e_err_string == type) ||
  1201. (e_err_sfunc == type)
  1202. );
  1203. }
  1204. token_type type;
  1205. std::string value;
  1206. std::size_t position;
  1207. };
  1208. class generator
  1209. {
  1210. public:
  1211. typedef token token_t;
  1212. typedef std::deque<token_t> token_list_t;
  1213. typedef std::deque<token_t>::iterator token_list_itr_t;
  1214. generator()
  1215. : base_itr_(0),
  1216. s_itr_(0),
  1217. s_end_(0)
  1218. {
  1219. clear();
  1220. }
  1221. inline void clear()
  1222. {
  1223. base_itr_ = 0;
  1224. s_itr_ = 0;
  1225. s_end_ = 0;
  1226. token_list_.clear();
  1227. token_itr_ = token_list_.end();
  1228. store_token_itr_ = token_list_.end();
  1229. }
  1230. inline bool process(const std::string& str)
  1231. {
  1232. base_itr_ = str.data();
  1233. s_itr_ = str.data();
  1234. s_end_ = str.data() + str.size();
  1235. eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
  1236. token_list_.clear();
  1237. while (s_end_ != s_itr_)
  1238. {
  1239. scan_token();
  1240. if (token_list_.back().is_error())
  1241. {
  1242. return false;
  1243. }
  1244. }
  1245. return true;
  1246. }
  1247. inline std::size_t size() const
  1248. {
  1249. return token_list_.size();
  1250. }
  1251. inline void begin()
  1252. {
  1253. token_itr_ = token_list_.begin();
  1254. store_token_itr_ = token_list_.begin();
  1255. }
  1256. inline void store()
  1257. {
  1258. store_token_itr_ = token_itr_;
  1259. }
  1260. inline void restore()
  1261. {
  1262. token_itr_ = store_token_itr_;
  1263. }
  1264. inline token_t& next_token()
  1265. {
  1266. if (token_list_.end() != token_itr_)
  1267. {
  1268. return *token_itr_++;
  1269. }
  1270. else
  1271. return eof_token_;
  1272. }
  1273. inline token_t& operator[](const std::size_t index)
  1274. {
  1275. if (index < token_list_.size())
  1276. return token_list_[index];
  1277. else
  1278. return eof_token_;
  1279. }
  1280. inline token_t operator[](const std::size_t index) const
  1281. {
  1282. if (index < token_list_.size())
  1283. return token_list_[index];
  1284. else
  1285. return eof_token_;
  1286. }
  1287. private:
  1288. inline void skip_whitespace()
  1289. {
  1290. while ((s_end_ != s_itr_) && details::is_whitespace(*s_itr_))
  1291. {
  1292. ++s_itr_;
  1293. }
  1294. }
  1295. inline void scan_token()
  1296. {
  1297. skip_whitespace();
  1298. if (s_end_ == s_itr_)
  1299. {
  1300. return;
  1301. }
  1302. else if (details::is_operator_char(*s_itr_))
  1303. {
  1304. scan_operator();
  1305. return;
  1306. }
  1307. else if (details::is_letter(*s_itr_))
  1308. {
  1309. scan_symbol();
  1310. return;
  1311. }
  1312. else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_)))
  1313. {
  1314. scan_number();
  1315. return;
  1316. }
  1317. else if ('$' == (*s_itr_))
  1318. {
  1319. scan_special_function();
  1320. return;
  1321. }
  1322. #ifndef exprtk_disable_string_capabilities
  1323. else if ('\'' == (*s_itr_))
  1324. {
  1325. scan_string();
  1326. return;
  1327. }
  1328. #endif
  1329. else
  1330. {
  1331. token_t t;
  1332. t.set_error(token::e_error,s_itr_,s_itr_ + 2);
  1333. token_list_.push_back(t);
  1334. ++s_itr_;
  1335. }
  1336. }
  1337. inline void scan_operator()
  1338. {
  1339. token_t t;
  1340. if ((s_itr_ + 1) != s_end_)
  1341. {
  1342. token_t::token_type ttype = token_t::e_none;
  1343. char c0 = s_itr_[0];
  1344. char c1 = s_itr_[1];
  1345. if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
  1346. else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
  1347. else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
  1348. else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
  1349. else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
  1350. else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
  1351. else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
  1352. else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
  1353. if (token_t::e_none != ttype)
  1354. {
  1355. t.set_operator(ttype,s_itr_,s_itr_ + 2,base_itr_);
  1356. token_list_.push_back(t);
  1357. s_itr_ += 2;
  1358. return;
  1359. }
  1360. }
  1361. if ('<' == *s_itr_)
  1362. t.set_operator(token_t::e_lt,s_itr_,s_itr_ + 1,base_itr_);
  1363. else if ('>' == *s_itr_)
  1364. t.set_operator(token_t::e_gt,s_itr_,s_itr_ + 1,base_itr_);
  1365. else
  1366. t.set_operator(token_t::token_type(*s_itr_),s_itr_,s_itr_ + 1,base_itr_);
  1367. token_list_.push_back(t);
  1368. ++s_itr_;
  1369. }
  1370. inline void scan_symbol()
  1371. {
  1372. const char* begin = s_itr_;
  1373. while (
  1374. (s_end_ != s_itr_) &&
  1375. (details::is_letter_or_digit(*s_itr_) || ((*s_itr_) == '_'))
  1376. )
  1377. {
  1378. ++s_itr_;
  1379. }
  1380. token_t t;
  1381. t.set_symbol(begin,s_itr_,base_itr_);
  1382. token_list_.push_back(t);
  1383. }
  1384. inline void scan_number()
  1385. {
  1386. /*
  1387. Attempt to match a valid numeric value in one of the following formats:
  1388. 1. 123456
  1389. 2. 123.456
  1390. 3. 123.456e3
  1391. 4. 123.456E3
  1392. 5. 123.456e+3
  1393. 6. 123.456E+3
  1394. 7. 123.456e-3
  1395. 8. 123.456E-3
  1396. */
  1397. const char* begin = s_itr_;
  1398. bool dot_found = false;
  1399. bool e_found = false;
  1400. bool post_e_sign_found = false;
  1401. token_t t;
  1402. while (s_end_ != s_itr_)
  1403. {
  1404. if ('.' == (*s_itr_))
  1405. {
  1406. if (dot_found)
  1407. {
  1408. t.set_error(token::e_err_number,begin,s_itr_,base_itr_);
  1409. token_list_.push_back(t);
  1410. return;
  1411. }
  1412. dot_found = true;
  1413. ++s_itr_;
  1414. continue;
  1415. }
  1416. else if (details::imatch('e',(*s_itr_)))
  1417. {
  1418. const char& c = *(s_itr_ + 1);
  1419. if (s_end_ == (s_itr_ + 1))
  1420. {
  1421. t.set_error(token::e_err_number,begin,s_itr_,base_itr_);
  1422. token_list_.push_back(t);
  1423. return;
  1424. }
  1425. else if (
  1426. ('+' != c) &&
  1427. ('-' != c) &&
  1428. !details::is_digit(c)
  1429. )
  1430. {
  1431. t.set_error(token::e_err_number,begin,s_itr_,base_itr_);
  1432. token_list_.push_back(t);
  1433. return;
  1434. }
  1435. e_found = true;
  1436. ++s_itr_;
  1437. continue;
  1438. }
  1439. else if (e_found && details::is_sign(*s_itr_))
  1440. {
  1441. if (post_e_sign_found)
  1442. {
  1443. t.set_error(token::e_err_number,begin,s_itr_,base_itr_);
  1444. token_list_.push_back(t);
  1445. return;
  1446. }
  1447. post_e_sign_found = true;
  1448. ++s_itr_;
  1449. continue;
  1450. }
  1451. else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
  1452. break;
  1453. else
  1454. ++s_itr_;
  1455. }
  1456. t.set_numeric(begin,s_itr_,base_itr_);
  1457. token_list_.push_back(t);
  1458. return;
  1459. }
  1460. inline void scan_special_function()
  1461. {
  1462. const char* begin = s_itr_;
  1463. token_t t;
  1464. //$fdd(x,x,x) = at least 11 chars
  1465. if (std::distance(s_itr_,s_end_) < 11)
  1466. {
  1467. t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_);
  1468. token_list_.push_back(t);
  1469. return;
  1470. }
  1471. if (
  1472. !(('$' == *s_itr_) &&
  1473. (details::imatch ('f',*(s_itr_ + 1))) &&
  1474. (details::is_digit(*(s_itr_ + 2))) &&
  1475. (details::is_digit(*(s_itr_ + 3))))
  1476. )
  1477. {
  1478. t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_);
  1479. token_list_.push_back(t);
  1480. return;
  1481. }
  1482. s_itr_ += 4; //$fdd = 4chars
  1483. t.set_symbol(begin,s_itr_,base_itr_);
  1484. token_list_.push_back(t);
  1485. return;
  1486. }
  1487. #ifndef exprtk_disable_string_capabilities
  1488. inline void scan_string()
  1489. {
  1490. const char* begin = s_itr_ + 1;
  1491. token_t t;
  1492. if (std::distance(s_itr_,s_end_) < 2)
  1493. {
  1494. t.set_error(token::e_err_string,begin,s_itr_,base_itr_);
  1495. token_list_.push_back(t);
  1496. return;
  1497. }
  1498. ++s_itr_;
  1499. bool escaped = false;
  1500. while (s_end_ != s_itr_)
  1501. {
  1502. if ('\\' == *s_itr_)
  1503. {
  1504. escaped = true;
  1505. ++s_itr_;
  1506. continue;
  1507. }
  1508. else if (!escaped)
  1509. {
  1510. if ('\'' == *s_itr_)
  1511. break;
  1512. }
  1513. else if (escaped)
  1514. escaped = false;
  1515. ++s_itr_;
  1516. }
  1517. if (s_end_ == s_itr_)
  1518. {
  1519. t.set_error(token::e_err_string,begin,s_itr_,base_itr_);
  1520. token_list_.push_back(t);
  1521. return;
  1522. }
  1523. t.set_string(begin,s_itr_,base_itr_);
  1524. token_list_.push_back(t);
  1525. ++s_itr_;
  1526. return;
  1527. }
  1528. #endif
  1529. private:
  1530. token_list_t token_list_;
  1531. token_list_itr_t token_itr_;
  1532. token_list_itr_t store_token_itr_;
  1533. token_t eof_token_;
  1534. const char* base_itr_;
  1535. const char* s_itr_;
  1536. const char* s_end_;
  1537. friend class token_scanner;
  1538. friend class token_modifier;
  1539. friend class token_inserter;
  1540. friend class token_joiner;
  1541. };
  1542. class helper_interface
  1543. {
  1544. public:
  1545. virtual void init() { }
  1546. virtual void reset() { }
  1547. virtual bool result() { return true; }
  1548. virtual std::size_t process(generator&) { return 0; }
  1549. };
  1550. class token_scanner : public helper_interface
  1551. {
  1552. public:
  1553. explicit token_scanner(const std::size_t& stride)
  1554. : stride_(stride)
  1555. {
  1556. if (stride > 4)
  1557. {
  1558. throw std::invalid_argument("token_scanner() - Invalid stride value");
  1559. }
  1560. }
  1561. inline std::size_t process(generator& g)
  1562. {
  1563. for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
  1564. {
  1565. token t;
  1566. switch (stride_)
  1567. {
  1568. case 1 :
  1569. {
  1570. const token& t0 = g.token_list_[i];
  1571. if (!operator()(t0)) return i;
  1572. }
  1573. break;
  1574. case 2 :
  1575. {
  1576. const token& t0 = g.token_list_[i ];
  1577. const token& t1 = g.token_list_[i + 1];
  1578. if (!operator()(t0,t1)) return i;
  1579. }
  1580. break;
  1581. case 3 :
  1582. {
  1583. const token& t0 = g.token_list_[i ];
  1584. const token& t1 = g.token_list_[i + 1];
  1585. const token& t2 = g.token_list_[i + 2];
  1586. if (!operator()(t0,t1,t2)) return i;
  1587. }
  1588. break;
  1589. case 4 :
  1590. {
  1591. const token& t0 = g.token_list_[i ];
  1592. const token& t1 = g.token_list_[i + 1];
  1593. const token& t2 = g.token_list_[i + 2];
  1594. const token& t3 = g.token_list_[i + 3];
  1595. if (!operator()(t0,t1,t2,t3)) return i;
  1596. }
  1597. break;
  1598. }
  1599. }
  1600. return (g.token_list_.size() - stride_ + 1);
  1601. }
  1602. virtual bool operator()(const token&)
  1603. {
  1604. return false;
  1605. }
  1606. virtual bool operator()(const token&, const token&)
  1607. {
  1608. return false;
  1609. }
  1610. virtual bool operator()(const token&, const token&, const token&)
  1611. {
  1612. return false;
  1613. }
  1614. virtual bool operator()(const token&, const token&, const token&, const token&)
  1615. {
  1616. return false;
  1617. }
  1618. private:
  1619. std::size_t stride_;
  1620. };
  1621. class token_modifier : public helper_interface
  1622. {
  1623. public:
  1624. inline std::size_t process(generator& g)
  1625. {
  1626. std::size_t changes = 0;
  1627. for (std::size_t i = 0; i < g.token_list_.size(); ++i)
  1628. {
  1629. if (modify(g.token_list_[i])) changes++;
  1630. }
  1631. return changes;
  1632. }
  1633. virtual bool modify(token& t) = 0;
  1634. };
  1635. class token_inserter : public helper_interface
  1636. {
  1637. public:
  1638. explicit token_inserter(const std::size_t& stride)
  1639. : stride_(stride)
  1640. {
  1641. if (stride > 5)
  1642. {
  1643. throw std::invalid_argument("token_inserter() - Invalid stride value");
  1644. }
  1645. }
  1646. inline std::size_t process(generator& g)
  1647. {
  1648. std::size_t changes = 0;
  1649. for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
  1650. {
  1651. token t;
  1652. int insert_index = -1;
  1653. switch (stride_)
  1654. {
  1655. case 1 : insert_index = insert(g.token_list_[i],t);
  1656. break;
  1657. case 2 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],t);
  1658. break;
  1659. case 3 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t);
  1660. break;
  1661. 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);
  1662. break;
  1663. 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);
  1664. break;
  1665. }
  1666. if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
  1667. {
  1668. g.token_list_.insert(g.token_list_.begin() + (i + insert_index),t);
  1669. changes++;
  1670. }
  1671. }
  1672. return changes;
  1673. }
  1674. virtual inline int insert(const token&, token& )
  1675. {
  1676. return -1;
  1677. }
  1678. virtual inline int insert(const token&, const token&, token&)
  1679. {
  1680. return -1;
  1681. }
  1682. virtual inline int insert(const token&, const token&, const token&, token&)
  1683. {
  1684. return -1;
  1685. }
  1686. virtual inline int insert(const token&, const token&, const token&, const token&, token&)
  1687. {
  1688. return -1;
  1689. }
  1690. virtual inline int insert(const token&, const token&, const token&, const token&, const token&, token&)
  1691. {
  1692. return -1;
  1693. }
  1694. private:
  1695. std::size_t stride_;
  1696. };
  1697. class token_joiner : public helper_interface
  1698. {
  1699. public:
  1700. inline std::size_t process(generator& g)
  1701. {
  1702. std::size_t changes = 0;
  1703. for (std::size_t i = 0; i < g.token_list_.size() - 1; ++i)
  1704. {
  1705. token t;
  1706. if (join(g.token_list_[i],g.token_list_[i + 1],t))
  1707. {
  1708. g.token_list_[i] = t;
  1709. g.token_list_.erase(g.token_list_.begin() + (i + 1));
  1710. ++changes;
  1711. }
  1712. }
  1713. return changes;
  1714. }
  1715. virtual bool join(const token&, const token&, token&) = 0;
  1716. };
  1717. namespace helper
  1718. {
  1719. inline void dump(lexer::generator& generator)
  1720. {
  1721. for (std::size_t i = 0; i < generator.size(); ++i)
  1722. {
  1723. lexer::token t = generator[i];
  1724. printf("Token[%02d] @ %03d %6s --> '%s'\n",
  1725. static_cast<unsigned int>(i),
  1726. static_cast<unsigned int>(t.position),
  1727. t.to_str(t.type).c_str(),
  1728. t.value.c_str());
  1729. }
  1730. }
  1731. class commutative_inserter : public lexer::token_inserter
  1732. {
  1733. public:
  1734. commutative_inserter()
  1735. : lexer::token_inserter(2)
  1736. {}
  1737. inline void ignore_symbol(const std::string& symbol)
  1738. {
  1739. ignore_set_.insert(symbol);
  1740. }
  1741. inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token)
  1742. {
  1743. new_token.type = lexer::token::e_mul;
  1744. new_token.value = "*";
  1745. new_token.position = t1.position;
  1746. bool match = false;
  1747. if (t0.type == lexer::token::e_symbol)
  1748. {
  1749. if (ignore_set_.end() != ignore_set_.find(t0.value))
  1750. {
  1751. return -1;
  1752. }
  1753. else if (!t0.value.empty() && ('$' == t0.value[0]))
  1754. {
  1755. return -1;
  1756. }
  1757. }
  1758. if (t1.type == lexer::token::e_symbol)
  1759. {
  1760. if (ignore_set_.end() != ignore_set_.find(t1.value))
  1761. {
  1762. return -1;
  1763. }
  1764. }
  1765. if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
  1766. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
  1767. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
  1768. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
  1769. else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
  1770. else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
  1771. else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
  1772. else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
  1773. else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
  1774. else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
  1775. else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
  1776. return (match) ? 1 : -1;
  1777. }
  1778. private:
  1779. std::set<std::string,details::ilesscompare> ignore_set_;
  1780. };
  1781. class operator_joiner : public token_joiner
  1782. {
  1783. public:
  1784. inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t)
  1785. {
  1786. //': =' --> ':='
  1787. if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
  1788. {
  1789. t.type = lexer::token::e_assign;
  1790. t.value = ":=";
  1791. t.position = t0.position;
  1792. return true;
  1793. }
  1794. //'> =' --> '>='
  1795. else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
  1796. {
  1797. t.type = lexer::token::e_gte;
  1798. t.value = ">=";
  1799. t.position = t0.position;
  1800. return true;
  1801. }
  1802. //'< =' --> '<='
  1803. else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
  1804. {
  1805. t.type = lexer::token::e_lte;
  1806. t.value = "<=";
  1807. t.position = t0.position;
  1808. return true;
  1809. }
  1810. //'= =' --> '=='
  1811. else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
  1812. {
  1813. t.type = lexer::token::e_eq;
  1814. t.value = "==";
  1815. t.position = t0.position;
  1816. return true;
  1817. }
  1818. //'! =' --> '!='
  1819. else if ((static_cast<char>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
  1820. {
  1821. t.type = lexer::token::e_ne;
  1822. t.value = "!=";
  1823. t.position = t0.position;
  1824. return true;
  1825. }
  1826. //'< >' --> '<>'
  1827. else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
  1828. {
  1829. t.type = lexer::token::e_ne;
  1830. t.value = "<>";
  1831. t.position = t0.position;
  1832. return true;
  1833. }
  1834. else
  1835. return false;
  1836. }
  1837. };
  1838. class bracket_checker : public lexer::token_scanner
  1839. {
  1840. public:
  1841. bracket_checker()
  1842. : token_scanner(1),
  1843. state_(true)
  1844. {}
  1845. bool result()
  1846. {
  1847. return state_ && stack_.empty();
  1848. }
  1849. lexer::token error_token()
  1850. {
  1851. return error_token_;
  1852. }
  1853. void reset()
  1854. {
  1855. //msvc doesn't support swap properly.
  1856. stack_ = std::stack<char>();
  1857. state_ = true;
  1858. error_token_.clear();
  1859. }
  1860. bool operator()(const lexer::token& t)
  1861. {
  1862. if (!t.value.empty() &&
  1863. (lexer::token::e_string != t.type) &&
  1864. (lexer::token::e_symbol != t.type) &&
  1865. exprtk::details::is_bracket(t.value[0])
  1866. )
  1867. {
  1868. char c = t.value[0];
  1869. if (t.type == lexer::token::e_lbracket) stack_.push(')');
  1870. else if (t.type == lexer::token::e_lcrlbracket) stack_.push('}');
  1871. else if (t.type == lexer::token::e_lsqrbracket) stack_.push(']');
  1872. else if (exprtk::details::is_right_bracket(c))
  1873. {
  1874. if (stack_.empty())
  1875. {
  1876. state_ = false;
  1877. error_token_ = t;
  1878. return false;
  1879. }
  1880. else if (c != stack_.top())
  1881. {
  1882. state_ = false;
  1883. error_token_ = t;
  1884. return false;
  1885. }
  1886. else
  1887. stack_.pop();
  1888. }
  1889. }
  1890. return true;
  1891. }
  1892. private:
  1893. bool state_;
  1894. std::stack<char> stack_;
  1895. lexer::token error_token_;
  1896. };
  1897. class numeric_checker : public lexer::token_scanner
  1898. {
  1899. public:
  1900. numeric_checker()
  1901. : token_scanner(1),
  1902. current_index_(0)
  1903. {}
  1904. bool result()
  1905. {
  1906. return error_list_.empty();
  1907. }
  1908. void reset()
  1909. {
  1910. error_list_.clear();
  1911. current_index_ = 0;
  1912. }
  1913. bool operator()(const lexer::token& t)
  1914. {
  1915. if (token::e_number == t.type)
  1916. {
  1917. double v;
  1918. if (!exprtk::details::string_to_real(t.value,v))
  1919. {
  1920. error_list_.push_back(current_index_);
  1921. }
  1922. }
  1923. ++current_index_;
  1924. return true;
  1925. }
  1926. std::size_t error_count() const
  1927. {
  1928. return error_list_.size();
  1929. }
  1930. std::size_t error_index(const std::size_t& i)
  1931. {
  1932. if (i < error_list_.size())
  1933. return error_list_[i];
  1934. else
  1935. return std::numeric_limits<std::size_t>::max();
  1936. }
  1937. private:
  1938. std::size_t current_index_;
  1939. std::deque<std::size_t> error_list_;
  1940. };
  1941. class symbol_replacer : public lexer::token_modifier
  1942. {
  1943. private:
  1944. typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
  1945. public:
  1946. bool add_replace(const std::string& target_symbol,
  1947. const std::string& replace_symbol,
  1948. const lexer::token::token_type token_type = lexer::token::e_symbol)
  1949. {
  1950. replace_map_t::iterator itr = replace_map_.find(target_symbol);
  1951. if (replace_map_.end() != itr)
  1952. {
  1953. return false;
  1954. }
  1955. replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
  1956. return true;
  1957. }
  1958. void clear()
  1959. {
  1960. replace_map_.clear();
  1961. }
  1962. private:
  1963. bool modify(lexer::token& t)
  1964. {
  1965. if (lexer::token::e_symbol == t.type)
  1966. {
  1967. if (replace_map_.empty())
  1968. return false;
  1969. replace_map_t::iterator itr = replace_map_.find(t.value);
  1970. if (replace_map_.end() != itr)
  1971. {
  1972. t.value = itr->second.first;
  1973. t.type = itr->second.second;
  1974. return true;
  1975. }
  1976. }
  1977. return false;
  1978. }
  1979. replace_map_t replace_map_;
  1980. };
  1981. class sequence_validator : public lexer::token_scanner
  1982. {
  1983. private:
  1984. typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
  1985. typedef std::set<token_pair_t> set_t;
  1986. public:
  1987. sequence_validator()
  1988. : lexer::token_scanner(2)
  1989. {
  1990. add_invalid(lexer::token::e_number,lexer::token::e_number);
  1991. add_invalid(lexer::token::e_string,lexer::token::e_string);
  1992. add_invalid(lexer::token::e_number,lexer::token::e_string);
  1993. add_invalid(lexer::token::e_string,lexer::token::e_number);
  1994. add_invalid(lexer::token::e_number,lexer::token::e_colon);
  1995. add_invalid(lexer::token::e_symbol,lexer::token::e_colon);
  1996. add_invalid(lexer::token::e_string,lexer::token::e_colon);
  1997. add_invalid(lexer::token::e_colon,lexer::token::e_number);
  1998. add_invalid(lexer::token::e_colon,lexer::token::e_symbol);
  1999. add_invalid(lexer::token::e_colon,lexer::token::e_string);
  2000. add_invalid_set1(lexer::token::e_assign);
  2001. add_invalid_set1(lexer::token::e_shr);
  2002. add_invalid_set1(lexer::token::e_shl);
  2003. add_invalid_set1(lexer::token::e_lte);
  2004. add_invalid_set1(lexer::token::e_ne);
  2005. add_invalid_set1(lexer::token::e_gte);
  2006. add_invalid_set1(lexer::token::e_lt);
  2007. add_invalid_set1(lexer::token::e_gt);
  2008. add_invalid_set1(lexer::token::e_eq);
  2009. add_invalid_set1(lexer::token::e_comma);
  2010. add_invalid_set1(lexer::token::e_add);
  2011. add_invalid_set1(lexer::token::e_sub);
  2012. add_invalid_set1(lexer::token::e_div);
  2013. add_invalid_set1(lexer::token::e_mul);
  2014. add_invalid_set1(lexer::token::e_mod);
  2015. add_invalid_set1(lexer::token::e_pow);
  2016. add_invalid_set1(lexer::token::e_colon);
  2017. }
  2018. bool result()
  2019. {
  2020. return error_list_.empty();
  2021. }
  2022. bool operator()(const lexer::token& t0, const lexer::token& t1)
  2023. {
  2024. set_t::value_type p = std::make_pair(t0.type,t1.type);
  2025. if (invalid_bracket_check(t0.type,t1.type))
  2026. {
  2027. invalid_bracket_check(t0.type,t1.type);
  2028. error_list_.push_back(std::make_pair(t0,t1));
  2029. }
  2030. else if (invalid_comb_.find(p) != invalid_comb_.end())
  2031. error_list_.push_back(std::make_pair(t0,t1));
  2032. return true;
  2033. }
  2034. std::size_t error_count()
  2035. {
  2036. return error_list_.size();
  2037. }
  2038. std::pair<lexer::token,lexer::token> error(const std::size_t index)
  2039. {
  2040. if (index < error_list_.size())
  2041. {
  2042. return error_list_[index];
  2043. }
  2044. else
  2045. {
  2046. static const lexer::token error_token;
  2047. return std::make_pair(error_token,error_token);
  2048. }
  2049. }
  2050. void clear_errors()
  2051. {
  2052. error_list_.clear();
  2053. }
  2054. private:
  2055. void add_invalid(lexer::token::token_type base, lexer::token::token_type t)
  2056. {
  2057. invalid_comb_.insert(std::make_pair(base,t));
  2058. }
  2059. void add_invalid_set1(lexer::token::token_type t)
  2060. {
  2061. add_invalid(t,lexer::token::e_assign);
  2062. add_invalid(t,lexer::token::e_shr);
  2063. add_invalid(t,lexer::token::e_shl);
  2064. add_invalid(t,lexer::token::e_lte);
  2065. add_invalid(t,lexer::token::e_ne);
  2066. add_invalid(t,lexer::token::e_gte);
  2067. add_invalid(t,lexer::token::e_lt);
  2068. add_invalid(t,lexer::token::e_gt);
  2069. add_invalid(t,lexer::token::e_eq);
  2070. add_invalid(t,lexer::token::e_comma);
  2071. add_invalid(t,lexer::token::e_div);
  2072. add_invalid(t,lexer::token::e_mul);
  2073. add_invalid(t,lexer::token::e_mod);
  2074. add_invalid(t,lexer::token::e_pow);
  2075. add_invalid(t,lexer::token::e_colon);
  2076. }
  2077. bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
  2078. {
  2079. if (details::is_right_bracket(static_cast<char>(base)))
  2080. {
  2081. if (details::is_left_bracket(static_cast<char>(t)))
  2082. return true;
  2083. else
  2084. {
  2085. switch (t)
  2086. {
  2087. case lexer::token::e_string : return true;
  2088. case lexer::token::e_assign : return true;
  2089. case lexer::token::e_colon : return true;
  2090. default : return false;
  2091. }
  2092. }
  2093. }
  2094. else if (details::is_left_bracket(static_cast<char>(base)))
  2095. {
  2096. if (details::is_right_bracket(static_cast<char>(t)))
  2097. return false;
  2098. else if (details::is_left_bracket(static_cast<char>(t)))
  2099. return false;
  2100. else
  2101. {
  2102. switch (t)
  2103. {
  2104. case lexer::token::e_number : return false;
  2105. case lexer::token::e_symbol : return false;
  2106. case lexer::token::e_string : return false;
  2107. case lexer::token::e_add : return false;
  2108. case lexer::token::e_sub : return false;
  2109. default : return true;
  2110. }
  2111. }
  2112. }
  2113. else if (details::is_right_bracket(static_cast<char>(t)))
  2114. {
  2115. switch (base)
  2116. {
  2117. case lexer::token::e_number : return false;
  2118. case lexer::token::e_symbol : return false;
  2119. case lexer::token::e_string : return false;
  2120. default : return true;
  2121. }
  2122. }
  2123. else if (details::is_left_bracket(static_cast<char>(t)))
  2124. {
  2125. switch (base)
  2126. {
  2127. case lexer::token::e_string : return true;
  2128. case lexer::token::e_rbracket : return true;
  2129. case lexer::token::e_rsqrbracket : return true;
  2130. case lexer::token::e_rcrlbracket : return true;
  2131. case lexer::token::e_colon : return true;
  2132. default : return false;
  2133. }
  2134. }
  2135. return false;
  2136. }
  2137. set_t invalid_comb_;
  2138. std::deque<std::pair<lexer::token,lexer::token> > error_list_;
  2139. };
  2140. struct helper_assembly
  2141. {
  2142. inline bool register_scanner(lexer::token_scanner* scanner)
  2143. {
  2144. if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
  2145. token_scanner_list.end(),
  2146. scanner))
  2147. {
  2148. return false;
  2149. }
  2150. token_scanner_list.push_back(scanner);
  2151. return true;
  2152. }
  2153. inline bool register_modifier(lexer::token_modifier* modifier)
  2154. {
  2155. if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
  2156. token_modifier_list.end(),
  2157. modifier))
  2158. {
  2159. return false;
  2160. }
  2161. token_modifier_list.push_back(modifier);
  2162. return true;
  2163. }
  2164. inline bool register_joiner(lexer::token_joiner* joiner)
  2165. {
  2166. if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
  2167. token_joiner_list.end(),
  2168. joiner))
  2169. {
  2170. return false;
  2171. }
  2172. token_joiner_list.push_back(joiner);
  2173. return true;
  2174. }
  2175. inline bool register_inserter(lexer::token_inserter* inserter)
  2176. {
  2177. if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
  2178. token_inserter_list.end(),
  2179. inserter))
  2180. {
  2181. return false;
  2182. }
  2183. token_inserter_list.push_back(inserter);
  2184. return true;
  2185. }
  2186. inline bool run_modifiers(lexer::generator& g)
  2187. {
  2188. error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
  2189. bool result = true;
  2190. for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
  2191. {
  2192. lexer::token_modifier& modifier = (*token_modifier_list[i]);
  2193. modifier.reset();
  2194. modifier.process(g);
  2195. if (!modifier.result())
  2196. {
  2197. error_token_modifier = token_modifier_list[i];
  2198. return false;
  2199. }
  2200. }
  2201. return result;
  2202. }
  2203. inline bool run_joiners(lexer::generator& g)
  2204. {
  2205. error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
  2206. bool result = true;
  2207. for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
  2208. {
  2209. lexer::token_joiner& joiner = (*token_joiner_list[i]);
  2210. joiner.reset();
  2211. joiner.process(g);
  2212. if (!joiner.result())
  2213. {
  2214. error_token_joiner = token_joiner_list[i];
  2215. return false;
  2216. }
  2217. }
  2218. return result;
  2219. }
  2220. inline bool run_inserters(lexer::generator& g)
  2221. {
  2222. error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
  2223. bool result = true;
  2224. for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
  2225. {
  2226. lexer::token_inserter& inserter = (*token_inserter_list[i]);
  2227. inserter.reset();
  2228. inserter.process(g);
  2229. if (!inserter.result())
  2230. {
  2231. error_token_inserter = token_inserter_list[i];
  2232. return false;
  2233. }
  2234. }
  2235. return result;
  2236. }
  2237. inline bool run_scanners(lexer::generator& g)
  2238. {
  2239. error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
  2240. bool result = true;
  2241. for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
  2242. {
  2243. lexer::token_scanner& scanner = (*token_scanner_list[i]);
  2244. scanner.reset();
  2245. scanner.process(g);
  2246. if (!scanner.result())
  2247. {
  2248. error_token_scanner = token_scanner_list[i];
  2249. return false;
  2250. }
  2251. }
  2252. return result;
  2253. }
  2254. std::deque<lexer::token_scanner*> token_scanner_list;
  2255. std::deque<lexer::token_modifier*> token_modifier_list;
  2256. std::deque<lexer::token_joiner*> token_joiner_list;
  2257. std::deque<lexer::token_inserter*> token_inserter_list;
  2258. lexer::token_scanner* error_token_scanner;
  2259. lexer::token_modifier* error_token_modifier;
  2260. lexer::token_joiner* error_token_joiner;
  2261. lexer::token_inserter* error_token_inserter;
  2262. };
  2263. }
  2264. }
  2265. namespace details
  2266. {
  2267. enum operator_type
  2268. {
  2269. e_default,
  2270. e_add ,
  2271. e_sub ,
  2272. e_mul ,
  2273. e_div ,
  2274. e_mod ,
  2275. e_pow ,
  2276. e_atan2 ,
  2277. e_min ,
  2278. e_max ,
  2279. e_avg ,
  2280. e_sum ,
  2281. e_prod ,
  2282. e_lt ,
  2283. e_lte ,
  2284. e_eq ,
  2285. e_equal ,
  2286. e_ne ,
  2287. e_nequal ,
  2288. e_gte ,
  2289. e_gt ,
  2290. e_and ,
  2291. e_nand ,
  2292. e_or ,
  2293. e_nor ,
  2294. e_xor ,
  2295. e_shr ,
  2296. e_shl ,
  2297. e_abs ,
  2298. e_acos ,
  2299. e_asin ,
  2300. e_atan ,
  2301. e_ceil ,
  2302. e_cos ,
  2303. e_cosh ,
  2304. e_exp ,
  2305. e_floor ,
  2306. e_log ,
  2307. e_log10 ,
  2308. e_logn ,
  2309. e_neg ,
  2310. e_pos ,
  2311. e_round ,
  2312. e_roundn ,
  2313. e_root ,
  2314. e_sqrt ,
  2315. e_sin ,
  2316. e_sinh ,
  2317. e_sec ,
  2318. e_csc ,
  2319. e_tan ,
  2320. e_tanh ,
  2321. e_cot ,
  2322. e_clamp ,
  2323. e_inrange,
  2324. e_sgn ,
  2325. e_r2d ,
  2326. e_d2r ,
  2327. e_d2g ,
  2328. e_g2d ,
  2329. e_hyp ,
  2330. e_notl ,
  2331. e_erf ,
  2332. e_erfc ,
  2333. e_frac ,
  2334. e_trunc ,
  2335. e_assign ,
  2336. e_in ,
  2337. e_like ,
  2338. e_ilike ,
  2339. // Do not add new functions/operators after this point.
  2340. e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
  2341. e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
  2342. e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
  2343. e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
  2344. e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
  2345. e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
  2346. e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
  2347. e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
  2348. e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
  2349. e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
  2350. e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
  2351. e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
  2352. e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
  2353. e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
  2354. e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
  2355. e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
  2356. e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
  2357. e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
  2358. e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
  2359. e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
  2360. e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082
  2361. };
  2362. struct base_operation_t
  2363. {
  2364. base_operation_t(const operator_type t, const unsigned int& np)
  2365. : type(t),
  2366. num_params(np)
  2367. {}
  2368. operator_type type;
  2369. unsigned int num_params;
  2370. };
  2371. namespace numeric
  2372. {
  2373. namespace details
  2374. {
  2375. template <typename T>
  2376. inline T process_impl(const operator_type operation, const T& arg, real_type_tag)
  2377. {
  2378. switch (operation)
  2379. {
  2380. case e_abs : return numeric::abs (arg);
  2381. case e_acos : return numeric::acos (arg);
  2382. case e_asin : return numeric::asin (arg);
  2383. case e_atan : return numeric::atan (arg);
  2384. case e_ceil : return numeric::ceil (arg);
  2385. case e_cos : return numeric::cos (arg);
  2386. case e_cosh : return numeric::cosh (arg);
  2387. case e_exp : return numeric::exp (arg);
  2388. case e_floor : return numeric::floor(arg);
  2389. case e_log : return numeric::log (arg);
  2390. case e_log10 : return numeric::log10(arg);
  2391. case e_neg : return numeric::neg (arg);
  2392. case e_pos : return numeric::pos (arg);
  2393. case e_round : return numeric::round(arg);
  2394. case e_sin : return numeric::sin (arg);
  2395. case e_sinh : return numeric::sinh (arg);
  2396. case e_sqrt : return numeric::sqrt (arg);
  2397. case e_tan : return numeric::tan (arg);
  2398. case e_tanh : return numeric::tanh (arg);
  2399. case e_cot : return numeric::cot (arg);
  2400. case e_sec : return numeric::sec (arg);
  2401. case e_csc : return numeric::csc (arg);
  2402. case e_r2d : return numeric::r2d (arg);
  2403. case e_d2r : return numeric::d2r (arg);
  2404. case e_d2g : return numeric::d2g (arg);
  2405. case e_g2d : return numeric::g2d (arg);
  2406. case e_notl : return numeric::notl (arg);
  2407. case e_sgn : return numeric::sgn (arg);
  2408. case e_erf : return numeric::erf (arg);
  2409. case e_erfc : return numeric::erfc (arg);
  2410. case e_frac : return numeric::frac (arg);
  2411. case e_trunc : return numeric::trunc(arg);
  2412. default : return std::numeric_limits<T>::quiet_NaN();
  2413. }
  2414. }
  2415. template <typename T>
  2416. inline T process_impl(const operator_type operation, const T& arg, int_type_tag)
  2417. {
  2418. switch (operation)
  2419. {
  2420. case e_abs : return numeric::abs (arg);
  2421. case e_exp : return numeric::exp (arg);
  2422. case e_log : return numeric::log (arg);
  2423. case e_log10 : return numeric::log10(arg);
  2424. case e_neg : return numeric::neg (arg);
  2425. case e_pos : return numeric::pos (arg);
  2426. case e_sqrt : return numeric::sqrt (arg);
  2427. case e_notl : return numeric::notl (arg);
  2428. case e_sgn : return numeric::sgn (arg);
  2429. default : return std::numeric_limits<T>::quiet_NaN();
  2430. }
  2431. }
  2432. template <typename T>
  2433. inline T process_impl(const operator_type operation, const T& arg0, const T& arg1, real_type_tag)
  2434. {
  2435. switch (operation)
  2436. {
  2437. case e_add : return (arg0 + arg1);
  2438. case e_sub : return (arg0 - arg1);
  2439. case e_mul : return (arg0 * arg1);
  2440. case e_div : return (arg0 / arg1);
  2441. case e_mod : return modulus<T>(arg0,arg1);
  2442. case e_pow : return pow<T>(arg0,arg1);
  2443. case e_atan2 : return atan2<T>(arg0,arg1);
  2444. case e_min : return std::min<T>(arg0,arg1);
  2445. case e_max : return std::max<T>(arg0,arg1);
  2446. case e_logn : return logn<T>(arg0,arg1);
  2447. case e_lt : return (arg0 < arg1) ? T(1) : T(0);
  2448. case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
  2449. case e_eq : return (arg0 == arg1) ? T(1) : T(0);
  2450. case e_ne : return (arg0 != arg1) ? T(1) : T(0);
  2451. case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
  2452. case e_gt : return (arg0 > arg1) ? T(1) : T(0);
  2453. case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
  2454. case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
  2455. case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
  2456. case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
  2457. case e_xor : return (arg0 != arg1) ? T(1) : T(0);
  2458. case e_root : return root<T>(arg0,arg1);
  2459. case e_roundn : return roundn<T>(arg0,arg1);
  2460. case e_equal : return equal<T>(arg0,arg1);
  2461. case e_nequal : return nequal<T>(arg0,arg1);
  2462. case e_hyp : return hyp<T>(arg0,arg1);
  2463. case e_avg : return (arg0 + arg1)/T(2);
  2464. case e_sum : return (arg0 + arg1);
  2465. case e_prod : return (arg0 * arg1);
  2466. case e_shr : return shr<T>(arg0,arg1);
  2467. case e_shl : return shl<T>(arg0,arg1);
  2468. default : return std::numeric_limits<T>::quiet_NaN();
  2469. }
  2470. }
  2471. template <typename T>
  2472. inline T process_impl(const operator_type operation, const T& arg0, const T& arg1, int_type_tag)
  2473. {
  2474. switch (operation)
  2475. {
  2476. case e_add : return (arg0 + arg1);
  2477. case e_sub : return (arg0 - arg1);
  2478. case e_mul : return (arg0 * arg1);
  2479. case e_div : return (arg0 / arg1);
  2480. case e_mod : return arg0 % arg1;
  2481. case e_pow : return pow<T>(arg0,arg1);
  2482. case e_min : return std::min<T>(arg0,arg1);
  2483. case e_max : return std::max<T>(arg0,arg1);
  2484. case e_logn : return logn<T>(arg0,arg1);
  2485. case e_lt : return (arg0 < arg1) ? T(1) : T(0);
  2486. case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
  2487. case e_eq : return (arg0 == arg1) ? T(1) : T(0);
  2488. case e_ne : return (arg0 != arg1) ? T(1) : T(0);
  2489. case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
  2490. case e_gt : return (arg0 > arg1) ? T(1) : T(0);
  2491. case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
  2492. case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
  2493. case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
  2494. case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
  2495. case e_xor : return arg0 ^ arg1;
  2496. case e_root : return root<T>(arg0,arg1);
  2497. case e_equal : return arg0 == arg1;
  2498. case e_nequal : return arg0 != arg1;
  2499. case e_hyp : return hyp<T>(arg0,arg1);
  2500. case e_avg : return (arg0 + arg1) >> 1;
  2501. case e_sum : return (arg0 + arg1);
  2502. case e_prod : return (arg0 * arg1);
  2503. case e_shr : return arg0 >> arg1;
  2504. case e_shl : return arg0 << arg1;
  2505. default : return std::numeric_limits<T>::quiet_NaN();
  2506. }
  2507. }
  2508. }
  2509. template <typename T>
  2510. inline T process(const operator_type operation, const T& arg)
  2511. {
  2512. typename details::number_type<T>::type num_type;
  2513. return details::process_impl<T>(operation,arg,num_type);
  2514. }
  2515. template <typename T>
  2516. inline T process(const operator_type operation, const T& arg0, const T& arg1)
  2517. {
  2518. typename details::number_type<T>::type num_type;
  2519. return details::process_impl<T>(operation,arg0,arg1,num_type);
  2520. }
  2521. }
  2522. template <typename T>
  2523. class expression_node
  2524. {
  2525. public:
  2526. enum node_type
  2527. {
  2528. e_none ,
  2529. e_constant ,
  2530. e_unary ,
  2531. e_binary ,
  2532. e_trinary ,
  2533. e_quaternary ,
  2534. e_quinary ,
  2535. e_senary ,
  2536. e_conditional ,
  2537. e_while ,
  2538. e_variable ,
  2539. e_stringvar ,
  2540. e_stringconst ,
  2541. e_function ,
  2542. e_add ,
  2543. e_sub ,
  2544. e_mul ,
  2545. e_div ,
  2546. e_mod ,
  2547. e_pow ,
  2548. e_lt ,
  2549. e_lte ,
  2550. e_gt ,
  2551. e_gte ,
  2552. e_eq ,
  2553. e_ne ,
  2554. e_and ,
  2555. e_nand ,
  2556. e_or ,
  2557. e_nor ,
  2558. e_xor ,
  2559. e_in ,
  2560. e_like ,
  2561. e_ilike ,
  2562. e_inranges ,
  2563. e_ipow ,
  2564. e_ipowinv ,
  2565. e_vov ,
  2566. e_abs ,
  2567. e_acos ,
  2568. e_asin ,
  2569. e_atan ,
  2570. e_ceil ,
  2571. e_cos ,
  2572. e_cosh ,
  2573. e_exp ,
  2574. e_floor ,
  2575. e_log ,
  2576. e_log10 ,
  2577. e_neg ,
  2578. e_pos ,
  2579. e_round ,
  2580. e_sin ,
  2581. e_sinh ,
  2582. e_sqrt ,
  2583. e_tan ,
  2584. e_tanh ,
  2585. e_cot ,
  2586. e_sec ,
  2587. e_csc ,
  2588. e_r2d ,
  2589. e_d2r ,
  2590. e_d2g ,
  2591. e_g2d ,
  2592. e_notl ,
  2593. e_sgn ,
  2594. e_erf ,
  2595. e_erfc ,
  2596. e_frac ,
  2597. e_trunc
  2598. };
  2599. typedef T value_type;
  2600. typedef expression_node<T>* expression_ptr;
  2601. virtual ~expression_node()
  2602. {}
  2603. virtual inline T value() const
  2604. {
  2605. return std::numeric_limits<T>::quiet_NaN();
  2606. }
  2607. virtual inline bool result() const
  2608. {
  2609. return (T(1.0) == value());
  2610. }
  2611. virtual inline expression_node<T>* branch(const std::size_t& index = 0) const
  2612. {
  2613. return reinterpret_cast<expression_ptr>(index * 0);
  2614. }
  2615. virtual inline node_type type() const
  2616. {
  2617. return e_none;
  2618. }
  2619. };
  2620. inline bool is_true(const double v)
  2621. {
  2622. return (0.0 != v);
  2623. }
  2624. inline bool is_true(const float v)
  2625. {
  2626. return (0.0f != v);
  2627. }
  2628. template <typename T>
  2629. inline bool is_true(const expression_node<T>* node)
  2630. {
  2631. return (T(0) != node->value());
  2632. }
  2633. template <typename T>
  2634. inline bool is_false(const expression_node<T>* node)
  2635. {
  2636. return (T(0) == node->value());
  2637. }
  2638. template <typename T>
  2639. inline bool is_unary_node(const expression_node<T>* node)
  2640. {
  2641. return (details::expression_node<T>::e_unary == node->type());
  2642. }
  2643. template <typename T>
  2644. inline bool is_binary_node(const expression_node<T>* node)
  2645. {
  2646. return (details::expression_node<T>::e_binary == node->type());
  2647. }
  2648. template <typename T>
  2649. inline bool is_variable_node(const expression_node<T>* node)
  2650. {
  2651. return (details::expression_node<T>::e_variable == node->type());
  2652. }
  2653. template <typename T>
  2654. inline bool is_constant_node(const expression_node<T>* node)
  2655. {
  2656. return (details::expression_node<T>::e_constant == node->type());
  2657. }
  2658. template <typename T>
  2659. inline bool is_function(const expression_node<T>* node)
  2660. {
  2661. return (details::expression_node<T>::e_function == node->type());
  2662. }
  2663. template <typename T>
  2664. inline bool branch_deletable(expression_node<T>* node)
  2665. {
  2666. return !is_variable_node(node);
  2667. }
  2668. template <typename T>
  2669. class null_node : public expression_node<T>
  2670. {
  2671. public:
  2672. inline T value() const
  2673. {
  2674. return std::numeric_limits<T>::quiet_NaN();
  2675. }
  2676. inline typename expression_node<T>::node_type type() const
  2677. {
  2678. return expression_node<T>::e_nul;
  2679. }
  2680. };
  2681. template <typename T>
  2682. class literal_node : public expression_node<T>
  2683. {
  2684. public:
  2685. explicit literal_node(const T& value)
  2686. : value_(value)
  2687. {}
  2688. inline T value() const
  2689. {
  2690. return value_;
  2691. }
  2692. inline typename expression_node<T>::node_type type() const
  2693. {
  2694. return expression_node<T>::e_constant;
  2695. }
  2696. inline expression_node<T>* branch(const std::size_t& index = 0) const
  2697. {
  2698. return reinterpret_cast<expression_node<T>*>(index * 0);
  2699. }
  2700. private:
  2701. T value_;
  2702. };
  2703. template <typename T>
  2704. class string_literal_node : public expression_node<T>
  2705. {
  2706. public:
  2707. explicit string_literal_node(const std::string& value)
  2708. : value_(value)
  2709. {}
  2710. inline T value() const
  2711. {
  2712. return std::numeric_limits<T>::quiet_NaN();
  2713. }
  2714. inline typename expression_node<T>::node_type type() const
  2715. {
  2716. return expression_node<T>::e_stringconst;
  2717. }
  2718. inline expression_node<T>* branch(const std::size_t& index = 0) const
  2719. {
  2720. return reinterpret_cast<expression_node<T>*>(index * 0);
  2721. }
  2722. inline std::string str()
  2723. {
  2724. return value_;
  2725. }
  2726. private:
  2727. string_literal_node(const string_literal_node<T>&);
  2728. string_literal_node<T>& operator=(const string_literal_node<T>&);
  2729. const std::string value_;
  2730. };
  2731. template <typename T>
  2732. class unary_node : public expression_node<T>
  2733. {
  2734. public:
  2735. typedef expression_node<T>* expression_ptr;
  2736. unary_node(const operator_type& operation,
  2737. expression_ptr branch)
  2738. : operation_(operation),
  2739. branch_(branch),
  2740. branch_deletable_(branch_deletable(branch_))
  2741. {}
  2742. ~unary_node()
  2743. {
  2744. if (branch_ && branch_deletable_)
  2745. {
  2746. delete branch_;
  2747. branch_ = 0;
  2748. }
  2749. }
  2750. inline T value() const
  2751. {
  2752. const T arg = branch_->value();
  2753. return numeric::process<T>(operation_,arg);
  2754. }
  2755. inline typename expression_node<T>::node_type type() const
  2756. {
  2757. return expression_node<T>::e_unary;
  2758. }
  2759. inline operator_type operation() const
  2760. {
  2761. return operation_;
  2762. }
  2763. inline expression_node<T>* branch(const std::size_t& index = 0) const
  2764. {
  2765. if (0 == index)
  2766. return branch_;
  2767. else
  2768. return reinterpret_cast<expression_ptr>(0);
  2769. }
  2770. private:
  2771. operator_type operation_;
  2772. expression_ptr branch_;
  2773. bool branch_deletable_;
  2774. };
  2775. template <typename T, std::size_t D, bool B>
  2776. struct construct_branch_pair
  2777. {
  2778. template <std::size_t N>
  2779. static inline void process(std::pair<expression_node<T>*,bool> (&)[N], expression_node<T>*)
  2780. {}
  2781. };
  2782. template <typename T, std::size_t D>
  2783. struct construct_branch_pair<T,D,true>
  2784. {
  2785. template <std::size_t N>
  2786. static inline void process(std::pair<expression_node<T>*,bool> (&branch)[N], expression_node<T>* b)
  2787. {
  2788. if (b)
  2789. {
  2790. branch[D] = std::make_pair(b,branch_deletable(b));
  2791. }
  2792. }
  2793. };
  2794. template <std::size_t N, typename T>
  2795. inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
  2796. expression_node<T>* b0,
  2797. expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
  2798. expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
  2799. expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
  2800. expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
  2801. expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
  2802. expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
  2803. expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
  2804. expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
  2805. expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
  2806. {
  2807. construct_branch_pair<T,0,(N > 0)>::process(branch,b0);
  2808. construct_branch_pair<T,1,(N > 1)>::process(branch,b1);
  2809. construct_branch_pair<T,2,(N > 2)>::process(branch,b2);
  2810. construct_branch_pair<T,3,(N > 3)>::process(branch,b3);
  2811. construct_branch_pair<T,4,(N > 4)>::process(branch,b4);
  2812. construct_branch_pair<T,5,(N > 5)>::process(branch,b5);
  2813. construct_branch_pair<T,6,(N > 6)>::process(branch,b6);
  2814. construct_branch_pair<T,7,(N > 7)>::process(branch,b7);
  2815. construct_branch_pair<T,8,(N > 8)>::process(branch,b8);
  2816. construct_branch_pair<T,9,(N > 9)>::process(branch,b9);
  2817. }
  2818. template <typename T, std::size_t N>
  2819. struct cleanup_branches
  2820. {
  2821. static inline void execute(std::pair<expression_node<T>*,bool> (&branch)[N])
  2822. {
  2823. for (std::size_t i = 0; i < N; ++i)
  2824. {
  2825. if (branch[i].first && branch[i].second)
  2826. {
  2827. delete branch[i].first;
  2828. branch[i].first = 0;
  2829. }
  2830. }
  2831. }
  2832. };
  2833. template <typename T>
  2834. class binary_node : public expression_node<T>
  2835. {
  2836. public:
  2837. typedef expression_node<T>* expression_ptr;
  2838. typedef std::pair<expression_ptr,bool> branch_t;
  2839. binary_node(const operator_type& operation,
  2840. expression_ptr branch0,
  2841. expression_ptr branch1)
  2842. : operation_(operation)
  2843. {
  2844. init_branches<2>(branch_,branch0,branch1);
  2845. }
  2846. ~binary_node()
  2847. {
  2848. cleanup_branches<T,2>::execute(branch_);
  2849. }
  2850. inline T value() const
  2851. {
  2852. const T arg0 = branch_[0].first->value();
  2853. const T arg1 = branch_[1].first->value();
  2854. return numeric::process<T>(operation_,arg0,arg1);
  2855. }
  2856. inline typename expression_node<T>::node_type type() const
  2857. {
  2858. return expression_node<T>::e_binary;
  2859. }
  2860. inline operator_type operation() const
  2861. {
  2862. return operation_;
  2863. }
  2864. inline expression_node<T>* branch(const std::size_t& index = 0) const
  2865. {
  2866. if (0 == index)
  2867. return branch_[0].first;
  2868. else if (1 == index)
  2869. return branch_[1].first;
  2870. else
  2871. return reinterpret_cast<expression_ptr>(0);
  2872. }
  2873. protected:
  2874. operator_type operation_;
  2875. branch_t branch_[2];
  2876. };
  2877. template <typename T>
  2878. class trinary_node : public expression_node<T>
  2879. {
  2880. public:
  2881. typedef expression_node<T>* expression_ptr;
  2882. typedef std::pair<expression_ptr,bool> branch_t;
  2883. trinary_node(const operator_type& operation,
  2884. expression_ptr branch0,
  2885. expression_ptr branch1,
  2886. expression_ptr branch2)
  2887. : operation_(operation)
  2888. {
  2889. init_branches<3>(branch_,branch0,branch1,branch2);
  2890. }
  2891. ~trinary_node()
  2892. {
  2893. cleanup_branches<T,3>::execute(branch_);
  2894. }
  2895. inline T value() const
  2896. {
  2897. const T arg0 = branch_[0].first->value();
  2898. const T arg1 = branch_[1].first->value();
  2899. const T arg2 = branch_[2].first->value();
  2900. switch (operation_)
  2901. {
  2902. case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
  2903. case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
  2904. case e_min : return std::min<T>(std::min<T>(arg0,arg1),arg2);
  2905. case e_max : return std::max<T>(std::max<T>(arg0,arg1),arg2);
  2906. case e_avg : return (arg0 + arg1 + arg2) / T(3.0);
  2907. case e_sum : return (arg0 + arg1 + arg2);
  2908. case e_prod : return (arg0 * arg1 * arg2);
  2909. default : return std::numeric_limits<T>::quiet_NaN();
  2910. }
  2911. }
  2912. inline typename expression_node<T>::node_type type() const
  2913. {
  2914. return expression_node<T>::e_trinary;
  2915. }
  2916. protected:
  2917. operator_type operation_;
  2918. branch_t branch_[3];
  2919. };
  2920. template <typename T>
  2921. class quaternary_node : public expression_node<T>
  2922. {
  2923. public:
  2924. typedef expression_node<T>* expression_ptr;
  2925. typedef std::pair<expression_ptr,bool> branch_t;
  2926. quaternary_node(const operator_type& operation,
  2927. expression_ptr branch0,
  2928. expression_ptr branch1,
  2929. expression_ptr branch2,
  2930. expression_ptr branch3)
  2931. : operation_(operation)
  2932. {
  2933. init_branches<4>(branch_,branch0,branch1,branch2,branch3);
  2934. }
  2935. ~quaternary_node()
  2936. {
  2937. cleanup_branches<T,4>::execute(branch_);
  2938. }
  2939. inline T value() const
  2940. {
  2941. const T arg0 = branch_[0].first->value();
  2942. const T arg1 = branch_[1].first->value();
  2943. const T arg2 = branch_[2].first->value();
  2944. const T arg3 = branch_[3].first->value();
  2945. switch (operation_)
  2946. {
  2947. case e_min : return std::min<T>(std::min<T>(arg0,arg1),std::min<T>(arg2,arg3));
  2948. case e_max : return std::max<T>(std::max<T>(arg0,arg1),std::max<T>(arg2,arg3));
  2949. case e_avg : return (arg0 + arg1 + arg2 + arg3) / T(4.0);
  2950. case e_sum : return (arg0 + arg1 + arg2 + arg3);
  2951. case e_prod : return (arg0 * arg1 * arg2 * arg3);
  2952. default : return std::numeric_limits<T>::quiet_NaN();
  2953. }
  2954. }
  2955. inline typename expression_node<T>::node_type type() const
  2956. {
  2957. return expression_node<T>::e_quaternary;
  2958. }
  2959. protected:
  2960. operator_type operation_;
  2961. branch_t branch_[4];
  2962. };
  2963. template <typename T>
  2964. class quinary_node : public expression_node<T>
  2965. {
  2966. public:
  2967. typedef expression_node<T>* expression_ptr;
  2968. typedef std::pair<expression_ptr,bool> branch_t;
  2969. quinary_node(const operator_type& operation,
  2970. expression_ptr branch0,
  2971. expression_ptr branch1,
  2972. expression_ptr branch2,
  2973. expression_ptr branch3,
  2974. expression_ptr branch4)
  2975. : operation_(operation)
  2976. {
  2977. init_branches<5>(branch_,branch0,branch1,branch2,branch3,branch4);
  2978. }
  2979. ~quinary_node()
  2980. {
  2981. cleanup_branches<T,5>::execute(branch_);
  2982. }
  2983. inline T value() const
  2984. {
  2985. const T arg0 = branch_[0].first->value();
  2986. const T arg1 = branch_[1].first->value();
  2987. const T arg2 = branch_[2].first->value();
  2988. const T arg3 = branch_[3].first->value();
  2989. const T arg4 = branch_[4].first->value();
  2990. switch (operation_)
  2991. {
  2992. case e_min : return std::min<T>(std::min<T>(std::min<T>(arg0,arg1),std::min<T>(arg2,arg3)),arg4);
  2993. case e_max : return std::max<T>(std::max<T>(std::max<T>(arg0,arg1),std::max<T>(arg2,arg3)),arg4);
  2994. case e_avg : return (arg0 + arg1 + arg2 + arg3 + arg4) / T(5.0);
  2995. case e_sum : return (arg0 + arg1 + arg2 + arg3 + arg4);
  2996. case e_prod : return (arg0 * arg1 * arg2 * arg3 * arg4);
  2997. default : return std::numeric_limits<T>::quiet_NaN();
  2998. }
  2999. }
  3000. inline typename expression_node<T>::node_type type() const
  3001. {
  3002. return expression_node<T>::e_quinary;
  3003. }
  3004. private:
  3005. operator_type operation_;
  3006. branch_t branch_[5];
  3007. };
  3008. template <typename T>
  3009. class senary_node : public expression_node<T>
  3010. {
  3011. public:
  3012. typedef expression_node<T>* expression_ptr;
  3013. typedef std::pair<expression_ptr,bool> branch_t;
  3014. senary_node(const operator_type& operation,
  3015. expression_ptr branch0,
  3016. expression_ptr branch1,
  3017. expression_ptr branch2,
  3018. expression_ptr branch3,
  3019. expression_ptr branch4,
  3020. expression_ptr branch5)
  3021. : operation_(operation)
  3022. {
  3023. init_branches<6>(branch_,branch0,branch1,branch2,branch3,branch4,branch5);
  3024. }
  3025. ~senary_node()
  3026. {
  3027. cleanup_branches<T,6>::execute(branch_);
  3028. }
  3029. inline T value() const
  3030. {
  3031. const T arg0 = branch_[0].first->value();
  3032. const T arg1 = branch_[1].first->value();
  3033. const T arg2 = branch_[2].first->value();
  3034. const T arg3 = branch_[3].first->value();
  3035. const T arg4 = branch_[4].first->value();
  3036. const T arg5 = branch_[5].first->value();
  3037. switch (operation_)
  3038. {
  3039. 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));
  3040. 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));
  3041. case e_avg : return (arg0 + arg1 + arg2 + arg3 + arg4 + arg5) / T(6.0);
  3042. case e_sum : return (arg0 + arg1 + arg2 + arg3 + arg4 + arg5);
  3043. case e_prod : return (arg0 * arg1 * arg2 * arg3 * arg4 * arg5);
  3044. case e_default :
  3045. default : return std::numeric_limits<T>::quiet_NaN();
  3046. }
  3047. }
  3048. inline typename expression_node<T>::node_type type() const
  3049. {
  3050. return expression_node<T>::e_senary;
  3051. }
  3052. private:
  3053. operator_type operation_;
  3054. branch_t branch_[6];
  3055. };
  3056. template <typename T>
  3057. class conditional_node : public expression_node<T>
  3058. {
  3059. public:
  3060. typedef expression_node<T>* expression_ptr;
  3061. conditional_node(expression_ptr test,
  3062. expression_ptr consequent,
  3063. expression_ptr alternative)
  3064. : test_(test),
  3065. consequent_(consequent),
  3066. alternative_(alternative),
  3067. test_deletable_(!is_variable_node(test_)),
  3068. consequent_deletable_(!is_variable_node(consequent_)),
  3069. alternative_deletable_(!is_variable_node(alternative_))
  3070. {}
  3071. ~conditional_node()
  3072. {
  3073. if (test_ && test_deletable_) delete test_;
  3074. if (consequent_ && consequent_deletable_) delete consequent_;
  3075. if (alternative_ && alternative_deletable_) delete alternative_;
  3076. }
  3077. inline T value() const
  3078. {
  3079. if (is_true(test_))
  3080. return consequent_->value();
  3081. else
  3082. return alternative_->value();
  3083. }
  3084. inline typename expression_node<T>::node_type type() const
  3085. {
  3086. return expression_node<T>::e_conditional;
  3087. }
  3088. private:
  3089. expression_ptr test_;
  3090. expression_ptr consequent_;
  3091. expression_ptr alternative_;
  3092. bool test_deletable_;
  3093. bool consequent_deletable_;
  3094. bool alternative_deletable_;
  3095. };
  3096. template <typename T>
  3097. class while_loop_node : public expression_node<T>
  3098. {
  3099. public:
  3100. typedef expression_node<T>* expression_ptr;
  3101. while_loop_node(expression_ptr test,
  3102. expression_ptr branch)
  3103. : test_(test),
  3104. branch_(branch),
  3105. test_deletable_(!is_variable_node(test_)),
  3106. branch_deletable_(!is_variable_node(branch_))
  3107. {}
  3108. ~while_loop_node()
  3109. {
  3110. if (test_ && test_deletable_) delete test_;
  3111. if (branch_ && branch_deletable_) delete branch_;
  3112. }
  3113. inline T value() const
  3114. {
  3115. T result = T(0);
  3116. while (is_true(test_))
  3117. {
  3118. result = branch_->value();
  3119. }
  3120. return result;
  3121. }
  3122. inline typename expression_node<T>::node_type type() const
  3123. {
  3124. return expression_node<T>::e_while;
  3125. }
  3126. private:
  3127. expression_ptr test_;
  3128. expression_ptr branch_;
  3129. bool test_deletable_;
  3130. bool branch_deletable_;
  3131. };
  3132. template <typename T>
  3133. class variable_node : public expression_node<T>
  3134. {
  3135. public:
  3136. static T null_value;
  3137. explicit variable_node()
  3138. : value_(&null_value)
  3139. {}
  3140. explicit variable_node(T& value)
  3141. : value_(&value)
  3142. {}
  3143. inline bool operator <(const variable_node<T>& v) const
  3144. {
  3145. return this < (&v);
  3146. }
  3147. inline T value() const
  3148. {
  3149. return (*value_);
  3150. }
  3151. inline T& ref()
  3152. {
  3153. return (*value_);
  3154. }
  3155. inline const T& ref() const
  3156. {
  3157. return (*value_);
  3158. }
  3159. inline typename expression_node<T>::node_type type() const
  3160. {
  3161. return expression_node<T>::e_variable;
  3162. }
  3163. private:
  3164. T* value_;
  3165. };
  3166. template <typename T>
  3167. T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
  3168. #ifndef exprtk_disable_string_capabilities
  3169. template <typename T>
  3170. class stringvar_node : public expression_node<T>
  3171. {
  3172. public:
  3173. static std::string null_value;
  3174. explicit stringvar_node()
  3175. : value_(&null_value)
  3176. {}
  3177. explicit stringvar_node(std::string& value)
  3178. : value_(&value)
  3179. {}
  3180. inline bool operator <(const stringvar_node<T>& v) const
  3181. {
  3182. return this < (&v);
  3183. }
  3184. inline T value() const
  3185. {
  3186. return std::numeric_limits<T>::quiet_NaN();
  3187. }
  3188. inline std::string str() const
  3189. {
  3190. return (*value_);
  3191. }
  3192. inline virtual std::string& ref()
  3193. {
  3194. return (*value_);
  3195. }
  3196. inline virtual const std::string& ref() const
  3197. {
  3198. return (*value_);
  3199. }
  3200. inline typename expression_node<T>::node_type type() const
  3201. {
  3202. return expression_node<T>::e_stringvar;
  3203. }
  3204. private:
  3205. std::string* value_;
  3206. };
  3207. template <typename T>
  3208. std::string stringvar_node<T>::null_value = std::string("");
  3209. #endif
  3210. template <typename T, std::size_t N> inline T axn(T a, T x) { return a * exprtk::details::numeric::fast_exp<T,N>::result(x); } // a*x^n
  3211. template <typename T, std::size_t N> inline T axnb(T a, T x, T b) { return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b; } // a*x^n+b
  3212. template <typename T> struct sf00_op { static inline T process(const T x, const T y, const T z) { return (x + y) / z; } };
  3213. template <typename T> struct sf01_op { static inline T process(const T x, const T y, const T z) { return (x + y) * z; } };
  3214. template <typename T> struct sf02_op { static inline T process(const T x, const T y, const T z) { return (x - y) / z; } };
  3215. template <typename T> struct sf03_op { static inline T process(const T x, const T y, const T z) { return (x - y) * z; } };
  3216. template <typename T> struct sf04_op { static inline T process(const T x, const T y, const T z) { return (x * y) + z; } };
  3217. template <typename T> struct sf05_op { static inline T process(const T x, const T y, const T z) { return (x * y) - z; } };
  3218. template <typename T> struct sf06_op { static inline T process(const T x, const T y, const T z) { return (x * y) / z; } };
  3219. template <typename T> struct sf07_op { static inline T process(const T x, const T y, const T z) { return (x * y) * z; } };
  3220. template <typename T> struct sf08_op { static inline T process(const T x, const T y, const T z) { return (x / y) + z; } };
  3221. template <typename T> struct sf09_op { static inline T process(const T x, const T y, const T z) { return (x / y) - z; } };
  3222. template <typename T> struct sf10_op { static inline T process(const T x, const T y, const T z) { return (x / y) / z; } };
  3223. template <typename T> struct sf11_op { static inline T process(const T x, const T y, const T z) { return (x / y) * z; } };
  3224. template <typename T> struct sf12_op { static inline T process(const T x, const T y, const T z) { return x / (y + z); } };
  3225. template <typename T> struct sf13_op { static inline T process(const T x, const T y, const T z) { return x / (y - z); } };
  3226. template <typename T> struct sf14_op { static inline T process(const T x, const T y, const T z) { return x / (y * z); } };
  3227. template <typename T> struct sf15_op { static inline T process(const T x, const T y, const T z) { return x / (y / z); } };
  3228. template <typename T> struct sf16_op { static inline T process(const T x, const T y, const T z) { return x - (y / z); } };
  3229. template <typename T> struct sf17_op { static inline T process(const T x, const T y, const T z) { return x - (y / z); } };
  3230. template <typename T> struct sf18_op { static inline T process(const T x, const T y, const T z) { return axnb<T,2>(x,y,z); } }; //x * y^2 + z
  3231. template <typename T> struct sf19_op { static inline T process(const T x, const T y, const T z) { return axnb<T,3>(x,y,z); } }; //x * y^3 + z
  3232. template <typename T> struct sf20_op { static inline T process(const T x, const T y, const T z) { return axnb<T,4>(x,y,z); } }; //x * y^4 + z
  3233. template <typename T> struct sf21_op { static inline T process(const T x, const T y, const T z) { return axnb<T,5>(x,y,z); } }; //x * y^5 + z
  3234. template <typename T> struct sf22_op { static inline T process(const T x, const T y, const T z) { return axnb<T,6>(x,y,z); } }; //x * y^6 + z
  3235. template <typename T> struct sf23_op { static inline T process(const T x, const T y, const T z) { return axnb<T,7>(x,y,z); } }; //x * y^7 + z
  3236. template <typename T> struct sf24_op { static inline T process(const T x, const T y, const T z) { return axnb<T,8>(x,y,z); } }; //x * y^8 + z
  3237. template <typename T> struct sf25_op { static inline T process(const T x, const T y, const T z) { return axnb<T,9>(x,y,z); } }; //x * y^9 + z
  3238. template <typename T> struct sf26_op { static inline T process(const T x, const T y, const T z) { return x * numeric::log(y) + z; } };
  3239. template <typename T> struct sf27_op { static inline T process(const T x, const T y, const T z) { return x * numeric::log(y) - z; } };
  3240. template <typename T> struct sf28_op { static inline T process(const T x, const T y, const T z) { return x * numeric::log10(y) + z; } };
  3241. template <typename T> struct sf29_op { static inline T process(const T x, const T y, const T z) { return x * numeric::log10(y) - z; } };
  3242. template <typename T> struct sf30_op { static inline T process(const T x, const T y, const T z) { return x * numeric::sin(y) + z; } };
  3243. template <typename T> struct sf31_op { static inline T process(const T x, const T y, const T z) { return x * numeric::sin(y) - z; } };
  3244. template <typename T> struct sf32_op { static inline T process(const T x, const T y, const T z) { return x * numeric::cos(y) + z; } };
  3245. template <typename T> struct sf33_op { static inline T process(const T x, const T y, const T z) { return x * numeric::cos(y) - z; } };
  3246. template <typename T> struct sf34_op { static inline T process(const T x, const T y, const T z) { return is_true(x) ? y : z; } };
  3247. template <typename T> struct sf35_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y + z) / w); } };
  3248. template <typename T> struct sf36_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y + z) * w); } };
  3249. template <typename T> struct sf37_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y - z) / w); } };
  3250. template <typename T> struct sf38_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y - z) * w); } };
  3251. template <typename T> struct sf39_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y * z) / w); } };
  3252. template <typename T> struct sf40_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y * z) * w); } };
  3253. template <typename T> struct sf41_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y / z) + w); } };
  3254. template <typename T> struct sf42_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y / z) / w); } };
  3255. template <typename T> struct sf43_op { static inline T process(const T x, const T y, const T z, const T w) { return x + ((y / z) * w); } };
  3256. template <typename T> struct sf44_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y + z) / w); } };
  3257. template <typename T> struct sf45_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y + z) * w); } };
  3258. template <typename T> struct sf46_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y - z) / w); } };
  3259. template <typename T> struct sf47_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y - z) * w); } };
  3260. template <typename T> struct sf48_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y * z) / w); } };
  3261. template <typename T> struct sf49_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y * z) * w); } };
  3262. template <typename T> struct sf50_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y / z) / w); } };
  3263. template <typename T> struct sf51_op { static inline T process(const T x, const T y, const T z, const T w) { return x - ((y / z) * w); } };
  3264. template <typename T> struct sf52_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x + y) * z) - w; } };
  3265. template <typename T> struct sf53_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x - y) * z) - w; } };
  3266. template <typename T> struct sf54_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x * y) * z) - w; } };
  3267. template <typename T> struct sf55_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x / y) * z) - w; } };
  3268. template <typename T> struct sf56_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x + y) / z) - w; } };
  3269. template <typename T> struct sf57_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x - y) / z) - w; } };
  3270. template <typename T> struct sf58_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x * y) / z) - w; } };
  3271. template <typename T> struct sf59_op { static inline T process(const T x, const T y, const T z, const T w) { return ((x / y) / z) - w; } };
  3272. template <typename T> struct sf60_op { static inline T process(const T x, const T y, const T z, const T w) { return (x * y) + (z * w); } };
  3273. template <typename T> struct sf61_op { static inline T process(const T x, const T y, const T z, const T w) { return (x * y) - (z * w); } };
  3274. template <typename T> struct sf62_op { static inline T process(const T x, const T y, const T z, const T w) { return (x * y) + (z / w); } };
  3275. template <typename T> struct sf63_op { static inline T process(const T x, const T y, const T z, const T w) { return (x * y) - (z / w); } };
  3276. template <typename T> struct sf64_op { static inline T process(const T x, const T y, const T z, const T w) { return (x / y) + (z / w); } };
  3277. template <typename T> struct sf65_op { static inline T process(const T x, const T y, const T z, const T w) { return (x / y) - (z / w); } };
  3278. template <typename T> struct sf66_op { static inline T process(const T x, const T y, const T z, const T w) { return (x / y) - (z * w); } };
  3279. template <typename T> struct sf67_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,2>(x,y) + axn<T,2>(z,w); } }; //x*y^2+z*w^2
  3280. template <typename T> struct sf68_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,3>(x,y) + axn<T,3>(z,w); } }; //x*y^3+z*w^3
  3281. template <typename T> struct sf69_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,4>(x,y) + axn<T,4>(z,w); } }; //x*y^4+z*w^4
  3282. template <typename T> struct sf70_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,5>(x,y) + axn<T,5>(z,w); } }; //x*y^5+z*w^5
  3283. template <typename T> struct sf71_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,6>(x,y) + axn<T,6>(z,w); } }; //x*y^6+z*w^6
  3284. template <typename T> struct sf72_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,7>(x,y) + axn<T,7>(z,w); } }; //x*y^7+z*w^7
  3285. template <typename T> struct sf73_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,8>(x,y) + axn<T,8>(z,w); } }; //x*y^8+z*w^8
  3286. template <typename T> struct sf74_op { static inline T process(const T x, const T y, const T z, const T w) { return axn<T,9>(x,y) + axn<T,9>(z,w); } }; //x*y^9+z*w^9
  3287. template <typename T> struct sf75_op { static inline T process(const T x, const T y, const T z, const T w) { return (is_true(x) && is_true(y)) ? z : w; } };
  3288. template <typename T> struct sf76_op { static inline T process(const T x, const T y, const T z, const T w) { return (is_true(x) || is_true(y)) ? z : w; } };
  3289. template <typename T> struct sf77_op { static inline T process(const T x, const T y, const T z, const T w) { return (x < y) ? z : w; } };
  3290. template <typename T> struct sf78_op { static inline T process(const T x, const T y, const T z, const T w) { return (x <= y) ? z : w; } };
  3291. template <typename T> struct sf79_op { static inline T process(const T x, const T y, const T z, const T w) { return (x > y) ? z : w; } };
  3292. template <typename T> struct sf80_op { static inline T process(const T x, const T y, const T z, const T w) { return (x >= y) ? z : w; } };
  3293. template <typename T> struct sf81_op { static inline T process(const T x, const T y, const T z, const T w) { return numeric::equal(x,y) ? z : w; } };
  3294. template <typename T> struct sf82_op { static inline T process(const T x, const T y, const T z, const T w) { return x * numeric::sin(y) + z * numeric::cos(w); } };
  3295. template <typename T, typename SpecialFunction>
  3296. class sf3_node : public trinary_node<T>
  3297. {
  3298. public:
  3299. typedef expression_node<T>* expression_ptr;
  3300. sf3_node(const operator_type& operation,
  3301. expression_ptr branch0,
  3302. expression_ptr branch1,
  3303. expression_ptr branch2)
  3304. : trinary_node<T>(operation,branch0,branch1,branch2)
  3305. {}
  3306. inline T value() const
  3307. {
  3308. const T x = trinary_node<T>::branch_[0].first->value();
  3309. const T y = trinary_node<T>::branch_[1].first->value();
  3310. const T z = trinary_node<T>::branch_[2].first->value();
  3311. return SpecialFunction::process(x,y,z);
  3312. }
  3313. };
  3314. template <typename T, typename SpecialFunction>
  3315. class sf4_node : public quaternary_node<T>
  3316. {
  3317. public:
  3318. typedef expression_node<T>* expression_ptr;
  3319. sf4_node(const operator_type& operation,
  3320. expression_ptr branch0,
  3321. expression_ptr branch1,
  3322. expression_ptr branch2,
  3323. expression_ptr branch3)
  3324. : quaternary_node<T>(operation,branch0,branch1,branch2,branch3)
  3325. {}
  3326. inline T value() const
  3327. {
  3328. const T x = quaternary_node<T>::branch_[0].first->value();
  3329. const T y = quaternary_node<T>::branch_[1].first->value();
  3330. const T z = quaternary_node<T>::branch_[2].first->value();
  3331. const T w = quaternary_node<T>::branch_[3].first->value();
  3332. return SpecialFunction::process(x,y,z,w);
  3333. }
  3334. };
  3335. template <typename T, typename SpecialFunction>
  3336. class sf3_var_node : public expression_node<T>
  3337. {
  3338. public:
  3339. typedef expression_node<T>* expression_ptr;
  3340. sf3_var_node(const T& v0, const T& v1, const T& v2)
  3341. : v0_(v0),
  3342. v1_(v1),
  3343. v2_(v2)
  3344. {}
  3345. inline T value() const
  3346. {
  3347. return SpecialFunction::process(v0_,v1_,v2_);
  3348. }
  3349. inline typename expression_node<T>::node_type type() const
  3350. {
  3351. return expression_node<T>::e_trinary;
  3352. }
  3353. private:
  3354. sf3_var_node(sf3_var_node<T,SpecialFunction>&);
  3355. sf3_var_node<T,SpecialFunction>& operator=(sf3_var_node<T,SpecialFunction>&);
  3356. const T& v0_;
  3357. const T& v1_;
  3358. const T& v2_;
  3359. };
  3360. template <typename T, typename SpecialFunction>
  3361. class sf4_var_node : public expression_node<T>
  3362. {
  3363. public:
  3364. typedef expression_node<T>* expression_ptr;
  3365. sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
  3366. : v0_(v0),
  3367. v1_(v1),
  3368. v2_(v2),
  3369. v3_(v3)
  3370. {}
  3371. inline T value() const
  3372. {
  3373. return SpecialFunction::process(v0_,v1_,v2_,v3_);
  3374. }
  3375. inline typename expression_node<T>::node_type type() const
  3376. {
  3377. return expression_node<T>::e_trinary;
  3378. }
  3379. private:
  3380. sf4_var_node(sf4_var_node<T,SpecialFunction>&);
  3381. sf4_var_node<T,SpecialFunction>& operator=(sf4_var_node<T,SpecialFunction>&);
  3382. const T& v0_;
  3383. const T& v1_;
  3384. const T& v2_;
  3385. const T& v3_;
  3386. };
  3387. template <typename T>
  3388. class assignment_node : public binary_node<T>
  3389. {
  3390. public:
  3391. typedef expression_node<T>* expression_ptr;
  3392. assignment_node(const operator_type& operation,
  3393. expression_ptr branch0,
  3394. expression_ptr branch1)
  3395. : binary_node<T>(operation,branch0,branch1)
  3396. {}
  3397. inline T value() const
  3398. {
  3399. if (is_variable_node(binary_node<T>::branch_[0].first))
  3400. {
  3401. variable_node<T>* var_node_ptr = dynamic_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
  3402. if (var_node_ptr)
  3403. {
  3404. T& result = var_node_ptr->ref();
  3405. result = binary_node<T>::branch_[1].first->value();
  3406. return result;
  3407. }
  3408. }
  3409. return std::numeric_limits<T>::quiet_NaN();
  3410. }
  3411. };
  3412. template <typename T, typename IFunction, std::size_t N>
  3413. class function_N_node : public expression_node<T>
  3414. {
  3415. public:
  3416. //function of N paramters.
  3417. typedef expression_node<T>* expression_ptr;
  3418. typedef std::pair<expression_ptr,bool> branch_t;
  3419. typedef IFunction ifunction;
  3420. function_N_node(ifunction* func)
  3421. : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
  3422. parameter_count_(func->param_count)
  3423. {}
  3424. ~function_N_node()
  3425. {
  3426. cleanup_branches<T,N>::execute(branch_);
  3427. }
  3428. template <std::size_t NumBranches>
  3429. bool init_branches(expression_ptr (&b)[NumBranches])
  3430. {
  3431. //Needed for incompetent and broken msvc compiler versions
  3432. #ifdef _MSC_VER
  3433. #pragma warning(push)
  3434. #pragma warning(disable: 4127)
  3435. #endif
  3436. if (N != NumBranches)
  3437. return false;
  3438. else
  3439. {
  3440. for (std::size_t i = 0; i < NumBranches; ++i)
  3441. {
  3442. if (b[i])
  3443. branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
  3444. else
  3445. return false;
  3446. }
  3447. return true;
  3448. }
  3449. #ifdef _MSC_VER
  3450. #pragma warning(pop)
  3451. #endif
  3452. }
  3453. inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
  3454. {
  3455. return this < (&fn);
  3456. }
  3457. inline T value() const
  3458. {
  3459. //Needed for incompetent and broken msvc compiler versions
  3460. #ifdef _MSC_VER
  3461. #pragma warning(push)
  3462. #pragma warning(disable: 4127)
  3463. #endif
  3464. if ((0 == function_) || (0 == N))
  3465. return std::numeric_limits<T>::quiet_NaN();
  3466. else
  3467. {
  3468. T v[N];
  3469. evaluate_branches<T,N>::execute(v,branch_);
  3470. return invoke<T,N>::execute(*function_,v);
  3471. }
  3472. #ifdef _MSC_VER
  3473. #pragma warning(pop)
  3474. #endif
  3475. }
  3476. template <typename T_, std::size_t BranchCount>
  3477. struct evaluate_branches
  3478. {
  3479. static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
  3480. {
  3481. for (std::size_t i = 0; i < BranchCount; ++i)
  3482. {
  3483. v[i] = b[i].first->value();
  3484. }
  3485. }
  3486. };
  3487. template <typename T_>
  3488. struct evaluate_branches <T_,5>
  3489. {
  3490. static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
  3491. {
  3492. v[0] = b[0].first->value();
  3493. v[1] = b[1].first->value();
  3494. v[2] = b[2].first->value();
  3495. v[3] = b[3].first->value();
  3496. v[4] = b[4].first->value();
  3497. }
  3498. };
  3499. template <typename T_>
  3500. struct evaluate_branches <T_,4>
  3501. {
  3502. static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
  3503. {
  3504. v[0] = b[0].first->value();
  3505. v[1] = b[1].first->value();
  3506. v[2] = b[2].first->value();
  3507. v[3] = b[3].first->value();
  3508. }
  3509. };
  3510. template <typename T_>
  3511. struct evaluate_branches <T_,3>
  3512. {
  3513. static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
  3514. {
  3515. v[0] = b[0].first->value();
  3516. v[1] = b[1].first->value();
  3517. v[2] = b[2].first->value();
  3518. }
  3519. };
  3520. template <typename T_>
  3521. struct evaluate_branches <T_,2>
  3522. {
  3523. static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
  3524. {
  3525. v[0] = b[0].first->value();
  3526. v[1] = b[1].first->value();
  3527. }
  3528. };
  3529. template <typename T_>
  3530. struct evaluate_branches <T_,1>
  3531. {
  3532. static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
  3533. {
  3534. v[0] = b[0].first->value();
  3535. }
  3536. };
  3537. template <typename T_, std::size_t ParamCount>
  3538. struct invoke { static inline T execute(ifunction*, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
  3539. template <typename T_>
  3540. struct invoke<T_,20>
  3541. {
  3542. static inline T_ execute(ifunction& f, T_ (&v)[20])
  3543. { 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]); }
  3544. };
  3545. template <typename T_>
  3546. struct invoke<T_,19>
  3547. {
  3548. static inline T_ execute(ifunction& f, T_ (&v)[19])
  3549. { 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]); }
  3550. };
  3551. template <typename T_>
  3552. struct invoke<T_,18>
  3553. {
  3554. static inline T_ execute(ifunction& f, T_ (&v)[18])
  3555. { 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]); }
  3556. };
  3557. template <typename T_>
  3558. struct invoke<T_,17>
  3559. {
  3560. static inline T_ execute(ifunction& f, T_ (&v)[17])
  3561. { 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]); }
  3562. };
  3563. template <typename T_>
  3564. struct invoke<T_,16>
  3565. {
  3566. static inline T_ execute(ifunction& f, T_ (&v)[16])
  3567. { 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]); }
  3568. };
  3569. template <typename T_>
  3570. struct invoke<T_,15>
  3571. {
  3572. static inline T_ execute(ifunction& f, T_ (&v)[15])
  3573. { 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]); }
  3574. };
  3575. template <typename T_>
  3576. struct invoke<T_,14>
  3577. {
  3578. static inline T_ execute(ifunction& f, T_ (&v)[14])
  3579. { 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]); }
  3580. };
  3581. template <typename T_>
  3582. struct invoke<T_,13>
  3583. {
  3584. static inline T_ execute(ifunction& f, T_ (&v)[13])
  3585. { 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]); }
  3586. };
  3587. template <typename T_>
  3588. struct invoke<T_,12>
  3589. {
  3590. static inline T_ execute(ifunction& f, T_ (&v)[12])
  3591. { 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]); }
  3592. };
  3593. template <typename T_>
  3594. struct invoke<T_,11>
  3595. {
  3596. static inline T_ execute(ifunction& f, T_ (&v)[11])
  3597. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10]); }
  3598. };
  3599. template <typename T_>
  3600. struct invoke<T_,10>
  3601. {
  3602. static inline T_ execute(ifunction& f, T_ (&v)[10])
  3603. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); }
  3604. };
  3605. template <typename T_>
  3606. struct invoke<T_,9>
  3607. {
  3608. static inline T_ execute(ifunction& f, T_ (&v)[9])
  3609. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); }
  3610. };
  3611. template <typename T_>
  3612. struct invoke<T_,8>
  3613. {
  3614. static inline T_ execute(ifunction& f, T_ (&v)[8])
  3615. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); }
  3616. };
  3617. template <typename T_>
  3618. struct invoke<T_, 7>
  3619. {
  3620. static inline T_ execute(ifunction& f, T_ (&v)[ 7])
  3621. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); }
  3622. };
  3623. template <typename T_>
  3624. struct invoke<T_,6>
  3625. {
  3626. static inline T_ execute(ifunction& f, T_ (&v)[6])
  3627. { return f(v[0],v[1],v[2],v[3],v[4],v[5]); }
  3628. };
  3629. template <typename T_>
  3630. struct invoke<T_,5>
  3631. {
  3632. static inline T_ execute(ifunction& f, T_ (&v)[5])
  3633. { return f(v[0],v[1],v[2],v[3],v[4]); }
  3634. };
  3635. template <typename T_>
  3636. struct invoke<T_,4>
  3637. {
  3638. static inline T_ execute(ifunction& f, T_ (&v)[4])
  3639. { return f(v[0],v[1],v[2],v[3]); }
  3640. };
  3641. template <typename T_>
  3642. struct invoke<T_,3>
  3643. {
  3644. static inline T_ execute(ifunction& f, T_ (&v)[3])
  3645. { return f(v[0],v[1],v[2]); }
  3646. };
  3647. template <typename T_>
  3648. struct invoke<T_,2>
  3649. {
  3650. static inline T_ execute(ifunction& f, T_ (&v)[2])
  3651. { return f(v[0],v[1]); }
  3652. };
  3653. template <typename T_>
  3654. struct invoke<T_,1>
  3655. {
  3656. static inline T_ execute(ifunction& f, T_ (&v)[1])
  3657. { return f(v[0]); }
  3658. };
  3659. inline typename expression_node<T>::node_type type() const
  3660. {
  3661. return expression_node<T>::e_function;
  3662. }
  3663. private:
  3664. ifunction* function_;
  3665. std::size_t parameter_count_;
  3666. branch_t branch_[N];
  3667. };
  3668. template <typename T, typename IFunction>
  3669. class function_N_node<T,IFunction,0> : public expression_node<T>
  3670. {
  3671. public:
  3672. typedef expression_node<T>* expression_ptr;
  3673. typedef IFunction ifunction;
  3674. function_N_node(ifunction* func)
  3675. : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
  3676. {}
  3677. inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
  3678. {
  3679. return this < (&fn);
  3680. }
  3681. inline T value() const
  3682. {
  3683. if (0 == function_)
  3684. return std::numeric_limits<T>::quiet_NaN();
  3685. else
  3686. return (*function_)();
  3687. }
  3688. inline typename expression_node<T>::node_type type() const
  3689. {
  3690. return expression_node<T>::e_function;
  3691. }
  3692. private:
  3693. ifunction* function_;
  3694. std::size_t parameter_count_;
  3695. };
  3696. #define exprtk_def_unary_op(OpName) \
  3697. template <typename T> \
  3698. struct OpName##_op \
  3699. { \
  3700. static inline T process(const T v) { return numeric:: OpName (v); } \
  3701. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_##OpName; } \
  3702. static inline details::operator_type operation() { return details::e_##OpName; } \
  3703. };
  3704. exprtk_def_unary_op(abs )
  3705. exprtk_def_unary_op(acos )
  3706. exprtk_def_unary_op(asin )
  3707. exprtk_def_unary_op(atan )
  3708. exprtk_def_unary_op(ceil )
  3709. exprtk_def_unary_op(cos )
  3710. exprtk_def_unary_op(cosh )
  3711. exprtk_def_unary_op(cot )
  3712. exprtk_def_unary_op(csc )
  3713. exprtk_def_unary_op(d2g )
  3714. exprtk_def_unary_op(d2r )
  3715. exprtk_def_unary_op(erf )
  3716. exprtk_def_unary_op(erfc )
  3717. exprtk_def_unary_op(exp )
  3718. exprtk_def_unary_op(floor)
  3719. exprtk_def_unary_op(frac )
  3720. exprtk_def_unary_op(g2d )
  3721. exprtk_def_unary_op(log )
  3722. exprtk_def_unary_op(log10)
  3723. exprtk_def_unary_op(neg )
  3724. exprtk_def_unary_op(notl )
  3725. exprtk_def_unary_op(pos )
  3726. exprtk_def_unary_op(r2d )
  3727. exprtk_def_unary_op(round)
  3728. exprtk_def_unary_op(sec )
  3729. exprtk_def_unary_op(sgn )
  3730. exprtk_def_unary_op(sin )
  3731. exprtk_def_unary_op(sinh )
  3732. exprtk_def_unary_op(sqrt )
  3733. exprtk_def_unary_op(tan )
  3734. exprtk_def_unary_op(tanh )
  3735. exprtk_def_unary_op(trunc)
  3736. #undef exprtk_def_unary_op
  3737. template <typename T>
  3738. struct add_op
  3739. {
  3740. static inline T process(const T t1, const T t2) { return t1 + t2; }
  3741. static inline T process(const T t1, const T t2, const T t3) { return t1 + t2 + t3; }
  3742. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; }
  3743. static inline details::operator_type operation() { return details::e_add; }
  3744. };
  3745. template <typename T>
  3746. struct mul_op
  3747. {
  3748. static inline T process(const T t1, const T t2) { return t1 * t2; }
  3749. static inline T process(const T t1, const T t2, const T t3) { return t1 * t2 * t3; }
  3750. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; }
  3751. static inline details::operator_type operation() { return details::e_mul; }
  3752. };
  3753. template <typename T>
  3754. struct sub_op
  3755. {
  3756. static inline T process(const T t1, const T t2) { return t1 - t2; }
  3757. static inline T process(const T t1, const T t2, const T t3) { return t1 - t2 - t3; }
  3758. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; }
  3759. static inline details::operator_type operation() { return details::e_sub; }
  3760. };
  3761. template <typename T>
  3762. struct div_op
  3763. {
  3764. static inline T process(const T t1, const T t2) { return t1 / t2; }
  3765. static inline T process(const T t1, const T t2, const T t3) { return t1 / t2 / t3; }
  3766. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; }
  3767. static inline details::operator_type operation() { return details::e_div; }
  3768. };
  3769. template <typename T>
  3770. struct mod_op
  3771. {
  3772. static inline T process(const T t1, const T t2) { return numeric::modulus<T>(t1,t2); }
  3773. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
  3774. static inline details::operator_type operation() { return details::e_mod; }
  3775. };
  3776. template <typename T>
  3777. struct pow_op
  3778. {
  3779. static inline T process(const T t1, const T t2) { return numeric::pow<T>(t1,t2); }
  3780. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
  3781. static inline details::operator_type operation() { return details::e_pow; }
  3782. };
  3783. template <typename T>
  3784. struct lt_op
  3785. {
  3786. static inline T process(const T t1, const T t2) { return ((t1 < t2) ? T(1) : T(0)); }
  3787. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
  3788. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
  3789. static inline details::operator_type operation() { return details::e_lt; }
  3790. };
  3791. template <typename T>
  3792. struct lte_op
  3793. {
  3794. static inline T process(const T t1, const T t2) { return ((t1 <= t2) ? T(1) : T(0)); }
  3795. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
  3796. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
  3797. static inline details::operator_type operation() { return details::e_lte; }
  3798. };
  3799. template <typename T>
  3800. struct gt_op
  3801. {
  3802. static inline T process(const T t1, const T t2) { return ((t1 > t2) ? T(1) : T(0)); }
  3803. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
  3804. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
  3805. static inline details::operator_type operation() { return details::e_gt; }
  3806. };
  3807. template <typename T>
  3808. struct gte_op
  3809. {
  3810. static inline T process(const T t1, const T t2) { return ((t1 >= t2) ? T(1) : T(0)); }
  3811. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
  3812. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
  3813. static inline details::operator_type operation() { return details::e_gte; }
  3814. };
  3815. template <typename T>
  3816. struct eq_op
  3817. {
  3818. static inline T process(const T t1, const T t2) { return ((t1 == t2) ? T(1) : T(0)); }
  3819. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
  3820. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
  3821. static inline details::operator_type operation() { return details::e_eq; }
  3822. };
  3823. template <typename T>
  3824. struct ne_op
  3825. {
  3826. static inline T process(const T t1, const T t2) { return ((t1 != t2) ? T(1) : T(0)); }
  3827. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
  3828. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
  3829. static inline details::operator_type operation() { return details::e_ne; }
  3830. };
  3831. template <typename T>
  3832. struct and_op
  3833. {
  3834. static inline T process(const T t1, const T t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
  3835. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
  3836. static inline details::operator_type operation() { return details::e_and; }
  3837. };
  3838. template <typename T>
  3839. struct nand_op
  3840. {
  3841. static inline T process(const T t1, const T t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
  3842. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; }
  3843. static inline details::operator_type operation() { return details::e_nand; }
  3844. };
  3845. template <typename T>
  3846. struct or_op
  3847. {
  3848. static inline T process(const T t1, const T t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
  3849. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
  3850. static inline details::operator_type operation() { return details::e_or; }
  3851. };
  3852. template <typename T>
  3853. struct nor_op
  3854. {
  3855. static inline T process(const T t1, const T t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
  3856. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  3857. static inline details::operator_type operation() { return details::e_nor; }
  3858. };
  3859. template <typename T>
  3860. struct xor_op
  3861. {
  3862. static inline T process(const T t1, const T t2) { return numeric::xor_opr<T>(t1,t2); }
  3863. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  3864. static inline details::operator_type operation() { return details::e_xor; }
  3865. };
  3866. template <typename T>
  3867. struct in_op
  3868. {
  3869. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  3870. static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
  3871. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
  3872. static inline details::operator_type operation() { return details::e_in; }
  3873. };
  3874. template <typename T>
  3875. struct like_op
  3876. {
  3877. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  3878. static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
  3879. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; }
  3880. static inline details::operator_type operation() { return details::e_like; }
  3881. };
  3882. template <typename T>
  3883. struct ilike_op
  3884. {
  3885. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  3886. static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
  3887. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; }
  3888. static inline details::operator_type operation() { return details::e_ilike; }
  3889. };
  3890. template <typename T>
  3891. struct inrange_op
  3892. {
  3893. static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
  3894. static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
  3895. {
  3896. return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
  3897. }
  3898. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_inranges; }
  3899. static inline details::operator_type operation() { return details::e_ilike; }
  3900. };
  3901. template <typename T>
  3902. class vov_base_node : public expression_node<T>
  3903. {
  3904. public:
  3905. inline virtual operator_type operation() const
  3906. {
  3907. return details::e_default;
  3908. }
  3909. };
  3910. template <typename T>
  3911. class cov_base_node : public expression_node<T>
  3912. {
  3913. public:
  3914. inline virtual operator_type operation() const
  3915. {
  3916. return details::e_default;
  3917. }
  3918. };
  3919. template <typename T>
  3920. class voc_base_node : public expression_node<T>
  3921. {
  3922. public:
  3923. inline virtual operator_type operation() const
  3924. {
  3925. return details::e_default;
  3926. }
  3927. };
  3928. template <typename T>
  3929. class uv_base_node : public expression_node<T>
  3930. {
  3931. public:
  3932. inline virtual operator_type operation() const
  3933. {
  3934. return details::e_default;
  3935. }
  3936. };
  3937. template <typename T>
  3938. class sos_base_node : public expression_node<T>
  3939. {
  3940. public:
  3941. inline virtual operator_type operation() const
  3942. {
  3943. return details::e_default;
  3944. }
  3945. };
  3946. template <typename T>
  3947. class sosos_base_node : public expression_node<T>
  3948. {
  3949. public:
  3950. inline virtual operator_type operation() const
  3951. {
  3952. return details::e_default;
  3953. }
  3954. };
  3955. template <typename T, typename Operation>
  3956. class unary_variable_node : public uv_base_node<T>
  3957. {
  3958. public:
  3959. typedef expression_node<T>* expression_ptr;
  3960. typedef Operation operation_t;
  3961. explicit unary_variable_node(const T& v)
  3962. : v_(v)
  3963. {}
  3964. inline T value() const
  3965. {
  3966. return Operation::process(v_);
  3967. }
  3968. inline typename expression_node<T>::node_type type() const
  3969. {
  3970. return Operation::type();
  3971. }
  3972. inline operator_type operation() const
  3973. {
  3974. return Operation::operation();
  3975. }
  3976. inline const T& v()
  3977. {
  3978. return v_;
  3979. }
  3980. private:
  3981. unary_variable_node(unary_variable_node<T,Operation>&);
  3982. unary_variable_node<T,Operation>& operator=(unary_variable_node<T,Operation>&);
  3983. const T& v_;
  3984. };
  3985. template <typename T, typename UOpr1, typename Operation, typename UOpr2>
  3986. class uvouv_node : public expression_node<T>
  3987. {
  3988. public:
  3989. // UOpr1(v0) Op UOpr2(v1)
  3990. typedef expression_node<T>* expression_ptr;
  3991. typedef UOpr1 opr1_t;
  3992. typedef UOpr2 opr2_t;
  3993. typedef Operation op_t;
  3994. explicit uvouv_node(const T& v0,const T& v1)
  3995. : v0_(v0),
  3996. v1_(v1)
  3997. {}
  3998. inline T value() const
  3999. {
  4000. return Operation::process(UOpr1::process(v0_),UOpr2::process(v1_));
  4001. }
  4002. inline typename expression_node<T>::node_type type() const
  4003. {
  4004. return Operation::type();
  4005. }
  4006. inline operator_type operation() const
  4007. {
  4008. return Operation::operation();
  4009. }
  4010. inline const T& v0()
  4011. {
  4012. return v0_;
  4013. }
  4014. inline const T& v1()
  4015. {
  4016. return v1_;
  4017. }
  4018. private:
  4019. uvouv_node(uvouv_node<T,UOpr1,Operation,UOpr2>&);
  4020. uvouv_node<T,UOpr1,Operation,UOpr2>& operator=(uvouv_node<T,UOpr1,Operation,UOpr2>&);
  4021. const T& v0_;
  4022. const T& v1_;
  4023. };
  4024. template <typename T, typename Operation>
  4025. class unary_branch_node : public expression_node<T>
  4026. {
  4027. public:
  4028. typedef expression_node<T>* expression_ptr;
  4029. typedef Operation operation_t;
  4030. explicit unary_branch_node(expression_ptr branch)
  4031. : branch_(branch),
  4032. branch_deletable_(branch_deletable(branch_))
  4033. {}
  4034. ~unary_branch_node()
  4035. {
  4036. if (branch_ && branch_deletable_)
  4037. {
  4038. delete branch_;
  4039. branch_ = 0;
  4040. }
  4041. }
  4042. inline T value() const
  4043. {
  4044. return Operation::process(branch_->value());
  4045. }
  4046. inline typename expression_node<T>::node_type type() const
  4047. {
  4048. return Operation::type();
  4049. }
  4050. inline operator_type operation() const
  4051. {
  4052. return Operation::operation();
  4053. }
  4054. private:
  4055. unary_branch_node(unary_branch_node<T,Operation>&);
  4056. unary_branch_node<T,Operation>& operator=(unary_branch_node<T,Operation>&);
  4057. expression_ptr branch_;
  4058. bool branch_deletable_;
  4059. };
  4060. template <typename T, typename Operation>
  4061. class vov_node : public vov_base_node<T>
  4062. {
  4063. public:
  4064. typedef expression_node<T>* expression_ptr;
  4065. typedef Operation operation_t;
  4066. //variable op variable node
  4067. explicit vov_node(const T& v0, const T& v1)
  4068. : v0_(v0),
  4069. v1_(v1)
  4070. {}
  4071. inline T value() const
  4072. {
  4073. return Operation::process(v0_,v1_);
  4074. }
  4075. inline typename expression_node<T>::node_type type() const
  4076. {
  4077. return Operation::type();
  4078. }
  4079. inline operator_type operation() const
  4080. {
  4081. return Operation::operation();
  4082. }
  4083. inline const T& v0() const
  4084. {
  4085. return v0_;
  4086. }
  4087. inline const T& v1() const
  4088. {
  4089. return v1_;
  4090. }
  4091. protected:
  4092. const T& v0_;
  4093. const T& v1_;
  4094. private:
  4095. vov_node(vov_node<T,Operation>&);
  4096. vov_node<T,Operation>& operator=(vov_node<T,Operation>&);
  4097. };
  4098. template <typename T, typename Operation>
  4099. class cov_node : public cov_base_node<T>
  4100. {
  4101. public:
  4102. typedef expression_node<T>* expression_ptr;
  4103. typedef Operation operation_t;
  4104. //constant op variable node
  4105. explicit cov_node(const T& c, const T& v)
  4106. : c_(c),
  4107. v_(v)
  4108. {}
  4109. inline T value() const
  4110. {
  4111. return Operation::process(c_,v_);
  4112. }
  4113. inline typename expression_node<T>::node_type type() const
  4114. {
  4115. return Operation::type();
  4116. }
  4117. inline operator_type operation() const
  4118. {
  4119. return Operation::operation();
  4120. }
  4121. inline T c()
  4122. {
  4123. return c_;
  4124. }
  4125. inline const T& v() const
  4126. {
  4127. return v_;
  4128. }
  4129. protected:
  4130. const T c_;
  4131. const T& v_;
  4132. private:
  4133. cov_node(const cov_node<T,Operation>&);
  4134. cov_node<T,Operation>& operator=(const cov_node<T,Operation>&);
  4135. };
  4136. template <typename T, typename Operation>
  4137. class voc_node : public voc_base_node<T>
  4138. {
  4139. public:
  4140. typedef expression_node<T>* expression_ptr;
  4141. typedef Operation operation_t;
  4142. //variable op constant node
  4143. explicit voc_node(const T& v, const T& c)
  4144. : v_(v),
  4145. c_(c)
  4146. {}
  4147. inline T value() const
  4148. {
  4149. return Operation::process(v_,c_);
  4150. }
  4151. inline operator_type operation() const
  4152. {
  4153. return Operation::operation();
  4154. }
  4155. inline T c()
  4156. {
  4157. return c_;
  4158. }
  4159. inline const T& v() const
  4160. {
  4161. return v_;
  4162. }
  4163. protected:
  4164. const T& v_;
  4165. const T c_;
  4166. private:
  4167. voc_node(const voc_node<T,Operation>&);
  4168. voc_node<T,Operation>& operator=(const voc_node<T,Operation>&);
  4169. };
  4170. template <typename T, typename Operation1, typename Operation2>
  4171. class vovov1_node : public expression_node<T>
  4172. {
  4173. public:
  4174. typedef expression_node<T>* expression_ptr;
  4175. typedef std::pair<expression_ptr,bool> branch_t;
  4176. //variable0 op1 (variable1 op2 variable2) node
  4177. explicit vovov1_node(const T& v0, vov_node<T,Operation2>& vn)
  4178. : v0_(v0),
  4179. v1_(vn.v0()),
  4180. v2_(vn.v1())
  4181. {}
  4182. inline T value() const
  4183. {
  4184. return Operation1::process(v0_,Operation2::process(v1_,v2_));
  4185. }
  4186. inline typename expression_node<T>::node_type type() const
  4187. {
  4188. return expression_node<T>::e_none;
  4189. }
  4190. inline typename expression_node<T>::node_type type1() const
  4191. {
  4192. return Operation1::type();
  4193. }
  4194. inline typename expression_node<T>::node_type type2() const
  4195. {
  4196. return Operation2::type();
  4197. }
  4198. protected:
  4199. const T& v0_;
  4200. const T& v1_;
  4201. const T& v2_;
  4202. private:
  4203. vovov1_node(const vovov1_node<T,Operation1,Operation2>&);
  4204. vovov1_node<T,Operation1,Operation2>& operator=(const vovov1_node<T,Operation1,Operation2>&);
  4205. };
  4206. template <typename T, typename Operation1, typename Operation2>
  4207. class vovov2_node : public expression_node<T>
  4208. {
  4209. public:
  4210. typedef expression_node<T>* expression_ptr;
  4211. typedef std::pair<expression_ptr,bool> branch_t;
  4212. //(variable0 op1 variable1) op2 variable2 node
  4213. explicit vovov2_node(vov_node<T,Operation1>& vn, const T& v2)
  4214. : v0_(vn.v0()),
  4215. v1_(vn.v1()),
  4216. v2_(v2)
  4217. {}
  4218. inline T value() const
  4219. {
  4220. return Operation2::process(Operation1::process(v0_,v1_),v2_);
  4221. }
  4222. inline typename expression_node<T>::node_type type() const
  4223. {
  4224. return expression_node<T>::e_none;
  4225. }
  4226. inline typename expression_node<T>::node_type type1() const
  4227. {
  4228. return Operation1::type();
  4229. }
  4230. inline typename expression_node<T>::node_type type2() const
  4231. {
  4232. return Operation2::type();
  4233. }
  4234. protected:
  4235. const T& v0_;
  4236. const T& v1_;
  4237. const T& v2_;
  4238. private:
  4239. vovov2_node(const vovov2_node<T,Operation1,Operation2>&);
  4240. vovov2_node<T,Operation1,Operation2>& operator=(const vovov2_node<T,Operation1,Operation2>&);
  4241. };
  4242. template <typename T, typename Operation1, typename Operation2>
  4243. class covov1_node : public expression_node<T>
  4244. {
  4245. public:
  4246. typedef expression_node<T>* expression_ptr;
  4247. typedef std::pair<expression_ptr,bool> branch_t;
  4248. //constant op1 (variable0 op2 variable1) node
  4249. explicit covov1_node(const T& c, vov_node<T,Operation2>& vn)
  4250. : c_ (c),
  4251. v0_(vn.v0()),
  4252. v1_(vn.v1())
  4253. {}
  4254. inline T value() const
  4255. {
  4256. return Operation1::process(c_,Operation2::process(v0_,v1_));
  4257. }
  4258. inline typename expression_node<T>::node_type type() const
  4259. {
  4260. return expression_node<T>::e_none;
  4261. }
  4262. inline typename expression_node<T>::node_type type1() const
  4263. {
  4264. return Operation1::type();
  4265. }
  4266. inline typename expression_node<T>::node_type type2() const
  4267. {
  4268. return Operation2::type();
  4269. }
  4270. protected:
  4271. const T c_;
  4272. const T& v0_;
  4273. const T& v1_;
  4274. private:
  4275. covov1_node(const covov1_node<T,Operation1,Operation2>&);
  4276. covov1_node<T,Operation1,Operation2>& operator=(const covov1_node<T,Operation1,Operation2>&);
  4277. };
  4278. template <typename T, typename Operation1, typename Operation2>
  4279. class covov2_node : public expression_node<T>
  4280. {
  4281. public:
  4282. typedef expression_node<T>* expression_ptr;
  4283. typedef std::pair<expression_ptr,bool> branch_t;
  4284. //(constant op1 variable0) op2 variable1 node
  4285. explicit covov2_node(cov_node<T,Operation1>& cvn, const T& v1)
  4286. : c_ (cvn.c()),
  4287. v0_(cvn.v()),
  4288. v1_(v1)
  4289. {}
  4290. inline T value() const
  4291. {
  4292. return Operation2::process(Operation1::process(c_,v0_),v1_);
  4293. }
  4294. inline typename expression_node<T>::node_type type() const
  4295. {
  4296. return expression_node<T>::e_none;
  4297. }
  4298. inline typename expression_node<T>::node_type type1() const
  4299. {
  4300. return Operation1::type();
  4301. }
  4302. inline typename expression_node<T>::node_type type2() const
  4303. {
  4304. return Operation2::type();
  4305. }
  4306. protected:
  4307. const T c_;
  4308. const T& v0_;
  4309. const T& v1_;
  4310. private:
  4311. covov2_node(covov2_node<T,Operation1,Operation2>&);
  4312. covov2_node<T,Operation1,Operation2>& operator=(covov2_node<T,Operation1,Operation2>&);
  4313. };
  4314. template <typename T, typename Operation1, typename Operation2>
  4315. class vovoc1_node : public expression_node<T>
  4316. {
  4317. public:
  4318. typedef expression_node<T>* expression_ptr;
  4319. typedef std::pair<expression_ptr,bool> branch_t;
  4320. //variable0 op1 (variable1 op2 constant) node
  4321. explicit vovoc1_node(const T& v0, voc_node<T,Operation2>& vcn)
  4322. : v0_(v0),
  4323. v1_(vcn.v()),
  4324. c_ (vcn.c())
  4325. {}
  4326. inline T value() const
  4327. {
  4328. return Operation1::process(v0_,Operation2::process(v1_,c_));
  4329. }
  4330. inline typename expression_node<T>::node_type type() const
  4331. {
  4332. return expression_node<T>::e_none;
  4333. }
  4334. inline typename expression_node<T>::node_type type1() const
  4335. {
  4336. return Operation1::type();
  4337. }
  4338. inline typename expression_node<T>::node_type type2() const
  4339. {
  4340. return Operation2::type();
  4341. }
  4342. protected:
  4343. const T& v0_;
  4344. const T& v1_;
  4345. const T c_;
  4346. private:
  4347. vovoc1_node(const vovoc1_node<T,Operation1,Operation2>&);
  4348. vovoc1_node<T,Operation1,Operation2>& operator=(const vovoc1_node<T,Operation1,Operation2>&);
  4349. };
  4350. template <typename T, typename Operation1, typename Operation2>
  4351. class vovoc2_node : public expression_node<T>
  4352. {
  4353. public:
  4354. typedef expression_node<T>* expression_ptr;
  4355. typedef std::pair<expression_ptr,bool> branch_t;
  4356. //(variable0 op1 variable1) op2 constant node
  4357. explicit vovoc2_node(vov_node<T,Operation1>& vvn, const T& c)
  4358. : v0_(vvn.v0()),
  4359. v1_(vvn.v1()),
  4360. c_ (c)
  4361. {}
  4362. inline T value() const
  4363. {
  4364. return Operation2::process(Operation1::process(v0_,v1_),c_);
  4365. }
  4366. inline typename expression_node<T>::node_type type() const
  4367. {
  4368. return expression_node<T>::e_none;
  4369. }
  4370. inline typename expression_node<T>::node_type type1() const
  4371. {
  4372. return Operation1::type();
  4373. }
  4374. inline typename expression_node<T>::node_type type2() const
  4375. {
  4376. return Operation2::type();
  4377. }
  4378. protected:
  4379. const T& v0_;
  4380. const T& v1_;
  4381. const T c_;
  4382. private:
  4383. vovoc2_node(vovoc2_node<T,Operation1,Operation2>&);
  4384. vovoc2_node<T,Operation1,Operation2>& operator=(vovoc2_node<T,Operation1,Operation2>&);
  4385. };
  4386. template <typename T, typename Operation1, typename Operation2>
  4387. class covoc1_node : public expression_node<T>
  4388. {
  4389. public:
  4390. typedef expression_node<T>* expression_ptr;
  4391. typedef std::pair<expression_ptr,bool> branch_t;
  4392. //const0 op1 (variable op2 const1) node
  4393. explicit covoc1_node(const T& c0, voc_node<T,Operation2>& vcn)
  4394. : c0_(c0),
  4395. v_ (vcn.v()),
  4396. c1_(vcn.c())
  4397. {}
  4398. inline T value() const
  4399. {
  4400. return Operation1::process(c0_,Operation2::process(v_,c1_));
  4401. }
  4402. inline typename expression_node<T>::node_type type() const
  4403. {
  4404. return expression_node<T>::e_none;
  4405. }
  4406. inline typename expression_node<T>::node_type type1() const
  4407. {
  4408. return Operation1::type();
  4409. }
  4410. inline typename expression_node<T>::node_type type2() const
  4411. {
  4412. return Operation2::type();
  4413. }
  4414. protected:
  4415. const T c0_;
  4416. const T& v_;
  4417. const T c1_;
  4418. private:
  4419. covoc1_node(const covoc1_node<T,Operation1,Operation2>&);
  4420. covoc1_node<T,Operation1,Operation2>& operator=(const covoc1_node<T,Operation1,Operation2>&);
  4421. };
  4422. template <typename T, typename Operation1, typename Operation2>
  4423. class covoc2_node : public expression_node<T>
  4424. {
  4425. public:
  4426. typedef expression_node<T>* expression_ptr;
  4427. typedef std::pair<expression_ptr,bool> branch_t;
  4428. //(const0 op1 variable) op2 const1 node
  4429. explicit covoc2_node(cov_node<T,Operation1>& cvn, const T& c1)
  4430. : c0_(cvn.c()),
  4431. v_ (cvn.v()),
  4432. c1_(c1)
  4433. {}
  4434. inline T value() const
  4435. {
  4436. return Operation2::process(Operation1::process(c0_,v_),c1_);
  4437. }
  4438. inline typename expression_node<T>::node_type type() const
  4439. {
  4440. return expression_node<T>::e_none;
  4441. }
  4442. inline typename expression_node<T>::node_type type1() const
  4443. {
  4444. return Operation1::type();
  4445. }
  4446. inline typename expression_node<T>::node_type type2() const
  4447. {
  4448. return Operation2::type();
  4449. }
  4450. protected:
  4451. const T c0_;
  4452. const T& v_;
  4453. const T c1_;
  4454. private:
  4455. covoc2_node(const covoc2_node<T,Operation1,Operation2>&);
  4456. covoc2_node<T,Operation1,Operation2>& operator=(const covoc2_node<T,Operation1,Operation2>&);
  4457. };
  4458. template <typename T, typename Operation1, typename Operation2>
  4459. class vocov1_node : public expression_node<T>
  4460. {
  4461. public:
  4462. typedef expression_node<T>* expression_ptr;
  4463. typedef std::pair<expression_ptr,bool> branch_t;
  4464. //variable0 op1 (const op2 variable1) node
  4465. explicit vocov1_node(const T& v0, cov_node<T,Operation2>& cvn)
  4466. : v0_(v0),
  4467. c_ (cvn.c()),
  4468. v1_(cvn.v())
  4469. {}
  4470. inline T value() const
  4471. {
  4472. return Operation1::process(v0_,Operation2::process(c_,v1_));
  4473. }
  4474. inline typename expression_node<T>::node_type type() const
  4475. {
  4476. return expression_node<T>::e_none;
  4477. }
  4478. inline typename expression_node<T>::node_type type1() const
  4479. {
  4480. return Operation1::type();
  4481. }
  4482. inline typename expression_node<T>::node_type type2() const
  4483. {
  4484. return Operation2::type();
  4485. }
  4486. protected:
  4487. const T& v0_;
  4488. const T c_;
  4489. const T& v1_;
  4490. private:
  4491. vocov1_node(const vocov1_node<T,Operation1,Operation2>&);
  4492. vocov1_node<T,Operation1,Operation2>& operator=(const vocov1_node<T,Operation1,Operation2>&);
  4493. };
  4494. template <typename T, typename Operation1, typename Operation2>
  4495. class vocov2_node : public expression_node<T>
  4496. {
  4497. public:
  4498. typedef expression_node<T>* expression_ptr;
  4499. typedef std::pair<expression_ptr,bool> branch_t;
  4500. //(variable0 op1 constant) op2 variable1 node
  4501. explicit vocov2_node(voc_node<T,Operation1>& vcn, const T& v1)
  4502. : v0_(vcn.v()),
  4503. c_ (vcn.c()),
  4504. v1_(v1)
  4505. {}
  4506. inline T value() const
  4507. {
  4508. return Operation2::process(Operation1::process(v0_,c_),v1_);
  4509. }
  4510. inline typename expression_node<T>::node_type type() const
  4511. {
  4512. return expression_node<T>::e_none;
  4513. }
  4514. inline typename expression_node<T>::node_type type1() const
  4515. {
  4516. return Operation1::type();
  4517. }
  4518. inline typename expression_node<T>::node_type type2() const
  4519. {
  4520. return Operation2::type();
  4521. }
  4522. protected:
  4523. const T& v0_;
  4524. const T c_;
  4525. const T& v1_;
  4526. private:
  4527. vocov2_node(const vocov2_node<T,Operation1,Operation2>&);
  4528. vocov2_node<T,Operation1,Operation2>& operator=(const vocov2_node<T,Operation1,Operation2>&);
  4529. };
  4530. template <typename T, typename Operation1, typename Operation2, typename Operation3>
  4531. class vovovov_node : public expression_node<T>
  4532. {
  4533. public:
  4534. typedef expression_node<T>* expression_ptr;
  4535. typedef std::pair<expression_ptr,bool> branch_t;
  4536. //(variable0 op1 variable1) op2 (variable2 op3 variable3) node
  4537. explicit vovovov_node(vov_node<T,Operation1>& vn0, vov_node<T,Operation3>& vn1)
  4538. : v0_(vn0.v0()),
  4539. v1_(vn0.v1()),
  4540. v2_(vn1.v0()),
  4541. v3_(vn1.v1())
  4542. {}
  4543. inline T value() const
  4544. {
  4545. return Operation2::process(Operation1::process(v0_,v1_),Operation3::process(v2_,v3_));
  4546. }
  4547. inline typename expression_node<T>::node_type type() const
  4548. {
  4549. return expression_node<T>::e_none;
  4550. }
  4551. inline typename expression_node<T>::node_type type1() const
  4552. {
  4553. return Operation1::type();
  4554. }
  4555. inline typename expression_node<T>::node_type type2() const
  4556. {
  4557. return Operation2::type();
  4558. }
  4559. protected:
  4560. const T& v0_;
  4561. const T& v1_;
  4562. const T& v2_;
  4563. const T& v3_;
  4564. private:
  4565. vovovov_node(vovovov_node<T,Operation1,Operation2,Operation3>&);
  4566. vovovov_node<T,Operation1,Operation2,Operation3>& operator=(const vovovov_node<T,Operation1,Operation2,Operation3>&);
  4567. };
  4568. #ifndef exprtk_disable_string_capabilities
  4569. template <typename T, typename SType0, typename SType1, typename Operation>
  4570. class sos_node : public sos_base_node<T>
  4571. {
  4572. public:
  4573. typedef expression_node<T>* expression_ptr;
  4574. typedef Operation operation_t;
  4575. //variable op variable node
  4576. explicit sos_node(SType0 s0, SType1 s1)
  4577. : s0_(s0),
  4578. s1_(s1)
  4579. {}
  4580. inline T value() const
  4581. {
  4582. return Operation::process(s0_,s1_);
  4583. }
  4584. inline typename expression_node<T>::node_type type() const
  4585. {
  4586. return Operation::type();
  4587. }
  4588. inline operator_type operation() const
  4589. {
  4590. return Operation::operation();
  4591. }
  4592. inline std::string& s0()
  4593. {
  4594. return s0_;
  4595. }
  4596. inline std::string& s1()
  4597. {
  4598. return s1_;
  4599. }
  4600. protected:
  4601. SType0 s0_;
  4602. SType1 s1_;
  4603. private:
  4604. sos_node(sos_node<T,SType0,SType1,Operation>&);
  4605. sos_node<T,SType0,SType1,Operation>& operator=(sos_node<T,SType0,SType1,Operation>&);
  4606. };
  4607. template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
  4608. class sosos_node : public sosos_base_node<T>
  4609. {
  4610. public:
  4611. typedef expression_node<T>* expression_ptr;
  4612. typedef Operation operation_t;
  4613. //variable op variable node
  4614. explicit sosos_node(SType0 s0, SType1 s1, SType2 s2)
  4615. : s0_(s0),
  4616. s1_(s1),
  4617. s2_(s2)
  4618. {}
  4619. inline T value() const
  4620. {
  4621. return Operation::process(s0_,s1_,s2_);
  4622. }
  4623. inline typename expression_node<T>::node_type type() const
  4624. {
  4625. return Operation::type();
  4626. }
  4627. inline operator_type operation() const
  4628. {
  4629. return Operation::operation();
  4630. }
  4631. inline std::string& s0()
  4632. {
  4633. return s0_;
  4634. }
  4635. inline std::string& s1()
  4636. {
  4637. return s1_;
  4638. }
  4639. inline std::string& s2()
  4640. {
  4641. return s2_;
  4642. }
  4643. protected:
  4644. SType0 s0_;
  4645. SType1 s1_;
  4646. SType2 s2_;
  4647. private:
  4648. sosos_node(sosos_node<T,SType0,SType1,SType2,Operation>&);
  4649. sosos_node<T,SType0,SType1,SType2,Operation>& operator=(sosos_node<T,SType0,SType1,SType2,Operation>&);
  4650. };
  4651. #endif
  4652. template <typename T, typename PowOp>
  4653. class ipow_node : public expression_node<T>
  4654. {
  4655. public:
  4656. typedef expression_node<T>* expression_ptr;
  4657. typedef PowOp operation_t;
  4658. explicit ipow_node(T& v)
  4659. : v_(v)
  4660. {}
  4661. inline T value() const
  4662. {
  4663. return PowOp::result(v_);
  4664. }
  4665. inline typename expression_node<T>::node_type type() const
  4666. {
  4667. return expression_node<T>::e_ipow;
  4668. }
  4669. private:
  4670. ipow_node(const ipow_node<T,PowOp>&);
  4671. ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&);
  4672. const T& v_;
  4673. };
  4674. template <typename T, typename PowOp>
  4675. class ipowinv_node : public expression_node<T>
  4676. {
  4677. public:
  4678. typedef expression_node<T>* expression_ptr;
  4679. typedef PowOp operation_t;
  4680. explicit ipowinv_node(T& v)
  4681. : v_(v)
  4682. {}
  4683. inline T value() const
  4684. {
  4685. return (T(1.0) / PowOp::result(v_));
  4686. }
  4687. inline typename expression_node<T>::node_type type() const
  4688. {
  4689. return expression_node<T>::e_ipowinv;
  4690. }
  4691. private:
  4692. ipowinv_node(const ipowinv_node<T,PowOp>&);
  4693. ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&);
  4694. const T& v_;
  4695. };
  4696. template <typename T>
  4697. inline bool is_vov_node(const expression_node<T>* node)
  4698. {
  4699. return (0 != dynamic_cast<const vov_base_node<T>*>(node));
  4700. }
  4701. template <typename T>
  4702. inline bool is_cov_node(const expression_node<T>* node)
  4703. {
  4704. return (0 != dynamic_cast<const cov_base_node<T>*>(node));
  4705. }
  4706. template <typename T>
  4707. inline bool is_voc_node(const expression_node<T>* node)
  4708. {
  4709. return (0 != dynamic_cast<const voc_base_node<T>*>(node));
  4710. }
  4711. template <typename T>
  4712. inline bool is_uv_node(const expression_node<T>* node)
  4713. {
  4714. return (0 != dynamic_cast<const uv_base_node<T>*>(node));
  4715. }
  4716. template <typename T>
  4717. inline bool is_string_node(const expression_node<T>* node)
  4718. {
  4719. return (expression_node<T>::e_stringvar == node->type());
  4720. }
  4721. template <typename T>
  4722. inline bool is_const_string_node(const expression_node<T>* node)
  4723. {
  4724. return (expression_node<T>::e_stringconst == node->type());
  4725. }
  4726. class node_allocator
  4727. {
  4728. public:
  4729. template <typename ResultNode, typename OpType, typename ExprNode>
  4730. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1])
  4731. {
  4732. return allocate<ResultNode>(operation,branch[0]);
  4733. }
  4734. template <typename ResultNode, typename OpType, typename ExprNode>
  4735. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2])
  4736. {
  4737. return allocate<ResultNode>(operation,branch[0],branch[1]);
  4738. }
  4739. template <typename ResultNode, typename OpType, typename ExprNode>
  4740. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3])
  4741. {
  4742. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2]);
  4743. }
  4744. template <typename ResultNode, typename OpType, typename ExprNode>
  4745. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4])
  4746. {
  4747. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3]);
  4748. }
  4749. template <typename ResultNode, typename OpType, typename ExprNode>
  4750. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5])
  4751. {
  4752. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4]);
  4753. }
  4754. template <typename ResultNode, typename OpType, typename ExprNode>
  4755. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6])
  4756. {
  4757. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4],branch[5]);
  4758. }
  4759. template <typename node_type, typename T1>
  4760. inline expression_node<typename node_type::value_type>* allocate(T1& t1) const
  4761. {
  4762. return new node_type(t1);
  4763. }
  4764. template <typename node_type, typename T1>
  4765. inline expression_node<typename node_type::value_type>* allocate_c(const T1& t1) const
  4766. {
  4767. return new node_type(t1);
  4768. }
  4769. template <typename node_type,
  4770. typename T1, typename T2>
  4771. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
  4772. {
  4773. return new node_type(t1,t2);
  4774. }
  4775. template <typename node_type,
  4776. typename T1, typename T2>
  4777. inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const
  4778. {
  4779. return new node_type(t1,t2);
  4780. }
  4781. template <typename node_type,
  4782. typename T1, typename T2>
  4783. inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
  4784. {
  4785. return new node_type(t1,t2);
  4786. }
  4787. template <typename node_type,
  4788. typename T1, typename T2>
  4789. inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const
  4790. {
  4791. return new node_type(t1,t2);
  4792. }
  4793. template <typename node_type,
  4794. typename T1, typename T2>
  4795. inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const
  4796. {
  4797. return new node_type(t1,t2);
  4798. }
  4799. template <typename node_type,
  4800. typename T1, typename T2, typename T3>
  4801. inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const
  4802. {
  4803. return new node_type(t1,t2,t3);
  4804. }
  4805. template <typename node_type,
  4806. typename T1, typename T2, typename T3, typename T4>
  4807. inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const
  4808. {
  4809. return new node_type(t1,t2,t3,t4);
  4810. }
  4811. template <typename node_type,
  4812. typename T1, typename T2, typename T3>
  4813. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const
  4814. {
  4815. return new node_type(t1,t2,t3);
  4816. }
  4817. template <typename node_type,
  4818. typename T1, typename T2, typename T3>
  4819. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4820. const T3& t3) const
  4821. {
  4822. return new node_type(t1,t2,t3);
  4823. }
  4824. template <typename node_type,
  4825. typename T1, typename T2,
  4826. typename T3, typename T4>
  4827. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4828. const T3& t3, const T4& t4) const
  4829. {
  4830. return new node_type(t1,t2,t3,t4);
  4831. }
  4832. template <typename node_type,
  4833. typename T1, typename T2,
  4834. typename T3, typename T4, typename T5>
  4835. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4836. const T3& t3, const T4& t4,
  4837. const T5& t5) const
  4838. {
  4839. return new node_type(t1,t2,t3,t4,t5);
  4840. }
  4841. template <typename node_type,
  4842. typename T1, typename T2,
  4843. typename T3, typename T4, typename T5, typename T6>
  4844. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4845. const T3& t3, const T4& t4,
  4846. const T5& t5, const T6& t6) const
  4847. {
  4848. return new node_type(t1,t2,t3,t4,t5,t6);
  4849. }
  4850. template <typename node_type,
  4851. typename T1, typename T2,
  4852. typename T3, typename T4,
  4853. typename T5, typename T6, typename T7>
  4854. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4855. const T3& t3, const T4& t4,
  4856. const T5& t5, const T6& t6,
  4857. const T7& t7) const
  4858. {
  4859. return new node_type(t1,t2,t3,t4,t5,t6,t7);
  4860. }
  4861. template <typename node_type,
  4862. typename T1, typename T2,
  4863. typename T3, typename T4,
  4864. typename T5, typename T6,
  4865. typename T7, typename T8>
  4866. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4867. const T3& t3, const T4& t4,
  4868. const T5& t5, const T6& t6,
  4869. const T7& t7, const T8& t8) const
  4870. {
  4871. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8);
  4872. }
  4873. template <typename node_type,
  4874. typename T1, typename T2,
  4875. typename T3, typename T4,
  4876. typename T5, typename T6,
  4877. typename T7, typename T8, typename T9>
  4878. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4879. const T3& t3, const T4& t4,
  4880. const T5& t5, const T6& t6,
  4881. const T7& t7, const T8& t8,
  4882. const T9& t9) const
  4883. {
  4884. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9);
  4885. }
  4886. template <typename node_type,
  4887. typename T1, typename T2,
  4888. typename T3, typename T4,
  4889. typename T5, typename T6,
  4890. typename T7, typename T8,
  4891. typename T9, typename T10>
  4892. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  4893. const T3& t3, const T4& t4,
  4894. const T5& t5, const T6& t6,
  4895. const T7& t7, const T8& t8,
  4896. const T9& t9, const T10& t10) const
  4897. {
  4898. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
  4899. }
  4900. template <typename T>
  4901. void inline free(expression_node<T>*& e) const
  4902. {
  4903. delete e;
  4904. e = 0;
  4905. }
  4906. };
  4907. inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
  4908. {
  4909. #define register_op(Symbol,Type,Args) m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args)));
  4910. register_op( "abs",e_abs , 1)
  4911. register_op( "acos",e_acos , 1)
  4912. register_op( "asin",e_asin , 1)
  4913. register_op( "atan",e_atan , 1)
  4914. register_op( "ceil",e_ceil , 1)
  4915. register_op( "cos",e_cos , 1)
  4916. register_op( "cosh",e_cosh , 1)
  4917. register_op( "exp",e_exp , 1)
  4918. register_op( "floor",e_floor , 1)
  4919. register_op( "log",e_log , 1)
  4920. register_op( "log10",e_log10 , 1)
  4921. register_op( "round",e_round , 1)
  4922. register_op( "sin",e_sin , 1)
  4923. register_op( "sinh",e_sinh , 1)
  4924. register_op( "sec",e_sec , 1)
  4925. register_op( "csc",e_csc , 1)
  4926. register_op( "sqrt",e_sqrt , 1)
  4927. register_op( "tan",e_tan , 1)
  4928. register_op( "tanh",e_tanh , 1)
  4929. register_op( "cot",e_cot , 1)
  4930. register_op( "rad2deg",e_r2d , 1)
  4931. register_op( "deg2rad",e_d2r , 1)
  4932. register_op( "deg2grad",e_d2g , 1)
  4933. register_op( "grad2deg",e_g2d , 1)
  4934. register_op( "sgn",e_sgn , 1)
  4935. register_op( "not",e_notl , 1)
  4936. register_op( "erf",e_erf , 1)
  4937. register_op( "erfc",e_erfc , 1)
  4938. register_op( "frac",e_frac , 1)
  4939. register_op( "trunc",e_trunc , 1)
  4940. register_op( "atan2",e_atan2 , 2)
  4941. register_op( "min",e_min , 2)
  4942. register_op( "max",e_max , 2)
  4943. register_op( "avg",e_avg , 2)
  4944. register_op( "sum",e_sum , 2)
  4945. register_op( "mul",e_prod , 2)
  4946. register_op( "mod",e_mod , 2)
  4947. register_op( "logn",e_logn , 2)
  4948. register_op( "pow",e_pow , 2)
  4949. register_op( "root",e_root , 2)
  4950. register_op( "roundn",e_roundn , 2)
  4951. register_op( "equal",e_equal , 2)
  4952. register_op("not_equal",e_nequal , 2)
  4953. register_op( "hyp",e_hyp , 2)
  4954. register_op( "shr",e_shr , 2)
  4955. register_op( "shl",e_shl , 2)
  4956. register_op( "clamp",e_clamp , 3)
  4957. register_op( "inrange",e_inrange , 3)
  4958. register_op( "min",e_min , 3)
  4959. register_op( "max",e_max , 3)
  4960. register_op( "avg",e_avg , 3)
  4961. register_op( "sum",e_sum , 3)
  4962. register_op( "mul",e_prod , 3)
  4963. register_op( "min",e_min , 4)
  4964. register_op( "max",e_max , 4)
  4965. register_op( "avg",e_avg , 4)
  4966. register_op( "sum",e_sum , 4)
  4967. register_op( "mul",e_prod , 4)
  4968. register_op( "min",e_min , 5)
  4969. register_op( "max",e_max , 5)
  4970. register_op( "avg",e_avg , 5)
  4971. register_op( "sum",e_sum , 5)
  4972. register_op( "mul",e_prod , 5)
  4973. register_op( "min",e_min , 6)
  4974. register_op( "max",e_max , 6)
  4975. register_op( "avg",e_avg , 6)
  4976. register_op( "sum",e_sum , 6)
  4977. register_op( "mul",e_prod , 6)
  4978. #undef register_op
  4979. }
  4980. } // namespace details
  4981. template <typename T>
  4982. class ifunction
  4983. {
  4984. public:
  4985. explicit ifunction(const std::size_t& pc)
  4986. : param_count(pc)
  4987. {}
  4988. virtual ~ifunction()
  4989. {}
  4990. std::size_t param_count;
  4991. inline virtual T operator()()
  4992. {
  4993. return std::numeric_limits<T>::quiet_NaN();
  4994. }
  4995. inline virtual T operator()(const T&)
  4996. {
  4997. return std::numeric_limits<T>::quiet_NaN();
  4998. }
  4999. inline virtual T operator()(const T&,const T&)
  5000. {
  5001. return std::numeric_limits<T>::quiet_NaN();
  5002. }
  5003. inline virtual T operator()(const T&, const T&, const T&)
  5004. {
  5005. return std::numeric_limits<T>::quiet_NaN();
  5006. }
  5007. inline virtual T operator()(const T&, const T&, const T&, const T&)
  5008. {
  5009. return std::numeric_limits<T>::quiet_NaN();
  5010. }
  5011. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&)
  5012. {
  5013. return std::numeric_limits<T>::quiet_NaN();
  5014. }
  5015. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&)
  5016. {
  5017. return std::numeric_limits<T>::quiet_NaN();
  5018. }
  5019. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5020. {
  5021. return std::numeric_limits<T>::quiet_NaN();
  5022. }
  5023. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5024. {
  5025. return std::numeric_limits<T>::quiet_NaN();
  5026. }
  5027. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5028. {
  5029. return std::numeric_limits<T>::quiet_NaN();
  5030. }
  5031. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5032. {
  5033. return std::numeric_limits<T>::quiet_NaN();
  5034. }
  5035. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5036. const T&)
  5037. {
  5038. return std::numeric_limits<T>::quiet_NaN();
  5039. }
  5040. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5041. const T&, const T&)
  5042. {
  5043. return std::numeric_limits<T>::quiet_NaN();
  5044. }
  5045. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5046. const T&, const T&, const T&)
  5047. {
  5048. return std::numeric_limits<T>::quiet_NaN();
  5049. }
  5050. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5051. const T&, const T&, const T&, const T&)
  5052. {
  5053. return std::numeric_limits<T>::quiet_NaN();
  5054. }
  5055. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5056. const T&, const T&, const T&, const T&, const T&)
  5057. {
  5058. return std::numeric_limits<T>::quiet_NaN();
  5059. }
  5060. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5061. const T&, const T&, const T&, const T&, const T&, const T&)
  5062. {
  5063. return std::numeric_limits<T>::quiet_NaN();
  5064. }
  5065. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5066. const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5067. {
  5068. return std::numeric_limits<T>::quiet_NaN();
  5069. }
  5070. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5071. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5072. {
  5073. return std::numeric_limits<T>::quiet_NaN();
  5074. }
  5075. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5076. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5077. {
  5078. return std::numeric_limits<T>::quiet_NaN();
  5079. }
  5080. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  5081. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  5082. {
  5083. return std::numeric_limits<T>::quiet_NaN();
  5084. }
  5085. };
  5086. template <typename T>
  5087. class symbol_table
  5088. {
  5089. private:
  5090. template <typename Type, typename RawType>
  5091. struct type_store
  5092. {
  5093. typedef typename details::variable_node<T> variable_node_t;
  5094. typedef ifunction<T> ifunction_t;
  5095. #ifndef exprtk_disable_string_capabilities
  5096. typedef typename details::stringvar_node<T> stringvar_node_t;
  5097. #endif
  5098. typedef Type type_t;
  5099. typedef type_t* type_ptr;
  5100. typedef std::pair<bool,type_ptr> type_pair_t;
  5101. typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
  5102. typedef typename type_map_t::iterator tm_itr_t;
  5103. typedef typename type_map_t::const_iterator tm_const_itr_t;
  5104. enum { lut_size = 256 };
  5105. type_pair_t short_type_lut[lut_size];
  5106. type_map_t map;
  5107. std::size_t size;
  5108. type_store()
  5109. : size(0)
  5110. {}
  5111. inline bool symbol_exists(const std::string& symbol_name) const
  5112. {
  5113. if (symbol_name.empty())
  5114. return false;
  5115. else if ((1 == symbol_name.size()) && short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))].second)
  5116. return true;
  5117. else if (map.end() != map.find(symbol_name))
  5118. return true;
  5119. else
  5120. return false;
  5121. }
  5122. inline bool is_constant(const std::string& symbol_name) const
  5123. {
  5124. if (symbol_name.empty())
  5125. return false;
  5126. else if (1 == symbol_name.size() && short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))].first)
  5127. return true;
  5128. else
  5129. {
  5130. tm_const_itr_t itr = map.find(symbol_name);
  5131. if (map.end() == itr)
  5132. return false;
  5133. else
  5134. return (*itr).second.first;
  5135. }
  5136. }
  5137. inline bool add(const std::string& symbol_name, RawType& t, const bool is_constant = false)
  5138. {
  5139. struct tie
  5140. {
  5141. static inline std::pair<bool,variable_node_t*> make(T& t,const bool is_constant = false)
  5142. {
  5143. return std::make_pair(is_constant,new variable_node_t(t));
  5144. }
  5145. #ifndef exprtk_disable_string_capabilities
  5146. static inline std::pair<bool,stringvar_node_t*> make(std::string& t,const bool is_constant = false)
  5147. {
  5148. return std::make_pair(is_constant,new stringvar_node_t(t));
  5149. }
  5150. #endif
  5151. static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
  5152. {
  5153. return std::make_pair(is_constant,&t);
  5154. }
  5155. };
  5156. if (1 == symbol_name.size())
  5157. {
  5158. short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))] = tie::make(t,is_constant);
  5159. ++size;
  5160. }
  5161. else
  5162. {
  5163. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  5164. {
  5165. if (details::imatch(symbol_name,details::reserved_symbols[i]))
  5166. {
  5167. return false;
  5168. }
  5169. }
  5170. tm_itr_t itr = map.find(symbol_name);
  5171. if (map.end() == itr)
  5172. {
  5173. map[symbol_name] = tie::make(t,is_constant);
  5174. ++size;
  5175. }
  5176. }
  5177. return true;
  5178. }
  5179. inline type_ptr get(const std::string& symbol_name)
  5180. {
  5181. if (1 == symbol_name.size())
  5182. {
  5183. type_pair_t& tp = short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))];
  5184. if (tp.second)
  5185. return tp.second;
  5186. else
  5187. return reinterpret_cast<type_ptr>(0);
  5188. }
  5189. else
  5190. {
  5191. tm_const_itr_t itr = map.find(symbol_name);
  5192. if (map.end() == itr)
  5193. return reinterpret_cast<type_ptr>(0);
  5194. else
  5195. return itr->second.second;
  5196. }
  5197. }
  5198. inline bool remove(const std::string& symbol_name)
  5199. {
  5200. if (1 == symbol_name.size())
  5201. {
  5202. type_pair_t& tp = short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))];
  5203. if (0 == tp.second)
  5204. return false;
  5205. struct deleter
  5206. {
  5207. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  5208. #ifndef exprtk_disable_string_capabilities
  5209. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  5210. #endif
  5211. static inline void process(std::pair<bool,function_t*>&) { }
  5212. };
  5213. deleter::process(tp);
  5214. tp.first = false;
  5215. tp.second = 0;
  5216. --size;
  5217. return true;
  5218. }
  5219. else
  5220. {
  5221. tm_itr_t itr = map.find(symbol_name);
  5222. if (map.end() != itr)
  5223. {
  5224. struct deleter
  5225. {
  5226. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  5227. #ifndef exprtk_disable_string_capabilities
  5228. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  5229. #endif
  5230. static inline void process(std::pair<bool,function_t*>&) { }
  5231. };
  5232. deleter::process((*itr).second);
  5233. map.erase(itr);
  5234. --size;
  5235. return true;
  5236. }
  5237. else
  5238. return false;
  5239. }
  5240. }
  5241. inline RawType& type_ref(const std::string& symbol_name)
  5242. {
  5243. struct init_type
  5244. {
  5245. static inline double set(long double) { return (0.0); }
  5246. static inline float set(float) { return (0.0f); }
  5247. static inline std::string set(std::string) { return std::string(""); }
  5248. };
  5249. static RawType null_type = init_type::set(RawType());
  5250. if (1 == symbol_name.size())
  5251. {
  5252. type_pair_t& tp = short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))];
  5253. if (tp.second)
  5254. return tp->second.ref();
  5255. else
  5256. return null_type;
  5257. }
  5258. else
  5259. {
  5260. tm_const_itr_t itr = map.find(symbol_name);
  5261. if (map.end() == itr)
  5262. return null_type;
  5263. else
  5264. return itr->second.second->ref();
  5265. }
  5266. }
  5267. inline void clear()
  5268. {
  5269. for (std::size_t i = 0; i < lut_size; ++i)
  5270. {
  5271. if (short_type_lut[i].second)
  5272. {
  5273. delete (short_type_lut[i]).second;
  5274. short_type_lut[i].first = false;
  5275. short_type_lut[i].second = reinterpret_cast<type_ptr>(0);
  5276. }
  5277. }
  5278. if (!map.empty())
  5279. {
  5280. tm_itr_t itr = map.begin();
  5281. tm_itr_t end = map.end();
  5282. while (end != itr)
  5283. {
  5284. struct deleter
  5285. {
  5286. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  5287. static inline void process(std::pair<bool,function_t*>&) { }
  5288. #ifndef exprtk_disable_string_capabilities
  5289. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  5290. #endif
  5291. };
  5292. deleter::process((*itr).second);
  5293. ++itr;
  5294. }
  5295. map.clear();
  5296. }
  5297. }
  5298. template <typename Allocator,
  5299. template <typename, typename> class Sequence>
  5300. inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
  5301. {
  5302. std::size_t count = 0;
  5303. for (std::size_t i = 0; i < lut_size; ++i)
  5304. {
  5305. const type_pair_t& tp = short_type_lut[static_cast<std::size_t>(i)];
  5306. if (0 != tp.second)
  5307. {
  5308. list.push_back(std::make_pair(std::string("") + static_cast<char>(i),tp.second->ref()));
  5309. ++count;
  5310. }
  5311. }
  5312. if (!map.empty())
  5313. {
  5314. tm_const_itr_t itr = map.begin();
  5315. tm_const_itr_t end = map.end();
  5316. while (end != itr)
  5317. {
  5318. list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
  5319. ++itr;
  5320. ++count;
  5321. }
  5322. }
  5323. return count;
  5324. }
  5325. template <typename Allocator,
  5326. template <typename, typename> class Sequence>
  5327. inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
  5328. {
  5329. std::size_t count = 0;
  5330. for (std::size_t i = 0; i < lut_size; ++i)
  5331. {
  5332. const type_pair_t& tp = short_type_lut[static_cast<std::size_t>(i)];
  5333. if (0 != tp.second)
  5334. {
  5335. vlist.push_back(std::string("") + static_cast<char>(i));
  5336. ++count;
  5337. }
  5338. }
  5339. if (!map.empty())
  5340. {
  5341. tm_const_itr_t itr = map.begin();
  5342. tm_const_itr_t end = map.end();
  5343. while (end != itr)
  5344. {
  5345. vlist.push_back((*itr).first);
  5346. ++itr;
  5347. ++count;
  5348. }
  5349. }
  5350. return count;
  5351. }
  5352. };
  5353. typedef typename details::variable_node<T> variable_t;
  5354. typedef variable_t* variable_ptr;
  5355. #ifndef exprtk_disable_string_capabilities
  5356. typedef typename details::stringvar_node<T> stringvar_t;
  5357. typedef stringvar_t* stringvar_ptr;
  5358. #endif
  5359. typedef ifunction<T> function_t;
  5360. typedef function_t* function_ptr;
  5361. static const std::size_t lut_size = 256;
  5362. //Symbol Table Holder
  5363. struct st_holder
  5364. {
  5365. struct st_data
  5366. {
  5367. type_store<typename details::variable_node<T>,T> variable_store;
  5368. #ifndef exprtk_disable_string_capabilities
  5369. type_store<typename details::stringvar_node<T>,std::string> stringvar_store;
  5370. #endif
  5371. type_store<ifunction<T>,ifunction<T> > function_store;
  5372. st_data()
  5373. {
  5374. for (std::size_t i = 0; i < details::reserved_words_size; ++i)
  5375. {
  5376. reserved_symbol_table_.insert(details::reserved_words[i]);
  5377. }
  5378. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  5379. {
  5380. reserved_symbol_table_.insert(details::reserved_symbols[i]);
  5381. }
  5382. }
  5383. inline bool is_reserved_symbol(const std::string& symbol) const
  5384. {
  5385. return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
  5386. }
  5387. std::list<T> local_symbol_list_;
  5388. std::list<std::string> local_stringvar_list_;
  5389. std::set<std::string> reserved_symbol_table_;
  5390. };
  5391. st_holder()
  5392. : ref_count(1),
  5393. data_(new st_data)
  5394. {}
  5395. st_holder(st_data* data)
  5396. : ref_count(1),
  5397. data_(data)
  5398. {}
  5399. ~st_holder()
  5400. {
  5401. if (data_ && (0 == ref_count))
  5402. {
  5403. delete data_;
  5404. data_ = 0;
  5405. }
  5406. }
  5407. std::size_t ref_count;
  5408. st_data* data_;
  5409. };
  5410. public:
  5411. symbol_table()
  5412. : holder_(new st_holder)
  5413. {
  5414. clear();
  5415. }
  5416. ~symbol_table()
  5417. {
  5418. if (holder_)
  5419. {
  5420. if (0 == --holder_->ref_count)
  5421. {
  5422. clear();
  5423. delete holder_;
  5424. }
  5425. }
  5426. }
  5427. symbol_table(const symbol_table<T>& st)
  5428. {
  5429. holder_ = st.holder_;
  5430. holder_->ref_count++;
  5431. }
  5432. inline symbol_table<T>& operator=(const symbol_table<T>& st)
  5433. {
  5434. if (holder_)
  5435. {
  5436. if (0 == --holder_->ref_count)
  5437. {
  5438. delete holder_;
  5439. }
  5440. holder_ = 0;
  5441. }
  5442. holder_ = st.holder_;
  5443. holder_->ref_count++;
  5444. return *this;
  5445. }
  5446. inline bool operator==(const symbol_table<T>& st)
  5447. {
  5448. return (this == *st);
  5449. }
  5450. inline void clear()
  5451. {
  5452. if (!valid()) return;
  5453. local_data().variable_store.clear();
  5454. local_data().function_store.clear();
  5455. #ifndef exprtk_disable_string_capabilities
  5456. local_data().stringvar_store.clear();
  5457. #endif
  5458. }
  5459. inline std::size_t variable_count() const
  5460. {
  5461. if (valid())
  5462. return local_data().variable_store().size;
  5463. else
  5464. return 0;
  5465. }
  5466. #ifndef exprtk_disable_string_capabilities
  5467. inline std::size_t stringvar_count() const
  5468. {
  5469. if (valid())
  5470. return local_data().stringvar_store().size;
  5471. else
  5472. return 0;
  5473. }
  5474. #endif
  5475. inline std::size_t function_count() const
  5476. {
  5477. if (valid())
  5478. return local_data().function_store().size;
  5479. else
  5480. return 0;
  5481. }
  5482. inline variable_ptr get_variable(const std::string& variable_name)
  5483. {
  5484. if (!valid())
  5485. return reinterpret_cast<variable_ptr>(0);
  5486. else if (!valid_symbol(variable_name))
  5487. return reinterpret_cast<variable_ptr>(0);
  5488. else
  5489. return local_data().variable_store.get(variable_name);
  5490. }
  5491. #ifndef exprtk_disable_string_capabilities
  5492. inline stringvar_ptr get_stringvar(const std::string& string_name)
  5493. {
  5494. if (!valid())
  5495. return reinterpret_cast<stringvar_ptr>(0);
  5496. else if (!valid_symbol(string_name))
  5497. return reinterpret_cast<stringvar_ptr>(0);
  5498. else
  5499. return local_data().stringvar_store.get(string_name);
  5500. }
  5501. #endif
  5502. inline function_ptr get_function(const std::string& function_name)
  5503. {
  5504. if (!valid())
  5505. return reinterpret_cast<function_ptr>(0);
  5506. else if (!valid_symbol(function_name))
  5507. return reinterpret_cast<function_ptr>(0);
  5508. else
  5509. return local_data().function_store.get(function_name);
  5510. }
  5511. inline T& variable_ref(const std::string& symbol_name)
  5512. {
  5513. static T null_var = T(0);
  5514. if (!valid())
  5515. return null_var;
  5516. else if (!valid_symbol(symbol_name))
  5517. return null_var;
  5518. else
  5519. return local_data().variable_store.type_ref(symbol_name);
  5520. }
  5521. #ifndef exprtk_disable_string_capabilities
  5522. inline std::string& stringvar_ref(const std::string& symbol_name)
  5523. {
  5524. static std::string null_stringvar;
  5525. if (!valid())
  5526. return null_stringvar;
  5527. else if (!valid_symbol(symbol_name))
  5528. return null_stringvar;
  5529. else
  5530. return local_data().stringvar_store.type_ref(symbol_name);
  5531. }
  5532. #endif
  5533. inline bool is_constant_node(const std::string& symbol_name) const
  5534. {
  5535. if (!valid())
  5536. return false;
  5537. else if (!valid_symbol(symbol_name))
  5538. return false;
  5539. else if (!local_data().variable_store.symbol_exists(symbol_name))
  5540. return false;
  5541. else
  5542. return local_data().variable_store.is_constant(symbol_name);
  5543. }
  5544. #ifndef exprtk_disable_string_capabilities
  5545. inline bool is_constant_string(const std::string& symbol_name) const
  5546. {
  5547. if (!valid())
  5548. return false;
  5549. else if (!valid_symbol(symbol_name))
  5550. return false;
  5551. else if (!local_data().stringvar_store.symbol_exists(symbol_name))
  5552. return false;
  5553. else
  5554. return local_data().stringvar_store.is_constant(symbol_name);
  5555. }
  5556. #endif
  5557. inline bool create_variable(const std::string& variable_name, const T& value = T(0))
  5558. {
  5559. if (!valid())
  5560. return false;
  5561. else if (!valid_symbol(variable_name))
  5562. return false;
  5563. else if (symbol_exists(variable_name))
  5564. return false;
  5565. local_data().local_symbol_list_.push_back(value);
  5566. T& t = local_data().local_symbol_list_.back();
  5567. return add_variable(variable_name,t);
  5568. }
  5569. #ifndef exprtk_disable_string_capabilities
  5570. inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
  5571. {
  5572. if (!valid())
  5573. return false;
  5574. else if (!valid_symbol(stringvar_name))
  5575. return false;
  5576. else if (symbol_exists(stringvar_name))
  5577. return false;
  5578. local_data().local_stringvar_list_.push_back(value);
  5579. std::string& s = local_data().local_stringvar_list_.back();
  5580. return add_stringvar(stringvar_name,s);
  5581. }
  5582. #endif
  5583. inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
  5584. {
  5585. if (!valid())
  5586. return false;
  5587. else if (!valid_symbol(variable_name))
  5588. return false;
  5589. else if (symbol_exists(variable_name))
  5590. return false;
  5591. else
  5592. return local_data().variable_store.add(variable_name,t,is_constant);
  5593. }
  5594. inline bool add_constant(const std::string& constant_name, const T& value)
  5595. {
  5596. if (!valid())
  5597. return false;
  5598. else if (!valid_symbol(constant_name))
  5599. return false;
  5600. else if (symbol_exists(constant_name))
  5601. return false;
  5602. local_data().local_symbol_list_.push_back(value);
  5603. T& t = local_data().local_symbol_list_.back();
  5604. return add_variable(constant_name,t,true);
  5605. }
  5606. #ifndef exprtk_disable_string_capabilities
  5607. inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
  5608. {
  5609. if (!valid())
  5610. return false;
  5611. else if (!valid_symbol(stringvar_name))
  5612. return false;
  5613. else if (symbol_exists(stringvar_name))
  5614. return false;
  5615. else
  5616. return local_data().stringvar_store.add(stringvar_name,s,is_constant);
  5617. }
  5618. #endif
  5619. inline bool add_function(const std::string& function_name, function_t& function)
  5620. {
  5621. if (!valid())
  5622. return false;
  5623. else if (!valid_symbol(function_name))
  5624. return false;
  5625. else if (symbol_exists(function_name))
  5626. return false;
  5627. else
  5628. return local_data().function_store.add(function_name,function);
  5629. }
  5630. inline bool remove_variable(const std::string& variable_name)
  5631. {
  5632. if (!valid())
  5633. return false;
  5634. else
  5635. return local_data().variable_store.remove(variable_name);
  5636. }
  5637. #ifndef exprtk_disable_string_capabilities
  5638. inline bool remove_stringvar(const std::string& string_name)
  5639. {
  5640. if (!valid())
  5641. return false;
  5642. else
  5643. return local_data().stringvar_store.remove(string_name);
  5644. }
  5645. #endif
  5646. inline bool remove_function(const std::string& function_name)
  5647. {
  5648. if (!valid())
  5649. return false;
  5650. else
  5651. return local_data().function_store.remove(function_name);
  5652. }
  5653. inline bool add_constants()
  5654. {
  5655. return add_pi() &&
  5656. add_epsilon() &&
  5657. add_infinity();
  5658. }
  5659. inline bool add_pi()
  5660. {
  5661. static const T local_pi = T(details::numeric::constant::pi);
  5662. return add_constant("pi",local_pi);
  5663. }
  5664. inline bool add_epsilon()
  5665. {
  5666. static const T local_epsilon = std::numeric_limits<T>::epsilon();
  5667. return add_constant("epsilon",local_epsilon);
  5668. }
  5669. inline bool add_infinity()
  5670. {
  5671. static const T local_infinity = std::numeric_limits<T>::infinity();
  5672. return add_constant("inf",local_infinity);
  5673. }
  5674. template <typename Allocator,
  5675. template <typename, typename> class Sequence>
  5676. inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
  5677. {
  5678. if (!valid())
  5679. return 0;
  5680. else
  5681. return local_data().variable_store.get_list(vlist);
  5682. }
  5683. template <typename Allocator,
  5684. template <typename, typename> class Sequence>
  5685. inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
  5686. {
  5687. if (!valid())
  5688. return 0;
  5689. else
  5690. return local_data().variable_store.get_list(vlist);
  5691. }
  5692. #ifndef exprtk_disable_string_capabilities
  5693. template <typename Allocator,
  5694. template <typename, typename> class Sequence>
  5695. inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
  5696. {
  5697. if (!valid())
  5698. return 0;
  5699. else
  5700. return local_data().stringvar_store.get_list(svlist);
  5701. }
  5702. template <typename Allocator,
  5703. template <typename, typename> class Sequence>
  5704. inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
  5705. {
  5706. if (!valid())
  5707. return 0;
  5708. else
  5709. return local_data().stringvar_store.get_list(svlist);
  5710. }
  5711. #endif
  5712. inline bool symbol_exists(const std::string& symbol_name) const
  5713. {
  5714. /*
  5715. Will return true if symbol_name exists as either a reserved symbol,
  5716. variable, stringvar or function name in any of the type stores.
  5717. */
  5718. if (!valid())
  5719. return false;
  5720. else if (local_data().variable_store.symbol_exists(symbol_name))
  5721. return true;
  5722. #ifndef exprtk_disable_string_capabilities
  5723. else if (local_data().stringvar_store.symbol_exists(symbol_name))
  5724. return true;
  5725. #endif
  5726. else if (local_data().function_store.symbol_exists(symbol_name))
  5727. return true;
  5728. else if (local_data().is_reserved_symbol(symbol_name))
  5729. return true;
  5730. else
  5731. return false;
  5732. }
  5733. inline bool is_variable(const std::string& variable_name) const
  5734. {
  5735. if (!valid())
  5736. return false;
  5737. else
  5738. return local_data().variable_store.symbol_exists(variable_name);
  5739. }
  5740. #ifndef exprtk_disable_string_capabilities
  5741. inline bool is_stringvar(const std::string& stringvar_name) const
  5742. {
  5743. if (!valid())
  5744. return false;
  5745. else
  5746. return local_data().stringvar_store.symbol_exists(stringvar_name);
  5747. }
  5748. #endif
  5749. inline bool is_function(const std::string& function_name) const
  5750. {
  5751. if (!valid())
  5752. return false;
  5753. else
  5754. return local_data().function_store.symbol_exists(function_name);
  5755. }
  5756. inline bool valid() const
  5757. {
  5758. //symbol table sanity check.
  5759. return holder_ && holder_->data_;
  5760. }
  5761. private:
  5762. inline bool valid_symbol(const std::string& symbol) const
  5763. {
  5764. if (symbol.empty())
  5765. return false;
  5766. if (!details::is_letter(symbol[0]))
  5767. return false;
  5768. else if (symbol.size() > 1)
  5769. {
  5770. for (std::size_t i = 1; i < symbol.size(); ++i)
  5771. {
  5772. if (
  5773. (!details::is_letter(symbol[i])) &&
  5774. (!details:: is_digit(symbol[i])) &&
  5775. ('_' != symbol[i])
  5776. )
  5777. return false;
  5778. }
  5779. }
  5780. return (!local_data().is_reserved_symbol(symbol));
  5781. }
  5782. inline typename st_holder::st_data& local_data()
  5783. {
  5784. return *(holder_->data_);
  5785. }
  5786. inline const typename st_holder::st_data& local_data() const
  5787. {
  5788. return *(holder_->data_);
  5789. }
  5790. st_holder* holder_;
  5791. };
  5792. template <typename T> class parser;
  5793. template <typename T> class expression_helper;
  5794. template <typename T>
  5795. class expression
  5796. {
  5797. private:
  5798. typedef details::expression_node<T>* expression_ptr;
  5799. struct expression_holder
  5800. {
  5801. expression_holder()
  5802. : ref_count(0),
  5803. expr(0)
  5804. {}
  5805. expression_holder(expression_ptr e)
  5806. : ref_count(1),
  5807. expr(e)
  5808. {}
  5809. ~expression_holder()
  5810. {
  5811. if (expr && !is_variable_node(expr))
  5812. {
  5813. delete expr;
  5814. }
  5815. }
  5816. std::size_t ref_count;
  5817. expression_ptr expr;
  5818. };
  5819. public:
  5820. expression()
  5821. : expression_holder_(0)
  5822. {}
  5823. expression(const expression<T>& e)
  5824. : expression_holder_(e.expression_holder_),
  5825. symbol_table_(e.symbol_table_)
  5826. {
  5827. expression_holder_->ref_count++;
  5828. }
  5829. inline expression<T>& operator=(const expression<T>& e)
  5830. {
  5831. if (this != &e)
  5832. {
  5833. if (expression_holder_)
  5834. {
  5835. if (0 == --expression_holder_->ref_count)
  5836. {
  5837. delete expression_holder_;
  5838. }
  5839. expression_holder_ = 0;
  5840. }
  5841. expression_holder_ = e.expression_holder_;
  5842. expression_holder_->ref_count++;
  5843. symbol_table_ = e.symbol_table_;
  5844. }
  5845. return *this;
  5846. }
  5847. inline bool operator==(const expression<T>& e)
  5848. {
  5849. return (this == &e);
  5850. }
  5851. inline bool operator!() const
  5852. {
  5853. return ((0 == expression_holder_) || (0 == expression_holder_->expr));
  5854. }
  5855. inline expression<T>& release()
  5856. {
  5857. if (expression_holder_)
  5858. {
  5859. if (0 == --expression_holder_->ref_count)
  5860. {
  5861. delete expression_holder_;
  5862. }
  5863. expression_holder_ = 0;
  5864. }
  5865. return *this;
  5866. }
  5867. ~expression()
  5868. {
  5869. if (expression_holder_)
  5870. {
  5871. if (0 == --expression_holder_->ref_count)
  5872. {
  5873. delete expression_holder_;
  5874. }
  5875. }
  5876. }
  5877. inline T value() const
  5878. {
  5879. return expression_holder_->expr->value();
  5880. }
  5881. inline T operator()() const
  5882. {
  5883. return value();
  5884. }
  5885. inline operator T() const
  5886. {
  5887. return value();
  5888. }
  5889. inline operator bool() const
  5890. {
  5891. return details::is_true(value());
  5892. }
  5893. inline void register_symbol_table(symbol_table<T>& st)
  5894. {
  5895. symbol_table_ = st;
  5896. }
  5897. inline const symbol_table<T>& get_symbol_table() const
  5898. {
  5899. return symbol_table_;
  5900. }
  5901. inline symbol_table<T>& get_symbol_table()
  5902. {
  5903. return symbol_table_;
  5904. }
  5905. private:
  5906. inline void set_expression(const expression_ptr expr)
  5907. {
  5908. if (expr)
  5909. {
  5910. if (expression_holder_)
  5911. {
  5912. if (0 == --expression_holder_->ref_count)
  5913. {
  5914. delete expression_holder_;
  5915. }
  5916. }
  5917. expression_holder_ = new expression_holder(expr);
  5918. }
  5919. }
  5920. expression_holder* expression_holder_;
  5921. symbol_table<T> symbol_table_;
  5922. friend class parser<T>;
  5923. friend class expression_helper<T>;
  5924. };
  5925. template <typename T>
  5926. class expression_helper
  5927. {
  5928. public:
  5929. static inline bool is_head_constant(const expression<T>& expr)
  5930. {
  5931. return details::is_constant_node(expr.expression_holder_->expr);
  5932. }
  5933. static inline bool is_head_variable(const expression<T>& expr)
  5934. {
  5935. return details::is_variable_node(expr.expression_holder_->expr);
  5936. }
  5937. static inline bool is_head_unary(const expression<T>& expr)
  5938. {
  5939. return details::is_unary_node(expr.expression_holder_->expr);
  5940. }
  5941. static inline bool is_head_binary(const expression<T>& expr)
  5942. {
  5943. return details::is_binary_node(expr.expression_holder_->expr);
  5944. }
  5945. static inline bool is_head_function(const expression<T>& expr)
  5946. {
  5947. return details::is_function(expr.expression_holder_->expr);
  5948. }
  5949. };
  5950. namespace parser_error
  5951. {
  5952. enum error_mode
  5953. {
  5954. e_unknown = 0,
  5955. e_syntax = 1,
  5956. e_token = 2,
  5957. e_numeric = 4,
  5958. e_symtab = 5,
  5959. e_lexer = 6,
  5960. e_helper = 7
  5961. };
  5962. struct type
  5963. {
  5964. lexer::token token;
  5965. error_mode mode;
  5966. std::string diagnostic;
  5967. };
  5968. inline type make_error(error_mode mode, const std::string& diagnostic = "")
  5969. {
  5970. type t;
  5971. t.mode = mode;
  5972. t.token.type = lexer::token::e_error;
  5973. t.diagnostic = diagnostic;
  5974. return t;
  5975. }
  5976. inline type make_error(error_mode mode, const lexer::token tk, const std::string& diagnostic = "")
  5977. {
  5978. type t;
  5979. t.mode = mode;
  5980. t.token = tk;
  5981. t.diagnostic = diagnostic;
  5982. return t;
  5983. }
  5984. inline std::string to_str(error_mode mode)
  5985. {
  5986. switch (mode)
  5987. {
  5988. case e_unknown : return std::string("Unknown Error");
  5989. case e_syntax : return std::string("Syntax Error");
  5990. case e_token : return std::string("Token Error");
  5991. case e_numeric : return std::string("Numeric Error");
  5992. case e_symtab : return std::string("Symbol Error");
  5993. case e_lexer : return std::string("Lexer Error");
  5994. case e_helper : return std::string("Helper Error");
  5995. default : return std::string("Unknown Error");
  5996. }
  5997. }
  5998. inline void dump_error(const type& error)
  5999. {
  6000. printf("Position: %02d Type: [%s] Msg: %s\n",
  6001. static_cast<unsigned int>(error.token.position),
  6002. exprtk::parser_error::to_str(error.mode).c_str(),
  6003. error.diagnostic.c_str());
  6004. }
  6005. }
  6006. template <typename T>
  6007. class parser
  6008. {
  6009. private:
  6010. enum precedence_level
  6011. {
  6012. e_level00,
  6013. e_level01,
  6014. e_level02,
  6015. e_level03,
  6016. e_level04,
  6017. e_level05,
  6018. e_level06,
  6019. e_level07,
  6020. e_level08,
  6021. e_level09,
  6022. e_level10,
  6023. e_level11,
  6024. e_level12,
  6025. e_level13
  6026. };
  6027. typedef ifunction <T> F;
  6028. typedef ifunction <T> ifunction_t;
  6029. typedef details::expression_node <T> expression_node_t;
  6030. typedef details::literal_node <T> literal_node_t;
  6031. typedef details::string_literal_node<T> string_literal_node_t;
  6032. typedef details::unary_node <T> unary_node_t;
  6033. typedef details::binary_node <T> binary_node_t;
  6034. typedef details::trinary_node <T> trinary_node_t;
  6035. typedef details::quaternary_node <T> quaternary_node_t;
  6036. typedef details::quinary_node <T> quinary_node_t;
  6037. typedef details::senary_node <T> senary_node_t;
  6038. typedef details::conditional_node<T> conditional_node_t;
  6039. typedef details::while_loop_node <T> while_loop_node_t;
  6040. typedef details::variable_node <T> variable_node_t;
  6041. #ifndef exprtk_disable_string_capabilities
  6042. typedef details::stringvar_node <T> stringvar_node_t;
  6043. #endif
  6044. typedef details::assignment_node <T> assignment_node_t;
  6045. typedef lexer::token token_t;
  6046. typedef expression_node_t* expression_node_ptr;
  6047. public:
  6048. enum optimization_level
  6049. {
  6050. e_none = 0,
  6051. e_level1 = 1,
  6052. e_level2 = 2,
  6053. e_level3 = 4,
  6054. e_all = 7
  6055. };
  6056. enum precompilation_step
  6057. {
  6058. e_unknown = 0,
  6059. e_replacer = 1,
  6060. e_joiner = 2,
  6061. e_numeric_check = 4,
  6062. e_bracket_check = 8,
  6063. e_sequence_check = 16,
  6064. e_commutative_check = 32
  6065. };
  6066. static const std::size_t precompile_all_opts = e_replacer +
  6067. e_joiner +
  6068. e_numeric_check +
  6069. e_bracket_check +
  6070. e_sequence_check +
  6071. e_commutative_check;
  6072. parser(const std::size_t precompile_options = precompile_all_opts)
  6073. : symbol_name_caching_(false),
  6074. precompile_options_(precompile_options)
  6075. {
  6076. init_precompilation();
  6077. load_operations_map(base_ops_map_);
  6078. }
  6079. inline void init_precompilation()
  6080. {
  6081. if (replacer_enabled())
  6082. {
  6083. symbol_replacer_.clear();
  6084. symbol_replacer_.add_replace("true" ,"1",lexer::token::e_number);
  6085. symbol_replacer_.add_replace("false","0",lexer::token::e_number);
  6086. helper_assembly_.token_modifier_list.clear();
  6087. helper_assembly_.register_modifier(&symbol_replacer_);
  6088. }
  6089. if (commutative_check_enabled())
  6090. {
  6091. for (std::size_t i = 0; i < details::reserved_words_size; ++i)
  6092. {
  6093. commutative_inserter_.ignore_symbol(details::reserved_words[i]);
  6094. }
  6095. helper_assembly_.token_inserter_list.clear();
  6096. helper_assembly_.register_inserter(&commutative_inserter_);
  6097. }
  6098. if (joiner_enabled())
  6099. {
  6100. helper_assembly_.token_joiner_list.clear();
  6101. helper_assembly_.register_joiner(&operator_joiner_);
  6102. }
  6103. if (
  6104. numeric_check_enabled() ||
  6105. bracket_check_enabled() ||
  6106. sequence_check_enabled()
  6107. )
  6108. {
  6109. helper_assembly_.token_scanner_list.clear();
  6110. if (numeric_check_enabled())
  6111. {
  6112. helper_assembly_.register_scanner(&numeric_checker_);
  6113. }
  6114. if (bracket_check_enabled())
  6115. {
  6116. helper_assembly_.register_scanner(&bracket_checker_);
  6117. }
  6118. if (sequence_check_enabled())
  6119. {
  6120. helper_assembly_.register_scanner(&sequence_validator_);
  6121. }
  6122. }
  6123. }
  6124. inline bool compile(const std::string& expression_string, expression<T>& expr, const optimization_level& opt_level = e_all)
  6125. {
  6126. error_list_.clear();
  6127. expression_generator_.set_optimization_level(opt_level);
  6128. expression_generator_.set_allocator(node_allocator_);
  6129. if (!lexer_.process(expression_string))
  6130. {
  6131. process_lexer_errors();
  6132. return false;
  6133. }
  6134. if (!run_assemblies())
  6135. {
  6136. return false;
  6137. }
  6138. symbol_table_ = expr.get_symbol_table();
  6139. symbol_name_cache_.clear();
  6140. lexer_.begin();
  6141. next_token();
  6142. expression_node_ptr e = parse_expression();
  6143. if ((0 != e) && (token_t::e_eof == current_token_.type))
  6144. {
  6145. expr.set_expression(e);
  6146. return !(!expr);
  6147. }
  6148. else
  6149. {
  6150. set_error(parser_error::make_error(parser_error::e_syntax, "ERR01 - Incomplete expression!"));
  6151. symbol_name_cache_.clear();
  6152. if (0 != e) delete e;
  6153. return false;
  6154. }
  6155. }
  6156. void process_lexer_errors()
  6157. {
  6158. for (std::size_t i = 0; i < lexer_.size(); ++i)
  6159. {
  6160. if (lexer_[i].is_error())
  6161. {
  6162. std::string diagnostic = "ERR02 - ";
  6163. switch (lexer_[i].type)
  6164. {
  6165. case lexer::token::e_error : diagnostic + "General token error";
  6166. break;
  6167. case lexer::token::e_err_symbol : diagnostic + "Symbol error";
  6168. break;
  6169. case lexer::token::e_err_number : diagnostic + "Invalid numeric token";
  6170. break;
  6171. case lexer::token::e_err_string : diagnostic + "Invalid string token";
  6172. break;
  6173. case lexer::token::e_err_sfunc : diagnostic + "Invalid special function token";
  6174. break;
  6175. default : diagnostic + "Unknown compiler error";
  6176. break;
  6177. }
  6178. set_error(make_error(parser_error::e_lexer,lexer_[i],diagnostic + ": " + lexer_[i].value));
  6179. }
  6180. }
  6181. }
  6182. inline bool replacer_enabled() const
  6183. {
  6184. return ((precompile_options_ & e_replacer) == e_replacer);
  6185. }
  6186. inline bool commutative_check_enabled() const
  6187. {
  6188. return ((precompile_options_ & e_commutative_check) == e_commutative_check);
  6189. }
  6190. inline bool joiner_enabled() const
  6191. {
  6192. return ((precompile_options_ & e_joiner) == e_joiner);
  6193. }
  6194. inline bool numeric_check_enabled() const
  6195. {
  6196. return ((precompile_options_ & e_numeric_check) == e_numeric_check);
  6197. }
  6198. inline bool bracket_check_enabled() const
  6199. {
  6200. return ((precompile_options_ & e_bracket_check) == e_bracket_check);
  6201. }
  6202. inline bool sequence_check_enabled() const
  6203. {
  6204. return ((precompile_options_ & e_sequence_check) == e_sequence_check);
  6205. }
  6206. inline bool run_assemblies()
  6207. {
  6208. if (commutative_check_enabled())
  6209. {
  6210. helper_assembly_.run_inserters(lexer_);
  6211. }
  6212. if (joiner_enabled())
  6213. {
  6214. helper_assembly_.run_joiners(lexer_);
  6215. }
  6216. if (replacer_enabled())
  6217. {
  6218. helper_assembly_.run_modifiers(lexer_);
  6219. }
  6220. if (
  6221. numeric_check_enabled() ||
  6222. bracket_check_enabled() ||
  6223. sequence_check_enabled()
  6224. )
  6225. {
  6226. if (!helper_assembly_.run_scanners(lexer_))
  6227. {
  6228. if (helper_assembly_.error_token_scanner)
  6229. {
  6230. lexer::helper::bracket_checker* bracket_checker_ptr = 0;
  6231. lexer::helper::numeric_checker* numeric_checker_ptr = 0;
  6232. lexer::helper::sequence_validator* sequence_validator_ptr = 0;
  6233. if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
  6234. {
  6235. set_error(
  6236. make_error(parser_error::e_token,
  6237. bracket_checker_ptr->error_token(),
  6238. "ERR03 - Mismatched brackets: " + bracket_checker_ptr->error_token().value));
  6239. }
  6240. else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker*>(helper_assembly_.error_token_scanner)))
  6241. {
  6242. for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i)
  6243. {
  6244. lexer::token error_token = lexer_[numeric_checker_ptr->error_index(i)];
  6245. set_error(
  6246. make_error(parser_error::e_token,
  6247. error_token,
  6248. "ERR04 - Invalid numeric token: " + error_token.value));
  6249. }
  6250. }
  6251. else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner)))
  6252. {
  6253. for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i)
  6254. {
  6255. std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i);
  6256. set_error(
  6257. make_error(parser_error::e_token,
  6258. error_token.first,
  6259. "ERR05 - Invalid token sequence: " +
  6260. error_token.first.value + " " +
  6261. error_token.second.value));
  6262. }
  6263. }
  6264. }
  6265. return false;
  6266. }
  6267. }
  6268. return true;
  6269. }
  6270. inline parser_error::type get_error(const std::size_t& index)
  6271. {
  6272. if (index < error_list_.size())
  6273. return error_list_[index];
  6274. else
  6275. throw std::invalid_argument("parser::get_error() - Invalid error index specificed.");
  6276. }
  6277. inline std::string error() const
  6278. {
  6279. if (!error_list_.empty())
  6280. {
  6281. return error_list_[0].diagnostic;
  6282. }
  6283. else
  6284. return std::string("No Error");
  6285. }
  6286. inline std::size_t error_count() const
  6287. {
  6288. return error_list_.size();
  6289. }
  6290. inline bool& cache_symbols()
  6291. {
  6292. return symbol_name_caching_;
  6293. }
  6294. template <typename Allocator,
  6295. template <typename,typename> class Sequence>
  6296. inline std::size_t expression_symbols(Sequence<std::string,Allocator>& symbols_list)
  6297. {
  6298. if (!symbol_name_caching_)
  6299. return 0;
  6300. if (symbol_name_cache_.empty())
  6301. return 0;
  6302. std::copy(symbol_name_cache_.begin(),
  6303. symbol_name_cache_.end(),
  6304. std::back_inserter(symbols_list));
  6305. return symbol_name_cache_.size();
  6306. }
  6307. inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol)
  6308. {
  6309. if (details::is_reserved_word(old_symbol))
  6310. return false;
  6311. else if (!replacer_enabled())
  6312. return false;
  6313. else
  6314. return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol);
  6315. }
  6316. private:
  6317. inline bool valid_base_operation(const std::string& symbol)
  6318. {
  6319. const std::size_t length = symbol.size();
  6320. if (
  6321. (length < 3) || //Shortest base op symbol length
  6322. (length > 9) //Longest base op symbol length
  6323. )
  6324. return false;
  6325. else
  6326. return (base_ops_map_.end() != base_ops_map_.find(symbol));
  6327. }
  6328. inline void store_token()
  6329. {
  6330. lexer_.store();
  6331. store_current_token_ = current_token_;
  6332. }
  6333. inline void restore_token()
  6334. {
  6335. lexer_.restore();
  6336. current_token_ = store_current_token_;
  6337. }
  6338. inline void next_token()
  6339. {
  6340. current_token_ = lexer_.next_token();
  6341. }
  6342. static const precedence_level default_precedence = e_level00;
  6343. struct state_t
  6344. {
  6345. inline void set(const precedence_level& l,
  6346. const precedence_level& r,
  6347. const details::operator_type& o)
  6348. {
  6349. left = l;
  6350. right = r;
  6351. operation = o;
  6352. }
  6353. inline void reset()
  6354. {
  6355. left = e_level00;
  6356. right = e_level00;
  6357. }
  6358. precedence_level left;
  6359. precedence_level right;
  6360. details::operator_type operation;
  6361. };
  6362. inline expression_node_ptr parse_expression(precedence_level precedence = e_level00)
  6363. {
  6364. expression_node_ptr expr = parse_branch();
  6365. if (0 == expr)
  6366. {
  6367. return expr;
  6368. }
  6369. bool break_loop = false;
  6370. state_t current_state;
  6371. for ( ; ; )
  6372. {
  6373. current_state.reset();
  6374. switch (current_token_.type)
  6375. {
  6376. case token_t::e_assign : current_state.set(e_level00,e_level00,details::e_assign); break;
  6377. case token_t::e_lt : current_state.set(e_level05,e_level06,details:: e_lt); break;
  6378. case token_t::e_lte : current_state.set(e_level05,e_level06,details:: e_lte); break;
  6379. case token_t::e_eq : current_state.set(e_level05,e_level06,details:: e_eq); break;
  6380. case token_t::e_ne : current_state.set(e_level05,e_level06,details:: e_ne); break;
  6381. case token_t::e_gte : current_state.set(e_level05,e_level06,details:: e_gte); break;
  6382. case token_t::e_gt : current_state.set(e_level05,e_level06,details:: e_gt); break;
  6383. case token_t::e_add : current_state.set(e_level07,e_level08,details:: e_add); break;
  6384. case token_t::e_sub : current_state.set(e_level07,e_level08,details:: e_sub); break;
  6385. case token_t::e_div : current_state.set(e_level10,e_level11,details:: e_div); break;
  6386. case token_t::e_mul : current_state.set(e_level10,e_level11,details:: e_mul); break;
  6387. case token_t::e_mod : current_state.set(e_level10,e_level11,details:: e_mod); break;
  6388. case token_t::e_pow : current_state.set(e_level12,e_level12,details:: e_pow); break;
  6389. default : if (token_t::e_symbol == current_token_.type)
  6390. {
  6391. static const std::string s_and = "and";
  6392. static const std::string s_nand = "nand";
  6393. static const std::string s_or = "or";
  6394. static const std::string s_nor = "nor";
  6395. static const std::string s_xor = "xor";
  6396. static const std::string s_in = "in";
  6397. static const std::string s_like = "like";
  6398. static const std::string s_ilike = "ilike";
  6399. if (details::imatch(current_token_.value,s_and))
  6400. {
  6401. current_state.set(e_level01,e_level02,details::e_and);
  6402. break;
  6403. }
  6404. else if (details::imatch(current_token_.value,s_nand))
  6405. {
  6406. current_state.set(e_level01,e_level02,details::e_nand);
  6407. break;
  6408. }
  6409. else if (details::imatch(current_token_.value,s_or))
  6410. {
  6411. current_state.set(e_level03,e_level04,details::e_or);
  6412. break;
  6413. }
  6414. else if (details::imatch(current_token_.value,s_nor))
  6415. {
  6416. current_state.set(e_level03,e_level04,details::e_nor);
  6417. break;
  6418. }
  6419. else if (details::imatch(current_token_.value,s_xor))
  6420. {
  6421. current_state.set(e_level03,e_level04,details::e_xor);
  6422. break;
  6423. }
  6424. else if (details::imatch(current_token_.value,s_in))
  6425. {
  6426. current_state.set(e_level03,e_level04,details::e_in);
  6427. break;
  6428. }
  6429. else if (details::imatch(current_token_.value,s_like))
  6430. {
  6431. current_state.set(e_level03,e_level04,details::e_like);
  6432. break;
  6433. }
  6434. else if (details::imatch(current_token_.value,s_ilike))
  6435. {
  6436. current_state.set(e_level03,e_level04,details::e_ilike);
  6437. break;
  6438. }
  6439. }
  6440. break_loop = true;
  6441. }
  6442. if (break_loop)
  6443. break;
  6444. else if (current_state.left < precedence)
  6445. break;
  6446. next_token();
  6447. expr = expression_generator_(current_state.operation,expr,parse_expression(current_state.right));
  6448. if (0 == expr)
  6449. {
  6450. return expr;
  6451. }
  6452. }
  6453. return expr;
  6454. }
  6455. static inline expression_node_ptr error_node()
  6456. {
  6457. return reinterpret_cast<expression_node_ptr>(0);
  6458. }
  6459. template <typename Type, std::size_t N>
  6460. struct scoped_delete
  6461. {
  6462. typedef Type* ptr_t;
  6463. scoped_delete(parser<T>& pr, ptr_t& p)
  6464. : delete_ptr(true),
  6465. parser_(pr),
  6466. p_(&p)
  6467. {}
  6468. scoped_delete(parser<T>& pr, ptr_t (&p)[N])
  6469. : delete_ptr(true),
  6470. parser_(pr),
  6471. p_(&p[0])
  6472. {}
  6473. ~scoped_delete()
  6474. {
  6475. if (delete_ptr)
  6476. {
  6477. for (std::size_t i = 0; i < N; ++i)
  6478. {
  6479. if (p_[i] && !is_variable_node(p_[i]))
  6480. {
  6481. parser_.node_allocator_.free(p_[i]);
  6482. }
  6483. }
  6484. }
  6485. }
  6486. bool delete_ptr;
  6487. parser<T>& parser_;
  6488. ptr_t* p_;
  6489. private:
  6490. scoped_delete<Type,N>& operator=(const scoped_delete<Type,N>&);
  6491. };
  6492. template <std::size_t NumberofParameters>
  6493. inline expression_node_ptr parse_function_call(const details::operator_type& opt_type)
  6494. {
  6495. expression_node_ptr branch[NumberofParameters];
  6496. expression_node_ptr result = 0;
  6497. std::fill_n(branch,NumberofParameters,reinterpret_cast<expression_node_ptr>(0));
  6498. scoped_delete<expression_node_t,NumberofParameters> sd(*this,branch);
  6499. store_token();
  6500. next_token();
  6501. if (!token_is(token_t::e_lbracket))
  6502. {
  6503. return error_node();
  6504. }
  6505. for (int i = 0; i < static_cast<int>(NumberofParameters); ++i)
  6506. {
  6507. branch[i] = parse_expression();
  6508. if (0 == branch[i])
  6509. {
  6510. return error_node();
  6511. }
  6512. else if (i < static_cast<int>(NumberofParameters - 1))
  6513. {
  6514. if (!token_is(token_t::e_comma))
  6515. {
  6516. return error_node();
  6517. }
  6518. }
  6519. }
  6520. if (!token_is(token_t::e_rbracket))
  6521. {
  6522. return error_node();
  6523. }
  6524. else
  6525. result = expression_generator_(opt_type,branch);
  6526. sd.delete_ptr = false;
  6527. return result;
  6528. }
  6529. template <std::size_t NumberofParameters>
  6530. inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name)
  6531. {
  6532. expression_node_ptr branch[NumberofParameters];
  6533. expression_node_ptr result = 0;
  6534. std::fill_n(branch,NumberofParameters,reinterpret_cast<expression_node_ptr>(0));
  6535. scoped_delete<expression_node_t,NumberofParameters> sd(*this,branch);
  6536. next_token();
  6537. if (!token_is(token_t::e_lbracket))
  6538. {
  6539. set_error(
  6540. make_error(parser_error::e_syntax,
  6541. current_token_,
  6542. "ERR06 - Expecting argument list for function: '" + function_name + "'"));
  6543. return error_node();
  6544. }
  6545. for (int i = 0; i < static_cast<int>(NumberofParameters); ++i)
  6546. {
  6547. branch[i] = parse_expression();
  6548. if (0 == branch[i])
  6549. {
  6550. set_error(
  6551. make_error(parser_error::e_syntax,
  6552. current_token_,
  6553. "ERR07 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'"));
  6554. return error_node();
  6555. }
  6556. else if (i < static_cast<int>(NumberofParameters - 1))
  6557. {
  6558. if (!token_is(token_t::e_comma))
  6559. {
  6560. set_error(
  6561. make_error(parser_error::e_syntax,
  6562. current_token_,
  6563. "ERR08 - Invalid number of arguments for function: '" + function_name + "'"));
  6564. return error_node();
  6565. }
  6566. }
  6567. }
  6568. if (!token_is(token_t::e_rbracket))
  6569. {
  6570. set_error(
  6571. make_error(parser_error::e_syntax,
  6572. current_token_,
  6573. "ERR09 - Invalid number of arguments for function: '" + function_name + "'"));
  6574. return error_node();
  6575. }
  6576. else
  6577. result = expression_generator_.function(function,branch);
  6578. sd.delete_ptr = false;
  6579. return result;
  6580. }
  6581. inline expression_node_ptr parse_base_operation()
  6582. {
  6583. typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> map_t;
  6584. typedef std::pair<map_t::iterator,map_t::iterator> map_range_t;
  6585. const std::string operation_name = current_token_.value;
  6586. map_range_t itr_range = base_ops_map_.equal_range(operation_name);
  6587. if (0 == std::distance(itr_range.first,itr_range.second))
  6588. {
  6589. set_error(
  6590. make_error(parser_error::e_syntax,
  6591. current_token_,
  6592. "ERR10 - No entries found for base operation: " + operation_name));
  6593. return error_node();
  6594. }
  6595. for (map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
  6596. {
  6597. store_token();
  6598. expression_node_ptr branch = reinterpret_cast<expression_node_ptr>(0);
  6599. details::base_operation_t& operation = itr->second;
  6600. switch (operation.num_params)
  6601. {
  6602. case 1 : branch = parse_function_call<1>(operation.type); break;
  6603. case 2 : branch = parse_function_call<2>(operation.type); break;
  6604. case 3 : branch = parse_function_call<3>(operation.type); break;
  6605. case 4 : branch = parse_function_call<4>(operation.type); break;
  6606. case 5 : branch = parse_function_call<5>(operation.type); break;
  6607. case 6 : branch = parse_function_call<6>(operation.type); break;
  6608. default :
  6609. {
  6610. set_error(
  6611. make_error(parser_error::e_syntax,
  6612. current_token_,
  6613. "ERR11 - Impossible argument count for base function: " + operation_name));
  6614. return error_node();
  6615. }
  6616. }
  6617. if (branch)
  6618. {
  6619. return branch;
  6620. }
  6621. remove_last_error();
  6622. restore_token();
  6623. }
  6624. set_error(
  6625. make_error(parser_error::e_syntax,
  6626. current_token_,
  6627. "ERR12 - Invalid parameter count for function: " + operation_name));
  6628. return error_node();
  6629. }
  6630. inline expression_node_ptr parse_conditional_statement()
  6631. {
  6632. //Parse: [if][(][condition][,][consequent][,][alternative][)]
  6633. expression_node_ptr condition = 0;
  6634. expression_node_ptr consequent = 0;
  6635. expression_node_ptr alternative = 0;
  6636. next_token();
  6637. if (!token_is(token_t::e_lbracket))
  6638. return error_node();
  6639. else if (0 == (condition = parse_expression()))
  6640. {
  6641. set_error(
  6642. make_error(parser_error::e_syntax,
  6643. current_token_,
  6644. "ERR13 - Failed to parse condition for if-statement"));
  6645. return error_node();
  6646. }
  6647. else if (!token_is(token_t::e_comma))
  6648. return error_node();
  6649. else if (0 == (consequent = parse_expression()))
  6650. {
  6651. set_error(
  6652. make_error(parser_error::e_syntax,
  6653. current_token_,
  6654. "ERR14 - Failed to parse consequent for if-statement"));
  6655. return error_node();
  6656. }
  6657. else if (!token_is(token_t::e_comma))
  6658. return error_node();
  6659. else if (0 == (alternative = parse_expression()))
  6660. {
  6661. set_error(
  6662. make_error(parser_error::e_syntax,
  6663. current_token_,
  6664. "ERR15 - Failed to parse alternative for if-statement"));
  6665. return error_node();
  6666. }
  6667. else if (!token_is(token_t::e_rbracket))
  6668. return error_node();
  6669. else
  6670. return expression_generator_.conditional(condition,consequent,alternative);
  6671. }
  6672. inline expression_node_ptr parse_while_loop()
  6673. {
  6674. //Parse: [while][(][test expr][)][{][expression][}]
  6675. expression_node_ptr condition = 0;
  6676. expression_node_ptr branch = 0;
  6677. next_token();
  6678. if (!token_is(token_t::e_lbracket))
  6679. return error_node();
  6680. else if (0 == (condition = parse_expression()))
  6681. {
  6682. set_error(
  6683. make_error(parser_error::e_syntax,
  6684. current_token_,
  6685. "ERR16 - Failed to parse condition for while-loop"));
  6686. return error_node();
  6687. }
  6688. else if (!token_is(token_t::e_rbracket))
  6689. return error_node();
  6690. else if (!token_is(token_t::e_lcrlbracket))
  6691. return error_node();
  6692. else if (0 == (branch = parse_expression()))
  6693. {
  6694. set_error(
  6695. make_error(parser_error::e_syntax,
  6696. current_token_,
  6697. "ERR17 - Failed to parse branch for while-loop"));
  6698. return error_node();
  6699. }
  6700. else if (!token_is(token_t::e_rcrlbracket))
  6701. return error_node();
  6702. else
  6703. return expression_generator_.while_loop(condition,branch);
  6704. }
  6705. template<typename Type, std::size_t NumberOfParameters>
  6706. struct parse_special_function_impl
  6707. {
  6708. static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type)
  6709. {
  6710. expression_node_ptr branch[NumberOfParameters];
  6711. expression_node_ptr result = 0;
  6712. std::fill_n(branch,NumberOfParameters,reinterpret_cast<expression_node_ptr>(0));
  6713. scoped_delete<expression_node_t,NumberOfParameters> sd(p,branch);
  6714. p.next_token();
  6715. if (!p.token_is(token_t::e_lbracket))
  6716. {
  6717. return error_node();
  6718. }
  6719. for (std::size_t i = 0; i < NumberOfParameters; ++i)
  6720. {
  6721. branch[i] = p.parse_expression();
  6722. if (0 == branch[i])
  6723. {
  6724. return p.error_node();
  6725. }
  6726. else if (i < (NumberOfParameters - 1))
  6727. {
  6728. if (!p.token_is(token_t::e_comma))
  6729. {
  6730. return p.error_node();
  6731. }
  6732. }
  6733. }
  6734. if (!p.token_is(token_t::e_rbracket))
  6735. return p.error_node();
  6736. else
  6737. result = p.expression_generator_.special_function(opt_type,branch);
  6738. sd.delete_ptr = false;
  6739. return result;
  6740. }
  6741. };
  6742. inline expression_node_ptr parse_special_function()
  6743. {
  6744. //Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
  6745. if (
  6746. !details::is_digit(current_token_.value[2]) ||
  6747. !details::is_digit(current_token_.value[3])
  6748. )
  6749. {
  6750. set_error(
  6751. make_error(parser_error::e_token,
  6752. current_token_,
  6753. "ERR18 - Invalid special function[1]: " + current_token_.value));
  6754. return error_node();
  6755. }
  6756. const unsigned int id = (current_token_.value[2] - '0') * 10 + (current_token_.value[3] - '0');
  6757. if (id > 82)
  6758. {
  6759. set_error(
  6760. make_error(parser_error::e_token,
  6761. current_token_,
  6762. "ERR19 - Invalid special function[2]: " + current_token_.value));
  6763. return error_node();
  6764. }
  6765. const std::size_t sf_3_to_4 = details::e_sf35;
  6766. const details::operator_type opt_type = details::operator_type(id + 1000);
  6767. const std::size_t NumberOfParameters = (id < (sf_3_to_4 - 1000)) ? 3 : 4;
  6768. switch (NumberOfParameters)
  6769. {
  6770. case 3 : return parse_special_function_impl<T,3>::process(*this,opt_type);
  6771. case 4 : return parse_special_function_impl<T,4>::process(*this,opt_type);
  6772. default : return error_node();
  6773. }
  6774. }
  6775. inline expression_node_ptr parse_symtab_symbol()
  6776. {
  6777. const std::string symbol = current_token_.value;
  6778. //Are we dealing with a variable or a special constant?
  6779. expression_node_ptr variable = symbol_table_.get_variable(symbol);
  6780. if (variable)
  6781. {
  6782. if (symbol_name_caching_)
  6783. {
  6784. symbol_name_cache_.push_back(symbol);
  6785. }
  6786. if (symbol_table_.is_constant_node(symbol))
  6787. {
  6788. variable = expression_generator_(variable->value());
  6789. }
  6790. next_token();
  6791. return variable;
  6792. }
  6793. #ifndef exprtk_disable_string_capabilities
  6794. //Are we dealing with a string variable?
  6795. variable = symbol_table_.get_stringvar(symbol);
  6796. if (variable)
  6797. {
  6798. if (symbol_name_caching_)
  6799. {
  6800. symbol_name_cache_.push_back(symbol);
  6801. }
  6802. if (symbol_table_.is_constant_node(symbol))
  6803. {
  6804. variable = expression_generator_(dynamic_cast<details::string_literal_node<T>*>(variable)->str());
  6805. }
  6806. next_token();
  6807. return variable;
  6808. }
  6809. #endif
  6810. //Are we dealing with a function?
  6811. ifunction<T>* function = symbol_table_.get_function(symbol);
  6812. if (function)
  6813. {
  6814. expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0);
  6815. switch (function->param_count)
  6816. {
  6817. case 0 : func_node = expression_generator_.function(function); break;
  6818. case 1 : func_node = parse_function_call< 1>(function,symbol); break;
  6819. case 2 : func_node = parse_function_call< 2>(function,symbol); break;
  6820. case 3 : func_node = parse_function_call< 3>(function,symbol); break;
  6821. case 4 : func_node = parse_function_call< 4>(function,symbol); break;
  6822. case 5 : func_node = parse_function_call< 5>(function,symbol); break;
  6823. case 6 : func_node = parse_function_call< 6>(function,symbol); break;
  6824. case 7 : func_node = parse_function_call< 7>(function,symbol); break;
  6825. case 8 : func_node = parse_function_call< 8>(function,symbol); break;
  6826. case 9 : func_node = parse_function_call< 9>(function,symbol); break;
  6827. case 10 : func_node = parse_function_call<10>(function,symbol); break;
  6828. case 11 : func_node = parse_function_call<11>(function,symbol); break;
  6829. case 12 : func_node = parse_function_call<12>(function,symbol); break;
  6830. case 13 : func_node = parse_function_call<13>(function,symbol); break;
  6831. case 14 : func_node = parse_function_call<14>(function,symbol); break;
  6832. case 15 : func_node = parse_function_call<15>(function,symbol); break;
  6833. case 16 : func_node = parse_function_call<16>(function,symbol); break;
  6834. case 17 : func_node = parse_function_call<17>(function,symbol); break;
  6835. case 18 : func_node = parse_function_call<18>(function,symbol); break;
  6836. case 19 : func_node = parse_function_call<19>(function,symbol); break;
  6837. case 20 : func_node = parse_function_call<20>(function,symbol); break;
  6838. default : {
  6839. set_error(
  6840. make_error(parser_error::e_syntax,
  6841. current_token_,
  6842. "ERR20 - Invalid number of parameters for function: " + symbol));
  6843. return expression_node_ptr(0);
  6844. }
  6845. }
  6846. if (func_node)
  6847. return func_node;
  6848. else
  6849. {
  6850. set_error(
  6851. make_error(parser_error::e_syntax,
  6852. current_token_,
  6853. "ERR21 - Failed to generate node for function: '" + symbol + "'"));
  6854. return error_node();
  6855. }
  6856. }
  6857. else
  6858. {
  6859. set_error(
  6860. make_error(parser_error::e_syntax,
  6861. current_token_,
  6862. "ERR22 - Undefined variable or function: '" + symbol + "'"));
  6863. return error_node();
  6864. }
  6865. }
  6866. inline expression_node_ptr parse_symbol()
  6867. {
  6868. static const std::string symbol_if = "if";
  6869. static const std::string symbol_while = "while";
  6870. if (valid_base_operation(current_token_.value))
  6871. {
  6872. return parse_base_operation();
  6873. }
  6874. else if (details::imatch(current_token_.value,symbol_if))
  6875. {
  6876. return parse_conditional_statement();
  6877. }
  6878. else if (details::imatch(current_token_.value,symbol_while))
  6879. {
  6880. return parse_while_loop();
  6881. }
  6882. else if (details::is_valid_sf_symbol(current_token_.value))
  6883. {
  6884. return parse_special_function();
  6885. }
  6886. else if (symbol_table_.valid())
  6887. {
  6888. return parse_symtab_symbol();
  6889. }
  6890. else
  6891. {
  6892. set_error(
  6893. make_error(parser_error::e_symtab,
  6894. current_token_,
  6895. "ERR23 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value));
  6896. return error_node();
  6897. }
  6898. }
  6899. inline expression_node_ptr parse_branch()
  6900. {
  6901. if (token_t::e_number == current_token_.type)
  6902. {
  6903. T numeric_value = T(0);
  6904. if (details::string_to_real(current_token_.value,numeric_value))
  6905. {
  6906. expression_node_ptr literal_exp = expression_generator_(numeric_value);
  6907. next_token();
  6908. return literal_exp;
  6909. }
  6910. else
  6911. return error_node();
  6912. }
  6913. else if (token_t::e_symbol == current_token_.type)
  6914. {
  6915. return parse_symbol();
  6916. }
  6917. #ifndef exprtk_disable_string_capabilities
  6918. else if (token_t::e_string == current_token_.type)
  6919. {
  6920. expression_node_ptr literal_exp = expression_generator_(current_token_.value);
  6921. next_token();
  6922. return literal_exp;
  6923. }
  6924. #endif
  6925. else if (token_t::e_lbracket == current_token_.type)
  6926. {
  6927. next_token();
  6928. expression_node_ptr branch = parse_expression();
  6929. if (token_is(token_t::e_rbracket))
  6930. return branch;
  6931. else
  6932. return error_node();
  6933. }
  6934. else if (token_t::e_lsqrbracket == current_token_.type)
  6935. {
  6936. next_token();
  6937. expression_node_ptr branch = parse_expression();
  6938. if (token_is(token_t::e_rsqrbracket))
  6939. return branch;
  6940. else
  6941. return error_node();
  6942. }
  6943. else if (token_t::e_lcrlbracket == current_token_.type)
  6944. {
  6945. next_token();
  6946. expression_node_ptr branch = parse_expression();
  6947. if (token_is(token_t::e_rcrlbracket))
  6948. return branch;
  6949. else
  6950. return error_node();
  6951. }
  6952. else if (token_t::e_sub == current_token_.type)
  6953. {
  6954. next_token();
  6955. return expression_generator_(details::e_neg,parse_expression(e_level09));
  6956. }
  6957. else if (token_t::e_add == current_token_.type)
  6958. {
  6959. next_token();
  6960. return expression_generator_(details::e_pos,parse_expression(e_level09));
  6961. }
  6962. else if (token_t::e_eof == current_token_.type)
  6963. {
  6964. set_error(
  6965. make_error(parser_error::e_syntax,
  6966. current_token_,
  6967. "ERR24 - Premature end of expression.[1]"));
  6968. return error_node();
  6969. }
  6970. else
  6971. {
  6972. set_error(
  6973. make_error(parser_error::e_syntax,
  6974. current_token_,
  6975. "ERR25 - Premature end of expression.[2]"));
  6976. return error_node();
  6977. }
  6978. }
  6979. inline bool token_is(const typename token_t::token_type& ttype)
  6980. {
  6981. if (current_token_.type != ttype)
  6982. {
  6983. if (!((']' == current_token_.type) && (token_t::e_rbracket == ttype)))
  6984. {
  6985. set_error(
  6986. make_error(parser_error::e_token,
  6987. current_token_,
  6988. std::string("ERR26 - Expected token: '") + static_cast<char>(ttype) + "'"));
  6989. return false;
  6990. }
  6991. }
  6992. next_token();
  6993. return true;
  6994. }
  6995. template <typename Type>
  6996. class expression_generator
  6997. {
  6998. public:
  6999. typedef details::expression_node<Type>* expression_node_ptr;
  7000. inline void set_optimization_level(const optimization_level& optimization_level)
  7001. {
  7002. optimization_level_ = optimization_level;
  7003. }
  7004. inline void set_allocator(details::node_allocator& na)
  7005. {
  7006. node_allocator_ = &na;
  7007. }
  7008. inline expression_node_ptr operator()(const Type& v) const
  7009. {
  7010. return node_allocator_->allocate<literal_node_t>(v);
  7011. }
  7012. inline expression_node_ptr operator()(const std::string& s) const
  7013. {
  7014. return node_allocator_->allocate<string_literal_node_t>(s);
  7015. }
  7016. inline bool unary_optimizable(const details::operator_type& operation) const
  7017. {
  7018. return (details::e_abs == operation) || (details::e_acos == operation) ||
  7019. (details::e_asin == operation) || (details::e_atan == operation) ||
  7020. (details::e_ceil == operation) || (details::e_cos == operation) ||
  7021. (details::e_cosh == operation) || (details::e_exp == operation) ||
  7022. (details::e_floor == operation) || (details::e_log == operation) ||
  7023. (details::e_log10 == operation) || (details::e_neg == operation) ||
  7024. (details::e_pos == operation) || (details::e_round == operation) ||
  7025. (details::e_sin == operation) || (details::e_sinh == operation) ||
  7026. (details::e_sqrt == operation) || (details::e_tan == operation) ||
  7027. (details::e_tanh == operation) || (details::e_cot == operation) ||
  7028. (details::e_sec == operation) || (details::e_csc == operation) ||
  7029. (details::e_r2d == operation) || (details::e_d2r == operation) ||
  7030. (details::e_d2g == operation) || (details::e_g2d == operation) ||
  7031. (details::e_notl == operation) || (details::e_sgn == operation) ||
  7032. (details::e_erf == operation) || (details::e_erfc == operation) ||
  7033. (details::e_frac == operation) || (details::e_trunc == operation);
  7034. }
  7035. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[1])
  7036. {
  7037. if (0 == branch[0])
  7038. return error_node();
  7039. else if (details::is_constant_node(branch[0]))
  7040. return synthesize_expression<unary_node_t,1>(operation,branch);
  7041. else if (unary_optimizable(operation) && details::is_variable_node(branch[0]))
  7042. return synthesize_uv_expression(operation,branch);
  7043. else
  7044. return synthesize_unary_expression(operation,branch);
  7045. }
  7046. #ifndef exprtk_disable_string_capabilities
  7047. inline bool valid_string_operation(const details::operator_type& operation) const
  7048. {
  7049. return (details::e_add == operation) ||
  7050. (details::e_lt == operation) ||
  7051. (details::e_lte == operation) ||
  7052. (details::e_gt == operation) ||
  7053. (details::e_gte == operation) ||
  7054. (details::e_eq == operation) ||
  7055. (details::e_ne == operation) ||
  7056. (details::e_in == operation) ||
  7057. (details::e_like == operation) ||
  7058. (details::e_ilike == operation);
  7059. }
  7060. #else
  7061. inline bool valid_string_operation(const details::operator_type&) const
  7062. {
  7063. return false;
  7064. }
  7065. #endif
  7066. inline bool operation_optimizable(const details::operator_type& operation) const
  7067. {
  7068. return (details::e_add == operation) ||
  7069. (details::e_sub == operation) ||
  7070. (details::e_mul == operation) ||
  7071. (details::e_div == operation) ||
  7072. (details::e_mod == operation) ||
  7073. (details::e_pow == operation) ||
  7074. #ifndef exprtk_disable_extended_operator_optimizations
  7075. (details::e_lt == operation) ||
  7076. (details::e_lte == operation) ||
  7077. (details::e_gt == operation) ||
  7078. (details::e_gte == operation) ||
  7079. (details::e_eq == operation) ||
  7080. (details::e_ne == operation) ||
  7081. (details::e_and == operation) ||
  7082. (details::e_nand == operation) ||
  7083. (details::e_or == operation) ||
  7084. (details::e_nor == operation) ||
  7085. (details::e_xor == operation) ||
  7086. #endif
  7087. false;
  7088. }
  7089. inline bool is_level_optimizable(const std::size_t& level = 0) const
  7090. {
  7091. switch (level)
  7092. {
  7093. case 1 : return (e_level1 == (optimization_level_ & e_level1));
  7094. case 2 : return (e_level2 == (optimization_level_ & e_level2)) && is_level_optimizable(1);
  7095. case 3 : return (e_level3 == (optimization_level_ & e_level3)) && is_level_optimizable(2);
  7096. case 0 : return (e_all == (optimization_level_ & e_all));
  7097. default : return false;
  7098. }
  7099. }
  7100. inline bool cov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7101. {
  7102. if (!operation_optimizable(operation))
  7103. return false;
  7104. else if (!is_level_optimizable(1))
  7105. return false;
  7106. else
  7107. return (details::is_constant_node(branch[0]) && details::is_variable_node(branch[1]));
  7108. }
  7109. inline bool voc_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7110. {
  7111. if (!operation_optimizable(operation))
  7112. return false;
  7113. else if (!is_level_optimizable(1))
  7114. return false;
  7115. else
  7116. return (details::is_variable_node(branch[0]) && details::is_constant_node(branch[1]));
  7117. }
  7118. inline bool vov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7119. {
  7120. if (!operation_optimizable(operation))
  7121. return false;
  7122. else if (!is_level_optimizable(1))
  7123. return false;
  7124. else
  7125. return (details::is_variable_node(branch[0]) && details::is_variable_node(branch[1]));
  7126. }
  7127. inline bool vovov1_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7128. {
  7129. if (!operation_optimizable(operation))
  7130. return false;
  7131. else if (!is_level_optimizable(2))
  7132. return false;
  7133. else
  7134. return (details::is_variable_node(branch[0]) && details::is_vov_node(branch[1]));
  7135. }
  7136. inline bool vovov2_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7137. {
  7138. if (!operation_optimizable(operation))
  7139. return false;
  7140. else if (!is_level_optimizable(2))
  7141. return false;
  7142. else
  7143. return (details::is_vov_node(branch[0]) && details::is_variable_node(branch[1]));
  7144. }
  7145. inline bool covov1_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7146. {
  7147. if (!operation_optimizable(operation))
  7148. return false;
  7149. else if (!is_level_optimizable(2))
  7150. return false;
  7151. else
  7152. return (details::is_constant_node(branch[0]) && details::is_vov_node(branch[1]));
  7153. }
  7154. inline bool covov2_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7155. {
  7156. if (!operation_optimizable(operation))
  7157. return false;
  7158. else if (!is_level_optimizable(2))
  7159. return false;
  7160. else
  7161. return (details::is_cov_node(branch[0]) && details::is_variable_node(branch[1]));
  7162. }
  7163. inline bool vovoc1_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7164. {
  7165. if (!operation_optimizable(operation))
  7166. return false;
  7167. else if (!is_level_optimizable(2))
  7168. return false;
  7169. else
  7170. return (details::is_variable_node(branch[0]) && details::is_voc_node(branch[1]));
  7171. }
  7172. inline bool vovoc2_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7173. {
  7174. if (!operation_optimizable(operation))
  7175. return false;
  7176. else if (!is_level_optimizable(2))
  7177. return false;
  7178. else
  7179. return (details::is_vov_node(branch[0]) && details::is_constant_node(branch[1]));
  7180. }
  7181. inline bool covoc1_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7182. {
  7183. if (!operation_optimizable(operation))
  7184. return false;
  7185. else if (!is_level_optimizable(2))
  7186. return false;
  7187. else
  7188. return (details::is_constant_node(branch[0]) && details::is_voc_node(branch[1]));
  7189. }
  7190. inline bool covoc2_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7191. {
  7192. if (!operation_optimizable(operation))
  7193. return false;
  7194. else if (!is_level_optimizable(2))
  7195. return false;
  7196. else
  7197. return (details::is_cov_node(branch[0]) && details::is_constant_node(branch[1]));
  7198. }
  7199. inline bool vocov1_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7200. {
  7201. if (!operation_optimizable(operation))
  7202. return false;
  7203. else if (!is_level_optimizable(2))
  7204. return false;
  7205. else
  7206. return (details::is_variable_node(branch[0]) && details::is_cov_node(branch[1]));
  7207. }
  7208. inline bool vocov2_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7209. {
  7210. if (!operation_optimizable(operation))
  7211. return false;
  7212. else if (!is_level_optimizable(2))
  7213. return false;
  7214. else
  7215. return (details::is_voc_node(branch[0]) && details::is_variable_node(branch[1]));
  7216. }
  7217. inline bool uvouv_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7218. {
  7219. if (!operation_optimizable(operation))
  7220. return false;
  7221. else if (!is_level_optimizable(2))
  7222. return false;
  7223. else
  7224. return (details::is_uv_node(branch[0]) && details::is_uv_node(branch[1]));
  7225. }
  7226. inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7227. {
  7228. const bool b0_string = details::is_string_node(branch[0]) || details::is_const_string_node(branch[0]);
  7229. const bool b1_string = details::is_string_node(branch[1]) || details::is_const_string_node(branch[1]);
  7230. if ((b0_string || b1_string) && !(b0_string && b1_string))
  7231. return true;
  7232. if (!valid_string_operation(operation) && b0_string && b1_string)
  7233. return true;
  7234. else
  7235. return false;
  7236. }
  7237. inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  7238. {
  7239. bool b0_string = details::is_string_node(branch[0]) || details::is_const_string_node(branch[0]);
  7240. bool b1_string = details::is_string_node(branch[1]) || details::is_const_string_node(branch[1]);
  7241. bool b2_string = details::is_string_node(branch[2]) || details::is_const_string_node(branch[2]);
  7242. if ((b0_string || b1_string || b2_string) && !(b0_string && b1_string && b2_string))
  7243. return true;
  7244. if ((details::e_inrange != operation) && b0_string && b1_string && b2_string)
  7245. return true;
  7246. else
  7247. return false;
  7248. }
  7249. inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7250. {
  7251. const bool b0_string = details::is_string_node(branch[0]) || details::is_const_string_node(branch[0]);
  7252. const bool b1_string = details::is_string_node(branch[1]) || details::is_const_string_node(branch[1]);
  7253. return (b0_string && b1_string && valid_string_operation(operation));
  7254. }
  7255. inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  7256. {
  7257. const bool b0_string = details::is_string_node(branch[0]) || details::is_const_string_node(branch[0]);
  7258. const bool b1_string = details::is_string_node(branch[1]) || details::is_const_string_node(branch[1]);
  7259. const bool b2_string = details::is_string_node(branch[2]) || details::is_const_string_node(branch[2]);
  7260. return (b0_string && b1_string && b2_string && (details::e_inrange == operation));
  7261. }
  7262. // Note: Extended Optimisations
  7263. // When using older C++ compilers due to the large number of type instantiations
  7264. // required by the extended optimisations the compiler may crash or not be able
  7265. // to compile this translation unit properly.
  7266. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  7267. #if (defined(_MSC_VER) && (_MSC_VER <= 1400))
  7268. #ifndef exprtk_disable_extended_optimisations
  7269. #define exprtk_disable_extended_optimisations
  7270. #endif
  7271. #endif
  7272. #endif
  7273. #ifndef exprtk_disable_extended_optimisations
  7274. inline bool vovovov_optimizable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
  7275. {
  7276. if (!operation_optimizable(operation))
  7277. return false;
  7278. else if (!is_level_optimizable(3))
  7279. return false;
  7280. else
  7281. return (details::is_vov_node(branch[0]) && details::is_vov_node(branch[1]));
  7282. }
  7283. #else
  7284. inline bool vovovov_optimizable(const details::operator_type&, expression_node_ptr (&)[2]) const
  7285. {
  7286. return false;
  7287. }
  7288. #endif
  7289. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7290. {
  7291. if ((0 == branch[0]) || (0 == branch[1]))
  7292. return error_node();
  7293. else if (is_invalid_string_op(operation,branch))
  7294. return error_node();
  7295. else if (details::e_assign == operation)
  7296. return synthesize_assignment_expression(operation,branch);
  7297. else if (is_string_operation(operation,branch))
  7298. return synthesize_string_expression(operation,branch);
  7299. else if (cov_optimizable(operation,branch))
  7300. return synthesize_cov_expression(operation,branch);
  7301. else if (voc_optimizable(operation,branch))
  7302. return synthesize_voc_expression(operation,branch);
  7303. else if (vov_optimizable(operation,branch))
  7304. return synthesize_vov_expression(operation,branch);
  7305. else if (vovov1_optimizable(operation,branch))
  7306. return synthesize_vovov1_expression(operation,branch);
  7307. else if (vovov2_optimizable(operation,branch))
  7308. return synthesize_vovov2_expression(operation,branch);
  7309. else if (covov1_optimizable(operation,branch))
  7310. return synthesize_covov1_expression(operation,branch);
  7311. else if (covov2_optimizable(operation,branch))
  7312. return synthesize_covov2_expression(operation,branch);
  7313. else if (vovoc1_optimizable(operation,branch))
  7314. return synthesize_vovoc1_expression(operation,branch);
  7315. else if (vovoc2_optimizable(operation,branch))
  7316. return synthesize_vovoc2_expression(operation,branch);
  7317. else if (covoc1_optimizable(operation,branch))
  7318. return synthesize_covoc1_expression(operation,branch);
  7319. else if (covoc2_optimizable(operation,branch))
  7320. return synthesize_covoc2_expression(operation,branch);
  7321. else if (vocov1_optimizable(operation,branch))
  7322. return synthesize_vocov1_expression(operation,branch);
  7323. else if (vocov2_optimizable(operation,branch))
  7324. return synthesize_vocov2_expression(operation,branch);
  7325. else if (vovovov_optimizable(operation,branch))
  7326. return synthesize_vovovov_expression(operation,branch);
  7327. else if (uvouv_optimizable(operation,branch))
  7328. return synthesize_uvouv_expression(operation,branch);
  7329. else
  7330. return synthesize_expression<binary_node_t,2>(operation,branch);
  7331. }
  7332. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  7333. {
  7334. if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
  7335. return error_node();
  7336. else if (is_invalid_string_op(operation,branch))
  7337. return error_node();
  7338. else if (is_string_operation(operation,branch))
  7339. return synthesize_string_expression(operation,branch);
  7340. else
  7341. return synthesize_expression<trinary_node_t,3>(operation,branch);
  7342. }
  7343. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  7344. {
  7345. return synthesize_expression<quaternary_node_t,4>(operation,branch);
  7346. }
  7347. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[5])
  7348. {
  7349. return synthesize_expression<quinary_node_t,5>(operation,branch);
  7350. }
  7351. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr (&branch)[6])
  7352. {
  7353. return synthesize_expression<senary_node_t,6>(operation,branch);
  7354. }
  7355. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr b0)
  7356. {
  7357. expression_node_ptr branch[1] = { b0 };
  7358. return synthesize_expression<unary_node_t,1>(operation,branch);
  7359. }
  7360. inline expression_node_ptr operator()(const details::operator_type& operation, expression_node_ptr b0, expression_node_ptr b1)
  7361. {
  7362. if ((0 == b0) || (0 == b1))
  7363. return error_node();
  7364. else
  7365. {
  7366. expression_node_ptr branch[2] = { b0, b1 };
  7367. return expression_generator<Type>::operator()(operation,branch);
  7368. }
  7369. }
  7370. inline expression_node_ptr conditional(expression_node_ptr condition,
  7371. expression_node_ptr consequent,
  7372. expression_node_ptr alternative) const
  7373. {
  7374. if ((0 == condition) || (0 == consequent) || (0 == alternative))
  7375. return error_node();
  7376. //Can the condition be immediately evaluated? if so optimize.
  7377. else if (details::is_constant_node(condition))
  7378. {
  7379. // True branch
  7380. if (details::is_true(condition))
  7381. {
  7382. node_allocator_->free(condition);
  7383. node_allocator_->free(alternative);
  7384. return consequent;
  7385. }
  7386. // False branch
  7387. else
  7388. {
  7389. node_allocator_->free(condition);
  7390. node_allocator_->free(consequent);
  7391. return alternative;
  7392. }
  7393. }
  7394. else
  7395. return node_allocator_->allocate<conditional_node_t>(condition,consequent,alternative);
  7396. }
  7397. inline expression_node_ptr while_loop(expression_node_ptr condition,
  7398. expression_node_ptr branch) const
  7399. {
  7400. return node_allocator_->allocate<while_loop_node_t>(condition,branch);
  7401. }
  7402. #define unary_opr_switch_statements \
  7403. case_stmt(details:: e_abs,details:: abs_op) \
  7404. case_stmt(details:: e_acos,details:: acos_op) \
  7405. case_stmt(details:: e_asin,details:: asin_op) \
  7406. case_stmt(details:: e_atan,details:: atan_op) \
  7407. case_stmt(details:: e_ceil,details:: ceil_op) \
  7408. case_stmt(details:: e_cos,details:: cos_op) \
  7409. case_stmt(details:: e_cosh,details:: cosh_op) \
  7410. case_stmt(details:: e_exp,details:: exp_op) \
  7411. case_stmt(details::e_floor,details::floor_op) \
  7412. case_stmt(details:: e_log,details:: log_op) \
  7413. case_stmt(details::e_log10,details::log10_op) \
  7414. case_stmt(details:: e_neg,details:: neg_op) \
  7415. case_stmt(details:: e_pos,details:: pos_op) \
  7416. case_stmt(details::e_round,details::round_op) \
  7417. case_stmt(details:: e_sin,details:: sin_op) \
  7418. case_stmt(details:: e_sinh,details:: sinh_op) \
  7419. case_stmt(details:: e_sqrt,details:: sqrt_op) \
  7420. case_stmt(details:: e_tan,details:: tan_op) \
  7421. case_stmt(details:: e_tanh,details:: tanh_op) \
  7422. case_stmt(details:: e_cot,details:: cot_op) \
  7423. case_stmt(details:: e_sec,details:: sec_op) \
  7424. case_stmt(details:: e_csc,details:: csc_op) \
  7425. case_stmt(details:: e_r2d,details:: r2d_op) \
  7426. case_stmt(details:: e_d2r,details:: d2r_op) \
  7427. case_stmt(details:: e_d2g,details:: d2g_op) \
  7428. case_stmt(details:: e_g2d,details:: g2d_op) \
  7429. case_stmt(details:: e_notl,details:: notl_op) \
  7430. case_stmt(details:: e_sgn,details:: sgn_op) \
  7431. case_stmt(details:: e_erf,details:: erf_op) \
  7432. case_stmt(details:: e_erfc,details:: erfc_op) \
  7433. case_stmt(details:: e_frac,details:: frac_op) \
  7434. case_stmt(details::e_trunc,details::trunc_op) \
  7435. inline expression_node_ptr synthesize_uv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[1])
  7436. {
  7437. T& v = dynamic_cast<details::variable_node<T>*>(branch[0])->ref();
  7438. switch (operation)
  7439. {
  7440. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<typename details::unary_variable_node<Type,op1<Type> > >(v);
  7441. unary_opr_switch_statements
  7442. #undef case_stmt
  7443. default : return error_node();
  7444. }
  7445. }
  7446. inline expression_node_ptr synthesize_unary_expression(const details::operator_type& operation, expression_node_ptr (&branch)[1])
  7447. {
  7448. switch (operation)
  7449. {
  7450. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]);
  7451. unary_opr_switch_statements
  7452. #undef case_stmt
  7453. default : return error_node();
  7454. }
  7455. }
  7456. inline expression_node_ptr const_optimize_sf3(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  7457. {
  7458. expression_node_ptr temp_node = error_node();
  7459. switch (operation)
  7460. {
  7461. #define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate<details::sf3_node<Type,op1<Type> > >(operation,branch); break;
  7462. case_stmt(details::e_sf00,details::sf00_op)
  7463. case_stmt(details::e_sf01,details::sf01_op)
  7464. case_stmt(details::e_sf02,details::sf02_op)
  7465. case_stmt(details::e_sf03,details::sf03_op)
  7466. case_stmt(details::e_sf04,details::sf04_op)
  7467. case_stmt(details::e_sf05,details::sf05_op)
  7468. case_stmt(details::e_sf06,details::sf06_op)
  7469. case_stmt(details::e_sf07,details::sf07_op)
  7470. case_stmt(details::e_sf08,details::sf08_op)
  7471. case_stmt(details::e_sf09,details::sf09_op)
  7472. case_stmt(details::e_sf10,details::sf10_op)
  7473. case_stmt(details::e_sf11,details::sf11_op)
  7474. case_stmt(details::e_sf12,details::sf12_op)
  7475. case_stmt(details::e_sf13,details::sf13_op)
  7476. case_stmt(details::e_sf14,details::sf14_op)
  7477. case_stmt(details::e_sf15,details::sf15_op)
  7478. case_stmt(details::e_sf16,details::sf16_op)
  7479. case_stmt(details::e_sf17,details::sf17_op)
  7480. case_stmt(details::e_sf18,details::sf18_op)
  7481. case_stmt(details::e_sf19,details::sf19_op)
  7482. case_stmt(details::e_sf20,details::sf20_op)
  7483. case_stmt(details::e_sf21,details::sf21_op)
  7484. case_stmt(details::e_sf22,details::sf22_op)
  7485. case_stmt(details::e_sf23,details::sf23_op)
  7486. case_stmt(details::e_sf24,details::sf24_op)
  7487. case_stmt(details::e_sf25,details::sf25_op)
  7488. case_stmt(details::e_sf26,details::sf26_op)
  7489. case_stmt(details::e_sf27,details::sf27_op)
  7490. case_stmt(details::e_sf28,details::sf28_op)
  7491. case_stmt(details::e_sf29,details::sf29_op)
  7492. case_stmt(details::e_sf30,details::sf30_op)
  7493. case_stmt(details::e_sf31,details::sf31_op)
  7494. case_stmt(details::e_sf32,details::sf32_op)
  7495. case_stmt(details::e_sf33,details::sf33_op)
  7496. case_stmt(details::e_sf34,details::sf34_op)
  7497. #undef case_stmt
  7498. default : return error_node();
  7499. }
  7500. T v = temp_node->value();
  7501. node_allocator_->free(temp_node);
  7502. return node_allocator_->allocate<literal_node_t>(v);
  7503. }
  7504. inline expression_node_ptr varnode_optimize_sf3(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  7505. {
  7506. Type& v0 = dynamic_cast<details::variable_node<Type>*>(branch[0])->ref();
  7507. Type& v1 = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
  7508. Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[2])->ref();
  7509. switch (operation)
  7510. {
  7511. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rrr<details::sf3_var_node<Type,op1<Type> > >(v0,v1,v2);
  7512. case_stmt(details::e_sf00,details::sf00_op)
  7513. case_stmt(details::e_sf01,details::sf01_op)
  7514. case_stmt(details::e_sf02,details::sf02_op)
  7515. case_stmt(details::e_sf03,details::sf03_op)
  7516. case_stmt(details::e_sf04,details::sf04_op)
  7517. case_stmt(details::e_sf05,details::sf05_op)
  7518. case_stmt(details::e_sf06,details::sf06_op)
  7519. case_stmt(details::e_sf07,details::sf07_op)
  7520. case_stmt(details::e_sf08,details::sf08_op)
  7521. case_stmt(details::e_sf09,details::sf09_op)
  7522. case_stmt(details::e_sf10,details::sf10_op)
  7523. case_stmt(details::e_sf11,details::sf11_op)
  7524. case_stmt(details::e_sf12,details::sf12_op)
  7525. case_stmt(details::e_sf13,details::sf13_op)
  7526. case_stmt(details::e_sf14,details::sf14_op)
  7527. case_stmt(details::e_sf15,details::sf15_op)
  7528. case_stmt(details::e_sf16,details::sf16_op)
  7529. case_stmt(details::e_sf17,details::sf17_op)
  7530. case_stmt(details::e_sf18,details::sf18_op)
  7531. case_stmt(details::e_sf19,details::sf19_op)
  7532. case_stmt(details::e_sf20,details::sf20_op)
  7533. case_stmt(details::e_sf21,details::sf21_op)
  7534. case_stmt(details::e_sf22,details::sf22_op)
  7535. case_stmt(details::e_sf23,details::sf23_op)
  7536. case_stmt(details::e_sf24,details::sf24_op)
  7537. case_stmt(details::e_sf25,details::sf25_op)
  7538. case_stmt(details::e_sf26,details::sf26_op)
  7539. case_stmt(details::e_sf27,details::sf27_op)
  7540. case_stmt(details::e_sf28,details::sf28_op)
  7541. case_stmt(details::e_sf29,details::sf29_op)
  7542. case_stmt(details::e_sf30,details::sf30_op)
  7543. case_stmt(details::e_sf31,details::sf31_op)
  7544. case_stmt(details::e_sf32,details::sf32_op)
  7545. case_stmt(details::e_sf33,details::sf33_op)
  7546. case_stmt(details::e_sf34,details::sf34_op)
  7547. #undef case_stmt
  7548. default : return error_node();
  7549. }
  7550. }
  7551. inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[3])
  7552. {
  7553. if (!all_nodes_valid(branch))
  7554. return error_node();
  7555. else if (is_constant_foldable(branch))
  7556. return const_optimize_sf3(operation,branch);
  7557. else if (all_nodes_variables(branch))
  7558. return varnode_optimize_sf3(operation,branch);
  7559. else
  7560. switch (operation)
  7561. {
  7562. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::sf3_node<Type,op1<Type> > >(operation,branch);
  7563. case_stmt(details::e_sf00,details::sf00_op)
  7564. case_stmt(details::e_sf01,details::sf01_op)
  7565. case_stmt(details::e_sf02,details::sf02_op)
  7566. case_stmt(details::e_sf03,details::sf03_op)
  7567. case_stmt(details::e_sf04,details::sf04_op)
  7568. case_stmt(details::e_sf05,details::sf05_op)
  7569. case_stmt(details::e_sf06,details::sf06_op)
  7570. case_stmt(details::e_sf07,details::sf07_op)
  7571. case_stmt(details::e_sf08,details::sf08_op)
  7572. case_stmt(details::e_sf09,details::sf09_op)
  7573. case_stmt(details::e_sf10,details::sf10_op)
  7574. case_stmt(details::e_sf11,details::sf11_op)
  7575. case_stmt(details::e_sf12,details::sf12_op)
  7576. case_stmt(details::e_sf13,details::sf13_op)
  7577. case_stmt(details::e_sf14,details::sf14_op)
  7578. case_stmt(details::e_sf15,details::sf15_op)
  7579. case_stmt(details::e_sf16,details::sf16_op)
  7580. case_stmt(details::e_sf17,details::sf17_op)
  7581. case_stmt(details::e_sf18,details::sf18_op)
  7582. case_stmt(details::e_sf19,details::sf19_op)
  7583. case_stmt(details::e_sf20,details::sf20_op)
  7584. case_stmt(details::e_sf21,details::sf21_op)
  7585. case_stmt(details::e_sf22,details::sf22_op)
  7586. case_stmt(details::e_sf23,details::sf23_op)
  7587. case_stmt(details::e_sf24,details::sf24_op)
  7588. case_stmt(details::e_sf25,details::sf25_op)
  7589. case_stmt(details::e_sf26,details::sf26_op)
  7590. case_stmt(details::e_sf27,details::sf27_op)
  7591. case_stmt(details::e_sf28,details::sf28_op)
  7592. case_stmt(details::e_sf29,details::sf29_op)
  7593. case_stmt(details::e_sf30,details::sf30_op)
  7594. case_stmt(details::e_sf31,details::sf31_op)
  7595. case_stmt(details::e_sf32,details::sf32_op)
  7596. case_stmt(details::e_sf33,details::sf33_op)
  7597. case_stmt(details::e_sf34,details::sf34_op)
  7598. #undef case_stmt
  7599. default : return error_node();
  7600. }
  7601. }
  7602. inline expression_node_ptr const_optimize_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  7603. {
  7604. expression_node_ptr temp_node = error_node();
  7605. switch (operation)
  7606. {
  7607. #define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate<details::sf4_node<Type,op1<Type> > >(operation,branch); break;
  7608. case_stmt(details::e_sf35,details::sf35_op)
  7609. case_stmt(details::e_sf36,details::sf36_op)
  7610. case_stmt(details::e_sf37,details::sf37_op)
  7611. case_stmt(details::e_sf38,details::sf38_op)
  7612. case_stmt(details::e_sf39,details::sf39_op)
  7613. case_stmt(details::e_sf40,details::sf40_op)
  7614. case_stmt(details::e_sf41,details::sf41_op)
  7615. case_stmt(details::e_sf42,details::sf42_op)
  7616. case_stmt(details::e_sf43,details::sf43_op)
  7617. case_stmt(details::e_sf44,details::sf44_op)
  7618. case_stmt(details::e_sf45,details::sf45_op)
  7619. case_stmt(details::e_sf46,details::sf46_op)
  7620. case_stmt(details::e_sf47,details::sf47_op)
  7621. case_stmt(details::e_sf48,details::sf48_op)
  7622. case_stmt(details::e_sf49,details::sf49_op)
  7623. case_stmt(details::e_sf50,details::sf50_op)
  7624. case_stmt(details::e_sf51,details::sf51_op)
  7625. case_stmt(details::e_sf52,details::sf52_op)
  7626. case_stmt(details::e_sf53,details::sf53_op)
  7627. case_stmt(details::e_sf54,details::sf54_op)
  7628. case_stmt(details::e_sf55,details::sf55_op)
  7629. case_stmt(details::e_sf56,details::sf56_op)
  7630. case_stmt(details::e_sf57,details::sf57_op)
  7631. case_stmt(details::e_sf58,details::sf58_op)
  7632. case_stmt(details::e_sf59,details::sf59_op)
  7633. case_stmt(details::e_sf60,details::sf60_op)
  7634. case_stmt(details::e_sf61,details::sf61_op)
  7635. case_stmt(details::e_sf62,details::sf62_op)
  7636. case_stmt(details::e_sf63,details::sf63_op)
  7637. case_stmt(details::e_sf64,details::sf64_op)
  7638. case_stmt(details::e_sf65,details::sf65_op)
  7639. case_stmt(details::e_sf66,details::sf66_op)
  7640. case_stmt(details::e_sf67,details::sf67_op)
  7641. case_stmt(details::e_sf68,details::sf68_op)
  7642. case_stmt(details::e_sf69,details::sf69_op)
  7643. case_stmt(details::e_sf70,details::sf70_op)
  7644. case_stmt(details::e_sf71,details::sf71_op)
  7645. case_stmt(details::e_sf72,details::sf72_op)
  7646. case_stmt(details::e_sf73,details::sf73_op)
  7647. case_stmt(details::e_sf74,details::sf74_op)
  7648. case_stmt(details::e_sf75,details::sf75_op)
  7649. case_stmt(details::e_sf76,details::sf76_op)
  7650. case_stmt(details::e_sf77,details::sf77_op)
  7651. case_stmt(details::e_sf78,details::sf78_op)
  7652. case_stmt(details::e_sf79,details::sf79_op)
  7653. case_stmt(details::e_sf80,details::sf80_op)
  7654. case_stmt(details::e_sf81,details::sf81_op)
  7655. case_stmt(details::e_sf82,details::sf82_op)
  7656. #undef case_stmt
  7657. default : return error_node();
  7658. }
  7659. T v = temp_node->value();
  7660. node_allocator_->free(temp_node);
  7661. return node_allocator_->allocate<literal_node_t>(v);
  7662. }
  7663. inline expression_node_ptr varnode_optimize_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  7664. {
  7665. Type& v0 = dynamic_cast<details::variable_node<Type>*>(branch[0])->ref();
  7666. Type& v1 = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
  7667. Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[2])->ref();
  7668. Type& v3 = dynamic_cast<details::variable_node<Type>*>(branch[3])->ref();
  7669. switch (operation)
  7670. {
  7671. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rrrr<details::sf4_var_node<Type,op1<Type> > >(v0,v1,v2,v3);
  7672. case_stmt(details::e_sf35,details::sf35_op)
  7673. case_stmt(details::e_sf36,details::sf36_op)
  7674. case_stmt(details::e_sf37,details::sf37_op)
  7675. case_stmt(details::e_sf38,details::sf38_op)
  7676. case_stmt(details::e_sf39,details::sf39_op)
  7677. case_stmt(details::e_sf40,details::sf40_op)
  7678. case_stmt(details::e_sf41,details::sf41_op)
  7679. case_stmt(details::e_sf42,details::sf42_op)
  7680. case_stmt(details::e_sf43,details::sf43_op)
  7681. case_stmt(details::e_sf44,details::sf44_op)
  7682. case_stmt(details::e_sf45,details::sf45_op)
  7683. case_stmt(details::e_sf46,details::sf46_op)
  7684. case_stmt(details::e_sf47,details::sf47_op)
  7685. case_stmt(details::e_sf48,details::sf48_op)
  7686. case_stmt(details::e_sf49,details::sf49_op)
  7687. case_stmt(details::e_sf50,details::sf50_op)
  7688. case_stmt(details::e_sf51,details::sf51_op)
  7689. case_stmt(details::e_sf52,details::sf52_op)
  7690. case_stmt(details::e_sf53,details::sf53_op)
  7691. case_stmt(details::e_sf54,details::sf54_op)
  7692. case_stmt(details::e_sf55,details::sf55_op)
  7693. case_stmt(details::e_sf56,details::sf56_op)
  7694. case_stmt(details::e_sf57,details::sf57_op)
  7695. case_stmt(details::e_sf58,details::sf58_op)
  7696. case_stmt(details::e_sf59,details::sf59_op)
  7697. case_stmt(details::e_sf60,details::sf60_op)
  7698. case_stmt(details::e_sf61,details::sf61_op)
  7699. case_stmt(details::e_sf62,details::sf62_op)
  7700. case_stmt(details::e_sf63,details::sf63_op)
  7701. case_stmt(details::e_sf64,details::sf64_op)
  7702. case_stmt(details::e_sf65,details::sf65_op)
  7703. case_stmt(details::e_sf66,details::sf66_op)
  7704. case_stmt(details::e_sf67,details::sf67_op)
  7705. case_stmt(details::e_sf68,details::sf68_op)
  7706. case_stmt(details::e_sf69,details::sf69_op)
  7707. case_stmt(details::e_sf70,details::sf70_op)
  7708. case_stmt(details::e_sf71,details::sf71_op)
  7709. case_stmt(details::e_sf72,details::sf72_op)
  7710. case_stmt(details::e_sf73,details::sf73_op)
  7711. case_stmt(details::e_sf74,details::sf74_op)
  7712. case_stmt(details::e_sf75,details::sf75_op)
  7713. case_stmt(details::e_sf76,details::sf76_op)
  7714. case_stmt(details::e_sf77,details::sf77_op)
  7715. case_stmt(details::e_sf78,details::sf78_op)
  7716. case_stmt(details::e_sf79,details::sf79_op)
  7717. case_stmt(details::e_sf80,details::sf80_op)
  7718. case_stmt(details::e_sf81,details::sf81_op)
  7719. case_stmt(details::e_sf82,details::sf82_op)
  7720. #undef case_stmt
  7721. default : return error_node();
  7722. }
  7723. }
  7724. inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[4])
  7725. {
  7726. if (!all_nodes_valid(branch))
  7727. return error_node();
  7728. else if (is_constant_foldable(branch))
  7729. return const_optimize_sf4(operation,branch);
  7730. else if (all_nodes_variables(branch))
  7731. return varnode_optimize_sf4(operation,branch);
  7732. switch (operation)
  7733. {
  7734. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::sf4_node<Type,op1<Type> > >(operation,branch);
  7735. case_stmt(details::e_sf35,details::sf35_op)
  7736. case_stmt(details::e_sf36,details::sf36_op)
  7737. case_stmt(details::e_sf37,details::sf37_op)
  7738. case_stmt(details::e_sf38,details::sf38_op)
  7739. case_stmt(details::e_sf39,details::sf39_op)
  7740. case_stmt(details::e_sf40,details::sf40_op)
  7741. case_stmt(details::e_sf41,details::sf41_op)
  7742. case_stmt(details::e_sf42,details::sf42_op)
  7743. case_stmt(details::e_sf43,details::sf43_op)
  7744. case_stmt(details::e_sf44,details::sf44_op)
  7745. case_stmt(details::e_sf45,details::sf45_op)
  7746. case_stmt(details::e_sf46,details::sf46_op)
  7747. case_stmt(details::e_sf47,details::sf47_op)
  7748. case_stmt(details::e_sf48,details::sf48_op)
  7749. case_stmt(details::e_sf49,details::sf49_op)
  7750. case_stmt(details::e_sf50,details::sf50_op)
  7751. case_stmt(details::e_sf51,details::sf51_op)
  7752. case_stmt(details::e_sf52,details::sf52_op)
  7753. case_stmt(details::e_sf53,details::sf53_op)
  7754. case_stmt(details::e_sf54,details::sf54_op)
  7755. case_stmt(details::e_sf55,details::sf55_op)
  7756. case_stmt(details::e_sf56,details::sf56_op)
  7757. case_stmt(details::e_sf57,details::sf57_op)
  7758. case_stmt(details::e_sf58,details::sf58_op)
  7759. case_stmt(details::e_sf59,details::sf59_op)
  7760. case_stmt(details::e_sf60,details::sf60_op)
  7761. case_stmt(details::e_sf61,details::sf61_op)
  7762. case_stmt(details::e_sf62,details::sf62_op)
  7763. case_stmt(details::e_sf63,details::sf63_op)
  7764. case_stmt(details::e_sf64,details::sf64_op)
  7765. case_stmt(details::e_sf65,details::sf65_op)
  7766. case_stmt(details::e_sf66,details::sf66_op)
  7767. case_stmt(details::e_sf67,details::sf67_op)
  7768. case_stmt(details::e_sf68,details::sf68_op)
  7769. case_stmt(details::e_sf69,details::sf69_op)
  7770. case_stmt(details::e_sf70,details::sf70_op)
  7771. case_stmt(details::e_sf71,details::sf71_op)
  7772. case_stmt(details::e_sf72,details::sf72_op)
  7773. case_stmt(details::e_sf73,details::sf73_op)
  7774. case_stmt(details::e_sf74,details::sf74_op)
  7775. case_stmt(details::e_sf75,details::sf75_op)
  7776. case_stmt(details::e_sf76,details::sf76_op)
  7777. case_stmt(details::e_sf77,details::sf77_op)
  7778. case_stmt(details::e_sf78,details::sf78_op)
  7779. case_stmt(details::e_sf79,details::sf79_op)
  7780. case_stmt(details::e_sf80,details::sf80_op)
  7781. case_stmt(details::e_sf81,details::sf81_op)
  7782. case_stmt(details::e_sf82,details::sf82_op)
  7783. #undef case_stmt
  7784. default : return error_node();
  7785. }
  7786. }
  7787. template <std::size_t N>
  7788. inline expression_node_ptr function(ifunction_t* f, expression_node_ptr (&b)[N])
  7789. {
  7790. typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
  7791. expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b);
  7792. if (0 == result)
  7793. return error_node();
  7794. else
  7795. {
  7796. //has the function call been completely optimized?
  7797. if (details::is_constant_node(result))
  7798. return result;
  7799. else if (!all_nodes_valid(b))
  7800. return error_node();
  7801. else if (N != f->param_count)
  7802. return error_node();
  7803. function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(result);
  7804. if (func_node_ptr)
  7805. {
  7806. if (func_node_ptr->init_branches(b))
  7807. return result;
  7808. else
  7809. return error_node();
  7810. }
  7811. else
  7812. return error_node();
  7813. }
  7814. }
  7815. inline expression_node_ptr function(ifunction_t* f)
  7816. {
  7817. typedef typename details::function_N_node<T,ifunction_t,0> function_N_node_t;
  7818. return node_allocator_->allocate<function_N_node_t>(f);
  7819. }
  7820. private:
  7821. template <std::size_t N, typename NodePtr>
  7822. inline bool is_constant_foldable(NodePtr (&b)[N]) const
  7823. {
  7824. for (std::size_t i = 0; i < N; ++i)
  7825. {
  7826. if (0 == b[i])
  7827. return false;
  7828. else if (!details::is_constant_node(b[i]))
  7829. return false;
  7830. }
  7831. return true;
  7832. }
  7833. template <std::size_t N>
  7834. inline bool all_nodes_valid(expression_node_ptr (&b)[N]) const
  7835. {
  7836. for (std::size_t i = 0; i < N; ++i)
  7837. {
  7838. if (0 == b[i]) return false;
  7839. }
  7840. return true;
  7841. }
  7842. template <std::size_t N>
  7843. inline bool all_nodes_variables(expression_node_ptr (&b)[N]) const
  7844. {
  7845. for (std::size_t i = 0; i < N; ++i)
  7846. {
  7847. if (0 == b[i])
  7848. return false;
  7849. else if (!is_variable_node(b[i]))
  7850. return false;
  7851. }
  7852. return true;
  7853. }
  7854. inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7855. {
  7856. if (details::is_variable_node(branch[0]))
  7857. return synthesize_expression<assignment_node_t,2>(operation,branch);
  7858. else
  7859. return error_node();
  7860. }
  7861. #define basic_opr_switch_statements \
  7862. case_stmt(details:: e_add,details:: add_op) \
  7863. case_stmt(details:: e_sub,details:: sub_op) \
  7864. case_stmt(details:: e_mul,details:: mul_op) \
  7865. case_stmt(details:: e_div,details:: div_op) \
  7866. case_stmt(details:: e_mod,details:: mod_op) \
  7867. case_stmt(details:: e_pow,details:: pow_op) \
  7868. #define extended_opr_switch_statements \
  7869. case_stmt(details:: e_lt,details:: lt_op) \
  7870. case_stmt(details:: e_lte,details:: lte_op) \
  7871. case_stmt(details:: e_gt,details:: gt_op) \
  7872. case_stmt(details:: e_gte,details:: gte_op) \
  7873. case_stmt(details:: e_eq,details:: eq_op) \
  7874. case_stmt(details:: e_ne,details:: ne_op) \
  7875. case_stmt(details:: e_and,details:: and_op) \
  7876. case_stmt(details::e_nand,details::nand_op) \
  7877. case_stmt(details:: e_or,details:: or_op) \
  7878. case_stmt(details:: e_nor,details:: nor_op) \
  7879. case_stmt(details:: e_xor,details:: xor_op) \
  7880. inline expression_node_ptr synthesize_cov_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7881. {
  7882. T c = dynamic_cast<details::literal_node<T>* >(branch[0])->value();
  7883. T& v = dynamic_cast<details::variable_node<T>*>(branch[1])->ref();
  7884. node_allocator_->free(branch[0]);
  7885. switch (operation)
  7886. {
  7887. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_cr<typename details::cov_node<Type,op1<Type> > >(c,v);
  7888. basic_opr_switch_statements
  7889. #ifndef exprtk_disable_extended_operator_optimizations
  7890. extended_opr_switch_statements
  7891. #endif
  7892. #undef case_stmt
  7893. default : return error_node();
  7894. }
  7895. }
  7896. #ifndef exprtk_disable_cardinal_pow_optimisation
  7897. template <template <typename,typename> class IPowNode>
  7898. inline expression_node_ptr cardinal_pow_optimization_impl(T& v, const unsigned int& p)
  7899. {
  7900. switch(p)
  7901. {
  7902. #define case_stmt(cp) case cp : return node_allocator_->allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v);
  7903. case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
  7904. case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
  7905. case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
  7906. case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
  7907. case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
  7908. case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
  7909. case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
  7910. case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
  7911. case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
  7912. case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
  7913. case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
  7914. case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
  7915. case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
  7916. case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
  7917. case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
  7918. #undef case_stmt
  7919. default : return error_node();
  7920. }
  7921. }
  7922. inline expression_node_ptr cardinal_pow_optimization(T& v, const T& c)
  7923. {
  7924. const bool not_recipricol = (c >= T(0.0));
  7925. const unsigned int p = static_cast<unsigned int>(std::abs(c));
  7926. if (0 == p)
  7927. return node_allocator_->allocate_c<literal_node_t>(T(1.0));
  7928. else
  7929. {
  7930. if (not_recipricol)
  7931. return cardinal_pow_optimization_impl<details::ipow_node>(v,p);
  7932. else
  7933. return cardinal_pow_optimization_impl<details::ipowinv_node>(v,p);
  7934. }
  7935. }
  7936. inline bool cardinal_pow_optimizable(const details::operator_type& operation, const T& c)
  7937. {
  7938. return (details::e_pow == operation) && (std::abs(c) <= T(60.0)) && details::numeric::is_integer(c);
  7939. }
  7940. #else
  7941. inline expression_node_ptr cardinal_pow_optimization(T&, const T&)
  7942. {
  7943. return error_node();
  7944. }
  7945. inline bool cardinal_pow_optimizable(const details::operator_type&, const T&)
  7946. {
  7947. return false;
  7948. }
  7949. #endif
  7950. inline expression_node_ptr synthesize_voc_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7951. {
  7952. T& v = dynamic_cast<details::variable_node<T>*>(branch[0])->ref();
  7953. T c = dynamic_cast<details::literal_node<T>* >(branch[1])->value();
  7954. node_allocator_->free(branch[1]);
  7955. if (cardinal_pow_optimizable(operation,c))
  7956. {
  7957. return cardinal_pow_optimization(v,c);
  7958. }
  7959. switch (operation)
  7960. {
  7961. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rc<typename details::voc_node<Type,op1<Type> > >(v,c);
  7962. basic_opr_switch_statements
  7963. #ifndef exprtk_disable_extended_operator_optimizations
  7964. extended_opr_switch_statements
  7965. #endif
  7966. #undef case_stmt
  7967. default : return error_node();
  7968. }
  7969. }
  7970. inline expression_node_ptr synthesize_vov_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  7971. {
  7972. Type& v1 = dynamic_cast<details::variable_node<Type>*>(branch[0])->ref();
  7973. Type& v2 = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
  7974. switch (operation)
  7975. {
  7976. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vov_node<Type,op1<Type> > >(v1,v2);
  7977. basic_opr_switch_statements
  7978. #ifndef exprtk_disable_extended_operator_optimizations
  7979. extended_opr_switch_statements
  7980. #endif
  7981. #undef case_stmt
  7982. default : return error_node();
  7983. }
  7984. }
  7985. template <typename Operation1>
  7986. inline expression_node_ptr synthesize_vovov1_expression_impl(Type& v0, expression_node_ptr node)
  7987. {
  7988. details::operator_type op = dynamic_cast<details::vov_base_node<Type>*>(node)->operation();
  7989. switch (op)
  7990. {
  7991. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vovov1_node<Type,Operation1,op1<Type> > >(v0,(*dynamic_cast<details::vov_node<T,op1<Type> >*>(node)));
  7992. basic_opr_switch_statements
  7993. #ifndef exprtk_disable_extended_operator_optimizations
  7994. extended_opr_switch_statements
  7995. #endif
  7996. #undef case_stmt
  7997. default : return error_node();
  7998. }
  7999. }
  8000. inline expression_node_ptr synthesize_vovov1_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8001. {
  8002. T& v0 = dynamic_cast<details::variable_node<T>*>(branch[0])->ref();
  8003. expression_node_ptr result = error_node();
  8004. switch (operation)
  8005. {
  8006. #define case_stmt(op0,op1) case op0 : result = synthesize_vovov1_expression_impl<op1<Type> >(v0,branch[1]); break;
  8007. basic_opr_switch_statements
  8008. #ifndef exprtk_disable_extended_operator_optimizations
  8009. extended_opr_switch_statements
  8010. #endif
  8011. #undef case_stmt
  8012. default : return error_node();
  8013. }
  8014. node_allocator_->free(branch[1]);
  8015. return result;
  8016. }
  8017. template <typename Operation1>
  8018. inline expression_node_ptr synthesize_vovov2_expression_impl(T& v0, expression_node_ptr node)
  8019. {
  8020. details::operator_type op = dynamic_cast<details::vov_base_node<T>*>(node)->operation();
  8021. switch (op)
  8022. {
  8023. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vovov2_node<T,op1<T>,Operation1> >((*dynamic_cast<details::vov_node<T,op1<T> >*>(node)),v0);
  8024. basic_opr_switch_statements
  8025. #ifndef exprtk_disable_extended_operator_optimizations
  8026. extended_opr_switch_statements
  8027. #endif
  8028. #undef case_stmt
  8029. default : return error_node();
  8030. }
  8031. }
  8032. inline expression_node_ptr synthesize_vovov2_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8033. {
  8034. T& v0 = dynamic_cast<details::variable_node<T>*>(branch[1])->ref();
  8035. expression_node_ptr result = error_node();
  8036. switch (operation)
  8037. {
  8038. #define case_stmt(op0,op1) case op0 : result = synthesize_vovov2_expression_impl<op1<Type> >(v0,branch[0]); break;
  8039. basic_opr_switch_statements
  8040. #ifndef exprtk_disable_extended_operator_optimizations
  8041. extended_opr_switch_statements
  8042. #endif
  8043. #undef case_stmt
  8044. default : return error_node();
  8045. }
  8046. node_allocator_->free(branch[0]);
  8047. return result;
  8048. }
  8049. template <typename Operation1>
  8050. inline expression_node_ptr synthesize_covov1_expression_impl(const T& c, expression_node_ptr node)
  8051. {
  8052. details::operator_type op = dynamic_cast<details::vov_base_node<T>*>(node)->operation();
  8053. switch (op)
  8054. {
  8055. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::covov1_node<Type,Operation1,op1<Type> > >(c,(*dynamic_cast<details::vov_node<T,op1<T> >*>(node)));
  8056. basic_opr_switch_statements
  8057. #ifndef exprtk_disable_extended_operator_optimizations
  8058. extended_opr_switch_statements
  8059. #endif
  8060. #undef case_stmt
  8061. default : return error_node();
  8062. }
  8063. }
  8064. inline expression_node_ptr synthesize_covov1_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8065. {
  8066. // Definition: (c)o(vov)
  8067. T c = dynamic_cast<details::literal_node<Type>*>(branch[0])->value();
  8068. expression_node_ptr result = error_node();
  8069. switch (operation)
  8070. {
  8071. #define case_stmt(op0,op1) case op0 : result = synthesize_covov1_expression_impl<op1<Type> >(c,branch[1]); break;
  8072. basic_opr_switch_statements
  8073. #ifndef exprtk_disable_extended_operator_optimizations
  8074. extended_opr_switch_statements
  8075. #endif
  8076. #undef case_stmt
  8077. default : return error_node();
  8078. }
  8079. node_allocator_->free(branch[0]);
  8080. node_allocator_->free(branch[1]);
  8081. return result;
  8082. }
  8083. template <typename Operation2>
  8084. inline expression_node_ptr synthesize_covov2_expression_impl(expression_node_ptr node, T& v)
  8085. {
  8086. details::operator_type op = dynamic_cast<details::cov_base_node<T>*>(node)->operation();
  8087. switch (op)
  8088. {
  8089. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::covov2_node<Type,op1<T>,Operation2> >((*dynamic_cast<details::cov_node<T,op1<T> >*>(node)),v);
  8090. basic_opr_switch_statements
  8091. #ifndef exprtk_disable_extended_operator_optimizations
  8092. extended_opr_switch_statements
  8093. #endif
  8094. #undef case_stmt
  8095. default : return error_node();
  8096. }
  8097. }
  8098. inline expression_node_ptr synthesize_covov2_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8099. {
  8100. // Definition: (cov)o(v)
  8101. T& v = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
  8102. expression_node_ptr result = error_node();
  8103. switch (operation)
  8104. {
  8105. #define case_stmt(op0,op1) case op0 : result = synthesize_covov2_expression_impl<op1<Type> >(branch[0],v); break;
  8106. basic_opr_switch_statements
  8107. #ifndef exprtk_disable_extended_operator_optimizations
  8108. extended_opr_switch_statements
  8109. #endif
  8110. #undef case_stmt
  8111. default : return error_node();
  8112. }
  8113. node_allocator_->free(branch[0]);
  8114. return result;
  8115. }
  8116. template <typename Operation1>
  8117. inline expression_node_ptr synthesize_vovoc1_expression_impl(const T& v, expression_node_ptr node)
  8118. {
  8119. details::operator_type op = dynamic_cast<details::voc_base_node<T>*>(node)->operation();
  8120. switch (op)
  8121. {
  8122. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vovoc1_node<Type,Operation1,op1<Type> > >(v,(*dynamic_cast<details::voc_node<T,op1<T> >*>(node)));
  8123. basic_opr_switch_statements
  8124. #ifndef exprtk_disable_extended_operator_optimizations
  8125. extended_opr_switch_statements
  8126. #endif
  8127. #undef case_stmt
  8128. default : return error_node();
  8129. }
  8130. }
  8131. inline expression_node_ptr synthesize_vovoc1_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8132. {
  8133. // Definition: (v)o(voc)
  8134. T& v = dynamic_cast<details::variable_node<Type>*>(branch[0])->ref();
  8135. expression_node_ptr result = error_node();
  8136. switch (operation)
  8137. {
  8138. #define case_stmt(op0,op1) case op0 : result = synthesize_vovoc1_expression_impl<op1<Type> >(v,branch[1]); break;
  8139. basic_opr_switch_statements
  8140. #ifndef exprtk_disable_extended_operator_optimizations
  8141. extended_opr_switch_statements
  8142. #endif
  8143. #undef case_stmt
  8144. default : return error_node();
  8145. }
  8146. node_allocator_->free(branch[1]);
  8147. return result;
  8148. }
  8149. template <typename Operation2>
  8150. inline expression_node_ptr synthesize_vovoc2_expression_impl(expression_node_ptr node, const T& c)
  8151. {
  8152. details::operator_type op = dynamic_cast<details::vov_base_node<T>*>(node)->operation();
  8153. switch (op)
  8154. {
  8155. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vovoc2_node<Type,op1<T>,Operation2> >((*dynamic_cast<details::vov_node<T,op1<T> >*>(node)),c);
  8156. basic_opr_switch_statements
  8157. #ifndef exprtk_disable_extended_operator_optimizations
  8158. extended_opr_switch_statements
  8159. #endif
  8160. #undef case_stmt
  8161. default : return error_node();
  8162. }
  8163. }
  8164. inline expression_node_ptr synthesize_vovoc2_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8165. {
  8166. // Definition: (vov)o(c)
  8167. T c = dynamic_cast<details::literal_node<Type>*>(branch[1])->value();
  8168. expression_node_ptr result = error_node();
  8169. switch (operation)
  8170. {
  8171. #define case_stmt(op0,op1) case op0 : result = synthesize_vovoc2_expression_impl<op1<Type> >(branch[0],c); break;
  8172. basic_opr_switch_statements
  8173. #ifndef exprtk_disable_extended_operator_optimizations
  8174. extended_opr_switch_statements
  8175. #endif
  8176. #undef case_stmt
  8177. default : return error_node();
  8178. }
  8179. node_allocator_->free(branch[0]);
  8180. node_allocator_->free(branch[1]);
  8181. return result;
  8182. }
  8183. template <typename Operation1>
  8184. inline expression_node_ptr synthesize_covoc1_expression_impl(const T& c, expression_node_ptr node)
  8185. {
  8186. details::operator_type op = dynamic_cast<details::voc_base_node<T>*>(node)->operation();
  8187. switch (op)
  8188. {
  8189. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_cr<typename details::covoc1_node<Type,Operation1,op1<Type> > >(c,(*dynamic_cast<details::voc_node<T,op1<T> >*>(node)));
  8190. basic_opr_switch_statements
  8191. #ifndef exprtk_disable_extended_operator_optimizations
  8192. extended_opr_switch_statements
  8193. #endif
  8194. #undef case_stmt
  8195. default : return error_node();
  8196. }
  8197. }
  8198. inline expression_node_ptr synthesize_covoc1_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8199. {
  8200. // Definition: (c)o(voc)
  8201. T c = dynamic_cast<details::literal_node<Type>*>(branch[0])->value();
  8202. expression_node_ptr result = error_node();
  8203. switch (operation)
  8204. {
  8205. #define case_stmt(op0,op1) case op0 : result = synthesize_covoc1_expression_impl<op1<Type> >(c,branch[1]); break;
  8206. basic_opr_switch_statements
  8207. #ifndef exprtk_disable_extended_operator_optimizations
  8208. extended_opr_switch_statements
  8209. #endif
  8210. #undef case_stmt
  8211. default : return error_node();
  8212. }
  8213. node_allocator_->free(branch[0]);
  8214. node_allocator_->free(branch[1]);
  8215. return result;
  8216. }
  8217. template <typename Operation2>
  8218. inline expression_node_ptr synthesize_covoc2_expression_impl(expression_node_ptr node, const T& c)
  8219. {
  8220. details::operator_type op = dynamic_cast<details::cov_base_node<T>*>(node)->operation();
  8221. switch (op)
  8222. {
  8223. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::covoc2_node<Type,op1<T>,Operation2> >((*dynamic_cast<details::cov_node<T,op1<T> >*>(node)),c);
  8224. basic_opr_switch_statements
  8225. #ifndef exprtk_disable_extended_operator_optimizations
  8226. extended_opr_switch_statements
  8227. #endif
  8228. #undef case_stmt
  8229. default : return error_node();
  8230. }
  8231. }
  8232. inline expression_node_ptr synthesize_covoc2_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8233. {
  8234. // Definition: (cov)o(c)
  8235. T c = dynamic_cast<details::literal_node<Type>*>(branch[1])->value();
  8236. expression_node_ptr result = error_node();
  8237. switch (operation)
  8238. {
  8239. #define case_stmt(op0,op1) case op0 : result = synthesize_covoc2_expression_impl<op1<Type> >(branch[0],c); break;
  8240. basic_opr_switch_statements
  8241. #ifndef exprtk_disable_extended_operator_optimizations
  8242. extended_opr_switch_statements
  8243. #endif
  8244. #undef case_stmt
  8245. default : return error_node();
  8246. }
  8247. node_allocator_->free(branch[0]);
  8248. node_allocator_->free(branch[1]);
  8249. return result;
  8250. }
  8251. template <typename Operation1>
  8252. inline expression_node_ptr synthesize_vocov1_expression_impl(const T& v, expression_node_ptr node)
  8253. {
  8254. details::operator_type op = dynamic_cast<details::cov_base_node<T>*>(node)->operation();
  8255. switch (op)
  8256. {
  8257. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vocov1_node<Type,Operation1,op1<Type> > >(v,(*dynamic_cast<details::cov_node<T,op1<T> >*>(node)));
  8258. basic_opr_switch_statements
  8259. #ifndef exprtk_disable_extended_operator_optimizations
  8260. extended_opr_switch_statements
  8261. #endif
  8262. #undef case_stmt
  8263. default : return error_node();
  8264. }
  8265. }
  8266. inline expression_node_ptr synthesize_vocov1_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8267. {
  8268. // Definition: (v)o(cov)
  8269. T& v = dynamic_cast<details::variable_node<T>*>(branch[0])->ref();
  8270. expression_node_ptr result = error_node();
  8271. switch (operation)
  8272. {
  8273. #define case_stmt(op0,op1) case op0 : result = synthesize_vocov1_expression_impl<op1<Type> >(v,branch[1]); break;
  8274. basic_opr_switch_statements
  8275. #ifndef exprtk_disable_extended_operator_optimizations
  8276. extended_opr_switch_statements
  8277. #endif
  8278. #undef case_stmt
  8279. default : return error_node();
  8280. }
  8281. node_allocator_->free(branch[1]);
  8282. return result;
  8283. }
  8284. template <typename Operation2>
  8285. inline expression_node_ptr synthesize_vocov2_expression_impl(expression_node_ptr node, const T& v)
  8286. {
  8287. details::operator_type op = dynamic_cast<details::voc_base_node<T>*>(node)->operation();
  8288. switch (op)
  8289. {
  8290. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vocov2_node<Type,op1<T>,Operation2> >((*dynamic_cast<details::voc_node<T,op1<T> >*>(node)),v);
  8291. basic_opr_switch_statements
  8292. #ifndef exprtk_disable_extended_operator_optimizations
  8293. extended_opr_switch_statements
  8294. #endif
  8295. #undef case_stmt
  8296. default : return error_node();
  8297. }
  8298. }
  8299. inline expression_node_ptr synthesize_vocov2_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8300. {
  8301. // Definition: (voc)o(v)
  8302. T& v = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
  8303. expression_node_ptr result = error_node();
  8304. switch (operation)
  8305. {
  8306. #define case_stmt(op0,op1) case op0 : result = synthesize_vocov2_expression_impl<op1<Type> >(branch[0],v); break;
  8307. basic_opr_switch_statements
  8308. #ifndef exprtk_disable_extended_operator_optimizations
  8309. extended_opr_switch_statements
  8310. #endif
  8311. #undef case_stmt
  8312. default : return error_node();
  8313. }
  8314. node_allocator_->free(branch[0]);
  8315. return result;
  8316. }
  8317. template <typename Op1, typename Op2, typename Op3>
  8318. inline expression_node_ptr gen_uvouv_node(expression_node_ptr (&branch)[2])
  8319. {
  8320. return node_allocator_->
  8321. allocate_rr<typename details::uvouv_node<Type,Op1,Op2,Op3> >(
  8322. dynamic_cast<details::unary_variable_node<Type,Op1>*>(branch[0])->v(),
  8323. dynamic_cast<details::unary_variable_node<Type,Op3>*>(branch[1])->v());
  8324. }
  8325. template <typename Op1, typename Op2>
  8326. inline expression_node_ptr synthesize_uvouv_expression_impl2(expression_node_ptr (&branch)[2])
  8327. {
  8328. details::operator_type op = dynamic_cast<details::uv_base_node<T>*>(branch[1])->operation();
  8329. switch (op)
  8330. {
  8331. #define case_stmt(op0,op1) case op0 : return gen_uvouv_node<Op1,Op2,op1<Type> >(branch);
  8332. unary_opr_switch_statements
  8333. #undef case_stmt
  8334. default : return error_node();
  8335. }
  8336. }
  8337. template <typename Operation2>
  8338. inline expression_node_ptr synthesize_uvouv_expression_impl1(expression_node_ptr (&branch)[2])
  8339. {
  8340. details::operator_type op = dynamic_cast<details::uv_base_node<Type>*>(branch[0])->operation();
  8341. switch (op)
  8342. {
  8343. #define case_stmt(op0,op1) case op0 : return synthesize_uvouv_expression_impl2<op1<Type>,Operation2>(branch); break;
  8344. unary_opr_switch_statements
  8345. #undef case_stmt
  8346. default : return error_node();
  8347. }
  8348. }
  8349. inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
  8350. {
  8351. // Definition: uv o uv
  8352. expression_node_ptr result = error_node();
  8353. switch (operation)
  8354. {
  8355. #define case_stmt(op0,op1) case op0 : result = synthesize_uvouv_expression_impl1<op1<Type> >(branch); break;
  8356. basic_opr_switch_statements
  8357. #ifndef exprtk_disable_extended_operator_optimizations
  8358. extended_opr_switch_statements
  8359. #endif
  8360. #undef case_stmt
  8361. default : return error_node();
  8362. }
  8363. node_allocator_->free(branch[0]);
  8364. node_allocator_->free(branch[1]);
  8365. return result;
  8366. }
  8367. #ifndef exprtk_disable_extended_optimisations
  8368. template <typename Op1, typename Op2>
  8369. inline expression_node_ptr synthesize_vovovov_expression_impl2(expression_node_ptr (&node)[2])
  8370. {
  8371. details::operator_type op = dynamic_cast<details::vov_base_node<Type>*>(node[1])->operation();
  8372. switch (op)
  8373. {
  8374. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_rr<typename details::vovovov_node<Type,Op1,Op2,op1<T> > >((*dynamic_cast<details::vov_node<T,Op1>*>(node[0])),(*dynamic_cast<details::vov_node<T,op1<T> >*>(node[1])));
  8375. basic_opr_switch_statements
  8376. #ifndef exprtk_disable_extended_operator_optimizations
  8377. extended_opr_switch_statements
  8378. #endif
  8379. #undef case_stmt
  8380. default : return error_node();
  8381. }
  8382. #else
  8383. template <typename Op1, typename Op2>
  8384. inline expression_node_ptr synthesize_vovovov_expression_impl2(expression_node_ptr (&)[2])
  8385. {
  8386. return error_node();
  8387. #endif
  8388. }
  8389. #ifndef exprtk_disable_extended_optimisations
  8390. template <typename Operation2>
  8391. inline expression_node_ptr synthesize_vovovov_expression_impl1(expression_node_ptr (&node)[2])
  8392. {
  8393. details::operator_type op = dynamic_cast<details::vov_base_node<Type>*>(node[0])->operation();
  8394. switch (op)
  8395. {
  8396. #define case_stmt(op0,op1) case op0 : return synthesize_vovovov_expression_impl2<op1<Type>,Operation2>(node); break;
  8397. basic_opr_switch_statements
  8398. #ifndef exprtk_disable_extended_operator_optimizations
  8399. extended_opr_switch_statements
  8400. #endif
  8401. #undef case_stmt
  8402. default : return error_node();
  8403. }
  8404. }
  8405. #else
  8406. template <typename Operation2>
  8407. inline expression_node_ptr synthesize_vovovov_expression_impl1(expression_node_ptr (&)[2])
  8408. {
  8409. return error_node();
  8410. }
  8411. #endif
  8412. #ifndef exprtk_disable_extended_optimisations
  8413. inline expression_node_ptr synthesize_vovovov_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  8414. {
  8415. //Definition: (vov)o(vov)
  8416. expression_node_ptr result = error_node();
  8417. switch (opr)
  8418. {
  8419. #define case_stmt(op0,op1) case op0 : result = synthesize_vovovov_expression_impl1<op1<Type> >(branch); break;
  8420. basic_opr_switch_statements
  8421. #ifndef exprtk_disable_extended_operator_optimizations
  8422. extended_opr_switch_statements
  8423. #endif
  8424. #undef case_stmt
  8425. default : return error_node();
  8426. }
  8427. node_allocator_->free(branch[0]);
  8428. node_allocator_->free(branch[1]);
  8429. return result;
  8430. }
  8431. #else
  8432. inline expression_node_ptr synthesize_vovovov_expression(const details::operator_type&, expression_node_ptr (&)[2])
  8433. {
  8434. return error_node();
  8435. }
  8436. #endif
  8437. #undef basic_opr_switch_statements
  8438. #undef extended_opr_switch_statements
  8439. #undef unary_opr_switch_statements
  8440. #ifndef exprtk_disable_string_capabilities
  8441. template <typename T0, typename T1>
  8442. inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1)
  8443. {
  8444. switch (opr)
  8445. {
  8446. #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0,s1);
  8447. case_stmt(details::e_lt ,details:: lt_op)
  8448. case_stmt(details::e_lte ,details:: lte_op)
  8449. case_stmt(details::e_gt ,details:: gt_op)
  8450. case_stmt(details::e_gte ,details:: gte_op)
  8451. case_stmt(details::e_eq ,details:: eq_op)
  8452. case_stmt(details::e_ne ,details:: ne_op)
  8453. case_stmt(details::e_in ,details:: in_op)
  8454. case_stmt(details::e_like ,details:: like_op)
  8455. case_stmt(details::e_ilike,details::ilike_op)
  8456. #undef case_stmt
  8457. default : return error_node();
  8458. }
  8459. }
  8460. inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  8461. {
  8462. std::string& s0 = dynamic_cast<details::stringvar_node<Type>*>(branch[0])->ref();
  8463. std::string& s1 = dynamic_cast<details::stringvar_node<Type>*>(branch[1])->ref();
  8464. return synthesize_sos_expression_impl<std::string&,std::string&>(opr,s0,s1);
  8465. }
  8466. inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  8467. {
  8468. std::string& s0 = dynamic_cast< details::stringvar_node<Type>*>(branch[0])->ref();
  8469. std::string s1 = dynamic_cast<details::string_literal_node<Type>*>(branch[1])->str();
  8470. node_allocator_->free(branch[1]);
  8471. return synthesize_sos_expression_impl<std::string&,const std::string>(opr,s0,s1);
  8472. }
  8473. inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  8474. {
  8475. std::string s0 = dynamic_cast<details::string_literal_node<Type>*>(branch[0])->str();
  8476. std::string& s1 = dynamic_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  8477. node_allocator_->free(branch[0]);
  8478. return synthesize_sos_expression_impl<const std::string,std::string&>(opr,s0,s1);
  8479. }
  8480. inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  8481. {
  8482. const std::string s0 = dynamic_cast<details::string_literal_node<Type>*>(branch[0])->str();
  8483. const std::string s1 = dynamic_cast<details::string_literal_node<Type>*>(branch[1])->str();
  8484. expression_node_ptr result = error_node();
  8485. if (details::e_add == opr)
  8486. result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
  8487. else if (details::e_in == opr)
  8488. result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op<Type>::process(s0,s1));
  8489. else if (details::e_like == opr)
  8490. result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op<Type>::process(s0,s1));
  8491. else if (details::e_ilike == opr)
  8492. result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
  8493. else
  8494. {
  8495. expression_node_ptr temp = synthesize_sos_expression_impl<const std::string,const std::string>(opr,s0,s1);
  8496. Type v = temp->value();
  8497. node_allocator_->free(temp);
  8498. result = node_allocator_->allocate<literal_node_t>(v);
  8499. }
  8500. node_allocator_->free(branch[0]);
  8501. node_allocator_->free(branch[1]);
  8502. return result;
  8503. }
  8504. #endif
  8505. #ifndef exprtk_disable_string_capabilities
  8506. inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
  8507. {
  8508. if (details::is_string_node(branch[0]))
  8509. {
  8510. if (details::is_string_node(branch[1])) return synthesize_sos_expression(opr,branch);
  8511. else if (details::is_const_string_node(branch[1])) return synthesize_socs_expression(opr,branch);
  8512. }
  8513. else if (details::is_const_string_node(branch[0]))
  8514. {
  8515. if (details::is_string_node(branch[1])) return synthesize_csos_expression(opr,branch);
  8516. else if (details::is_const_string_node(branch[1])) return synthesize_csocs_expression(opr,branch);
  8517. }
  8518. return error_node();
  8519. }
  8520. #else
  8521. inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&)[2])
  8522. {
  8523. return error_node();
  8524. }
  8525. #endif
  8526. #ifndef exprtk_disable_string_capabilities
  8527. inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3])
  8528. {
  8529. if (details::e_inrange != opr)
  8530. return error_node();
  8531. else if (
  8532. details::is_const_string_node(branch[0]) &&
  8533. details::is_const_string_node(branch[1]) &&
  8534. details::is_const_string_node(branch[2])
  8535. )
  8536. {
  8537. const std::string s0 = dynamic_cast<details::string_literal_node<Type>*>(branch[0])->str();
  8538. const std::string s1 = dynamic_cast<details::string_literal_node<Type>*>(branch[1])->str();
  8539. const std::string s2 = dynamic_cast<details::string_literal_node<Type>*>(branch[2])->str();
  8540. Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
  8541. node_allocator_->free(branch[0]);
  8542. node_allocator_->free(branch[1]);
  8543. node_allocator_->free(branch[2]);
  8544. return node_allocator_->allocate_c<details::literal_node<Type> >(v);
  8545. }
  8546. else if (
  8547. details::is_string_node(branch[0]) &&
  8548. details::is_string_node(branch[1]) &&
  8549. details::is_string_node(branch[2])
  8550. )
  8551. {
  8552. std::string& s0 = dynamic_cast<details::stringvar_node<Type>*>(branch[0])->ref();
  8553. std::string& s1 = dynamic_cast<details::stringvar_node<Type>*>(branch[1])->ref();
  8554. std::string& s2 = dynamic_cast<details::stringvar_node<Type>*>(branch[2])->ref();
  8555. typedef typename details::sosos_node<Type,std::string&,std::string&,std::string&,details::inrange_op<Type> > inrange_t;
  8556. return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string&>(s0,s1,s2);
  8557. }
  8558. else if (
  8559. details::is_const_string_node(branch[0]) &&
  8560. details::is_string_node(branch[1]) &&
  8561. details::is_const_string_node(branch[2])
  8562. )
  8563. {
  8564. std::string s0 = dynamic_cast<details::string_literal_node<Type>*>(branch[0])->str();
  8565. std::string& s1 = dynamic_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  8566. std::string s2 = dynamic_cast<details::string_literal_node<Type>*>(branch[2])->str();
  8567. typedef typename details::sosos_node<Type,std::string,std::string&,std::string,details::inrange_op<Type> > inrange_t;
  8568. node_allocator_->free(branch[0]);
  8569. node_allocator_->free(branch[2]);
  8570. return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string>(s0,s1,s2);
  8571. }
  8572. else if (
  8573. details::is_string_node(branch[0]) &&
  8574. details::is_const_string_node(branch[1]) &&
  8575. details::is_string_node(branch[2])
  8576. )
  8577. {
  8578. std::string& s0 = dynamic_cast< details::stringvar_node<Type>*>(branch[0])->ref();
  8579. std::string s1 = dynamic_cast<details::string_literal_node<Type>*>(branch[1])->str();
  8580. std::string& s2 = dynamic_cast< details::stringvar_node<Type>*>(branch[2])->ref();
  8581. typedef typename details::sosos_node<Type,std::string&,std::string,std::string&,details::inrange_op<Type> > inrange_t;
  8582. node_allocator_->free(branch[1]);
  8583. return node_allocator_->allocate_type<inrange_t,std::string&,std::string,std::string&>(s0,s1,s2);
  8584. }
  8585. else if (
  8586. details::is_string_node(branch[0]) &&
  8587. details::is_string_node(branch[1]) &&
  8588. details::is_const_string_node(branch[2])
  8589. )
  8590. {
  8591. std::string& s0 = dynamic_cast< details::stringvar_node<Type>*>(branch[0])->ref();
  8592. std::string& s1 = dynamic_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  8593. std::string s2 = dynamic_cast<details::string_literal_node<Type>*>(branch[2])->str();
  8594. typedef typename details::sosos_node<Type,std::string&,std::string&,std::string,details::inrange_op<Type> > inrange_t;
  8595. node_allocator_->free(branch[2]);
  8596. return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string>(s0,s1,s2);
  8597. }
  8598. else if (
  8599. details::is_const_string_node(branch[0]) &&
  8600. details:: is_string_node(branch[1]) &&
  8601. details:: is_string_node(branch[2])
  8602. )
  8603. {
  8604. std::string s0 = dynamic_cast<details::string_literal_node<Type>*>(branch[0])->str();
  8605. std::string& s1 = dynamic_cast< details::stringvar_node<Type>*>(branch[1])->ref();
  8606. std::string& s2 = dynamic_cast< details::stringvar_node<Type>*>(branch[2])->ref();
  8607. typedef typename details::sosos_node<Type,std::string,std::string&,std::string&,details::inrange_op<Type> > inrange_t;
  8608. node_allocator_->free(branch[0]);
  8609. return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string&>(s0,s1,s2);
  8610. }
  8611. else
  8612. return error_node();
  8613. }
  8614. #else
  8615. inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&)[3])
  8616. {
  8617. return error_node();
  8618. }
  8619. #endif
  8620. template <typename NodeType, std::size_t N>
  8621. inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N])
  8622. {
  8623. if ((details::e_in == operation) || (details::e_like == operation) || (details::e_ilike == operation))
  8624. return error_node();
  8625. else if ((details::e_default != operation) && all_nodes_valid<N>(branch))
  8626. {
  8627. //Attempt simple constant folding optimization.
  8628. expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
  8629. if (is_constant_foldable<N>(branch))
  8630. {
  8631. Type v = expression_point->value();
  8632. node_allocator_->free(expression_point);
  8633. return node_allocator_->allocate<literal_node_t>(v);
  8634. }
  8635. else
  8636. return expression_point;
  8637. }
  8638. else
  8639. return error_node();
  8640. }
  8641. template <typename NodeType, std::size_t N>
  8642. inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N])
  8643. {
  8644. if (all_nodes_valid<N>(branch))
  8645. {
  8646. typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
  8647. //Attempt simple constant folding optimization.
  8648. expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
  8649. dynamic_cast<function_N_node_t*>(expression_point)->init_branches(branch);
  8650. if (is_constant_foldable<N>(branch))
  8651. {
  8652. Type v = expression_point->value();
  8653. node_allocator_->free(expression_point);
  8654. return node_allocator_->allocate<literal_node_t>(v);
  8655. }
  8656. else
  8657. return expression_point;
  8658. }
  8659. else
  8660. return error_node();
  8661. }
  8662. details::node_allocator* node_allocator_;
  8663. optimization_level optimization_level_;
  8664. };
  8665. inline void set_error(const parser_error::type& error_type)
  8666. {
  8667. error_list_.push_back(error_type);
  8668. }
  8669. inline void remove_last_error()
  8670. {
  8671. error_list_.pop_back();
  8672. }
  8673. private:
  8674. parser(const parser<T>&);
  8675. parser<T>& operator=(const parser<T>&);
  8676. lexer::generator lexer_;
  8677. lexer::token current_token_;
  8678. lexer::token store_current_token_;
  8679. expression_generator<T> expression_generator_;
  8680. details::node_allocator node_allocator_;
  8681. symbol_table<T> symbol_table_;
  8682. bool symbol_name_caching_;
  8683. std::size_t precompile_options_;
  8684. std::deque<std::string> symbol_name_cache_;
  8685. std::deque<parser_error::type> error_list_;
  8686. std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_;
  8687. lexer::helper::helper_assembly helper_assembly_;
  8688. lexer::helper::commutative_inserter commutative_inserter_;
  8689. lexer::helper::operator_joiner operator_joiner_;
  8690. lexer::helper::symbol_replacer symbol_replacer_;
  8691. lexer::helper::bracket_checker bracket_checker_;
  8692. lexer::helper::numeric_checker numeric_checker_;
  8693. lexer::helper::sequence_validator sequence_validator_;
  8694. };
  8695. template <typename T>
  8696. inline T integrate(expression<T>& e,
  8697. T& x,
  8698. const T& r0, const T& r1,
  8699. const std::size_t number_of_intervals = 1000000)
  8700. {
  8701. if (r0 > r1) return T(0);
  8702. T h = (r1 - r0) / (T(2.0) * number_of_intervals);
  8703. T total_area = T(0);
  8704. for (std::size_t i = 0; i < number_of_intervals; ++i)
  8705. {
  8706. x = r0 + T(2.0) * i * h;
  8707. T y0 = e.value(); x += h;
  8708. T y1 = e.value(); x += h;
  8709. T y2 = e.value(); x += h;
  8710. total_area += h * (y0 + T(4.0) * y1 + y2) / T(3.0);
  8711. }
  8712. return total_area;
  8713. }
  8714. template <typename T>
  8715. inline T integrate(expression<T>& e,
  8716. const std::string& variable_name,
  8717. const T& r0, const T& r1,
  8718. const std::size_t number_of_intervals = 1000000)
  8719. {
  8720. symbol_table<T>& sym_table = e.get_symbol_table();
  8721. if (!sym_table.valid())
  8722. return std::numeric_limits<T>::quiet_NaN();
  8723. details::variable_node<T>* var = sym_table.get_variable(variable_name);
  8724. if (var)
  8725. {
  8726. T& x = var->ref();
  8727. T x_original = x;
  8728. T result = integrate(e,x,r0,r1,number_of_intervals);
  8729. x = x_original;
  8730. return result;
  8731. }
  8732. else
  8733. return std::numeric_limits<T>::quiet_NaN();
  8734. }
  8735. template <typename T>
  8736. inline T derivative(expression<T>& e,
  8737. T& x,
  8738. const double& h = 0.00001)
  8739. {
  8740. T x_init = x;
  8741. x = x_init + T(2.0) * h;
  8742. T y0 = e.value();
  8743. x = x_init + h;
  8744. T y1 = e.value();
  8745. x = x_init - h;
  8746. T y2 = e.value();
  8747. x = x_init - T(2.0) * h;
  8748. T y3 = e.value();
  8749. x = x_init;
  8750. return (-y0 + T(8.0) * (y1 - y2) + y3) / (T(12.0) * h);
  8751. }
  8752. template <typename T>
  8753. inline T derivative(expression<T>& e,
  8754. const std::string& variable_name,
  8755. const double& h = 0.00001)
  8756. {
  8757. symbol_table<T>& sym_table = e.get_symbol_table();
  8758. if (!sym_table.valid())
  8759. return std::numeric_limits<T>::quiet_NaN();
  8760. details::variable_node<T>* var = sym_table.get_variable(variable_name);
  8761. if (var)
  8762. {
  8763. T& x = var->ref();
  8764. T x_original = x;
  8765. T result = derivative(e,x,h);
  8766. x = x_original;
  8767. return result;
  8768. }
  8769. else
  8770. return std::numeric_limits<T>::quiet_NaN();
  8771. }
  8772. /*
  8773. Note: The following 'compute' routines are very simple helpers,
  8774. for quickly setting up the required pieces of code in order to
  8775. evaluate an expression. By virtue of how they the operate there
  8776. will be an overhead with regards to their setup and teardown and
  8777. hence should not be used in time critical sections of code.
  8778. Furthermore they only assume a small sub set of variables - no
  8779. string variables or user defined functions.
  8780. */
  8781. template <typename T>
  8782. inline bool compute(const std::string& expression_string, T& result)
  8783. {
  8784. //No variables
  8785. symbol_table<T> symbol_table;
  8786. symbol_table.add_constants();
  8787. expression<T> expression;
  8788. parser<T> parser;
  8789. if (parser.compile(expression_string,expression))
  8790. {
  8791. result = expression.value();
  8792. return true;
  8793. }
  8794. else
  8795. return false;
  8796. }
  8797. template <typename T>
  8798. inline bool compute(const std::string& expression_string,
  8799. const T& x,
  8800. T& result)
  8801. {
  8802. //Only 'x'
  8803. static const std::string x_var("x");
  8804. symbol_table<T> symbol_table;
  8805. symbol_table.add_constants();
  8806. symbol_table.add_variable(x_var,x);
  8807. expression<T> expression;
  8808. parser<T> parser;
  8809. if (parser.compile(expression_string,expression))
  8810. {
  8811. result = expression.value();
  8812. return true;
  8813. }
  8814. else
  8815. return false;
  8816. }
  8817. template <typename T>
  8818. inline bool compute(const std::string& expression_string,
  8819. const T&x, const T& y,
  8820. T& result)
  8821. {
  8822. //Only 'x' and 'y'
  8823. static const std::string x_var("x");
  8824. static const std::string y_var("y");
  8825. symbol_table<T> symbol_table;
  8826. symbol_table.add_constants();
  8827. symbol_table.add_variable(x_var,x);
  8828. symbol_table.add_variable(y_var,y);
  8829. expression<T> expression;
  8830. parser<T> parser;
  8831. if (parser.compile(expression_string,expression))
  8832. {
  8833. result = expression.value();
  8834. return true;
  8835. }
  8836. else
  8837. return false;
  8838. }
  8839. template <typename T>
  8840. inline bool compute(const std::string& expression_string,
  8841. const T& x, const T& y, const T& z,
  8842. T& result)
  8843. {
  8844. //Only 'x', 'y' or 'z'
  8845. static const std::string x_var("x");
  8846. static const std::string y_var("y");
  8847. static const std::string z_var("z");
  8848. symbol_table<T> symbol_table;
  8849. symbol_table.add_constants();
  8850. symbol_table.add_variable(x_var,x);
  8851. symbol_table.add_variable(y_var,y);
  8852. symbol_table.add_variable(z_var,z);
  8853. expression<T> expression;
  8854. parser<T> parser;
  8855. if (parser.compile(expression_string,expression))
  8856. {
  8857. result = expression.value();
  8858. return true;
  8859. }
  8860. else
  8861. return false;
  8862. }
  8863. template <typename T, std::size_t N>
  8864. class polynomial : public ifunction<T>
  8865. {
  8866. private:
  8867. template <typename Type, std::size_t NumberOfCoefficients>
  8868. struct poly_impl { };
  8869. template <typename Type>
  8870. struct poly_impl <Type,10>
  8871. {
  8872. static inline T evaluate(const Type x,
  8873. const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
  8874. const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
  8875. const Type c0)
  8876. {
  8877. //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
  8878. return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  8879. }
  8880. };
  8881. template <typename Type>
  8882. struct poly_impl <Type,9>
  8883. {
  8884. static inline T evaluate(const Type x,
  8885. const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
  8886. const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
  8887. {
  8888. //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
  8889. return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  8890. }
  8891. };
  8892. template <typename Type>
  8893. struct poly_impl <Type,8>
  8894. {
  8895. static inline T evaluate(const Type x,
  8896. const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
  8897. const Type c3, const Type c2, const Type c1, const Type c0)
  8898. {
  8899. //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
  8900. return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  8901. }
  8902. };
  8903. template <typename Type>
  8904. struct poly_impl <Type,7>
  8905. {
  8906. static inline T evaluate(const Type x,
  8907. const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
  8908. const Type c2, const Type c1, const Type c0)
  8909. {
  8910. //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
  8911. return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  8912. }
  8913. };
  8914. template <typename Type>
  8915. struct poly_impl <Type,6>
  8916. {
  8917. static inline T evaluate(const Type x,
  8918. const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
  8919. const Type c1, const Type c0)
  8920. {
  8921. //p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  8922. return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  8923. }
  8924. };
  8925. template <typename Type>
  8926. struct poly_impl <Type,5>
  8927. {
  8928. static inline T evaluate(const Type x,
  8929. const Type c5, const Type c4, const Type c3, const Type c2,
  8930. const Type c1, const Type c0)
  8931. {
  8932. //p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  8933. return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
  8934. }
  8935. };
  8936. template <typename Type>
  8937. struct poly_impl <Type,4>
  8938. {
  8939. static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
  8940. {
  8941. //p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  8942. return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
  8943. }
  8944. };
  8945. template <typename Type>
  8946. struct poly_impl <Type,3>
  8947. {
  8948. static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
  8949. {
  8950. //p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
  8951. return (((c3 * x + c2) * x + c1) * x + c0);
  8952. }
  8953. };
  8954. template <typename Type>
  8955. struct poly_impl <Type,2>
  8956. {
  8957. static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
  8958. {
  8959. //p(x) = c_2x^2 + c_1x^1 + c_0x^0
  8960. return ((c2 * x + c1) * x + c0);
  8961. }
  8962. };
  8963. template <typename Type>
  8964. struct poly_impl <Type,1>
  8965. {
  8966. static inline T evaluate(const Type x, const Type c1, const Type c0)
  8967. {
  8968. //p(x) = c_1x^1 + c_0x^0
  8969. return (c1 * x + c0);
  8970. }
  8971. };
  8972. public:
  8973. polynomial() : exprtk::ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max()) {}
  8974. inline virtual T operator()(const T& x, const T& c1, const T& c0)
  8975. {
  8976. return ((1 == N) ? poly_impl<T,1>::evaluate(x,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  8977. }
  8978. inline virtual T operator()(const T& x, const T& c2, const T& c1, const T& c0)
  8979. {
  8980. return ((2 == N) ? poly_impl<T,2>::evaluate(x,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  8981. }
  8982. inline virtual T operator()(const T& x, const T& c3, const T& c2, const T& c1, const T& c0)
  8983. {
  8984. return ((3 == N) ? poly_impl<T,3>::evaluate(x,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  8985. }
  8986. inline virtual T operator()(const T& x, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
  8987. {
  8988. return ((4 == N) ? poly_impl<T,4>::evaluate(x,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  8989. }
  8990. 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)
  8991. {
  8992. return ((5 == N) ? poly_impl<T,5>::evaluate(x,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  8993. }
  8994. 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)
  8995. {
  8996. return ((6 == N) ? poly_impl<T,6>::evaluate(x,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  8997. }
  8998. 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)
  8999. {
  9000. return ((7 == N) ? poly_impl<T,7>::evaluate(x,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  9001. }
  9002. 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)
  9003. {
  9004. return ((8 == N) ? poly_impl<T,8>::evaluate(x,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
  9005. }
  9006. 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)
  9007. {
  9008. 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());
  9009. }
  9010. 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)
  9011. {
  9012. 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());
  9013. }
  9014. inline virtual T operator()()
  9015. {
  9016. return std::numeric_limits<T>::quiet_NaN();
  9017. }
  9018. inline virtual T operator()(const T&)
  9019. {
  9020. return std::numeric_limits<T>::quiet_NaN();
  9021. }
  9022. inline virtual T operator()(const T&, const T&)
  9023. {
  9024. return std::numeric_limits<T>::quiet_NaN();
  9025. }
  9026. };
  9027. template <typename T>
  9028. inline bool pgo_primer()
  9029. {
  9030. static const std::string expression_list[]
  9031. = {
  9032. "(y + x)",
  9033. "2 * (y + x)",
  9034. "(2 * y + 2 * x)",
  9035. "(y + x / y) * (x - y / x)",
  9036. "x / ((x + y) * (x - y)) / y",
  9037. "1 - ((x * y) + (y / x)) - 3",
  9038. "sin(2 * x) + cos(pi / y)",
  9039. "1 - sin(2 * x) + cos(pi / y)",
  9040. "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
  9041. "(x^2 / sin(2 * pi / y)) -x / 2",
  9042. "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
  9043. "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
  9044. "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
  9045. "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
  9046. "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
  9047. "(yy + xx)",
  9048. "2 * (yy + xx)",
  9049. "(2 * yy + 2 * xx)",
  9050. "(yy + xx / yy) * (xx - yy / xx)",
  9051. "xx / ((xx + yy) * (xx - yy)) / yy",
  9052. "1 - ((xx * yy) + (yy / xx)) - 3",
  9053. "sin(2 * xx) + cos(pi / yy)",
  9054. "1 - sin(2 * xx) + cos(pi / yy)",
  9055. "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
  9056. "(xx^2 / sin(2 * pi / yy)) -xx / 2",
  9057. "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
  9058. "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
  9059. "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
  9060. "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
  9061. "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55"
  9062. };
  9063. static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
  9064. T x = T(0);
  9065. T y = T(0);
  9066. T xx = T(0);
  9067. T yy = T(0);
  9068. exprtk::symbol_table<T> symbol_table;
  9069. symbol_table.add_constants();
  9070. symbol_table.add_variable( "x", x);
  9071. symbol_table.add_variable( "y", y);
  9072. symbol_table.add_variable("xx",xx);
  9073. symbol_table.add_variable("yy",yy);
  9074. typedef typename std::deque<exprtk::expression<T> > expr_list_t;
  9075. expr_list_t optimized_expr_list;
  9076. expr_list_t unoptimized_expr_list;
  9077. const std::size_t rounds = 100;
  9078. //Generate optimised expressions
  9079. {
  9080. for (std::size_t r = 0; r < rounds; ++r)
  9081. {
  9082. optimized_expr_list.clear();
  9083. exprtk::parser<T> parser;
  9084. for (std::size_t i = 0; i < expression_list_size; ++i)
  9085. {
  9086. exprtk::expression<T> expression;
  9087. expression.register_symbol_table(symbol_table);
  9088. if (!parser.compile(expression_list[i],expression,exprtk::parser<T>::e_all))
  9089. {
  9090. return false;
  9091. }
  9092. optimized_expr_list.push_back(expression);
  9093. }
  9094. }
  9095. }
  9096. //Generate unoptimised expressions
  9097. {
  9098. for (std::size_t r = 0; r < rounds; ++r)
  9099. {
  9100. unoptimized_expr_list.clear();
  9101. exprtk::parser<T> parser;
  9102. for (std::size_t i = 0; i < expression_list_size; ++i)
  9103. {
  9104. exprtk::expression<T> expression;
  9105. expression.register_symbol_table(symbol_table);
  9106. if (!parser.compile(expression_list[i],expression,exprtk::parser<T>::e_none))
  9107. {
  9108. return false;
  9109. }
  9110. unoptimized_expr_list.push_back(expression);
  9111. }
  9112. }
  9113. }
  9114. struct execute
  9115. {
  9116. static inline T process(T& x, T& y, expression<T>& expression)
  9117. {
  9118. static const T lower_bound = T(-20.0);
  9119. static const T upper_bound = T(+20.0);
  9120. T delta = T(0.1);
  9121. T total = T(0.0);
  9122. for (x = lower_bound; x <= upper_bound; x += delta)
  9123. {
  9124. for (y = lower_bound; y <= upper_bound; y += delta)
  9125. {
  9126. total += expression.value();
  9127. }
  9128. }
  9129. return total;
  9130. }
  9131. };
  9132. for (std::size_t i = 0; i < optimized_expr_list.size(); ++i)
  9133. {
  9134. execute::process( x, y, optimized_expr_list[i]);
  9135. execute::process(xx,yy, optimized_expr_list[i]);
  9136. execute::process( x, y,unoptimized_expr_list[i]);
  9137. execute::process(xx,yy,unoptimized_expr_list[i]);
  9138. }
  9139. {
  9140. for (std::size_t i = 0; i < 10000; ++i)
  9141. {
  9142. T v = T(123.456 + i);
  9143. if (details::numeric::nequal(details::numeric::fast_exp<T, 1>::result(v),std::pow(v,T( 1.0)))) return false;
  9144. else if (details::numeric::nequal(details::numeric::fast_exp<T, 2>::result(v),std::pow(v,T( 2.0)))) return false;
  9145. else if (details::numeric::nequal(details::numeric::fast_exp<T, 3>::result(v),std::pow(v,T( 3.0)))) return false;
  9146. else if (details::numeric::nequal(details::numeric::fast_exp<T, 4>::result(v),std::pow(v,T( 4.0)))) return false;
  9147. else if (details::numeric::nequal(details::numeric::fast_exp<T, 5>::result(v),std::pow(v,T( 5.0)))) return false;
  9148. else if (details::numeric::nequal(details::numeric::fast_exp<T, 6>::result(v),std::pow(v,T( 6.0)))) return false;
  9149. else if (details::numeric::nequal(details::numeric::fast_exp<T, 7>::result(v),std::pow(v,T( 7.0)))) return false;
  9150. else if (details::numeric::nequal(details::numeric::fast_exp<T, 8>::result(v),std::pow(v,T( 8.0)))) return false;
  9151. else if (details::numeric::nequal(details::numeric::fast_exp<T, 9>::result(v),std::pow(v,T( 9.0)))) return false;
  9152. else if (details::numeric::nequal(details::numeric::fast_exp<T,10>::result(v),std::pow(v,T(10.0)))) return false;
  9153. else if (details::numeric::nequal(details::numeric::fast_exp<T,11>::result(v),std::pow(v,T(11.0)))) return false;
  9154. else if (details::numeric::nequal(details::numeric::fast_exp<T,12>::result(v),std::pow(v,T(12.0)))) return false;
  9155. else if (details::numeric::nequal(details::numeric::fast_exp<T,13>::result(v),std::pow(v,T(13.0)))) return false;
  9156. else if (details::numeric::nequal(details::numeric::fast_exp<T,14>::result(v),std::pow(v,T(14.0)))) return false;
  9157. else if (details::numeric::nequal(details::numeric::fast_exp<T,15>::result(v),std::pow(v,T(15.0)))) return false;
  9158. else if (details::numeric::nequal(details::numeric::fast_exp<T,16>::result(v),std::pow(v,T(16.0)))) return false;
  9159. else if (details::numeric::nequal(details::numeric::fast_exp<T,17>::result(v),std::pow(v,T(17.0)))) return false;
  9160. else if (details::numeric::nequal(details::numeric::fast_exp<T,18>::result(v),std::pow(v,T(18.0)))) return false;
  9161. else if (details::numeric::nequal(details::numeric::fast_exp<T,19>::result(v),std::pow(v,T(19.0)))) return false;
  9162. else if (details::numeric::nequal(details::numeric::fast_exp<T,20>::result(v),std::pow(v,T(20.0)))) return false;
  9163. else if (details::numeric::nequal(details::numeric::fast_exp<T,21>::result(v),std::pow(v,T(21.0)))) return false;
  9164. else if (details::numeric::nequal(details::numeric::fast_exp<T,22>::result(v),std::pow(v,T(22.0)))) return false;
  9165. else if (details::numeric::nequal(details::numeric::fast_exp<T,23>::result(v),std::pow(v,T(23.0)))) return false;
  9166. else if (details::numeric::nequal(details::numeric::fast_exp<T,24>::result(v),std::pow(v,T(24.0)))) return false;
  9167. else if (details::numeric::nequal(details::numeric::fast_exp<T,25>::result(v),std::pow(v,T(25.0)))) return false;
  9168. else if (details::numeric::nequal(details::numeric::fast_exp<T,26>::result(v),std::pow(v,T(26.0)))) return false;
  9169. else if (details::numeric::nequal(details::numeric::fast_exp<T,27>::result(v),std::pow(v,T(27.0)))) return false;
  9170. else if (details::numeric::nequal(details::numeric::fast_exp<T,28>::result(v),std::pow(v,T(28.0)))) return false;
  9171. else if (details::numeric::nequal(details::numeric::fast_exp<T,29>::result(v),std::pow(v,T(29.0)))) return false;
  9172. else if (details::numeric::nequal(details::numeric::fast_exp<T,30>::result(v),std::pow(v,T(30.0)))) return false;
  9173. else if (details::numeric::nequal(details::numeric::fast_exp<T,31>::result(v),std::pow(v,T(31.0)))) return false;
  9174. else if (details::numeric::nequal(details::numeric::fast_exp<T,32>::result(v),std::pow(v,T(32.0)))) return false;
  9175. else if (details::numeric::nequal(details::numeric::fast_exp<T,33>::result(v),std::pow(v,T(33.0)))) return false;
  9176. else if (details::numeric::nequal(details::numeric::fast_exp<T,34>::result(v),std::pow(v,T(34.0)))) return false;
  9177. else if (details::numeric::nequal(details::numeric::fast_exp<T,35>::result(v),std::pow(v,T(35.0)))) return false;
  9178. else if (details::numeric::nequal(details::numeric::fast_exp<T,36>::result(v),std::pow(v,T(36.0)))) return false;
  9179. else if (details::numeric::nequal(details::numeric::fast_exp<T,37>::result(v),std::pow(v,T(37.0)))) return false;
  9180. else if (details::numeric::nequal(details::numeric::fast_exp<T,38>::result(v),std::pow(v,T(38.0)))) return false;
  9181. else if (details::numeric::nequal(details::numeric::fast_exp<T,39>::result(v),std::pow(v,T(39.0)))) return false;
  9182. else if (details::numeric::nequal(details::numeric::fast_exp<T,40>::result(v),std::pow(v,T(40.0)))) return false;
  9183. else if (details::numeric::nequal(details::numeric::fast_exp<T,41>::result(v),std::pow(v,T(41.0)))) return false;
  9184. else if (details::numeric::nequal(details::numeric::fast_exp<T,42>::result(v),std::pow(v,T(42.0)))) return false;
  9185. else if (details::numeric::nequal(details::numeric::fast_exp<T,43>::result(v),std::pow(v,T(43.0)))) return false;
  9186. else if (details::numeric::nequal(details::numeric::fast_exp<T,44>::result(v),std::pow(v,T(44.0)))) return false;
  9187. else if (details::numeric::nequal(details::numeric::fast_exp<T,45>::result(v),std::pow(v,T(45.0)))) return false;
  9188. else if (details::numeric::nequal(details::numeric::fast_exp<T,46>::result(v),std::pow(v,T(46.0)))) return false;
  9189. else if (details::numeric::nequal(details::numeric::fast_exp<T,47>::result(v),std::pow(v,T(47.0)))) return false;
  9190. else if (details::numeric::nequal(details::numeric::fast_exp<T,48>::result(v),std::pow(v,T(48.0)))) return false;
  9191. else if (details::numeric::nequal(details::numeric::fast_exp<T,49>::result(v),std::pow(v,T(49.0)))) return false;
  9192. else if (details::numeric::nequal(details::numeric::fast_exp<T,50>::result(v),std::pow(v,T(50.0)))) return false;
  9193. else if (details::numeric::nequal(details::numeric::fast_exp<T,51>::result(v),std::pow(v,T(51.0)))) return false;
  9194. else if (details::numeric::nequal(details::numeric::fast_exp<T,52>::result(v),std::pow(v,T(52.0)))) return false;
  9195. else if (details::numeric::nequal(details::numeric::fast_exp<T,53>::result(v),std::pow(v,T(53.0)))) return false;
  9196. else if (details::numeric::nequal(details::numeric::fast_exp<T,54>::result(v),std::pow(v,T(54.0)))) return false;
  9197. else if (details::numeric::nequal(details::numeric::fast_exp<T,55>::result(v),std::pow(v,T(55.0)))) return false;
  9198. else if (details::numeric::nequal(details::numeric::fast_exp<T,56>::result(v),std::pow(v,T(56.0)))) return false;
  9199. else if (details::numeric::nequal(details::numeric::fast_exp<T,57>::result(v),std::pow(v,T(57.0)))) return false;
  9200. else if (details::numeric::nequal(details::numeric::fast_exp<T,58>::result(v),std::pow(v,T(58.0)))) return false;
  9201. else if (details::numeric::nequal(details::numeric::fast_exp<T,59>::result(v),std::pow(v,T(59.0)))) return false;
  9202. else if (details::numeric::nequal(details::numeric::fast_exp<T,60>::result(v),std::pow(v,T(60.0)))) return false;
  9203. else
  9204. return true;
  9205. }
  9206. }
  9207. return true;
  9208. }
  9209. }
  9210. #ifdef WIN32
  9211. # ifndef NOMINMAX
  9212. # define NOMINMAX
  9213. # endif
  9214. # ifndef WIN32_LEAN_AND_MEAN
  9215. # define WIN32_LEAN_AND_MEAN
  9216. # endif
  9217. # include <windows.h>
  9218. #else
  9219. # include <sys/time.h>
  9220. # include <sys/types.h>
  9221. #endif
  9222. namespace exprtk
  9223. {
  9224. class timer
  9225. {
  9226. public:
  9227. #ifdef WIN32
  9228. timer()
  9229. : in_use_(false)
  9230. {
  9231. QueryPerformanceFrequency(&clock_frequency_);
  9232. }
  9233. inline void start()
  9234. {
  9235. in_use_ = true;
  9236. QueryPerformanceCounter(&start_time_);
  9237. }
  9238. inline void stop()
  9239. {
  9240. QueryPerformanceCounter(&stop_time_);
  9241. in_use_ = false;
  9242. }
  9243. inline double time() const
  9244. {
  9245. return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
  9246. }
  9247. #else
  9248. timer()
  9249. : in_use_(false)
  9250. {
  9251. start_time_.tv_sec = 0;
  9252. start_time_.tv_usec = 0;
  9253. stop_time_.tv_sec = 0;
  9254. stop_time_.tv_usec = 0;
  9255. }
  9256. inline void start()
  9257. {
  9258. in_use_ = true;
  9259. gettimeofday(&start_time_,0);
  9260. }
  9261. inline void stop()
  9262. {
  9263. gettimeofday(&stop_time_, 0);
  9264. in_use_ = false;
  9265. }
  9266. inline unsigned long long int usec_time() const
  9267. {
  9268. if (!in_use_)
  9269. {
  9270. if (stop_time_.tv_sec >= start_time_.tv_sec)
  9271. {
  9272. return 1000000 * (stop_time_.tv_sec - start_time_.tv_sec ) +
  9273. (stop_time_.tv_usec - start_time_.tv_usec);
  9274. }
  9275. else
  9276. return std::numeric_limits<unsigned long long int>::max();
  9277. }
  9278. else
  9279. return std::numeric_limits<unsigned long long int>::max();
  9280. }
  9281. inline double time() const
  9282. {
  9283. return usec_time() * 0.000001;
  9284. }
  9285. #endif
  9286. inline bool in_use() const
  9287. {
  9288. return in_use_;
  9289. }
  9290. private:
  9291. bool in_use_;
  9292. #ifdef WIN32
  9293. LARGE_INTEGER start_time_;
  9294. LARGE_INTEGER stop_time_;
  9295. LARGE_INTEGER clock_frequency_;
  9296. #else
  9297. struct timeval start_time_;
  9298. struct timeval stop_time_;
  9299. #endif
  9300. };
  9301. void print_compiler_options()
  9302. {
  9303. #ifdef exprtk_enable_all_optimizations
  9304. printf("[+] exprtk_enable_all_optimizations\n");
  9305. #else
  9306. printf("[-] exprtk_enable_all_optimizations\n");
  9307. #endif
  9308. #ifdef exprtk_lean_and_mean
  9309. printf("[+] exprtk_lean_and_mean\n");
  9310. #else
  9311. printf("[-] exprtk_lean_and_mean\n");
  9312. #endif
  9313. #ifdef exprtk_lean_and_mean_numeric_only
  9314. printf("[+] exprtk_lean_and_mean_numeric_only\n");
  9315. #else
  9316. printf("[-] exprtk_lean_and_mean_numeric_only\n");
  9317. #endif
  9318. #ifdef exprtk_disable_string_capabilities
  9319. printf("[+] exprtk_disable_string_capabilities\n");
  9320. #else
  9321. printf("[-] exprtk_disable_string_capabilities\n");
  9322. #endif
  9323. #ifdef exprtk_disable_extended_operator_optimizations
  9324. printf("[+] exprtk_disable_extended_operator_optimizations\n");
  9325. #else
  9326. printf("[-] exprtk_disable_extended_operator_optimizations\n");
  9327. #endif
  9328. #ifdef exprtk_disable_extended_optimisations
  9329. printf("[+] exprtk_disable_extended_optimisations\n");
  9330. #else
  9331. printf("[-] exprtk_disable_extended_optimisations\n");
  9332. #endif
  9333. }
  9334. namespace information
  9335. {
  9336. static const char* library = "Mathematical Expression Toolkit";
  9337. static const char* version = "2.7182818284590452353602874713";
  9338. static const char* date = "20130126";
  9339. static inline std::string data()
  9340. {
  9341. static const std::string info_str = std::string(library) +
  9342. std::string(" v") + std::string(version) +
  9343. std::string(" (") + date + std::string(")");
  9344. return info_str;
  9345. }
  9346. } // namespace information
  9347. } // namespace exprtk
  9348. #endif