PageRenderTime 67ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 3ms

/exprtk.hpp

http://nanocalc.codeplex.com
C++ Header | 15710 lines | 13003 code | 2594 blank | 113 comment | 1608 complexity | 304dd65fa1664a3781c0e72ef5a01b4d MD5 | raw file
  1. /*
  2. ******************************************************************
  3. * C++ Mathematical Expression Toolkit Library *
  4. * *
  5. * Author: Arash Partow (1999-2015) *
  6. * URL: http://www.partow.net/programming/exprtk/index.html *
  7. * *
  8. * Copyright notice: *
  9. * Free use of the C++ Mathematical Expression Toolkit Library is *
  10. * permitted under the guidelines and in accordance with the most *
  11. * current version of the Common Public License. *
  12. * http://www.opensource.org/licenses/cpl1.0.php *
  13. * *
  14. * Example expressions: *
  15. * (00) (y + x / y) * (x - y / x) *
  16. * (01) (x^2 / sin(2 * pi / y)) - x / 2 *
  17. * (02) sqrt(1 - (x^2)) *
  18. * (03) 1 - sin(2 * x) + cos(pi / y) *
  19. * (04) a * exp(2 * t) + c *
  20. * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) *
  21. * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x *
  22. * (07) z := x + sin(2 * pi / y) *
  23. * (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) *
  24. * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1) *
  25. * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0) *
  26. * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
  27. * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
  28. * *
  29. ******************************************************************
  30. */
  31. #ifndef INCLUDE_EXPRTK_HPP
  32. #define INCLUDE_EXPRTK_HPP
  33. #include <algorithm>
  34. #include <cctype>
  35. #include <cmath>
  36. #include <complex>
  37. #include <cstdio>
  38. #include <cstdlib>
  39. #include <deque>
  40. #include <exception>
  41. #include <functional>
  42. #include <iterator>
  43. #include <limits>
  44. #include <list>
  45. #include <map>
  46. #include <set>
  47. #include <stack>
  48. #include <stdexcept>
  49. #include <string>
  50. #include <utility>
  51. #include <vector>
  52. namespace exprtk
  53. {
  54. #if exprtk_enable_debugging
  55. #define exprtk_debug(params) printf params
  56. #else
  57. #define exprtk_debug(params) (void)0
  58. #endif
  59. namespace details
  60. {
  61. inline bool is_whitespace(const char c)
  62. {
  63. return (' ' == c) || ('\n' == c) ||
  64. ('\r' == c) || ('\t' == c) ||
  65. ('\b' == c) || ('\v' == c) ||
  66. ('\f' == c) ;
  67. }
  68. inline bool is_operator_char(const char c)
  69. {
  70. return ('+' == c) || ('-' == c) ||
  71. ('*' == c) || ('/' == c) ||
  72. ('^' == c) || ('<' == c) ||
  73. ('>' == c) || ('=' == c) ||
  74. (',' == c) || ('!' == c) ||
  75. ('(' == c) || (')' == c) ||
  76. ('[' == c) || (']' == c) ||
  77. ('{' == c) || ('}' == c) ||
  78. ('%' == c) || (':' == c) ||
  79. ('?' == c) || ('&' == c) ||
  80. ('|' == c) || (';' == c) ;
  81. }
  82. inline bool is_letter(const char c)
  83. {
  84. return (('a' <= c) && (c <= 'z')) ||
  85. (('A' <= c) && (c <= 'Z')) ;
  86. }
  87. inline bool is_digit(const char c)
  88. {
  89. return ('0' <= c) && (c <= '9');
  90. }
  91. inline bool is_letter_or_digit(const char c)
  92. {
  93. return is_letter(c) || is_digit(c);
  94. }
  95. inline bool is_left_bracket(const char c)
  96. {
  97. return ('(' == c) || ('[' == c) || ('{' == c);
  98. }
  99. inline bool is_right_bracket(const char c)
  100. {
  101. return (')' == c) || (']' == c) || ('}' == c);
  102. }
  103. inline bool is_bracket(const char c)
  104. {
  105. return is_left_bracket(c) || is_right_bracket(c);
  106. }
  107. inline bool is_sign(const char c)
  108. {
  109. return ('+' == c) || ('-' == c);
  110. }
  111. inline bool is_invalid(const char c)
  112. {
  113. return !is_whitespace (c) &&
  114. !is_operator_char(c) &&
  115. !is_letter (c) &&
  116. !is_digit (c) &&
  117. ('.' != c) &&
  118. ('_' != c) &&
  119. ('$' != c) &&
  120. ('~' != c) &&
  121. ('\'' != c);
  122. }
  123. inline bool imatch(const char c1, const char c2)
  124. {
  125. return std::tolower(c1) == std::tolower(c2);
  126. }
  127. inline bool imatch(const std::string& s1, const std::string& s2)
  128. {
  129. if (s1.size() == s2.size())
  130. {
  131. for (std::size_t i = 0; i < s1.size(); ++i)
  132. {
  133. if (std::tolower(s1[i]) != std::tolower(s2[i]))
  134. {
  135. return false;
  136. }
  137. }
  138. return true;
  139. }
  140. return false;
  141. }
  142. inline bool is_valid_sf_symbol(const std::string& symbol)
  143. {
  144. // Special function: $f12 or $F34
  145. return (4 == symbol.size()) &&
  146. ('$' == symbol[0]) &&
  147. imatch('f',symbol[1]) &&
  148. is_digit(symbol[2]) &&
  149. is_digit(symbol[3]);
  150. }
  151. inline const char& front(const std::string& s)
  152. {
  153. return s[0];
  154. }
  155. inline const char& back(const std::string& s)
  156. {
  157. return s[s.size() - 1];
  158. }
  159. inline std::string to_str(int i)
  160. {
  161. if (0 == i)
  162. return std::string("0");
  163. std::string result;
  164. if (i < 0)
  165. {
  166. for ( ; i; i /= 10)
  167. {
  168. result += '0' + char(-(i % 10));
  169. }
  170. result += '-';
  171. }
  172. else
  173. {
  174. for ( ; i; i /= 10)
  175. {
  176. result += '0' + char(i % 10);
  177. }
  178. }
  179. std::reverse(result.begin(), result.end());
  180. return result;
  181. }
  182. inline bool is_hex_digit(const std::string::value_type digit)
  183. {
  184. return (('0' <= digit) && (digit <= '9')) ||
  185. (('A' <= digit) && (digit <= 'F')) ||
  186. (('a' <= digit) && (digit <= 'f')) ;
  187. }
  188. inline unsigned char hex_to_bin(unsigned char h)
  189. {
  190. if (('0' <= h) && (h <= '9'))
  191. return (h - '0');
  192. else
  193. return (std::toupper(h) - 'A');
  194. }
  195. template <typename Iterator>
  196. inline void parse_hex(Iterator& itr, Iterator end, std::string::value_type& result)
  197. {
  198. if (
  199. (end != (itr )) &&
  200. (end != (itr + 1)) &&
  201. (end != (itr + 2)) &&
  202. (end != (itr + 3)) &&
  203. ('0' == *(itr )) &&
  204. (
  205. ('x' == *(itr + 1)) ||
  206. ('X' == *(itr + 1))
  207. ) &&
  208. (is_hex_digit(*(itr + 2))) &&
  209. (is_hex_digit(*(itr + 3)))
  210. )
  211. {
  212. result = hex_to_bin(*(itr + 2)) << 4 | hex_to_bin(*(itr + 3));
  213. itr += 3;
  214. }
  215. else
  216. result = '\0';
  217. }
  218. inline void cleanup_escapes(std::string& s)
  219. {
  220. typedef std::string::iterator str_itr_t;
  221. str_itr_t itr1 = s.begin();
  222. str_itr_t itr2 = s.begin();
  223. str_itr_t end = s.end ();
  224. std::size_t removal_count = 0;
  225. while (end != itr1)
  226. {
  227. if ('\\' == (*itr1))
  228. {
  229. ++removal_count;
  230. if (end == ++itr1)
  231. break;
  232. else if ('\\' != (*itr1))
  233. {
  234. switch (*itr1)
  235. {
  236. case 'n' : (*itr1) = '\n'; break;
  237. case 'r' : (*itr1) = '\r'; break;
  238. case 't' : (*itr1) = '\t'; break;
  239. case '0' : parse_hex(itr1, end, (*itr1));
  240. removal_count += 3;
  241. break;
  242. }
  243. continue;
  244. }
  245. }
  246. if (itr1 != itr2)
  247. {
  248. (*itr2) = (*itr1);
  249. }
  250. ++itr1;
  251. ++itr2;
  252. }
  253. s.resize(s.size() - removal_count);
  254. }
  255. class build_string
  256. {
  257. public:
  258. build_string(const std::size_t& initial_size = 64)
  259. {
  260. data_.reserve(initial_size);
  261. }
  262. inline build_string& operator << (const std::string& s)
  263. {
  264. data_ += s;
  265. return (*this);
  266. }
  267. inline build_string& operator << (const char* s)
  268. {
  269. data_ += std::string(s);
  270. return (*this);
  271. }
  272. inline operator std::string () const
  273. {
  274. return data_;
  275. }
  276. inline std::string as_string() const
  277. {
  278. return data_;
  279. }
  280. private:
  281. std::string data_;
  282. };
  283. struct ilesscompare
  284. {
  285. inline bool operator()(const std::string& s1, const std::string& s2) const
  286. {
  287. const std::size_t length = std::min(s1.size(),s2.size());
  288. for (std::size_t i = 0; i < length; ++i)
  289. {
  290. const char c1 = static_cast<char>(std::tolower(s1[i]));
  291. const char c2 = static_cast<char>(std::tolower(s2[i]));
  292. if (c1 > c2)
  293. return false;
  294. else if (c1 < c2)
  295. return true;
  296. }
  297. return s1.size() < s2.size();
  298. }
  299. };
  300. static const std::string reserved_words[] =
  301. {
  302. "break", "case", "continue", "default", "false", "for",
  303. "if", "else", "ilike", "in", "like", "and", "nand", "nor",
  304. "not", "null", "or", "repeat", "return", "shl", "shr",
  305. "swap", "switch", "true", "until", "var", "while", "xnor",
  306. "xor", "&", "|"
  307. };
  308. static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
  309. static const std::string reserved_symbols[] =
  310. {
  311. "abs", "acos", "acosh", "and", "asin", "asinh", "atan",
  312. "atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
  313. "continue", "cos", "cosh", "cot", "csc", "default",
  314. "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp",
  315. "expm1", "false", "floor", "for", "frac", "grad2deg",
  316. "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
  317. "like", "log", "log10", "log2", "logn", "log1p", "mand",
  318. "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
  319. "not", "not_equal", "null", "or", "pow", "rad2deg",
  320. "repeat", "return", "root", "round", "roundn", "sec", "sgn",
  321. "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
  322. "switch", "tan", "tanh", "true", "trunc", "until", "var",
  323. "while", "xnor", "xor", "&", "|"
  324. };
  325. static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
  326. static const std::string base_function_list[] =
  327. {
  328. "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
  329. "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
  330. "csc", "equal", "erf", "erfc", "exp", "expm1", "floor",
  331. "frac", "hypot", "iclamp", "like", "log", "log10", "log2",
  332. "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul",
  333. "ncdf", "pow", "root", "round", "roundn", "sec", "sgn",
  334. "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
  335. "trunc", "not_equal", "inrange", "deg2grad", "deg2rad",
  336. "rad2deg", "grad2deg"
  337. };
  338. static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
  339. static const std::string logic_ops_list[] =
  340. {
  341. "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
  342. };
  343. static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
  344. static const std::string cntrl_struct_list[] =
  345. {
  346. "for", "if", "repeat", "switch", "while"
  347. };
  348. static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
  349. inline bool is_reserved_word(const std::string& symbol)
  350. {
  351. for (std::size_t i = 0; i < reserved_words_size; ++i)
  352. {
  353. if (imatch(symbol,reserved_words[i]))
  354. {
  355. return true;
  356. }
  357. }
  358. return false;
  359. }
  360. inline bool is_reserved_symbol(const std::string& symbol)
  361. {
  362. for (std::size_t i = 0; i < reserved_symbols_size; ++i)
  363. {
  364. if (imatch(symbol,reserved_symbols[i]))
  365. {
  366. return true;
  367. }
  368. }
  369. return false;
  370. }
  371. inline bool is_base_function(const std::string& function_name)
  372. {
  373. for (std::size_t i = 0; i < base_function_list_size; ++i)
  374. {
  375. if (imatch(function_name,base_function_list[i]))
  376. {
  377. return true;
  378. }
  379. }
  380. return false;
  381. }
  382. inline bool is_control_struct(const std::string& cntrl_strct)
  383. {
  384. for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
  385. {
  386. if (imatch(cntrl_strct,cntrl_struct_list[i]))
  387. {
  388. return true;
  389. }
  390. }
  391. return false;
  392. }
  393. inline bool is_logic_opr(const std::string& lgc_opr)
  394. {
  395. for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
  396. {
  397. if (imatch(lgc_opr,logic_ops_list[i]))
  398. {
  399. return true;
  400. }
  401. }
  402. return false;
  403. }
  404. struct cs_match
  405. {
  406. static inline bool cmp(const char c0, const char c1)
  407. {
  408. return (c0 == c1);
  409. }
  410. };
  411. struct cis_match
  412. {
  413. static inline bool cmp(const char c0, const char c1)
  414. {
  415. return (std::tolower(c0) == std::tolower(c1));
  416. }
  417. };
  418. template <typename Iterator, typename Compare>
  419. inline bool match_impl(const Iterator pattern_begin,
  420. const Iterator pattern_end,
  421. const Iterator data_begin,
  422. const Iterator data_end,
  423. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  424. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  425. {
  426. if (0 == std::distance(data_begin,data_end))
  427. {
  428. return false;
  429. }
  430. Iterator d_itr = data_begin;
  431. Iterator p_itr = pattern_begin;
  432. Iterator c_itr = data_begin;
  433. Iterator m_itr = data_begin;
  434. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  435. {
  436. if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr)))
  437. {
  438. return false;
  439. }
  440. ++p_itr;
  441. ++d_itr;
  442. }
  443. while (data_end != d_itr)
  444. {
  445. if (zero_or_more == (*p_itr))
  446. {
  447. if (pattern_end == (++p_itr))
  448. {
  449. return true;
  450. }
  451. m_itr = p_itr;
  452. c_itr = d_itr;
  453. ++c_itr;
  454. }
  455. else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr)))
  456. {
  457. ++p_itr;
  458. ++d_itr;
  459. }
  460. else
  461. {
  462. p_itr = m_itr;
  463. d_itr = c_itr++;
  464. }
  465. }
  466. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) { ++p_itr; }
  467. return (p_itr == pattern_end);
  468. }
  469. inline bool wc_match(const std::string& wild_card,
  470. const std::string& str)
  471. {
  472. return match_impl<const char*,cs_match>(wild_card.data(),
  473. wild_card.data() + wild_card.size(),
  474. str.data(),
  475. str.data() + str.size(),
  476. '*',
  477. '?');
  478. }
  479. inline bool wc_imatch(const std::string& wild_card,
  480. const std::string& str)
  481. {
  482. return match_impl<const char*,cis_match>(wild_card.data(),
  483. wild_card.data() + wild_card.size(),
  484. str.data(),
  485. str.data() + str.size(),
  486. '*',
  487. '?');
  488. }
  489. inline bool sequence_match(const std::string& pattern,
  490. const std::string& str,
  491. std::size_t& diff_index,
  492. char& diff_value)
  493. {
  494. if (str.empty() || pattern.empty())
  495. return false;
  496. else if ('*' == pattern[0])
  497. return false;
  498. typedef std::string::const_iterator itr_t;
  499. itr_t p_itr = pattern.begin();
  500. itr_t s_itr = str .begin();
  501. itr_t p_end = pattern.end();
  502. itr_t s_end = str .end();
  503. while ((s_end != s_itr) && (p_end != p_itr))
  504. {
  505. if ('*' == (*p_itr))
  506. {
  507. const char target = std::toupper(*(p_itr - 1));
  508. if ('*' == target)
  509. {
  510. diff_index = std::distance(str.begin(),s_itr);
  511. diff_value = std::toupper(*p_itr);
  512. return false;
  513. }
  514. else
  515. ++p_itr;
  516. while (s_itr != s_end)
  517. {
  518. if (target != std::toupper(*s_itr))
  519. break;
  520. else
  521. ++s_itr;
  522. }
  523. continue;
  524. }
  525. else if (
  526. ('?' != *p_itr) &&
  527. std::toupper(*p_itr) != std::toupper(*s_itr)
  528. )
  529. {
  530. diff_index = std::distance(str.begin(),s_itr);
  531. diff_value = std::toupper(*p_itr);
  532. return false;
  533. }
  534. ++p_itr;
  535. ++s_itr;
  536. }
  537. return (
  538. (s_end == s_itr) &&
  539. (
  540. (p_end == p_itr) ||
  541. ('*' == *p_itr)
  542. )
  543. );
  544. }
  545. static const double pow10[] = {
  546. 1.0,
  547. 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
  548. 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
  549. 1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
  550. 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
  551. };
  552. static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
  553. namespace numeric
  554. {
  555. namespace constant
  556. {
  557. static const double e = 2.718281828459045235360;
  558. static const double pi = 3.141592653589793238462;
  559. static const double pi_2 = 1.570796326794896619231;
  560. static const double pi_4 = 0.785398163397448309616;
  561. static const double pi_180 = 0.017453292519943295769;
  562. static const double _1_pi = 0.318309886183790671538;
  563. static const double _2_pi = 0.636619772367581343076;
  564. static const double _180_pi = 57.295779513082320876798;
  565. static const double log2 = 0.693147180559945309417;
  566. static const double sqrt2 = 1.414213562373095048801;
  567. }
  568. namespace details
  569. {
  570. struct unknown_type_tag {};
  571. struct real_type_tag {};
  572. struct complex_type_tag {};
  573. struct int_type_tag {};
  574. template <typename T>
  575. struct number_type { typedef unknown_type_tag type; };
  576. #define exprtk_register_real_type_tag(T) \
  577. template<> struct number_type<T> { typedef real_type_tag type; }; \
  578. #define exprtk_register_complex_type_tag(T) \
  579. template<> struct number_type<std::complex<T> > \
  580. { typedef complex_type_tag type; }; \
  581. #define exprtk_register_int_type_tag(T) \
  582. template<> struct number_type<T> { typedef int_type_tag type; }; \
  583. exprtk_register_real_type_tag(double )
  584. exprtk_register_real_type_tag(long double)
  585. exprtk_register_real_type_tag(float )
  586. exprtk_register_complex_type_tag(double )
  587. exprtk_register_complex_type_tag(long double)
  588. exprtk_register_complex_type_tag(float )
  589. exprtk_register_int_type_tag(short )
  590. exprtk_register_int_type_tag(int )
  591. exprtk_register_int_type_tag(long long int )
  592. exprtk_register_int_type_tag(unsigned short )
  593. exprtk_register_int_type_tag(unsigned int )
  594. exprtk_register_int_type_tag(unsigned long long int)
  595. #undef exprtk_register_real_type_tag
  596. #undef exprtk_register_int_type_tag
  597. template <typename T>
  598. struct epsilon_type
  599. {
  600. static inline T value()
  601. {
  602. const T epsilon = T(0.0000000001);
  603. return epsilon;
  604. }
  605. };
  606. template <>
  607. struct epsilon_type <float>
  608. {
  609. static inline float value()
  610. {
  611. const float epsilon = float(0.000001f);
  612. return epsilon;
  613. }
  614. };
  615. template <>
  616. struct epsilon_type <long double>
  617. {
  618. static inline long double value()
  619. {
  620. const long double epsilon = (long double)(0.000000000001);
  621. return epsilon;
  622. }
  623. };
  624. template <typename T>
  625. inline bool is_nan_impl(const T v, real_type_tag)
  626. {
  627. return std::not_equal_to<T>()(v,v);
  628. }
  629. template <typename T>
  630. inline int to_int32_impl(const T v, real_type_tag)
  631. {
  632. return static_cast<int>(v);
  633. }
  634. template <typename T>
  635. inline long long int to_int64_impl(const T v, real_type_tag)
  636. {
  637. return static_cast<long long int>(v);
  638. }
  639. template <typename T>
  640. inline bool is_true_impl(const T v)
  641. {
  642. return std::not_equal_to<T>()(T(0),v);
  643. }
  644. template <typename T>
  645. inline bool is_false_impl(const T v)
  646. {
  647. return std::equal_to<T>()(T(0),v);
  648. }
  649. template <typename T>
  650. inline T abs_impl(const T v, real_type_tag)
  651. {
  652. return ((v >= T(0)) ? v : -v);
  653. }
  654. template <typename T>
  655. inline T min_impl(const T v0, const T v1, real_type_tag)
  656. {
  657. return std::min<T>(v0,v1);
  658. }
  659. template <typename T>
  660. inline T max_impl(const T v0, const T v1, real_type_tag)
  661. {
  662. return std::max<T>(v0,v1);
  663. }
  664. template <typename T>
  665. inline T equal_impl(const T v0, const T v1, real_type_tag)
  666. {
  667. const T epsilon = epsilon_type<T>::value();
  668. return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
  669. }
  670. inline float equal_impl(const float v0, const float v1, real_type_tag)
  671. {
  672. const float epsilon = epsilon_type<float>::value();
  673. return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
  674. }
  675. template <typename T>
  676. inline T equal_impl(const T v0, const T v1, int_type_tag)
  677. {
  678. return (v0 == v1) ? 1 : 0;
  679. }
  680. template <typename T>
  681. inline T expm1_impl(const T v, real_type_tag)
  682. {
  683. // return std::expm1<T>(v);
  684. if (abs_impl(v,real_type_tag()) < T(0.00001))
  685. return v + (T(0.5) * v * v);
  686. else
  687. return std::exp(v) - T(1);
  688. }
  689. template <typename T>
  690. inline T expm1_impl(const T v, int_type_tag)
  691. {
  692. return T(std::exp<double>(v)) - T(1);
  693. }
  694. template <typename T>
  695. inline T nequal_impl(const T v0, const T v1, real_type_tag)
  696. {
  697. typedef real_type_tag rtg;
  698. const T epsilon = epsilon_type<T>::value();
  699. return (abs_impl(v0 - v1,rtg()) > (std::max(T(1),std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? T(1) : T(0);
  700. }
  701. inline float nequal_impl(const float v0, const float v1, real_type_tag)
  702. {
  703. typedef real_type_tag rtg;
  704. const float epsilon = epsilon_type<float>::value();
  705. return (abs_impl(v0 - v1,rtg()) > (std::max(1.0f,std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? 1.0f : 0.0f;
  706. }
  707. template <typename T>
  708. inline T nequal_impl(const T v0, const T v1, int_type_tag)
  709. {
  710. return (v0 != v1) ? 1 : 0;
  711. }
  712. template <typename T>
  713. inline T modulus_impl(const T v0, const T v1, real_type_tag)
  714. {
  715. return std::fmod(v0,v1);
  716. }
  717. template <typename T>
  718. inline T modulus_impl(const T v0, const T v1, int_type_tag)
  719. {
  720. return v0 % v1;
  721. }
  722. template <typename T>
  723. inline T pow_impl(const T v0, const T v1, real_type_tag)
  724. {
  725. return std::pow(v0,v1);
  726. }
  727. template <typename T>
  728. inline T pow_impl(const T v0, const T v1, int_type_tag)
  729. {
  730. return std::pow(static_cast<double>(v0),static_cast<double>(v1));
  731. }
  732. template <typename T>
  733. inline T logn_impl(const T v0, const T v1, real_type_tag)
  734. {
  735. return std::log(v0) / std::log(v1);
  736. }
  737. template <typename T>
  738. inline T logn_impl(const T v0, const T v1, int_type_tag)
  739. {
  740. return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
  741. }
  742. template <typename T>
  743. inline T log1p_impl(const T v, real_type_tag)
  744. {
  745. if (v > T(-1))
  746. {
  747. if (abs_impl(v,real_type_tag()) > T(0.0001))
  748. {
  749. return std::log(T(1) + v);
  750. }
  751. else
  752. return (T(-0.5) * v + T(1)) * v;
  753. }
  754. else
  755. return std::numeric_limits<T>::quiet_NaN();
  756. }
  757. template <typename T>
  758. inline T log1p_impl(const T v, int_type_tag)
  759. {
  760. if (v > T(-1))
  761. {
  762. return std::log(T(1) + v);
  763. }
  764. else
  765. return std::numeric_limits<T>::quiet_NaN();
  766. }
  767. template <typename T>
  768. inline T root_impl(const T v0, const T v1, real_type_tag)
  769. {
  770. return std::pow(v0,T(1) / v1);
  771. }
  772. template <typename T>
  773. inline T root_impl(const T v0, const T v1, int_type_tag)
  774. {
  775. return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
  776. }
  777. template <typename T>
  778. inline T round_impl(const T v, real_type_tag)
  779. {
  780. return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
  781. }
  782. template <typename T>
  783. inline T roundn_impl(const T v0, const T v1, real_type_tag)
  784. {
  785. const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1)));
  786. const T p10 = T(pow10[index]);
  787. if (v0 < T(0))
  788. return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
  789. else
  790. return T(std::floor((v0 * p10) + T(0.5)) / p10);
  791. }
  792. template <typename T>
  793. inline T roundn_impl(const T v0, const T, int_type_tag)
  794. {
  795. return v0;
  796. }
  797. template <typename T>
  798. inline T hypot_impl(const T v0, const T v1, real_type_tag)
  799. {
  800. return std::sqrt((v0 * v0) + (v1 * v1));
  801. }
  802. template <typename T>
  803. inline T hypot_impl(const T v0, const T v1, int_type_tag)
  804. {
  805. return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
  806. }
  807. template <typename T>
  808. inline T atan2_impl(const T v0, const T v1, real_type_tag)
  809. {
  810. return std::atan2(v0,v1);
  811. }
  812. template <typename T>
  813. inline T atan2_impl(const T, const T, int_type_tag)
  814. {
  815. return 0;
  816. }
  817. template <typename T>
  818. inline T shr_impl(const T v0, const T v1, real_type_tag)
  819. {
  820. return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
  821. }
  822. template <typename T>
  823. inline T shr_impl(const T v0, const T v1, int_type_tag)
  824. {
  825. return v0 >> v1;
  826. }
  827. template <typename T>
  828. inline T shl_impl(const T v0, const T v1, real_type_tag)
  829. {
  830. return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
  831. }
  832. template <typename T>
  833. inline T shl_impl(const T v0, const T v1, int_type_tag)
  834. {
  835. return v0 << v1;
  836. }
  837. template <typename T>
  838. inline T sgn_impl(const T v, real_type_tag)
  839. {
  840. if (v > T(0)) return T(+1);
  841. else if (v < T(0)) return T(-1);
  842. else return T( 0);
  843. }
  844. template <typename T>
  845. inline T sgn_impl(const T v, int_type_tag)
  846. {
  847. if (v > T(0)) return T(+1);
  848. else if (v < T(0)) return T(-1);
  849. else return T( 0);
  850. }
  851. template <typename T>
  852. inline T and_impl(const T v0, const T v1, real_type_tag)
  853. {
  854. return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
  855. }
  856. template <typename T>
  857. inline T and_impl(const T v0, const T v1, int_type_tag)
  858. {
  859. return v0 && v1;
  860. }
  861. template <typename T>
  862. inline T nand_impl(const T v0, const T v1, real_type_tag)
  863. {
  864. return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
  865. }
  866. template <typename T>
  867. inline T nand_impl(const T v0, const T v1, int_type_tag)
  868. {
  869. return !(v0 && v1);
  870. }
  871. template <typename T>
  872. inline T or_impl(const T v0, const T v1, real_type_tag)
  873. {
  874. return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
  875. }
  876. template <typename T>
  877. inline T or_impl(const T v0, const T v1, int_type_tag)
  878. {
  879. return (v0 || v1);
  880. }
  881. template <typename T>
  882. inline T nor_impl(const T v0, const T v1, real_type_tag)
  883. {
  884. return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
  885. }
  886. template <typename T>
  887. inline T nor_impl(const T v0, const T v1, int_type_tag)
  888. {
  889. return !(v0 || v1);
  890. }
  891. template <typename T>
  892. inline T xor_impl(const T v0, const T v1, real_type_tag)
  893. {
  894. return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
  895. }
  896. template <typename T>
  897. inline T xor_impl(const T v0, const T v1, int_type_tag)
  898. {
  899. return v0 ^ v1;
  900. }
  901. template <typename T>
  902. inline T xnor_impl(const T v0, const T v1, real_type_tag)
  903. {
  904. const bool v0_true = is_true_impl(v0);
  905. const bool v1_true = is_true_impl(v1);
  906. if ((v0_true && v1_true) || (!v0_true && !v1_true))
  907. return T(1);
  908. else
  909. return T(0);
  910. }
  911. template <typename T>
  912. inline T xnor_impl(const T v0, const T v1, int_type_tag)
  913. {
  914. const bool v0_true = is_true_impl(v0);
  915. const bool v1_true = is_true_impl(v1);
  916. if ((v0_true && v1_true) || (!v0_true && !v1_true))
  917. return T(1);
  918. else
  919. return T(0);
  920. }
  921. template <typename T>
  922. inline T erf_impl(T v, real_type_tag)
  923. {
  924. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  925. // Credits: Abramowitz & Stegun Equations 7.1.25-28
  926. const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
  927. static const T c[] = {
  928. T( 1.26551223), T(1.00002368),
  929. T( 0.37409196), T(0.09678418),
  930. T(-0.18628806), T(0.27886807),
  931. T(-1.13520398), T(1.48851587),
  932. T(-0.82215223), T(0.17087277)
  933. };
  934. T result = T(1) - t * std::exp((-v * v) -
  935. c[0] + t * (c[1] + t *
  936. (c[2] + t * (c[3] + t *
  937. (c[4] + t * (c[5] + t *
  938. (c[6] + t * (c[7] + t *
  939. (c[8] + t * (c[9]))))))))));
  940. return (v >= T(0)) ? result : -result;
  941. #else
  942. return ::erf(v);
  943. #endif
  944. }
  945. template <typename T>
  946. inline T erf_impl(T v, int_type_tag)
  947. {
  948. return erf_impl(static_cast<double>(v),real_type_tag());
  949. }
  950. template <typename T>
  951. inline T erfc_impl(T v, real_type_tag)
  952. {
  953. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  954. return T(1) - erf_impl(v,real_type_tag());
  955. #else
  956. return ::erfc(v);
  957. #endif
  958. }
  959. template <typename T>
  960. inline T erfc_impl(T v, int_type_tag)
  961. {
  962. return erfc_impl(static_cast<double>(v),real_type_tag());
  963. }
  964. template <typename T>
  965. inline T ncdf_impl(T v, real_type_tag)
  966. {
  967. T cnd = T(0.5) * (T(1) + erf_impl(
  968. abs_impl(v,real_type_tag()) /
  969. T(numeric::constant::sqrt2),real_type_tag()));
  970. return (v < T(0)) ? (T(1) - cnd) : cnd;
  971. }
  972. template <typename T>
  973. inline T ncdf_impl(T v, int_type_tag)
  974. {
  975. return ncdf_impl(static_cast<double>(v),real_type_tag());
  976. }
  977. template <typename T>
  978. inline T sinc_impl(T v, real_type_tag)
  979. {
  980. if (std::abs(v) >= std::numeric_limits<T>::epsilon())
  981. return(std::sin(v) / v);
  982. else
  983. return T(1);
  984. }
  985. template <typename T>
  986. inline T sinc_impl(T v, int_type_tag)
  987. {
  988. return sinc_impl(static_cast<double>(v),real_type_tag());
  989. }
  990. template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
  991. template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
  992. template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
  993. template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
  994. template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
  995. template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - log(T(1) - v)) / T(2); }
  996. template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
  997. template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
  998. template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
  999. template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
  1000. template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
  1001. template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
  1002. template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
  1003. template <typename T> inline T log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
  1004. template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
  1005. template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
  1006. template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
  1007. template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
  1008. template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
  1009. template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
  1010. template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
  1011. template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
  1012. template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
  1013. template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
  1014. template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
  1015. template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
  1016. template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); }
  1017. template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); }
  1018. template <typename T> inline T notl_impl(const T v, real_type_tag) { return (std::not_equal_to<T>()(T(0),v) ? T(0) : T(1)); }
  1019. template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
  1020. template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
  1021. template <typename T> inline T abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
  1022. template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
  1023. template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
  1024. template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
  1025. template <typename T> inline T log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
  1026. template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
  1027. template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
  1028. template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
  1029. template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
  1030. template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
  1031. template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
  1032. template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
  1033. template <typename T> inline T frac_impl(const T , int_type_tag) { return T(0); }
  1034. template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
  1035. template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1036. template <typename T> inline T acosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1037. template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1038. template <typename T> inline T asinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1039. template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1040. template <typename T> inline T atanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1041. template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1042. template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1043. template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1044. template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1045. template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1046. template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1047. template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1048. template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1049. template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  1050. template <typename T>
  1051. inline bool is_integer_impl(const T& v, real_type_tag)
  1052. {
  1053. return std::equal_to<T>()(T(0),std::fmod(v,T(1)));
  1054. }
  1055. template <typename T>
  1056. inline bool is_integer_impl(const T&, int_type_tag)
  1057. {
  1058. return true;
  1059. }
  1060. }
  1061. template <typename Type>
  1062. struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
  1063. template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
  1064. template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
  1065. template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
  1066. template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
  1067. template <typename T>
  1068. inline int to_int32(const T v)
  1069. {
  1070. typename details::number_type<T>::type num_type;
  1071. return to_int32_impl(v,num_type);
  1072. }
  1073. template <typename T>
  1074. inline long long int to_int64(const T v)
  1075. {
  1076. typename details::number_type<T>::type num_type;
  1077. return to_int64_impl(v,num_type);
  1078. }
  1079. template <typename T>
  1080. inline bool is_nan(const T v)
  1081. {
  1082. typename details::number_type<T>::type num_type;
  1083. return is_nan_impl(v,num_type);
  1084. }
  1085. template <typename T>
  1086. inline T min(const T v0, const T v1)
  1087. {
  1088. typename details::number_type<T>::type num_type;
  1089. return min_impl(v0,v1,num_type);
  1090. }
  1091. template <typename T>
  1092. inline T max(const T v0, const T v1)
  1093. {
  1094. typename details::number_type<T>::type num_type;
  1095. return max_impl(v0,v1,num_type);
  1096. }
  1097. template <typename T>
  1098. inline T equal(const T v0, const T v1)
  1099. {
  1100. typename details::number_type<T>::type num_type;
  1101. return equal_impl(v0,v1,num_type);
  1102. }
  1103. template <typename T>
  1104. inline T nequal(const T v0, const T v1)
  1105. {
  1106. typename details::number_type<T>::type num_type;
  1107. return nequal_impl(v0,v1,num_type);
  1108. }
  1109. template <typename T>
  1110. inline T modulus(const T v0, const T v1)
  1111. {
  1112. typename details::number_type<T>::type num_type;
  1113. return modulus_impl(v0,v1,num_type);
  1114. }
  1115. template <typename T>
  1116. inline T pow(const T v0, const T v1)
  1117. {
  1118. typename details::number_type<T>::type num_type;
  1119. return pow_impl(v0,v1,num_type);
  1120. }
  1121. template <typename T>
  1122. inline T logn(const T v0, const T v1)
  1123. {
  1124. typename details::number_type<T>::type num_type;
  1125. return logn_impl(v0,v1,num_type);
  1126. }
  1127. template <typename T>
  1128. inline T root(const T v0, const T v1)
  1129. {
  1130. typename details::number_type<T>::type num_type;
  1131. return root_impl(v0,v1,num_type);
  1132. }
  1133. template <typename T>
  1134. inline T roundn(const T v0, const T v1)
  1135. {
  1136. typename details::number_type<T>::type num_type;
  1137. return roundn_impl(v0,v1,num_type);
  1138. }
  1139. template <typename T>
  1140. inline T hypot(const T v0, const T v1)
  1141. {
  1142. typename details::number_type<T>::type num_type;
  1143. return hypot_impl(v0,v1,num_type);
  1144. }
  1145. template <typename T>
  1146. inline T atan2(const T v0, const T v1)
  1147. {
  1148. typename details::number_type<T>::type num_type;
  1149. return atan2_impl(v0,v1,num_type);
  1150. }
  1151. template <typename T>
  1152. inline T shr(const T v0, const T v1)
  1153. {
  1154. typename details::number_type<T>::type num_type;
  1155. return shr_impl(v0,v1,num_type);
  1156. }
  1157. template <typename T>
  1158. inline T shl(const T v0, const T v1)
  1159. {
  1160. typename details::number_type<T>::type num_type;
  1161. return shl_impl(v0,v1,num_type);
  1162. }
  1163. template <typename T>
  1164. inline T and_opr(const T v0, const T v1)
  1165. {
  1166. typename details::number_type<T>::type num_type;
  1167. return and_impl(v0,v1,num_type);
  1168. }
  1169. template <typename T>
  1170. inline T nand_opr(const T v0, const T v1)
  1171. {
  1172. typename details::number_type<T>::type num_type;
  1173. return nand_impl(v0,v1,num_type);
  1174. }
  1175. template <typename T>
  1176. inline T or_opr(const T v0, const T v1)
  1177. {
  1178. typename details::number_type<T>::type num_type;
  1179. return or_impl(v0,v1,num_type);
  1180. }
  1181. template <typename T>
  1182. inline T nor_opr(const T v0, const T v1)
  1183. {
  1184. typename details::number_type<T>::type num_type;
  1185. return nor_impl(v0,v1,num_type);
  1186. }
  1187. template <typename T>
  1188. inline T xor_opr(const T v0, const T v1)
  1189. {
  1190. typename details::number_type<T>::type num_type;
  1191. return xor_impl(v0,v1,num_type);
  1192. }
  1193. template <typename T>
  1194. inline T xnor_opr(const T v0, const T v1)
  1195. {
  1196. typename details::number_type<T>::type num_type;
  1197. return xnor_impl(v0,v1,num_type);
  1198. }
  1199. template <typename T>
  1200. inline bool is_integer(const T v)
  1201. {
  1202. typename details::number_type<T>::type num_type;
  1203. return is_integer_impl(v,num_type);
  1204. }
  1205. template <typename T, unsigned int N>
  1206. struct fast_exp
  1207. {
  1208. static inline T result(T v)
  1209. {
  1210. unsigned int k = N;
  1211. T l = T(1);
  1212. while (k)
  1213. {
  1214. if (k & 1)
  1215. {
  1216. l *= v;
  1217. --k;
  1218. }
  1219. v *= v;
  1220. k >>= 1;
  1221. }
  1222. return l;
  1223. }
  1224. };
  1225. 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; } };
  1226. template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
  1227. 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; } };
  1228. template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
  1229. 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; } };
  1230. template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
  1231. template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
  1232. template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
  1233. template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v; } };
  1234. template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } };
  1235. template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } };
  1236. #define exprtk_define_unary_function(FunctionName) \
  1237. template <typename T> \
  1238. inline T FunctionName (const T v) \
  1239. { \
  1240. typename details::number_type<T>::type num_type; \
  1241. return FunctionName##_impl(v,num_type); \
  1242. } \
  1243. exprtk_define_unary_function(abs )
  1244. exprtk_define_unary_function(acos )
  1245. exprtk_define_unary_function(acosh)
  1246. exprtk_define_unary_function(asin )
  1247. exprtk_define_unary_function(asinh)
  1248. exprtk_define_unary_function(atan )
  1249. exprtk_define_unary_function(atanh)
  1250. exprtk_define_unary_function(ceil )
  1251. exprtk_define_unary_function(cos )
  1252. exprtk_define_unary_function(cosh )
  1253. exprtk_define_unary_function(exp )
  1254. exprtk_define_unary_function(expm1)
  1255. exprtk_define_unary_function(floor)
  1256. exprtk_define_unary_function(log )
  1257. exprtk_define_unary_function(log10)
  1258. exprtk_define_unary_function(log2 )
  1259. exprtk_define_unary_function(log1p)
  1260. exprtk_define_unary_function(neg )
  1261. exprtk_define_unary_function(pos )
  1262. exprtk_define_unary_function(round)
  1263. exprtk_define_unary_function(sin )
  1264. exprtk_define_unary_function(sinc )
  1265. exprtk_define_unary_function(sinh )
  1266. exprtk_define_unary_function(sqrt )
  1267. exprtk_define_unary_function(tan )
  1268. exprtk_define_unary_function(tanh )
  1269. exprtk_define_unary_function(cot )
  1270. exprtk_define_unary_function(sec )
  1271. exprtk_define_unary_function(csc )
  1272. exprtk_define_unary_function(r2d )
  1273. exprtk_define_unary_function(d2r )
  1274. exprtk_define_unary_function(d2g )
  1275. exprtk_define_unary_function(g2d )
  1276. exprtk_define_unary_function(notl )
  1277. exprtk_define_unary_function(sgn )
  1278. exprtk_define_unary_function(erf )
  1279. exprtk_define_unary_function(erfc )
  1280. exprtk_define_unary_function(ncdf )
  1281. exprtk_define_unary_function(frac )
  1282. exprtk_define_unary_function(trunc)
  1283. #undef exprtk_define_unary_function
  1284. }
  1285. template <typename T>
  1286. inline T compute_pow10(T d, const int exponent)
  1287. {
  1288. static const double fract10[] =
  1289. {
  1290. 0.0,
  1291. 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,
  1292. 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,
  1293. 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,
  1294. 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,
  1295. 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,
  1296. 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,
  1297. 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,
  1298. 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,
  1299. 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,
  1300. 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,
  1301. 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,
  1302. 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,
  1303. 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,
  1304. 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,
  1305. 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,
  1306. 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,
  1307. 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,
  1308. 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,
  1309. 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,
  1310. 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,
  1311. 1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
  1312. 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
  1313. 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,
  1314. 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,
  1315. 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,
  1316. 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,
  1317. 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,
  1318. 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,
  1319. 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,
  1320. 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,
  1321. 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
  1322. };
  1323. static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
  1324. const int e = std::abs(exponent);
  1325. if (exponent >= std::numeric_limits<T>::min_exponent10)
  1326. {
  1327. if (e < fract10_size)
  1328. {
  1329. if (exponent > 0)
  1330. return T(d * fract10[e]);
  1331. else
  1332. return T(d / fract10[e]);
  1333. }
  1334. else
  1335. return T(d * std::pow(10.0, 10.0 * exponent));
  1336. }
  1337. else
  1338. {
  1339. d /= T(fract10[ -std::numeric_limits<T>::min_exponent10]);
  1340. return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
  1341. }
  1342. }
  1343. template <typename Iterator, typename T>
  1344. inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result)
  1345. {
  1346. if (itr == end)
  1347. return false;
  1348. bool negative = ('-' == (*itr));
  1349. if (negative || ('+' == (*itr)))
  1350. {
  1351. if (end == ++itr)
  1352. return false;
  1353. }
  1354. while ((end != itr) && ('0' == (*itr))) ++itr;
  1355. bool return_result = true;
  1356. unsigned int digit = 0;
  1357. const std::size_t length = std::distance(itr,end);
  1358. if (length <= 4)
  1359. {
  1360. switch (length)
  1361. {
  1362. #ifdef exprtk_use_lut
  1363. #define exprtk_process_digit \
  1364. if ((digit = details::digit_table[(int)*itr++]) < 10) result = result * 10 + (digit); else { return_result = false; break; }
  1365. #else
  1366. #define exprtk_process_digit \
  1367. if ((digit = (*itr++ - '0')) < 10) result = result * 10 + (digit); else { return_result = false; break; }
  1368. #endif
  1369. case 4 : exprtk_process_digit
  1370. case 3 : exprtk_process_digit
  1371. case 2 : exprtk_process_digit
  1372. case 1 : if ((digit = (*itr - '0'))>= 10) { digit = 0; return_result = false; }
  1373. #undef exprtk_process_digit
  1374. }
  1375. }
  1376. else
  1377. return_result = false;
  1378. if (length && return_result)
  1379. {
  1380. result = result * 10 + static_cast<T>(digit);
  1381. ++itr;
  1382. }
  1383. result = negative ? -result : result;
  1384. return return_result;
  1385. }
  1386. template <typename Iterator, typename T>
  1387. static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
  1388. {
  1389. typedef typename std::iterator_traits<Iterator>::value_type type;
  1390. static const std::size_t nan_length = 3;
  1391. if (std::distance(itr,end) != static_cast<int>(nan_length))
  1392. return false;
  1393. if (static_cast<type>('n') == (*itr))
  1394. {
  1395. if (
  1396. (static_cast<type>('a') != *(itr + 1)) ||
  1397. (static_cast<type>('n') != *(itr + 2))
  1398. )
  1399. {
  1400. return false;
  1401. }
  1402. }
  1403. else if (
  1404. (static_cast<type>('A') != *(itr + 1)) ||
  1405. (static_cast<type>('N') != *(itr + 2))
  1406. )
  1407. {
  1408. return false;
  1409. }
  1410. t = std::numeric_limits<T>::quiet_NaN();
  1411. return true;
  1412. }
  1413. template <typename Iterator, typename T>
  1414. static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
  1415. {
  1416. static const char inf_uc[] = "INFINITY";
  1417. static const char inf_lc[] = "infinity";
  1418. static const std::size_t inf_length = 8;
  1419. const std::size_t length = std::distance(itr,end);
  1420. if ((3 != length) && (inf_length != length))
  1421. return false;
  1422. const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
  1423. while (end != itr)
  1424. {
  1425. if (*inf_itr == static_cast<char>(*itr))
  1426. {
  1427. ++itr;
  1428. ++inf_itr;
  1429. continue;
  1430. }
  1431. else
  1432. return false;
  1433. }
  1434. if (negative)
  1435. t = -std::numeric_limits<T>::infinity();
  1436. else
  1437. t = std::numeric_limits<T>::infinity();
  1438. return true;
  1439. }
  1440. template <typename Iterator, typename T>
  1441. inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t, numeric::details::real_type_tag)
  1442. {
  1443. if (end == itr_external) return false;
  1444. Iterator itr = itr_external;
  1445. T d = T(0);
  1446. bool negative = ('-' == (*itr));
  1447. if (negative || '+' == (*itr))
  1448. {
  1449. if (end == ++itr)
  1450. return false;
  1451. }
  1452. bool instate = false;
  1453. #define parse_digit_1(d) \
  1454. if ((digit = (*itr - '0')) < 10) { d = d * T(10) + digit; } else break; if (end == ++itr) break; \
  1455. #define parse_digit_2(d) \
  1456. if ((digit = (*itr - '0')) < 10) { d = d * T(10) + digit; } else break; ++itr; \
  1457. if ('.' != (*itr))
  1458. {
  1459. const Iterator curr = itr;
  1460. while ((end != itr) && ('0' == (*itr))) ++itr;
  1461. unsigned int digit;
  1462. while (end != itr)
  1463. {
  1464. // Note: For 'physical' superscalar architectures it
  1465. // is advised that the following loop be: 4xPD1 and 1xPD2
  1466. #ifdef exprtk_enable_superscalar
  1467. parse_digit_1(d)
  1468. parse_digit_1(d)
  1469. #endif
  1470. parse_digit_1(d)
  1471. parse_digit_1(d)
  1472. parse_digit_2(d)
  1473. }
  1474. if (curr != itr) instate = true;
  1475. }
  1476. int exponent = 0;
  1477. if (end != itr)
  1478. {
  1479. if ('.' == (*itr))
  1480. {
  1481. const Iterator curr = ++itr;
  1482. unsigned int digit;
  1483. T tmp_d = T(0);
  1484. while (end != itr)
  1485. {
  1486. #ifdef exprtk_enable_superscalar
  1487. parse_digit_1(tmp_d)
  1488. parse_digit_1(tmp_d)
  1489. parse_digit_1(tmp_d)
  1490. #endif
  1491. parse_digit_1(tmp_d)
  1492. parse_digit_1(tmp_d)
  1493. parse_digit_2(tmp_d)
  1494. }
  1495. if (curr != itr)
  1496. {
  1497. instate = true;
  1498. d += compute_pow10(tmp_d,-std::distance(curr,itr));
  1499. }
  1500. #undef parse_digit_1
  1501. #undef parse_digit_2
  1502. }
  1503. if (end != itr)
  1504. {
  1505. typename std::iterator_traits<Iterator>::value_type c = (*itr);
  1506. if (('e' == c) || ('E' == c))
  1507. {
  1508. int exp = 0;
  1509. if (!details::string_to_type_converter_impl_ref(++itr,end,exp))
  1510. {
  1511. if (end == itr)
  1512. return false;
  1513. else
  1514. c = (*itr);
  1515. }
  1516. exponent += exp;
  1517. }
  1518. if (end != itr)
  1519. {
  1520. if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
  1521. ++itr;
  1522. else if ('#' == c)
  1523. {
  1524. if (end == ++itr)
  1525. return false;
  1526. else if (('I' <= (*itr)) && ((*itr) <= 'n'))
  1527. {
  1528. if (('i' == (*itr)) || ('I' == (*itr)))
  1529. {
  1530. return parse_inf(itr,end,t,negative);
  1531. }
  1532. else if (('n' == (*itr)) || ('N' == (*itr)))
  1533. {
  1534. return parse_nan(itr,end,t);
  1535. }
  1536. else
  1537. return false;
  1538. }
  1539. else
  1540. return false;
  1541. }
  1542. else if (('I' <= (*itr)) && ((*itr) <= 'n'))
  1543. {
  1544. if (('i' == (*itr)) || ('I' == (*itr)))
  1545. {
  1546. return parse_inf(itr,end,t,negative);
  1547. }
  1548. else if (('n' == (*itr)) || ('N' == (*itr)))
  1549. {
  1550. return parse_nan(itr,end,t);
  1551. }
  1552. else
  1553. return false;
  1554. }
  1555. else
  1556. return false;
  1557. }
  1558. }
  1559. }
  1560. if ((end != itr) || (!instate))
  1561. return false;
  1562. else if (exponent)
  1563. d = compute_pow10(d,exponent);
  1564. t = static_cast<T>((negative) ? -d : d);
  1565. return true;
  1566. }
  1567. template <typename T>
  1568. inline bool string_to_real(const std::string& s, T& t)
  1569. {
  1570. const char* begin = s.data();
  1571. const char* end = s.data() + s.size();
  1572. typename numeric::details::number_type<T>::type num_type;
  1573. return string_to_real(begin,end,t,num_type);
  1574. }
  1575. template <typename T>
  1576. struct functor_t
  1577. {
  1578. /*
  1579. Note: The following definitions for Type, may require tweaking
  1580. based on the compiler and target architecture. The benchmark
  1581. should provide enough information to make the right choice.
  1582. */
  1583. //typedef T Type;
  1584. //typedef const T Type;
  1585. typedef const T& Type;
  1586. typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3);
  1587. typedef T (*tfunc_t)(Type t0, Type t1, Type t2);
  1588. typedef T (*bfunc_t)(Type t0, Type t1);
  1589. typedef T (*ufunc_t)(Type t0);
  1590. };
  1591. } // namespace details
  1592. namespace lexer
  1593. {
  1594. struct token
  1595. {
  1596. enum token_type
  1597. {
  1598. e_none = 0, e_error = 1, e_err_symbol = 2,
  1599. e_err_number = 3, e_err_string = 4, e_err_sfunc = 5,
  1600. e_eof = 6, e_number = 7, e_symbol = 8,
  1601. e_string = 9, e_assign = 10, e_addass = 11,
  1602. e_subass = 12, e_mulass = 13, e_divass = 14,
  1603. e_modass = 15, e_shr = 16, e_shl = 17,
  1604. e_lte = 18, e_ne = 19, e_gte = 20,
  1605. e_swap = 21, e_lt = '<', e_gt = '>',
  1606. e_eq = '=', e_rbracket = ')', e_lbracket = '(',
  1607. e_rsqrbracket = ']', e_lsqrbracket = '[', e_rcrlbracket = '}',
  1608. e_lcrlbracket = '{', e_comma = ',', e_add = '+',
  1609. e_sub = '-', e_div = '/', e_mul = '*',
  1610. e_mod = '%', e_pow = '^', e_colon = ':',
  1611. e_ternary = '?'
  1612. };
  1613. token()
  1614. : type(e_none),
  1615. value(""),
  1616. position(std::numeric_limits<std::size_t>::max())
  1617. {}
  1618. void clear()
  1619. {
  1620. type = e_none;
  1621. value = "";
  1622. position = std::numeric_limits<std::size_t>::max();
  1623. }
  1624. template <typename Iterator>
  1625. inline token& set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1626. {
  1627. type = tt;
  1628. value.assign(begin,end);
  1629. if (base_begin)
  1630. position = std::distance(base_begin,begin);
  1631. return *this;
  1632. }
  1633. template <typename Iterator>
  1634. inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1635. {
  1636. type = e_symbol;
  1637. value.assign(begin,end);
  1638. if (base_begin)
  1639. position = std::distance(base_begin,begin);
  1640. return *this;
  1641. }
  1642. template <typename Iterator>
  1643. inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1644. {
  1645. type = e_number;
  1646. value.assign(begin,end);
  1647. if (base_begin)
  1648. position = std::distance(base_begin,begin);
  1649. return *this;
  1650. }
  1651. template <typename Iterator>
  1652. inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1653. {
  1654. type = e_string;
  1655. value.assign(begin,end);
  1656. if (base_begin)
  1657. position = std::distance(base_begin,begin);
  1658. return *this;
  1659. }
  1660. inline token& set_string(const std::string& s, const std::size_t p)
  1661. {
  1662. type = e_string;
  1663. value = s;
  1664. position = p;
  1665. return *this;
  1666. }
  1667. template <typename Iterator>
  1668. inline token& set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
  1669. {
  1670. if (
  1671. (e_error == et) ||
  1672. (e_err_symbol == et) ||
  1673. (e_err_number == et) ||
  1674. (e_err_string == et) ||
  1675. (e_err_sfunc == et)
  1676. )
  1677. {
  1678. type = et;
  1679. }
  1680. else
  1681. type = e_error;
  1682. value.assign(begin,end);
  1683. if (base_begin)
  1684. position = std::distance(base_begin,begin);
  1685. return *this;
  1686. }
  1687. static inline std::string to_str(token_type t)
  1688. {
  1689. switch (t)
  1690. {
  1691. case e_none : return "NONE";
  1692. case e_error : return "ERROR";
  1693. case e_err_symbol : return "ERROR_SYMBOL";
  1694. case e_err_number : return "ERROR_NUMBER";
  1695. case e_err_string : return "ERROR_STRING";
  1696. case e_eof : return "EOF";
  1697. case e_number : return "NUMBER";
  1698. case e_symbol : return "SYMBOL";
  1699. case e_string : return "STRING";
  1700. case e_assign : return ":=";
  1701. case e_addass : return "+=";
  1702. case e_subass : return "-=";
  1703. case e_mulass : return "*=";
  1704. case e_divass : return "/=";
  1705. case e_modass : return "%=";
  1706. case e_shr : return ">>";
  1707. case e_shl : return "<<";
  1708. case e_lte : return "<=";
  1709. case e_ne : return "!=";
  1710. case e_gte : return ">=";
  1711. case e_lt : return "<";
  1712. case e_gt : return ">";
  1713. case e_eq : return "=";
  1714. case e_rbracket : return ")";
  1715. case e_lbracket : return "(";
  1716. case e_rsqrbracket : return "]";
  1717. case e_lsqrbracket : return "[";
  1718. case e_rcrlbracket : return "}";
  1719. case e_lcrlbracket : return "{";
  1720. case e_comma : return ",";
  1721. case e_add : return "+";
  1722. case e_sub : return "-";
  1723. case e_div : return "/";
  1724. case e_mul : return "*";
  1725. case e_mod : return "%";
  1726. case e_pow : return "^";
  1727. case e_colon : return ":";
  1728. case e_ternary : return "?";
  1729. case e_swap : return "<=>";
  1730. default : return "UNKNOWN";
  1731. }
  1732. }
  1733. inline bool is_error() const
  1734. {
  1735. return (
  1736. (e_error == type) ||
  1737. (e_err_symbol == type) ||
  1738. (e_err_number == type) ||
  1739. (e_err_string == type) ||
  1740. (e_err_sfunc == type)
  1741. );
  1742. }
  1743. token_type type;
  1744. std::string value;
  1745. std::size_t position;
  1746. };
  1747. class generator
  1748. {
  1749. public:
  1750. typedef token token_t;
  1751. typedef std::vector<token_t> token_list_t;
  1752. typedef std::vector<token_t>::iterator token_list_itr_t;
  1753. generator()
  1754. : base_itr_(0),
  1755. s_itr_ (0),
  1756. s_end_ (0)
  1757. {
  1758. clear();
  1759. }
  1760. inline void clear()
  1761. {
  1762. base_itr_ = 0;
  1763. s_itr_ = 0;
  1764. s_end_ = 0;
  1765. token_list_.clear();
  1766. token_itr_ = token_list_.end();
  1767. store_token_itr_ = token_list_.end();
  1768. }
  1769. inline bool process(const std::string& str)
  1770. {
  1771. base_itr_ = str.data();
  1772. s_itr_ = str.data();
  1773. s_end_ = str.data() + str.size();
  1774. eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
  1775. token_list_.clear();
  1776. while (!is_end(s_itr_))
  1777. {
  1778. scan_token();
  1779. if (token_list_.empty())
  1780. return true;
  1781. else if (token_list_.back().is_error())
  1782. {
  1783. return false;
  1784. }
  1785. }
  1786. return true;
  1787. }
  1788. inline bool empty() const
  1789. {
  1790. return token_list_.empty();
  1791. }
  1792. inline std::size_t size() const
  1793. {
  1794. return token_list_.size();
  1795. }
  1796. inline void begin()
  1797. {
  1798. token_itr_ = token_list_.begin();
  1799. store_token_itr_ = token_list_.begin();
  1800. }
  1801. inline void store()
  1802. {
  1803. store_token_itr_ = token_itr_;
  1804. }
  1805. inline void restore()
  1806. {
  1807. token_itr_ = store_token_itr_;
  1808. }
  1809. inline token_t& next_token()
  1810. {
  1811. if (token_list_.end() != token_itr_)
  1812. {
  1813. return *token_itr_++;
  1814. }
  1815. else
  1816. return eof_token_;
  1817. }
  1818. inline token_t& peek_next_token()
  1819. {
  1820. if (token_list_.end() != token_itr_)
  1821. {
  1822. return *token_itr_;
  1823. }
  1824. else
  1825. return eof_token_;
  1826. }
  1827. inline token_t& operator[](const std::size_t& index)
  1828. {
  1829. if (index < token_list_.size())
  1830. return token_list_[index];
  1831. else
  1832. return eof_token_;
  1833. }
  1834. inline token_t operator[](const std::size_t& index) const
  1835. {
  1836. if (index < token_list_.size())
  1837. return token_list_[index];
  1838. else
  1839. return eof_token_;
  1840. }
  1841. inline bool finished() const
  1842. {
  1843. return (token_list_.end() == token_itr_);
  1844. }
  1845. inline void insert_front(token_t::token_type tk_type)
  1846. {
  1847. if (
  1848. !token_list_.empty() &&
  1849. (token_list_.end() != token_itr_)
  1850. )
  1851. {
  1852. token_t t = *token_itr_;
  1853. t.type = tk_type;
  1854. token_itr_ = token_list_.insert(token_itr_,t);
  1855. }
  1856. }
  1857. inline std::string substr(const std::size_t& begin, const std::size_t& end)
  1858. {
  1859. const char* begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
  1860. const char* end_itr = ((base_itr_ + end) < s_end_) ? (base_itr_ + end) : s_end_;
  1861. return std::string(begin_itr,end_itr);
  1862. }
  1863. inline std::string remaining() const
  1864. {
  1865. if (finished())
  1866. return "";
  1867. else if (token_list_.begin() != token_itr_)
  1868. return std::string(base_itr_ + (token_itr_ - 1)->position,s_end_);
  1869. else
  1870. return std::string(base_itr_ + token_itr_->position,s_end_);
  1871. }
  1872. private:
  1873. inline bool is_end(const char* itr)
  1874. {
  1875. return (s_end_ == itr);
  1876. }
  1877. inline void skip_whitespace()
  1878. {
  1879. while (!is_end(s_itr_) && details::is_whitespace(*s_itr_))
  1880. {
  1881. ++s_itr_;
  1882. }
  1883. }
  1884. inline void skip_comments()
  1885. {
  1886. #ifndef exprtk_disable_comments
  1887. // The following comment styles are supported:
  1888. // 1. // .... \n
  1889. // 2. # .... \n
  1890. // 3. /* .... */
  1891. struct test
  1892. {
  1893. static inline bool comment_start(const char c0, const char c1, int& mode, int& incr)
  1894. {
  1895. mode = 0;
  1896. if ('#' == c0) { mode = 1; incr = 1; }
  1897. else if ('/' == c0)
  1898. {
  1899. if ('/' == c1) { mode = 1; incr = 2; }
  1900. else if ('*' == c1) { mode = 2; incr = 2; }
  1901. }
  1902. return (0 != mode);
  1903. }
  1904. static inline bool comment_end(const char c0, const char c1, const int mode)
  1905. {
  1906. return (
  1907. ((1 == mode) && ('\n' == c0)) ||
  1908. ((2 == mode) && ( '*' == c0) && ('/' == c1))
  1909. );
  1910. }
  1911. };
  1912. int mode = 0;
  1913. int increment = 0;
  1914. if (is_end(s_itr_) || is_end((s_itr_ + 1)))
  1915. return;
  1916. else if (!test::comment_start(*s_itr_,*(s_itr_ + 1),mode,increment))
  1917. return;
  1918. s_itr_ += increment;
  1919. while (!is_end(s_itr_) && !test::comment_end(*s_itr_,*(s_itr_ + 1),mode))
  1920. {
  1921. ++s_itr_;
  1922. }
  1923. if (!is_end(s_itr_))
  1924. {
  1925. s_itr_ += mode;
  1926. skip_whitespace();
  1927. skip_comments();
  1928. }
  1929. #endif
  1930. }
  1931. inline void scan_token()
  1932. {
  1933. skip_whitespace();
  1934. skip_comments();
  1935. if (is_end(s_itr_))
  1936. {
  1937. return;
  1938. }
  1939. else if (details::is_operator_char(*s_itr_))
  1940. {
  1941. scan_operator();
  1942. return;
  1943. }
  1944. else if (details::is_letter(*s_itr_))
  1945. {
  1946. scan_symbol();
  1947. return;
  1948. }
  1949. else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_)))
  1950. {
  1951. scan_number();
  1952. return;
  1953. }
  1954. else if ('$' == (*s_itr_))
  1955. {
  1956. scan_special_function();
  1957. return;
  1958. }
  1959. #ifndef exprtk_disable_string_capabilities
  1960. else if ('\'' == (*s_itr_))
  1961. {
  1962. scan_string();
  1963. return;
  1964. }
  1965. #endif
  1966. else if ('~' == (*s_itr_))
  1967. {
  1968. token_t t;
  1969. t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
  1970. token_list_.push_back(t);
  1971. ++s_itr_;
  1972. return;
  1973. }
  1974. else
  1975. {
  1976. token_t t;
  1977. t.set_error(token::e_error,s_itr_,s_itr_ + 2,base_itr_);
  1978. token_list_.push_back(t);
  1979. ++s_itr_;
  1980. }
  1981. }
  1982. inline void scan_operator()
  1983. {
  1984. token_t t;
  1985. const char c0 = s_itr_[0];
  1986. if (!is_end(s_itr_ + 1))
  1987. {
  1988. const char c1 = s_itr_[1];
  1989. if (!is_end(s_itr_ + 2))
  1990. {
  1991. const char c2 = s_itr_[2];
  1992. if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
  1993. {
  1994. t.set_operator(token_t::e_swap,s_itr_,s_itr_ + 3,base_itr_);
  1995. token_list_.push_back(t);
  1996. s_itr_ += 3;
  1997. return;
  1998. }
  1999. }
  2000. token_t::token_type ttype = token_t::e_none;
  2001. if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
  2002. else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
  2003. else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
  2004. else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
  2005. else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
  2006. else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
  2007. else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
  2008. else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
  2009. else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass;
  2010. else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass;
  2011. else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass;
  2012. else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass;
  2013. else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass;
  2014. if (token_t::e_none != ttype)
  2015. {
  2016. t.set_operator(ttype,s_itr_,s_itr_ + 2,base_itr_);
  2017. token_list_.push_back(t);
  2018. s_itr_ += 2;
  2019. return;
  2020. }
  2021. }
  2022. if ('<' == c0)
  2023. t.set_operator(token_t::e_lt ,s_itr_,s_itr_ + 1,base_itr_);
  2024. else if ('>' == c0)
  2025. t.set_operator(token_t::e_gt ,s_itr_,s_itr_ + 1,base_itr_);
  2026. else if (';' == c0)
  2027. t.set_operator(token_t::e_eof,s_itr_,s_itr_ + 1,base_itr_);
  2028. else if ('&' == c0)
  2029. t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
  2030. else if ('|' == c0)
  2031. t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
  2032. else
  2033. t.set_operator(token_t::token_type(c0),s_itr_,s_itr_ + 1,base_itr_);
  2034. token_list_.push_back(t);
  2035. ++s_itr_;
  2036. }
  2037. inline void scan_symbol()
  2038. {
  2039. const char* initial_itr = s_itr_;
  2040. while (
  2041. (!is_end(s_itr_)) &&
  2042. (details::is_letter_or_digit(*s_itr_) || ((*s_itr_) == '_'))
  2043. )
  2044. {
  2045. ++s_itr_;
  2046. }
  2047. token_t t;
  2048. t.set_symbol(initial_itr,s_itr_,base_itr_);
  2049. token_list_.push_back(t);
  2050. }
  2051. inline void scan_number()
  2052. {
  2053. /*
  2054. Attempt to match a valid numeric value in one of the following formats:
  2055. 1. 123456
  2056. 2. 123.456
  2057. 3. 123.456e3
  2058. 4. 123.456E3
  2059. 5. 123.456e+3
  2060. 6. 123.456E+3
  2061. 7. 123.456e-3
  2062. 8. 123.456E-3
  2063. */
  2064. const char* initial_itr = s_itr_;
  2065. bool dot_found = false;
  2066. bool e_found = false;
  2067. bool post_e_sign_found = false;
  2068. token_t t;
  2069. while (!is_end(s_itr_))
  2070. {
  2071. if ('.' == (*s_itr_))
  2072. {
  2073. if (dot_found)
  2074. {
  2075. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  2076. token_list_.push_back(t);
  2077. return;
  2078. }
  2079. dot_found = true;
  2080. ++s_itr_;
  2081. continue;
  2082. }
  2083. else if (details::imatch('e',(*s_itr_)))
  2084. {
  2085. const char& c = *(s_itr_ + 1);
  2086. if (is_end(s_itr_ + 1))
  2087. {
  2088. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  2089. token_list_.push_back(t);
  2090. return;
  2091. }
  2092. else if (
  2093. ('+' != c) &&
  2094. ('-' != c) &&
  2095. !details::is_digit(c)
  2096. )
  2097. {
  2098. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  2099. token_list_.push_back(t);
  2100. return;
  2101. }
  2102. e_found = true;
  2103. ++s_itr_;
  2104. continue;
  2105. }
  2106. else if (e_found && details::is_sign(*s_itr_))
  2107. {
  2108. if (post_e_sign_found)
  2109. {
  2110. t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
  2111. token_list_.push_back(t);
  2112. return;
  2113. }
  2114. post_e_sign_found = true;
  2115. ++s_itr_;
  2116. continue;
  2117. }
  2118. else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
  2119. break;
  2120. else
  2121. ++s_itr_;
  2122. }
  2123. t.set_numeric(initial_itr,s_itr_,base_itr_);
  2124. token_list_.push_back(t);
  2125. return;
  2126. }
  2127. inline void scan_special_function()
  2128. {
  2129. const char* initial_itr = s_itr_;
  2130. token_t t;
  2131. // $fdd(x,x,x) = at least 11 chars
  2132. if (std::distance(s_itr_,s_end_) < 11)
  2133. {
  2134. t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_);
  2135. token_list_.push_back(t);
  2136. return;
  2137. }
  2138. if (
  2139. !(('$' == *s_itr_) &&
  2140. (details::imatch ('f',*(s_itr_ + 1))) &&
  2141. (details::is_digit(*(s_itr_ + 2))) &&
  2142. (details::is_digit(*(s_itr_ + 3))))
  2143. )
  2144. {
  2145. t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_);
  2146. token_list_.push_back(t);
  2147. return;
  2148. }
  2149. s_itr_ += 4; // $fdd = 4chars
  2150. t.set_symbol(initial_itr,s_itr_,base_itr_);
  2151. token_list_.push_back(t);
  2152. return;
  2153. }
  2154. #ifndef exprtk_disable_string_capabilities
  2155. inline void scan_string()
  2156. {
  2157. const char* initial_itr = s_itr_ + 1;
  2158. token_t t;
  2159. if (std::distance(s_itr_,s_end_) < 2)
  2160. {
  2161. t.set_error(token::e_err_string,s_itr_,s_end_,base_itr_);
  2162. token_list_.push_back(t);
  2163. return;
  2164. }
  2165. ++s_itr_;
  2166. bool escaped_found = false;
  2167. bool escaped = false;
  2168. while (!is_end(s_itr_))
  2169. {
  2170. if (!escaped && ('\\' == *s_itr_))
  2171. {
  2172. escaped_found = true;
  2173. escaped = true;
  2174. ++s_itr_;
  2175. continue;
  2176. }
  2177. else if (!escaped)
  2178. {
  2179. if ('\'' == *s_itr_)
  2180. break;
  2181. }
  2182. else if (escaped)
  2183. {
  2184. if (!is_end(s_itr_) && ('0' == *(s_itr_)))
  2185. {
  2186. /*
  2187. Note: The following 'awkward' conditional is
  2188. due to various broken msvc compilers.
  2189. */
  2190. #if _MSC_VER == 1600
  2191. const bool within_range = !is_end(s_itr_ + 2) &&
  2192. !is_end(s_itr_ + 3) ;
  2193. #else
  2194. const bool within_range = !is_end(s_itr_ + 1) &&
  2195. !is_end(s_itr_ + 2) &&
  2196. !is_end(s_itr_ + 3) ;
  2197. #endif
  2198. const bool x_seperator = ('x' == *(s_itr_ + 1)) ||
  2199. ('X' == *(s_itr_ + 1)) ;
  2200. const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
  2201. details::is_hex_digit(*(s_itr_ + 3)) ;
  2202. if (!within_range || !x_seperator || !both_digits)
  2203. {
  2204. t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_);
  2205. token_list_.push_back(t);
  2206. return;
  2207. }
  2208. else
  2209. s_itr_ += 3;
  2210. }
  2211. escaped = false;
  2212. }
  2213. ++s_itr_;
  2214. }
  2215. if (is_end(s_itr_))
  2216. {
  2217. t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_);
  2218. token_list_.push_back(t);
  2219. return;
  2220. }
  2221. if (!escaped_found)
  2222. t.set_string(initial_itr,s_itr_,base_itr_);
  2223. else
  2224. {
  2225. std::string parsed_string(initial_itr,s_itr_);
  2226. details::cleanup_escapes(parsed_string);
  2227. t.set_string(parsed_string, std::distance(base_itr_,initial_itr));
  2228. }
  2229. token_list_.push_back(t);
  2230. ++s_itr_;
  2231. return;
  2232. }
  2233. #endif
  2234. private:
  2235. token_list_t token_list_;
  2236. token_list_itr_t token_itr_;
  2237. token_list_itr_t store_token_itr_;
  2238. token_t eof_token_;
  2239. const char* base_itr_;
  2240. const char* s_itr_;
  2241. const char* s_end_;
  2242. friend class token_scanner;
  2243. friend class token_modifier;
  2244. friend class token_inserter;
  2245. friend class token_joiner;
  2246. };
  2247. class helper_interface
  2248. {
  2249. public:
  2250. virtual void init() { }
  2251. virtual void reset() { }
  2252. virtual bool result() { return true; }
  2253. virtual std::size_t process(generator&) { return 0; }
  2254. virtual ~helper_interface() { }
  2255. };
  2256. class token_scanner : public helper_interface
  2257. {
  2258. public:
  2259. virtual ~token_scanner()
  2260. {}
  2261. explicit token_scanner(const std::size_t& stride)
  2262. : stride_(stride)
  2263. {
  2264. if (stride > 4)
  2265. {
  2266. throw std::invalid_argument("token_scanner() - Invalid stride value");
  2267. }
  2268. }
  2269. inline std::size_t process(generator& g)
  2270. {
  2271. if (g.token_list_.size() >= stride_)
  2272. {
  2273. for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
  2274. {
  2275. token t;
  2276. switch (stride_)
  2277. {
  2278. case 1 :
  2279. {
  2280. const token& t0 = g.token_list_[i];
  2281. if (!operator()(t0))
  2282. {
  2283. return i;
  2284. }
  2285. }
  2286. break;
  2287. case 2 :
  2288. {
  2289. const token& t0 = g.token_list_[i ];
  2290. const token& t1 = g.token_list_[i + 1];
  2291. if (!operator()(t0,t1))
  2292. {
  2293. return i;
  2294. }
  2295. }
  2296. break;
  2297. case 3 :
  2298. {
  2299. const token& t0 = g.token_list_[i ];
  2300. const token& t1 = g.token_list_[i + 1];
  2301. const token& t2 = g.token_list_[i + 2];
  2302. if (!operator()(t0,t1,t2))
  2303. {
  2304. return i;
  2305. }
  2306. }
  2307. break;
  2308. case 4 :
  2309. {
  2310. const token& t0 = g.token_list_[i ];
  2311. const token& t1 = g.token_list_[i + 1];
  2312. const token& t2 = g.token_list_[i + 2];
  2313. const token& t3 = g.token_list_[i + 3];
  2314. if (!operator()(t0,t1,t2,t3))
  2315. {
  2316. return i;
  2317. }
  2318. }
  2319. break;
  2320. }
  2321. }
  2322. }
  2323. return (g.token_list_.size() - stride_ + 1);
  2324. }
  2325. virtual bool operator()(const token&)
  2326. {
  2327. return false;
  2328. }
  2329. virtual bool operator()(const token&, const token&)
  2330. {
  2331. return false;
  2332. }
  2333. virtual bool operator()(const token&, const token&, const token&)
  2334. {
  2335. return false;
  2336. }
  2337. virtual bool operator()(const token&, const token&, const token&, const token&)
  2338. {
  2339. return false;
  2340. }
  2341. private:
  2342. std::size_t stride_;
  2343. };
  2344. class token_modifier : public helper_interface
  2345. {
  2346. public:
  2347. inline std::size_t process(generator& g)
  2348. {
  2349. std::size_t changes = 0;
  2350. for (std::size_t i = 0; i < g.token_list_.size(); ++i)
  2351. {
  2352. if (modify(g.token_list_[i])) changes++;
  2353. }
  2354. return changes;
  2355. }
  2356. virtual bool modify(token& t) = 0;
  2357. };
  2358. class token_inserter : public helper_interface
  2359. {
  2360. public:
  2361. explicit token_inserter(const std::size_t& stride)
  2362. : stride_(stride)
  2363. {
  2364. if (stride > 5)
  2365. {
  2366. throw std::invalid_argument("token_inserter() - Invalid stride value");
  2367. }
  2368. }
  2369. inline std::size_t process(generator& g)
  2370. {
  2371. if (g.token_list_.empty())
  2372. return 0;
  2373. else if (g.token_list_.size() < stride_)
  2374. return 0;
  2375. std::size_t changes = 0;
  2376. for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
  2377. {
  2378. int insert_index = -1;
  2379. token t;
  2380. switch (stride_)
  2381. {
  2382. case 1 : insert_index = insert(g.token_list_[i],t);
  2383. break;
  2384. case 2 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],t);
  2385. break;
  2386. case 3 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t);
  2387. break;
  2388. 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);
  2389. break;
  2390. 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);
  2391. break;
  2392. }
  2393. if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
  2394. {
  2395. g.token_list_.insert(g.token_list_.begin() + (i + insert_index),t);
  2396. changes++;
  2397. }
  2398. }
  2399. return changes;
  2400. }
  2401. inline virtual int insert(const token&, token& )
  2402. {
  2403. return -1;
  2404. }
  2405. inline virtual int insert(const token&, const token&, token&)
  2406. {
  2407. return -1;
  2408. }
  2409. inline virtual int insert(const token&, const token&, const token&, token&)
  2410. {
  2411. return -1;
  2412. }
  2413. inline virtual int insert(const token&, const token&, const token&, const token&, token&)
  2414. {
  2415. return -1;
  2416. }
  2417. inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
  2418. {
  2419. return -1;
  2420. }
  2421. private:
  2422. std::size_t stride_;
  2423. };
  2424. class token_joiner : public helper_interface
  2425. {
  2426. public:
  2427. token_joiner(const std::size_t& stride)
  2428. : stride_(stride)
  2429. {}
  2430. inline std::size_t process(generator& g)
  2431. {
  2432. if (g.token_list_.empty())
  2433. return 0;
  2434. switch (stride_)
  2435. {
  2436. case 2 : return process_stride_2(g);
  2437. case 3 : return process_stride_3(g);
  2438. default : return 0;
  2439. }
  2440. }
  2441. virtual bool join(const token&, const token&, token&) { return false; }
  2442. virtual bool join(const token&, const token&, const token&, token&) { return false; }
  2443. private:
  2444. inline std::size_t process_stride_2(generator& g)
  2445. {
  2446. if (g.token_list_.size() < 2)
  2447. return 0;
  2448. std::size_t changes = 0;
  2449. for (std::size_t i = 0; i < g.token_list_.size() - 1; ++i)
  2450. {
  2451. token t;
  2452. while (join(g.token_list_[i],g.token_list_[i + 1],t))
  2453. {
  2454. g.token_list_[i] = t;
  2455. g.token_list_.erase(g.token_list_.begin() + (i + 1));
  2456. ++changes;
  2457. }
  2458. }
  2459. return changes;
  2460. }
  2461. inline std::size_t process_stride_3(generator& g)
  2462. {
  2463. if (g.token_list_.size() < 3)
  2464. return 0;
  2465. std::size_t changes = 0;
  2466. for (std::size_t i = 0; i < g.token_list_.size() - 2; ++i)
  2467. {
  2468. token t;
  2469. while (join(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t))
  2470. {
  2471. g.token_list_[i] = t;
  2472. g.token_list_.erase(g.token_list_.begin() + (i + 1),
  2473. g.token_list_.begin() + (i + 3));
  2474. ++changes;
  2475. }
  2476. }
  2477. return changes;
  2478. }
  2479. std::size_t stride_;
  2480. };
  2481. namespace helper
  2482. {
  2483. inline void dump(lexer::generator& generator)
  2484. {
  2485. for (std::size_t i = 0; i < generator.size(); ++i)
  2486. {
  2487. lexer::token t = generator[i];
  2488. printf("Token[%02d] @ %03d %6s --> '%s'\n",
  2489. static_cast<int>(i),
  2490. static_cast<int>(t.position),
  2491. t.to_str(t.type).c_str(),
  2492. t.value.c_str());
  2493. }
  2494. }
  2495. class commutative_inserter : public lexer::token_inserter
  2496. {
  2497. public:
  2498. commutative_inserter()
  2499. : lexer::token_inserter(2)
  2500. {}
  2501. inline void ignore_symbol(const std::string& symbol)
  2502. {
  2503. ignore_set_.insert(symbol);
  2504. }
  2505. inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token)
  2506. {
  2507. bool match = false;
  2508. new_token.type = lexer::token::e_mul;
  2509. new_token.value = "*";
  2510. new_token.position = t1.position;
  2511. if (t0.type == lexer::token::e_symbol)
  2512. {
  2513. if (ignore_set_.end() != ignore_set_.find(t0.value))
  2514. {
  2515. return -1;
  2516. }
  2517. else if (!t0.value.empty() && ('$' == t0.value[0]))
  2518. {
  2519. return -1;
  2520. }
  2521. }
  2522. if (t1.type == lexer::token::e_symbol)
  2523. {
  2524. if (ignore_set_.end() != ignore_set_.find(t1.value))
  2525. {
  2526. return -1;
  2527. }
  2528. }
  2529. if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
  2530. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
  2531. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
  2532. else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
  2533. else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
  2534. else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
  2535. else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
  2536. else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
  2537. else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
  2538. else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
  2539. else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
  2540. return (match) ? 1 : -1;
  2541. }
  2542. private:
  2543. std::set<std::string,details::ilesscompare> ignore_set_;
  2544. };
  2545. class operator_joiner : public token_joiner
  2546. {
  2547. public:
  2548. operator_joiner(const std::size_t& stride)
  2549. : token_joiner(stride)
  2550. {}
  2551. inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t)
  2552. {
  2553. // ': =' --> ':='
  2554. if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
  2555. {
  2556. t.type = lexer::token::e_assign;
  2557. t.value = ":=";
  2558. t.position = t0.position;
  2559. return true;
  2560. }
  2561. // '+ =' --> '+='
  2562. else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq))
  2563. {
  2564. t.type = lexer::token::e_addass;
  2565. t.value = "+=";
  2566. t.position = t0.position;
  2567. return true;
  2568. }
  2569. // '- =' --> '-='
  2570. else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq))
  2571. {
  2572. t.type = lexer::token::e_subass;
  2573. t.value = "-=";
  2574. t.position = t0.position;
  2575. return true;
  2576. }
  2577. // '* =' --> '*='
  2578. else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq))
  2579. {
  2580. t.type = lexer::token::e_mulass;
  2581. t.value = "*=";
  2582. t.position = t0.position;
  2583. return true;
  2584. }
  2585. // '/ =' --> '/='
  2586. else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq))
  2587. {
  2588. t.type = lexer::token::e_divass;
  2589. t.value = "/=";
  2590. t.position = t0.position;
  2591. return true;
  2592. }
  2593. // '% =' --> '%='
  2594. else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq))
  2595. {
  2596. t.type = lexer::token::e_modass;
  2597. t.value = "%=";
  2598. t.position = t0.position;
  2599. return true;
  2600. }
  2601. // '> =' --> '>='
  2602. else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
  2603. {
  2604. t.type = lexer::token::e_gte;
  2605. t.value = ">=";
  2606. t.position = t0.position;
  2607. return true;
  2608. }
  2609. // '< =' --> '<='
  2610. else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
  2611. {
  2612. t.type = lexer::token::e_lte;
  2613. t.value = "<=";
  2614. t.position = t0.position;
  2615. return true;
  2616. }
  2617. // '= =' --> '=='
  2618. else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
  2619. {
  2620. t.type = lexer::token::e_eq;
  2621. t.value = "==";
  2622. t.position = t0.position;
  2623. return true;
  2624. }
  2625. // '! =' --> '!='
  2626. else if ((static_cast<char>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
  2627. {
  2628. t.type = lexer::token::e_ne;
  2629. t.value = "!=";
  2630. t.position = t0.position;
  2631. return true;
  2632. }
  2633. // '< >' --> '<>'
  2634. else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
  2635. {
  2636. t.type = lexer::token::e_ne;
  2637. t.value = "<>";
  2638. t.position = t0.position;
  2639. return true;
  2640. }
  2641. // '<= >' --> '<=>'
  2642. else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt))
  2643. {
  2644. t.type = lexer::token::e_swap;
  2645. t.value = "<=>";
  2646. t.position = t0.position;
  2647. return true;
  2648. }
  2649. else
  2650. return false;
  2651. }
  2652. inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, lexer::token& t)
  2653. {
  2654. // '[ * ]' --> '[*]'
  2655. if (
  2656. (t0.type == lexer::token::e_lsqrbracket) &&
  2657. (t1.type == lexer::token::e_mul ) &&
  2658. (t2.type == lexer::token::e_rsqrbracket)
  2659. )
  2660. {
  2661. t.type = lexer::token::e_symbol;
  2662. t.value = "[*]";
  2663. t.position = t0.position;
  2664. return true;
  2665. }
  2666. else
  2667. return false;
  2668. }
  2669. };
  2670. class bracket_checker : public lexer::token_scanner
  2671. {
  2672. public:
  2673. bracket_checker()
  2674. : token_scanner(1),
  2675. state_(true)
  2676. {}
  2677. bool result()
  2678. {
  2679. if (!stack_.empty())
  2680. {
  2681. lexer::token t;
  2682. t.value = stack_.top().first;
  2683. t.position = stack_.top().second;
  2684. error_token_ = t;
  2685. state_ = false;
  2686. return false;
  2687. }
  2688. else
  2689. return state_;
  2690. }
  2691. lexer::token error_token()
  2692. {
  2693. return error_token_;
  2694. }
  2695. void reset()
  2696. {
  2697. // Why? because msvc doesn't support swap properly.
  2698. stack_ = std::stack<std::pair<char,std::size_t> >();
  2699. state_ = true;
  2700. error_token_.clear();
  2701. }
  2702. bool operator()(const lexer::token& t)
  2703. {
  2704. if (
  2705. !t.value.empty() &&
  2706. (lexer::token::e_string != t.type) &&
  2707. (lexer::token::e_symbol != t.type) &&
  2708. exprtk::details::is_bracket(t.value[0])
  2709. )
  2710. {
  2711. char c = t.value[0];
  2712. if (t.type == lexer::token::e_lbracket) stack_.push(std::make_pair(')',t.position));
  2713. else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
  2714. else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
  2715. else if (exprtk::details::is_right_bracket(c))
  2716. {
  2717. if (stack_.empty())
  2718. {
  2719. state_ = false;
  2720. error_token_ = t;
  2721. return false;
  2722. }
  2723. else if (c != stack_.top().first)
  2724. {
  2725. state_ = false;
  2726. error_token_ = t;
  2727. return false;
  2728. }
  2729. else
  2730. stack_.pop();
  2731. }
  2732. }
  2733. return true;
  2734. }
  2735. private:
  2736. bool state_;
  2737. std::stack<std::pair<char,std::size_t> > stack_;
  2738. lexer::token error_token_;
  2739. };
  2740. class numeric_checker : public lexer::token_scanner
  2741. {
  2742. public:
  2743. numeric_checker()
  2744. : token_scanner (1),
  2745. current_index_(0)
  2746. {}
  2747. bool result()
  2748. {
  2749. return error_list_.empty();
  2750. }
  2751. void reset()
  2752. {
  2753. error_list_.clear();
  2754. current_index_ = 0;
  2755. }
  2756. bool operator()(const lexer::token& t)
  2757. {
  2758. if (token::e_number == t.type)
  2759. {
  2760. double v;
  2761. if (!exprtk::details::string_to_real(t.value,v))
  2762. {
  2763. error_list_.push_back(current_index_);
  2764. }
  2765. }
  2766. ++current_index_;
  2767. return true;
  2768. }
  2769. std::size_t error_count() const
  2770. {
  2771. return error_list_.size();
  2772. }
  2773. std::size_t error_index(const std::size_t& i)
  2774. {
  2775. if (i < error_list_.size())
  2776. return error_list_[i];
  2777. else
  2778. return std::numeric_limits<std::size_t>::max();
  2779. }
  2780. void clear_errors()
  2781. {
  2782. error_list_.clear();
  2783. }
  2784. private:
  2785. std::size_t current_index_;
  2786. std::vector<std::size_t> error_list_;
  2787. };
  2788. class symbol_replacer : public lexer::token_modifier
  2789. {
  2790. private:
  2791. typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
  2792. public:
  2793. bool remove(const std::string& target_symbol)
  2794. {
  2795. replace_map_t::iterator itr = replace_map_.find(target_symbol);
  2796. if (replace_map_.end() == itr)
  2797. return false;
  2798. replace_map_.erase(itr);
  2799. return true;
  2800. }
  2801. bool add_replace(const std::string& target_symbol,
  2802. const std::string& replace_symbol,
  2803. const lexer::token::token_type token_type = lexer::token::e_symbol)
  2804. {
  2805. replace_map_t::iterator itr = replace_map_.find(target_symbol);
  2806. if (replace_map_.end() != itr)
  2807. {
  2808. return false;
  2809. }
  2810. replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
  2811. return true;
  2812. }
  2813. void clear()
  2814. {
  2815. replace_map_.clear();
  2816. }
  2817. private:
  2818. bool modify(lexer::token& t)
  2819. {
  2820. if (lexer::token::e_symbol == t.type)
  2821. {
  2822. if (replace_map_.empty())
  2823. return false;
  2824. replace_map_t::iterator itr = replace_map_.find(t.value);
  2825. if (replace_map_.end() != itr)
  2826. {
  2827. t.value = itr->second.first;
  2828. t.type = itr->second.second;
  2829. return true;
  2830. }
  2831. }
  2832. return false;
  2833. }
  2834. replace_map_t replace_map_;
  2835. };
  2836. class sequence_validator : public lexer::token_scanner
  2837. {
  2838. private:
  2839. typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
  2840. typedef std::set<token_pair_t> set_t;
  2841. public:
  2842. sequence_validator()
  2843. : lexer::token_scanner(2)
  2844. {
  2845. add_invalid(lexer::token::e_number ,lexer::token::e_number );
  2846. add_invalid(lexer::token::e_string ,lexer::token::e_string );
  2847. add_invalid(lexer::token::e_number ,lexer::token::e_string );
  2848. add_invalid(lexer::token::e_string ,lexer::token::e_number );
  2849. add_invalid(lexer::token::e_string ,lexer::token::e_ternary);
  2850. add_invalid_set1(lexer::token::e_assign );
  2851. add_invalid_set1(lexer::token::e_shr );
  2852. add_invalid_set1(lexer::token::e_shl );
  2853. add_invalid_set1(lexer::token::e_lte );
  2854. add_invalid_set1(lexer::token::e_ne );
  2855. add_invalid_set1(lexer::token::e_gte );
  2856. add_invalid_set1(lexer::token::e_lt );
  2857. add_invalid_set1(lexer::token::e_gt );
  2858. add_invalid_set1(lexer::token::e_eq );
  2859. add_invalid_set1(lexer::token::e_comma );
  2860. add_invalid_set1(lexer::token::e_add );
  2861. add_invalid_set1(lexer::token::e_sub );
  2862. add_invalid_set1(lexer::token::e_div );
  2863. add_invalid_set1(lexer::token::e_mul );
  2864. add_invalid_set1(lexer::token::e_mod );
  2865. add_invalid_set1(lexer::token::e_pow );
  2866. add_invalid_set1(lexer::token::e_colon );
  2867. add_invalid_set1(lexer::token::e_ternary);
  2868. }
  2869. bool result()
  2870. {
  2871. return error_list_.empty();
  2872. }
  2873. bool operator()(const lexer::token& t0, const lexer::token& t1)
  2874. {
  2875. set_t::value_type p = std::make_pair(t0.type,t1.type);
  2876. if (invalid_bracket_check(t0.type,t1.type))
  2877. {
  2878. error_list_.push_back(std::make_pair(t0,t1));
  2879. }
  2880. else if (invalid_comb_.find(p) != invalid_comb_.end())
  2881. {
  2882. error_list_.push_back(std::make_pair(t0,t1));
  2883. }
  2884. return true;
  2885. }
  2886. std::size_t error_count()
  2887. {
  2888. return error_list_.size();
  2889. }
  2890. std::pair<lexer::token,lexer::token> error(const std::size_t index)
  2891. {
  2892. if (index < error_list_.size())
  2893. {
  2894. return error_list_[index];
  2895. }
  2896. else
  2897. {
  2898. static const lexer::token error_token;
  2899. return std::make_pair(error_token,error_token);
  2900. }
  2901. }
  2902. void clear_errors()
  2903. {
  2904. error_list_.clear();
  2905. }
  2906. private:
  2907. void add_invalid(lexer::token::token_type base, lexer::token::token_type t)
  2908. {
  2909. invalid_comb_.insert(std::make_pair(base,t));
  2910. }
  2911. void add_invalid_set1(lexer::token::token_type t)
  2912. {
  2913. add_invalid(t,lexer::token::e_assign);
  2914. add_invalid(t,lexer::token::e_shr );
  2915. add_invalid(t,lexer::token::e_shl );
  2916. add_invalid(t,lexer::token::e_lte );
  2917. add_invalid(t,lexer::token::e_ne );
  2918. add_invalid(t,lexer::token::e_gte );
  2919. add_invalid(t,lexer::token::e_lt );
  2920. add_invalid(t,lexer::token::e_gt );
  2921. add_invalid(t,lexer::token::e_eq );
  2922. add_invalid(t,lexer::token::e_comma );
  2923. add_invalid(t,lexer::token::e_div );
  2924. add_invalid(t,lexer::token::e_mul );
  2925. add_invalid(t,lexer::token::e_mod );
  2926. add_invalid(t,lexer::token::e_pow );
  2927. add_invalid(t,lexer::token::e_colon );
  2928. }
  2929. bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
  2930. {
  2931. if (details::is_right_bracket(static_cast<char>(base)))
  2932. {
  2933. switch (t)
  2934. {
  2935. case lexer::token::e_assign : return (']' != base);
  2936. case lexer::token::e_string : return true;
  2937. default : return false;
  2938. }
  2939. }
  2940. else if (details::is_left_bracket(static_cast<char>(base)))
  2941. {
  2942. if (details::is_right_bracket(static_cast<char>(t)))
  2943. return false;
  2944. else if (details::is_left_bracket(static_cast<char>(t)))
  2945. return false;
  2946. else
  2947. {
  2948. switch (t)
  2949. {
  2950. case lexer::token::e_number : return false;
  2951. case lexer::token::e_symbol : return false;
  2952. case lexer::token::e_string : return false;
  2953. case lexer::token::e_add : return false;
  2954. case lexer::token::e_sub : return false;
  2955. case lexer::token::e_colon : return false;
  2956. case lexer::token::e_ternary : return false;
  2957. default : return true;
  2958. }
  2959. }
  2960. }
  2961. else if (details::is_right_bracket(static_cast<char>(t)))
  2962. {
  2963. switch (base)
  2964. {
  2965. case lexer::token::e_number : return false;
  2966. case lexer::token::e_symbol : return false;
  2967. case lexer::token::e_string : return false;
  2968. case lexer::token::e_eof : return false;
  2969. case lexer::token::e_colon : return false;
  2970. case lexer::token::e_ternary : return false;
  2971. default : return true;
  2972. }
  2973. }
  2974. else if (details::is_left_bracket(static_cast<char>(t)))
  2975. {
  2976. switch (base)
  2977. {
  2978. case lexer::token::e_rbracket : return true;
  2979. case lexer::token::e_rsqrbracket : return true;
  2980. case lexer::token::e_rcrlbracket : return true;
  2981. default : return false;
  2982. }
  2983. }
  2984. return false;
  2985. }
  2986. set_t invalid_comb_;
  2987. std::vector<std::pair<lexer::token,lexer::token> > error_list_;
  2988. };
  2989. struct helper_assembly
  2990. {
  2991. inline bool register_scanner(lexer::token_scanner* scanner)
  2992. {
  2993. if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
  2994. token_scanner_list.end(),
  2995. scanner))
  2996. {
  2997. return false;
  2998. }
  2999. token_scanner_list.push_back(scanner);
  3000. return true;
  3001. }
  3002. inline bool register_modifier(lexer::token_modifier* modifier)
  3003. {
  3004. if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
  3005. token_modifier_list.end(),
  3006. modifier))
  3007. {
  3008. return false;
  3009. }
  3010. token_modifier_list.push_back(modifier);
  3011. return true;
  3012. }
  3013. inline bool register_joiner(lexer::token_joiner* joiner)
  3014. {
  3015. if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
  3016. token_joiner_list.end(),
  3017. joiner))
  3018. {
  3019. return false;
  3020. }
  3021. token_joiner_list.push_back(joiner);
  3022. return true;
  3023. }
  3024. inline bool register_inserter(lexer::token_inserter* inserter)
  3025. {
  3026. if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
  3027. token_inserter_list.end(),
  3028. inserter))
  3029. {
  3030. return false;
  3031. }
  3032. token_inserter_list.push_back(inserter);
  3033. return true;
  3034. }
  3035. inline bool run_modifiers(lexer::generator& g)
  3036. {
  3037. error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
  3038. bool result = true;
  3039. for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
  3040. {
  3041. lexer::token_modifier& modifier = (*token_modifier_list[i]);
  3042. modifier.reset();
  3043. modifier.process(g);
  3044. if (!modifier.result())
  3045. {
  3046. error_token_modifier = token_modifier_list[i];
  3047. return false;
  3048. }
  3049. }
  3050. return result;
  3051. }
  3052. inline bool run_joiners(lexer::generator& g)
  3053. {
  3054. error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
  3055. bool result = true;
  3056. for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
  3057. {
  3058. lexer::token_joiner& joiner = (*token_joiner_list[i]);
  3059. joiner.reset();
  3060. joiner.process(g);
  3061. if (!joiner.result())
  3062. {
  3063. error_token_joiner = token_joiner_list[i];
  3064. return false;
  3065. }
  3066. }
  3067. return result;
  3068. }
  3069. inline bool run_inserters(lexer::generator& g)
  3070. {
  3071. error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
  3072. bool result = true;
  3073. for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
  3074. {
  3075. lexer::token_inserter& inserter = (*token_inserter_list[i]);
  3076. inserter.reset();
  3077. inserter.process(g);
  3078. if (!inserter.result())
  3079. {
  3080. error_token_inserter = token_inserter_list[i];
  3081. return false;
  3082. }
  3083. }
  3084. return result;
  3085. }
  3086. inline bool run_scanners(lexer::generator& g)
  3087. {
  3088. error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
  3089. bool result = true;
  3090. for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
  3091. {
  3092. lexer::token_scanner& scanner = (*token_scanner_list[i]);
  3093. scanner.reset();
  3094. scanner.process(g);
  3095. if (!scanner.result())
  3096. {
  3097. error_token_scanner = token_scanner_list[i];
  3098. return false;
  3099. }
  3100. }
  3101. return result;
  3102. }
  3103. std::vector<lexer::token_scanner*> token_scanner_list;
  3104. std::vector<lexer::token_modifier*> token_modifier_list;
  3105. std::vector<lexer::token_joiner*> token_joiner_list;
  3106. std::vector<lexer::token_inserter*> token_inserter_list;
  3107. lexer::token_scanner* error_token_scanner;
  3108. lexer::token_modifier* error_token_modifier;
  3109. lexer::token_joiner* error_token_joiner;
  3110. lexer::token_inserter* error_token_inserter;
  3111. };
  3112. }
  3113. class parser_helper
  3114. {
  3115. public:
  3116. typedef token token_t;
  3117. typedef generator generator_t;
  3118. inline bool init(const std::string& str)
  3119. {
  3120. if (!lexer_.process(str))
  3121. {
  3122. return false;
  3123. }
  3124. lexer_.begin();
  3125. next_token();
  3126. return true;
  3127. }
  3128. inline generator_t& lexer()
  3129. {
  3130. return lexer_;
  3131. }
  3132. inline const generator_t& lexer() const
  3133. {
  3134. return lexer_;
  3135. }
  3136. inline void store_token()
  3137. {
  3138. lexer_.store();
  3139. store_current_token_ = current_token_;
  3140. }
  3141. inline void restore_token()
  3142. {
  3143. lexer_.restore();
  3144. current_token_ = store_current_token_;
  3145. }
  3146. inline void next_token()
  3147. {
  3148. current_token_ = lexer_.next_token();
  3149. }
  3150. inline const token_t& current_token() const
  3151. {
  3152. return current_token_;
  3153. }
  3154. inline bool token_is(const token_t::token_type& ttype, const bool advance_token = true)
  3155. {
  3156. if (current_token().type != ttype)
  3157. {
  3158. return false;
  3159. }
  3160. if (advance_token)
  3161. {
  3162. next_token();
  3163. }
  3164. return true;
  3165. }
  3166. inline bool token_is(const token_t::token_type& ttype,
  3167. const std::string& value,
  3168. const bool advance_token = true)
  3169. {
  3170. if (
  3171. (current_token().type != ttype) ||
  3172. !exprtk::details::imatch(value,current_token().value)
  3173. )
  3174. {
  3175. return false;
  3176. }
  3177. if (advance_token)
  3178. {
  3179. next_token();
  3180. }
  3181. return true;
  3182. }
  3183. inline bool token_is_then_assign(const token_t::token_type& ttype,
  3184. std::string& token,
  3185. const bool advance_token = true)
  3186. {
  3187. if (current_token_.type != ttype)
  3188. {
  3189. return false;
  3190. }
  3191. token = current_token_.value;
  3192. if (advance_token)
  3193. {
  3194. next_token();
  3195. }
  3196. return true;
  3197. }
  3198. template <typename Allocator,
  3199. template <typename,typename> class Container>
  3200. inline bool token_is_then_assign(const token_t::token_type& ttype,
  3201. Container<std::string,Allocator>& token_list,
  3202. const bool advance_token = true)
  3203. {
  3204. if (current_token_.type != ttype)
  3205. {
  3206. return false;
  3207. }
  3208. token_list.push_back(current_token_.value);
  3209. if (advance_token)
  3210. {
  3211. next_token();
  3212. }
  3213. return true;
  3214. }
  3215. inline bool peek_token_is(const token_t::token_type& ttype)
  3216. {
  3217. return (lexer_.peek_next_token().type == ttype);
  3218. }
  3219. inline bool peek_token_is(const std::string& s)
  3220. {
  3221. return (exprtk::details::imatch(lexer_.peek_next_token().value,s));
  3222. }
  3223. private:
  3224. generator_t lexer_;
  3225. token_t current_token_;
  3226. token_t store_current_token_;
  3227. };
  3228. }
  3229. template <typename T> class results_context;
  3230. template <typename T>
  3231. struct type_store
  3232. {
  3233. enum store_type
  3234. {
  3235. e_unknown,
  3236. e_scalar,
  3237. e_vector,
  3238. e_string
  3239. };
  3240. type_store()
  3241. : size(0),
  3242. data(0),
  3243. type(e_unknown)
  3244. {}
  3245. std::size_t size;
  3246. void* data;
  3247. store_type type;
  3248. class parameter_list
  3249. {
  3250. public:
  3251. parameter_list(std::vector<type_store>& pl)
  3252. : parameter_list_(pl)
  3253. {}
  3254. inline bool empty() const
  3255. {
  3256. return parameter_list_.empty();
  3257. }
  3258. inline std::size_t size() const
  3259. {
  3260. return parameter_list_.size();
  3261. }
  3262. inline type_store& operator[](const std::size_t& index)
  3263. {
  3264. return parameter_list_[index];
  3265. }
  3266. inline const type_store& operator[](const std::size_t& index) const
  3267. {
  3268. return parameter_list_[index];
  3269. }
  3270. inline type_store& front()
  3271. {
  3272. return parameter_list_[0];
  3273. }
  3274. inline const type_store& front() const
  3275. {
  3276. return parameter_list_[0];
  3277. }
  3278. inline type_store& back()
  3279. {
  3280. return parameter_list_.back();
  3281. }
  3282. inline const type_store& back() const
  3283. {
  3284. return parameter_list_.back();
  3285. }
  3286. private:
  3287. std::vector<type_store>& parameter_list_;
  3288. friend class results_context<T>;
  3289. };
  3290. template <typename ViewType>
  3291. struct type_view
  3292. {
  3293. typedef type_store<T> type_store_t;
  3294. typedef ViewType value_t;
  3295. type_view(type_store_t& ts)
  3296. : ts_(ts),
  3297. data_(reinterpret_cast<value_t*>(ts_.data))
  3298. {}
  3299. inline std::size_t size() const
  3300. {
  3301. return ts_.size;
  3302. }
  3303. inline value_t& operator[](const std::size_t& i)
  3304. {
  3305. return data_[i];
  3306. }
  3307. inline const value_t& operator[](const std::size_t& i) const
  3308. {
  3309. return data_[i];
  3310. }
  3311. inline const value_t* begin() const { return data_; }
  3312. inline value_t* begin() { return data_; }
  3313. inline const value_t* end() const
  3314. {
  3315. return static_cast<value_t*>(data_ + ts_.size);
  3316. }
  3317. inline value_t* end()
  3318. {
  3319. return static_cast<value_t*>(data_ + ts_.size);
  3320. }
  3321. type_store_t& ts_;
  3322. value_t* data_;
  3323. };
  3324. typedef type_view<T> vector_view;
  3325. typedef type_view<char> string_view;
  3326. struct scalar_view
  3327. {
  3328. typedef type_store<T> type_store_t;
  3329. typedef T value_t;
  3330. scalar_view(type_store_t& ts)
  3331. : v_(*reinterpret_cast<value_t*>(ts.data))
  3332. {}
  3333. scalar_view(const type_store_t& ts)
  3334. : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
  3335. {}
  3336. value_t& operator()()
  3337. {
  3338. return v_;
  3339. }
  3340. const value_t& operator()() const
  3341. {
  3342. return v_;
  3343. }
  3344. T& v_;
  3345. };
  3346. };
  3347. template <typename StringView>
  3348. inline std::string to_str(const StringView& view)
  3349. {
  3350. return std::string(view.begin(),view.size());
  3351. }
  3352. namespace details
  3353. {
  3354. template <typename T> class return_node;
  3355. template <typename T> class return_envelope_node;
  3356. }
  3357. template <typename T>
  3358. class results_context
  3359. {
  3360. public:
  3361. typedef type_store<T> type_store_t;
  3362. results_context()
  3363. : results_available_(false)
  3364. {}
  3365. inline std::size_t count() const
  3366. {
  3367. if (results_available_)
  3368. return parameter_list_.size();
  3369. else
  3370. return 0;
  3371. }
  3372. inline type_store_t& operator[](const std::size_t& index)
  3373. {
  3374. return parameter_list_[index];
  3375. }
  3376. inline const type_store_t& operator[](const std::size_t& index) const
  3377. {
  3378. return parameter_list_[index];
  3379. }
  3380. private:
  3381. inline void clear()
  3382. {
  3383. results_available_ = false;
  3384. }
  3385. typedef std::vector<type_store_t> ts_list_t;
  3386. typedef typename type_store_t::parameter_list parameter_list_t;
  3387. inline void assign(const parameter_list_t& pl)
  3388. {
  3389. parameter_list_ = pl.parameter_list_;
  3390. results_available_ = true;
  3391. }
  3392. bool results_available_;
  3393. ts_list_t parameter_list_;
  3394. friend class details::return_node<T>;
  3395. friend class details::return_envelope_node<T>;
  3396. };
  3397. namespace details
  3398. {
  3399. enum operator_type
  3400. {
  3401. e_default , e_null , e_add , e_sub ,
  3402. e_mul , e_div , e_mod , e_pow ,
  3403. e_atan2 , e_min , e_max , e_avg ,
  3404. e_sum , e_prod , e_lt , e_lte ,
  3405. e_eq , e_equal , e_ne , e_nequal ,
  3406. e_gte , e_gt , e_and , e_nand ,
  3407. e_or , e_nor , e_xor , e_xnor ,
  3408. e_mand , e_mor , e_scand , e_scor ,
  3409. e_shr , e_shl , e_abs , e_acos ,
  3410. e_acosh , e_asin , e_asinh , e_atan ,
  3411. e_atanh , e_ceil , e_cos , e_cosh ,
  3412. e_exp , e_expm1 , e_floor , e_log ,
  3413. e_log10 , e_log2 , e_log1p , e_logn ,
  3414. e_neg , e_pos , e_round , e_roundn ,
  3415. e_root , e_sqrt , e_sin , e_sinc ,
  3416. e_sinh , e_sec , e_csc , e_tan ,
  3417. e_tanh , e_cot , e_clamp , e_iclamp ,
  3418. e_inrange , e_sgn , e_r2d , e_d2r ,
  3419. e_d2g , e_g2d , e_hypot , e_notl ,
  3420. e_erf , e_erfc , e_ncdf , e_frac ,
  3421. e_trunc , e_assign , e_addass , e_subass ,
  3422. e_mulass , e_divass , e_modass , e_in ,
  3423. e_like , e_ilike , e_multi , e_swap ,
  3424. // Do not add new functions/operators after this point.
  3425. e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
  3426. e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
  3427. e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
  3428. e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
  3429. e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
  3430. e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
  3431. e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
  3432. e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
  3433. e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
  3434. e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
  3435. e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
  3436. e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
  3437. e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
  3438. e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
  3439. e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
  3440. e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
  3441. e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
  3442. e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
  3443. e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
  3444. e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
  3445. e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083,
  3446. e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087,
  3447. e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091,
  3448. e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095,
  3449. e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099,
  3450. e_sffinal = 1100,
  3451. e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003,
  3452. e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007,
  3453. e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011,
  3454. e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015,
  3455. e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019,
  3456. e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023,
  3457. e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027,
  3458. e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031,
  3459. e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035,
  3460. e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
  3461. e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043,
  3462. e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
  3463. e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
  3464. e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
  3465. e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059
  3466. };
  3467. struct base_operation_t
  3468. {
  3469. base_operation_t(const operator_type t, const unsigned int& np)
  3470. : type(t),
  3471. num_params(np)
  3472. {}
  3473. operator_type type;
  3474. unsigned int num_params;
  3475. };
  3476. namespace numeric
  3477. {
  3478. namespace details
  3479. {
  3480. template <typename T>
  3481. inline T process_impl(const operator_type operation, const T arg)
  3482. {
  3483. switch (operation)
  3484. {
  3485. case e_abs : return numeric::abs (arg);
  3486. case e_acos : return numeric::acos (arg);
  3487. case e_acosh : return numeric::acosh(arg);
  3488. case e_asin : return numeric::asin (arg);
  3489. case e_asinh : return numeric::asinh(arg);
  3490. case e_atan : return numeric::atan (arg);
  3491. case e_atanh : return numeric::atanh(arg);
  3492. case e_ceil : return numeric::ceil (arg);
  3493. case e_cos : return numeric::cos (arg);
  3494. case e_cosh : return numeric::cosh (arg);
  3495. case e_exp : return numeric::exp (arg);
  3496. case e_expm1 : return numeric::expm1(arg);
  3497. case e_floor : return numeric::floor(arg);
  3498. case e_log : return numeric::log (arg);
  3499. case e_log10 : return numeric::log10(arg);
  3500. case e_log2 : return numeric::log2 (arg);
  3501. case e_log1p : return numeric::log1p(arg);
  3502. case e_neg : return numeric::neg (arg);
  3503. case e_pos : return numeric::pos (arg);
  3504. case e_round : return numeric::round(arg);
  3505. case e_sin : return numeric::sin (arg);
  3506. case e_sinc : return numeric::sinc (arg);
  3507. case e_sinh : return numeric::sinh (arg);
  3508. case e_sqrt : return numeric::sqrt (arg);
  3509. case e_tan : return numeric::tan (arg);
  3510. case e_tanh : return numeric::tanh (arg);
  3511. case e_cot : return numeric::cot (arg);
  3512. case e_sec : return numeric::sec (arg);
  3513. case e_csc : return numeric::csc (arg);
  3514. case e_r2d : return numeric::r2d (arg);
  3515. case e_d2r : return numeric::d2r (arg);
  3516. case e_d2g : return numeric::d2g (arg);
  3517. case e_g2d : return numeric::g2d (arg);
  3518. case e_notl : return numeric::notl (arg);
  3519. case e_sgn : return numeric::sgn (arg);
  3520. case e_erf : return numeric::erf (arg);
  3521. case e_erfc : return numeric::erfc (arg);
  3522. case e_ncdf : return numeric::ncdf (arg);
  3523. case e_frac : return numeric::frac (arg);
  3524. case e_trunc : return numeric::trunc(arg);
  3525. default : return std::numeric_limits<T>::quiet_NaN();
  3526. }
  3527. }
  3528. template <typename T>
  3529. inline T process_impl(const operator_type operation, const T arg0, const T arg1)
  3530. {
  3531. switch (operation)
  3532. {
  3533. case e_add : return (arg0 + arg1);
  3534. case e_sub : return (arg0 - arg1);
  3535. case e_mul : return (arg0 * arg1);
  3536. case e_div : return (arg0 / arg1);
  3537. case e_mod : return modulus<T>(arg0,arg1);
  3538. case e_pow : return pow<T>(arg0,arg1);
  3539. case e_atan2 : return atan2<T>(arg0,arg1);
  3540. case e_min : return std::min<T>(arg0,arg1);
  3541. case e_max : return std::max<T>(arg0,arg1);
  3542. case e_logn : return logn<T>(arg0,arg1);
  3543. case e_lt : return (arg0 < arg1) ? T(1) : T(0);
  3544. case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
  3545. case e_eq : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0);
  3546. case e_ne : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0);
  3547. case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
  3548. case e_gt : return (arg0 > arg1) ? T(1) : T(0);
  3549. case e_and : return and_opr<T> (arg0,arg1);
  3550. case e_nand : return nand_opr<T>(arg0,arg1);
  3551. case e_or : return or_opr<T> (arg0,arg1);
  3552. case e_nor : return nor_opr<T> (arg0,arg1);
  3553. case e_xor : return xor_opr<T> (arg0,arg1);
  3554. case e_xnor : return xnor_opr<T>(arg0,arg1);
  3555. case e_root : return root<T> (arg0,arg1);
  3556. case e_roundn : return roundn<T> (arg0,arg1);
  3557. case e_equal : return equal<T> (arg0,arg1);
  3558. case e_nequal : return nequal<T> (arg0,arg1);
  3559. case e_hypot : return hypot<T> (arg0,arg1);
  3560. case e_shr : return shr<T> (arg0,arg1);
  3561. case e_shl : return shl<T> (arg0,arg1);
  3562. default : return std::numeric_limits<T>::quiet_NaN();
  3563. }
  3564. }
  3565. template <typename T>
  3566. inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
  3567. {
  3568. switch (operation)
  3569. {
  3570. case e_add : return (arg0 + arg1);
  3571. case e_sub : return (arg0 - arg1);
  3572. case e_mul : return (arg0 * arg1);
  3573. case e_div : return (arg0 / arg1);
  3574. case e_mod : return arg0 % arg1;
  3575. case e_pow : return pow<T>(arg0,arg1);
  3576. case e_min : return std::min<T>(arg0,arg1);
  3577. case e_max : return std::max<T>(arg0,arg1);
  3578. case e_logn : return logn<T>(arg0,arg1);
  3579. case e_lt : return (arg0 < arg1) ? T(1) : T(0);
  3580. case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
  3581. case e_eq : return (arg0 == arg1) ? T(1) : T(0);
  3582. case e_ne : return (arg0 != arg1) ? T(1) : T(0);
  3583. case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
  3584. case e_gt : return (arg0 > arg1) ? T(1) : T(0);
  3585. case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
  3586. case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
  3587. case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
  3588. case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
  3589. case e_xor : return arg0 ^ arg1;
  3590. case e_xnor : return !(arg0 ^ arg1);
  3591. case e_root : return root<T>(arg0,arg1);
  3592. case e_equal : return arg0 == arg1;
  3593. case e_nequal : return arg0 != arg1;
  3594. case e_hypot : return hypot<T>(arg0,arg1);
  3595. case e_shr : return arg0 >> arg1;
  3596. case e_shl : return arg0 << arg1;
  3597. default : return std::numeric_limits<T>::quiet_NaN();
  3598. }
  3599. }
  3600. }
  3601. template <typename T>
  3602. inline T process(const operator_type operation, const T arg)
  3603. {
  3604. return exprtk::details::numeric::details::process_impl(operation,arg);
  3605. }
  3606. template <typename T>
  3607. inline T process(const operator_type operation, const T arg0, const T arg1)
  3608. {
  3609. return exprtk::details::numeric::details::process_impl(operation,arg0,arg1);
  3610. }
  3611. }
  3612. template <typename T>
  3613. class expression_node
  3614. {
  3615. public:
  3616. enum node_type
  3617. {
  3618. e_none , e_null , e_constant , e_unary ,
  3619. e_binary , e_binary_ext , e_trinary , e_quaternary ,
  3620. e_vararg , e_conditional , e_while , e_repeat ,
  3621. e_for , e_switch , e_mswitch , e_return ,
  3622. e_retenv , e_variable , e_stringvar , e_stringconst ,
  3623. e_stringvarrng , e_cstringvarrng, e_strgenrange , e_strconcat ,
  3624. e_stringvarsize, e_strswap , e_stringsize , e_function ,
  3625. e_vafunction , e_genfunction , e_strfunction , e_strcondition ,
  3626. e_strccondition, e_add , e_sub , e_mul ,
  3627. e_div , e_mod , e_pow , e_lt ,
  3628. e_lte , e_gt , e_gte , e_eq ,
  3629. e_ne , e_and , e_nand , e_or ,
  3630. e_nor , e_xor , e_xnor , e_in ,
  3631. e_like , e_ilike , e_inranges , e_ipow ,
  3632. e_ipowinv , e_abs , e_acos , e_acosh ,
  3633. e_asin , e_asinh , e_atan , e_atanh ,
  3634. e_ceil , e_cos , e_cosh , e_exp ,
  3635. e_expm1 , e_floor , e_log , e_log10 ,
  3636. e_log2 , e_log1p , e_neg , e_pos ,
  3637. e_round , e_sin , e_sinc , e_sinh ,
  3638. e_sqrt , e_tan , e_tanh , e_cot ,
  3639. e_sec , e_csc , e_r2d , e_d2r ,
  3640. e_d2g , e_g2d , e_notl , e_sgn ,
  3641. e_erf , e_erfc , e_ncdf , e_frac ,
  3642. e_trunc , e_uvouv , e_vov , e_cov ,
  3643. e_voc , e_vob , e_bov , e_cob ,
  3644. e_boc , e_vovov , e_vovoc , e_vocov ,
  3645. e_covov , e_covoc , e_vovovov , e_vovovoc ,
  3646. e_vovocov , e_vocovov , e_covovov , e_covocov ,
  3647. e_vocovoc , e_covovoc , e_vococov , e_sf3ext ,
  3648. e_sf4ext , e_nulleq , e_strass , e_vector ,
  3649. e_vecelem , e_vecdefass , e_vecvalass , e_vecvecass ,
  3650. e_vecopvalass , e_vecopvecass , e_vecfunc , e_vecvecswap ,
  3651. e_vecvecineq , e_vecvalineq , e_valvecineq , e_vecvecarith ,
  3652. e_vecvalarith , e_valvecarith , e_vecunaryop , e_break ,
  3653. e_continue , e_swap
  3654. };
  3655. typedef T value_type;
  3656. typedef expression_node<T>* expression_ptr;
  3657. virtual ~expression_node()
  3658. {}
  3659. inline virtual T value() const
  3660. {
  3661. return std::numeric_limits<T>::quiet_NaN();
  3662. }
  3663. inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
  3664. {
  3665. return reinterpret_cast<expression_ptr>(index * 0);
  3666. }
  3667. inline virtual node_type type() const
  3668. {
  3669. return e_none;
  3670. }
  3671. };
  3672. template <typename T>
  3673. inline bool is_generally_string_node(const expression_node<T>* node);
  3674. inline bool is_true(const double v)
  3675. {
  3676. return std::not_equal_to<double>()(0.0,v);
  3677. }
  3678. inline bool is_true(const long double v)
  3679. {
  3680. return std::not_equal_to<long double>()(0.0L,v);
  3681. }
  3682. inline bool is_true(const float v)
  3683. {
  3684. return std::not_equal_to<float>()(0.0f,v);
  3685. }
  3686. template <typename T>
  3687. inline bool is_true(const std::complex<T>& v)
  3688. {
  3689. return std::not_equal_to<std::complex<T> >()(std::complex<T>(0),v);
  3690. }
  3691. template <typename T>
  3692. inline bool is_true(const expression_node<T>* node)
  3693. {
  3694. return std::not_equal_to<T>()(T(0),node->value());
  3695. }
  3696. template <typename T>
  3697. inline bool is_false(const expression_node<T>* node)
  3698. {
  3699. return std::equal_to<T>()(T(0),node->value());
  3700. }
  3701. template <typename T>
  3702. inline bool is_unary_node(const expression_node<T>* node)
  3703. {
  3704. return node && (details::expression_node<T>::e_unary == node->type());
  3705. }
  3706. template <typename T>
  3707. inline bool is_neg_unary_node(const expression_node<T>* node)
  3708. {
  3709. return node && (details::expression_node<T>::e_neg == node->type());
  3710. }
  3711. template <typename T>
  3712. inline bool is_binary_node(const expression_node<T>* node)
  3713. {
  3714. return node && (details::expression_node<T>::e_binary == node->type());
  3715. }
  3716. template <typename T>
  3717. inline bool is_variable_node(const expression_node<T>* node)
  3718. {
  3719. return node && (details::expression_node<T>::e_variable == node->type());
  3720. }
  3721. template <typename T>
  3722. inline bool is_ivariable_node(const expression_node<T>* node)
  3723. {
  3724. return node &&
  3725. (
  3726. details::expression_node<T>::e_variable == node->type() ||
  3727. details::expression_node<T>::e_vecelem == node->type()
  3728. );
  3729. }
  3730. template <typename T>
  3731. inline bool is_vector_elem_node(const expression_node<T>* node)
  3732. {
  3733. return node && (details::expression_node<T>::e_vecelem == node->type());
  3734. }
  3735. template <typename T>
  3736. inline bool is_vector_node(const expression_node<T>* node)
  3737. {
  3738. return node && (details::expression_node<T>::e_vector == node->type());
  3739. }
  3740. template <typename T>
  3741. inline bool is_ivector_node(const expression_node<T>* node)
  3742. {
  3743. if (node)
  3744. {
  3745. switch (node->type())
  3746. {
  3747. case details::expression_node<T>::e_vector :
  3748. case details::expression_node<T>::e_vecvalass :
  3749. case details::expression_node<T>::e_vecvecass :
  3750. case details::expression_node<T>::e_vecopvalass :
  3751. case details::expression_node<T>::e_vecopvecass :
  3752. case details::expression_node<T>::e_vecvecswap :
  3753. case details::expression_node<T>::e_vecvecarith :
  3754. case details::expression_node<T>::e_vecvalarith :
  3755. case details::expression_node<T>::e_valvecarith :
  3756. case details::expression_node<T>::e_vecunaryop : return true;
  3757. default : return false;
  3758. }
  3759. }
  3760. else
  3761. return false;
  3762. }
  3763. template <typename T>
  3764. inline bool is_constant_node(const expression_node<T>* node)
  3765. {
  3766. return node && (details::expression_node<T>::e_constant == node->type());
  3767. }
  3768. template <typename T>
  3769. inline bool is_null_node(const expression_node<T>* node)
  3770. {
  3771. return node && (details::expression_node<T>::e_null == node->type());
  3772. }
  3773. template <typename T>
  3774. inline bool is_break_node(const expression_node<T>* node)
  3775. {
  3776. return node && (details::expression_node<T>::e_break == node->type());
  3777. }
  3778. template <typename T>
  3779. inline bool is_continue_node(const expression_node<T>* node)
  3780. {
  3781. return node && (details::expression_node<T>::e_continue == node->type());
  3782. }
  3783. template <typename T>
  3784. inline bool is_swap_node(const expression_node<T>* node)
  3785. {
  3786. return node && (details::expression_node<T>::e_swap == node->type());
  3787. }
  3788. template <typename T>
  3789. inline bool is_function(const expression_node<T>* node)
  3790. {
  3791. return node && (details::expression_node<T>::e_function == node->type());
  3792. }
  3793. template <typename T>
  3794. inline bool is_return_node(const expression_node<T>* node)
  3795. {
  3796. return node && (details::expression_node<T>::e_return == node->type());
  3797. }
  3798. template <typename T> class unary_node;
  3799. template <typename T>
  3800. inline bool is_negate_node(const expression_node<T>* node)
  3801. {
  3802. if (node && is_unary_node(node))
  3803. {
  3804. return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
  3805. }
  3806. else
  3807. return false;
  3808. }
  3809. template <typename T>
  3810. inline bool branch_deletable(expression_node<T>* node)
  3811. {
  3812. return !is_variable_node(node) &&
  3813. !is_string_node (node) ;
  3814. }
  3815. template <std::size_t N, typename T>
  3816. inline bool all_nodes_valid(expression_node<T>* (&b)[N])
  3817. {
  3818. for (std::size_t i = 0; i < N; ++i)
  3819. {
  3820. if (0 == b[i]) return false;
  3821. }
  3822. return true;
  3823. }
  3824. template <typename T,
  3825. typename Allocator,
  3826. template <typename,typename> class Sequence>
  3827. inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b)
  3828. {
  3829. for (std::size_t i = 0; i < b.size(); ++i)
  3830. {
  3831. if (0 == b[i]) return false;
  3832. }
  3833. return true;
  3834. }
  3835. template <std::size_t N, typename T>
  3836. inline bool all_nodes_variables(expression_node<T>* (&b)[N])
  3837. {
  3838. for (std::size_t i = 0; i < N; ++i)
  3839. {
  3840. if (0 == b[i])
  3841. return false;
  3842. else if (!is_variable_node(b[i]))
  3843. return false;
  3844. }
  3845. return true;
  3846. }
  3847. template <typename T,
  3848. typename Allocator,
  3849. template <typename,typename> class Sequence>
  3850. inline bool all_nodes_variables(Sequence<expression_node<T>*,Allocator>& b)
  3851. {
  3852. for (std::size_t i = 0; i < b.size(); ++i)
  3853. {
  3854. if (0 == b[i])
  3855. return false;
  3856. else if (!is_variable_node(b[i]))
  3857. return false;
  3858. }
  3859. return true;
  3860. }
  3861. template <typename NodeAllocator, typename T, std::size_t N>
  3862. inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N])
  3863. {
  3864. for (std::size_t i = 0; i < N; ++i)
  3865. {
  3866. free_node(node_allocator,b[i]);
  3867. }
  3868. }
  3869. template <typename NodeAllocator,
  3870. typename T,
  3871. typename Allocator,
  3872. template <typename,typename> class Sequence>
  3873. inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b)
  3874. {
  3875. for (std::size_t i = 0; i < b.size(); ++i)
  3876. {
  3877. free_node(node_allocator,b[i]);
  3878. }
  3879. b.clear();
  3880. }
  3881. template <typename NodeAllocator, typename T>
  3882. inline void free_node(NodeAllocator& node_allocator, expression_node<T>*& node, const bool force_delete = false)
  3883. {
  3884. if (0 != node)
  3885. {
  3886. if (
  3887. (is_variable_node(node) || is_string_node(node)) ||
  3888. force_delete
  3889. )
  3890. return;
  3891. node_allocator.free(node);
  3892. node = 0;
  3893. }
  3894. }
  3895. template <typename Type>
  3896. class vector_holder
  3897. {
  3898. private:
  3899. typedef Type value_type;
  3900. typedef value_type* value_ptr;
  3901. typedef const value_ptr const_value_ptr;
  3902. class vector_holder_base
  3903. {
  3904. public:
  3905. virtual ~vector_holder_base(){}
  3906. inline value_ptr operator[](const std::size_t& index) const
  3907. {
  3908. return value_at(index);
  3909. }
  3910. inline std::size_t size() const
  3911. {
  3912. return vector_size();
  3913. }
  3914. protected:
  3915. virtual value_ptr value_at(const std::size_t&) const = 0;
  3916. virtual std::size_t vector_size() const = 0;
  3917. };
  3918. class array_vector_impl : public vector_holder_base
  3919. {
  3920. public:
  3921. array_vector_impl(const Type* vec, const std::size_t& vec_size)
  3922. : vec_(vec),
  3923. size_(vec_size)
  3924. {}
  3925. protected:
  3926. value_ptr value_at(const std::size_t& index) const
  3927. {
  3928. if (index < size_)
  3929. return const_cast<const_value_ptr>(vec_ + index);
  3930. else
  3931. return const_value_ptr(0);
  3932. }
  3933. std::size_t vector_size() const
  3934. {
  3935. return size_;
  3936. }
  3937. private:
  3938. array_vector_impl operator=(const array_vector_impl&);
  3939. const Type* vec_;
  3940. const std::size_t size_;
  3941. };
  3942. template <typename Allocator,
  3943. template <typename,typename> class Sequence>
  3944. class sequence_vector_impl : public vector_holder_base
  3945. {
  3946. public:
  3947. typedef Sequence<Type,Allocator> sequence_t;
  3948. sequence_vector_impl(sequence_t& seq)
  3949. : sequence_(seq)
  3950. {}
  3951. protected:
  3952. value_ptr value_at(const std::size_t& index) const
  3953. {
  3954. return (index < sequence_.size()) ? (&sequence_[index]) : const_value_ptr(0);
  3955. }
  3956. std::size_t vector_size() const
  3957. {
  3958. return sequence_.size();
  3959. }
  3960. private:
  3961. sequence_vector_impl operator=(const sequence_vector_impl&);
  3962. sequence_t& sequence_;
  3963. };
  3964. public:
  3965. vector_holder(Type* vec, const std::size_t& vec_size)
  3966. : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
  3967. {}
  3968. template <typename Allocator>
  3969. vector_holder(std::vector<Type,Allocator>& vec)
  3970. : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
  3971. {}
  3972. template <typename Allocator>
  3973. vector_holder(std::deque<Type,Allocator>& deq)
  3974. : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::deque>(deq))
  3975. {}
  3976. inline value_ptr operator[](const std::size_t& index) const
  3977. {
  3978. return (*vector_holder_base_)[index];
  3979. }
  3980. inline std::size_t size() const
  3981. {
  3982. return vector_holder_base_->size();
  3983. }
  3984. private:
  3985. mutable vector_holder_base* vector_holder_base_;
  3986. unsigned char buffer[64];
  3987. };
  3988. template <typename T>
  3989. class null_node : public expression_node<T>
  3990. {
  3991. public:
  3992. inline T value() const
  3993. {
  3994. return std::numeric_limits<T>::quiet_NaN();
  3995. }
  3996. inline typename expression_node<T>::node_type type() const
  3997. {
  3998. return expression_node<T>::e_null;
  3999. }
  4000. };
  4001. template <typename T>
  4002. class null_eq_node : public expression_node<T>
  4003. {
  4004. public:
  4005. typedef expression_node<T>* expression_ptr;
  4006. null_eq_node(expression_ptr brnch, const bool equality = true)
  4007. : branch_(brnch),
  4008. branch_deletable_(branch_deletable(branch_)),
  4009. equality_(equality)
  4010. {}
  4011. ~null_eq_node()
  4012. {
  4013. if (branch_ && branch_deletable_)
  4014. {
  4015. delete branch_;
  4016. branch_ = 0;
  4017. }
  4018. }
  4019. inline T value() const
  4020. {
  4021. const T v = branch_->value();
  4022. const bool result = details::numeric::is_nan(v);
  4023. if (result)
  4024. return (equality_) ? T(1) : T(0);
  4025. else
  4026. return (equality_) ? T(0) : T(1);
  4027. }
  4028. inline typename expression_node<T>::node_type type() const
  4029. {
  4030. return expression_node<T>::e_nulleq;
  4031. }
  4032. inline operator_type operation() const
  4033. {
  4034. return details::e_eq;
  4035. }
  4036. inline expression_node<T>* branch(const std::size_t&) const
  4037. {
  4038. return branch_;
  4039. }
  4040. private:
  4041. expression_ptr branch_;
  4042. bool branch_deletable_;
  4043. bool equality_;
  4044. };
  4045. template <typename T>
  4046. class literal_node : public expression_node<T>
  4047. {
  4048. public:
  4049. explicit literal_node(const T& v)
  4050. : value_(v)
  4051. {}
  4052. inline T value() const
  4053. {
  4054. return value_;
  4055. }
  4056. inline typename expression_node<T>::node_type type() const
  4057. {
  4058. return expression_node<T>::e_constant;
  4059. }
  4060. inline expression_node<T>* branch(const std::size_t&) const
  4061. {
  4062. return reinterpret_cast<expression_node<T>*>(0);
  4063. }
  4064. private:
  4065. literal_node(literal_node<T>&) {}
  4066. literal_node<T>& operator=(literal_node<T>&) { return *this; }
  4067. const T value_;
  4068. };
  4069. template <typename T>
  4070. struct range_pack;
  4071. template <typename T>
  4072. struct range_data_type;
  4073. template <typename T>
  4074. class range_interface
  4075. {
  4076. public:
  4077. typedef range_pack<T> range_t;
  4078. virtual range_t& range_ref() = 0;
  4079. virtual const range_t& range_ref() const = 0;
  4080. };
  4081. template <typename T>
  4082. class string_base_node
  4083. {
  4084. public:
  4085. typedef range_data_type<T> range_data_type_t;
  4086. virtual std::string str () const = 0;
  4087. virtual const char* base() const = 0;
  4088. virtual std::size_t size() const = 0;
  4089. };
  4090. template <typename T>
  4091. class string_literal_node : public expression_node <T>,
  4092. public string_base_node<T>,
  4093. public range_interface <T>
  4094. {
  4095. public:
  4096. typedef range_pack<T> range_t;
  4097. explicit string_literal_node(const std::string& v)
  4098. : value_(v)
  4099. {
  4100. rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  4101. rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
  4102. rp_.cache.first = rp_.n0_c.second;
  4103. rp_.cache.second = rp_.n1_c.second;
  4104. }
  4105. inline T value() const
  4106. {
  4107. return std::numeric_limits<T>::quiet_NaN();
  4108. }
  4109. inline typename expression_node<T>::node_type type() const
  4110. {
  4111. return expression_node<T>::e_stringconst;
  4112. }
  4113. inline expression_node<T>* branch(const std::size_t&) const
  4114. {
  4115. return reinterpret_cast<expression_node<T>*>(0);
  4116. }
  4117. std::string str() const
  4118. {
  4119. return value_;
  4120. }
  4121. const char* base() const
  4122. {
  4123. return value_.data();
  4124. }
  4125. std::size_t size() const
  4126. {
  4127. return value_.size();
  4128. }
  4129. range_t& range_ref()
  4130. {
  4131. return rp_;
  4132. }
  4133. const range_t& range_ref() const
  4134. {
  4135. return rp_;
  4136. }
  4137. private:
  4138. string_literal_node(const string_literal_node<T>&);
  4139. string_literal_node<T>& operator=(const string_literal_node<T>&);
  4140. const std::string value_;
  4141. range_t rp_;
  4142. };
  4143. template <typename T>
  4144. class unary_node : public expression_node<T>
  4145. {
  4146. public:
  4147. typedef expression_node<T>* expression_ptr;
  4148. unary_node(const operator_type& opr,
  4149. expression_ptr brnch)
  4150. : operation_(opr),
  4151. branch_(brnch),
  4152. branch_deletable_(branch_deletable(branch_))
  4153. {}
  4154. ~unary_node()
  4155. {
  4156. if (branch_ && branch_deletable_)
  4157. {
  4158. delete branch_;
  4159. branch_ = 0;
  4160. }
  4161. }
  4162. inline T value() const
  4163. {
  4164. const T arg = branch_->value();
  4165. return numeric::process<T>(operation_,arg);
  4166. }
  4167. inline typename expression_node<T>::node_type type() const
  4168. {
  4169. return expression_node<T>::e_unary;
  4170. }
  4171. inline operator_type operation() const
  4172. {
  4173. return operation_;
  4174. }
  4175. inline expression_node<T>* branch(const std::size_t&) const
  4176. {
  4177. return branch_;
  4178. }
  4179. inline void release()
  4180. {
  4181. branch_deletable_ = false;
  4182. }
  4183. protected:
  4184. operator_type operation_;
  4185. expression_ptr branch_;
  4186. bool branch_deletable_;
  4187. };
  4188. template <typename T, std::size_t D, bool B>
  4189. struct construct_branch_pair
  4190. {
  4191. template <std::size_t N>
  4192. static inline void process(std::pair<expression_node<T>*,bool> (&)[N], expression_node<T>*)
  4193. {}
  4194. };
  4195. template <typename T, std::size_t D>
  4196. struct construct_branch_pair<T,D,true>
  4197. {
  4198. template <std::size_t N>
  4199. static inline void process(std::pair<expression_node<T>*,bool> (&branch)[N], expression_node<T>* b)
  4200. {
  4201. if (b)
  4202. {
  4203. branch[D] = std::make_pair(b,branch_deletable(b));
  4204. }
  4205. }
  4206. };
  4207. template <std::size_t N, typename T>
  4208. inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
  4209. expression_node<T>* b0,
  4210. expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
  4211. expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
  4212. expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
  4213. expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
  4214. expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
  4215. expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
  4216. expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
  4217. expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
  4218. expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
  4219. {
  4220. construct_branch_pair<T,0,(N > 0)>::process(branch,b0);
  4221. construct_branch_pair<T,1,(N > 1)>::process(branch,b1);
  4222. construct_branch_pair<T,2,(N > 2)>::process(branch,b2);
  4223. construct_branch_pair<T,3,(N > 3)>::process(branch,b3);
  4224. construct_branch_pair<T,4,(N > 4)>::process(branch,b4);
  4225. construct_branch_pair<T,5,(N > 5)>::process(branch,b5);
  4226. construct_branch_pair<T,6,(N > 6)>::process(branch,b6);
  4227. construct_branch_pair<T,7,(N > 7)>::process(branch,b7);
  4228. construct_branch_pair<T,8,(N > 8)>::process(branch,b8);
  4229. construct_branch_pair<T,9,(N > 9)>::process(branch,b9);
  4230. }
  4231. struct cleanup_branches
  4232. {
  4233. template <typename T, std::size_t N>
  4234. static inline void execute(std::pair<expression_node<T>*,bool> (&branch)[N])
  4235. {
  4236. for (std::size_t i = 0; i < N; ++i)
  4237. {
  4238. if (branch[i].first && branch[i].second)
  4239. {
  4240. delete branch[i].first;
  4241. branch[i].first = 0;
  4242. }
  4243. }
  4244. }
  4245. template <typename T,
  4246. typename Allocator,
  4247. template <typename,typename> class Sequence>
  4248. static inline void execute(Sequence<std::pair<expression_node<T>*,bool>,Allocator>& branch)
  4249. {
  4250. for (std::size_t i = 0; i < branch.size(); ++i)
  4251. {
  4252. if (branch[i].first && branch[i].second)
  4253. {
  4254. delete branch[i].first;
  4255. branch[i].first = 0;
  4256. }
  4257. }
  4258. }
  4259. };
  4260. template <typename T>
  4261. class binary_node : public expression_node<T>
  4262. {
  4263. public:
  4264. typedef expression_node<T>* expression_ptr;
  4265. typedef std::pair<expression_ptr,bool> branch_t;
  4266. binary_node(const operator_type& opr,
  4267. expression_ptr branch0,
  4268. expression_ptr branch1)
  4269. : operation_(opr)
  4270. {
  4271. init_branches<2>(branch_,branch0,branch1);
  4272. }
  4273. ~binary_node()
  4274. {
  4275. cleanup_branches::execute<T,2>(branch_);
  4276. }
  4277. inline T value() const
  4278. {
  4279. const T arg0 = branch_[0].first->value();
  4280. const T arg1 = branch_[1].first->value();
  4281. return numeric::process<T>(operation_,arg0,arg1);
  4282. }
  4283. inline typename expression_node<T>::node_type type() const
  4284. {
  4285. return expression_node<T>::e_binary;
  4286. }
  4287. inline operator_type operation()
  4288. {
  4289. return operation_;
  4290. }
  4291. inline expression_node<T>* branch(const std::size_t& index = 0) const
  4292. {
  4293. if (0 == index)
  4294. return branch_[0].first;
  4295. else if (1 == index)
  4296. return branch_[1].first;
  4297. else
  4298. return reinterpret_cast<expression_ptr>(0);
  4299. }
  4300. protected:
  4301. operator_type operation_;
  4302. branch_t branch_[2];
  4303. };
  4304. template <typename T, typename Operation>
  4305. class binary_ext_node : public expression_node<T>
  4306. {
  4307. public:
  4308. typedef expression_node<T>* expression_ptr;
  4309. typedef std::pair<expression_ptr,bool> branch_t;
  4310. binary_ext_node(expression_ptr branch0, expression_ptr branch1)
  4311. {
  4312. init_branches<2>(branch_,branch0,branch1);
  4313. }
  4314. ~binary_ext_node()
  4315. {
  4316. cleanup_branches::execute<T,2>(branch_);
  4317. }
  4318. inline T value() const
  4319. {
  4320. const T arg0 = branch_[0].first->value();
  4321. const T arg1 = branch_[1].first->value();
  4322. return Operation::process(arg0,arg1);
  4323. }
  4324. inline typename expression_node<T>::node_type type() const
  4325. {
  4326. return expression_node<T>::e_binary_ext;
  4327. }
  4328. inline operator_type operation()
  4329. {
  4330. return Operation::operation();
  4331. }
  4332. inline expression_node<T>* branch(const std::size_t& index = 0) const
  4333. {
  4334. if (0 == index)
  4335. return branch_[0].first;
  4336. else if (1 == index)
  4337. return branch_[1].first;
  4338. else
  4339. return reinterpret_cast<expression_ptr>(0);
  4340. }
  4341. protected:
  4342. branch_t branch_[2];
  4343. };
  4344. template <typename T>
  4345. class trinary_node : public expression_node<T>
  4346. {
  4347. public:
  4348. typedef expression_node<T>* expression_ptr;
  4349. typedef std::pair<expression_ptr,bool> branch_t;
  4350. trinary_node(const operator_type& opr,
  4351. expression_ptr branch0,
  4352. expression_ptr branch1,
  4353. expression_ptr branch2)
  4354. : operation_(opr)
  4355. {
  4356. init_branches<3>(branch_,branch0,branch1,branch2);
  4357. }
  4358. ~trinary_node()
  4359. {
  4360. cleanup_branches::execute<T,3>(branch_);
  4361. }
  4362. inline T value() const
  4363. {
  4364. const T arg0 = branch_[0].first->value();
  4365. const T arg1 = branch_[1].first->value();
  4366. const T arg2 = branch_[2].first->value();
  4367. switch (operation_)
  4368. {
  4369. case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
  4370. case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
  4371. case e_iclamp : if ((arg1 <= arg0) || (arg1 >= arg2))
  4372. return arg1;
  4373. else
  4374. return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2);
  4375. default : return std::numeric_limits<T>::quiet_NaN();
  4376. }
  4377. }
  4378. inline typename expression_node<T>::node_type type() const
  4379. {
  4380. return expression_node<T>::e_trinary;
  4381. }
  4382. protected:
  4383. operator_type operation_;
  4384. branch_t branch_[3];
  4385. };
  4386. template <typename T>
  4387. class quaternary_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. quaternary_node(const operator_type& opr,
  4393. expression_ptr branch0,
  4394. expression_ptr branch1,
  4395. expression_ptr branch2,
  4396. expression_ptr branch3)
  4397. : operation_(opr)
  4398. {
  4399. init_branches<4>(branch_,branch0,branch1,branch2,branch3);
  4400. }
  4401. ~quaternary_node()
  4402. {
  4403. cleanup_branches::execute<T,4>(branch_);
  4404. }
  4405. inline T value() const
  4406. {
  4407. return std::numeric_limits<T>::quiet_NaN();
  4408. }
  4409. inline typename expression_node<T>::node_type type() const
  4410. {
  4411. return expression_node<T>::e_quaternary;
  4412. }
  4413. protected:
  4414. operator_type operation_;
  4415. branch_t branch_[4];
  4416. };
  4417. template <typename T>
  4418. class conditional_node : public expression_node<T>
  4419. {
  4420. public:
  4421. typedef expression_node<T>* expression_ptr;
  4422. conditional_node(expression_ptr test,
  4423. expression_ptr consequent,
  4424. expression_ptr alternative)
  4425. : test_(test),
  4426. consequent_(consequent),
  4427. alternative_(alternative),
  4428. test_deletable_(branch_deletable(test_)),
  4429. consequent_deletable_(branch_deletable(consequent_)),
  4430. alternative_deletable_(branch_deletable(alternative_))
  4431. {}
  4432. ~conditional_node()
  4433. {
  4434. if (test_ && test_deletable_ ) delete test_;
  4435. if (consequent_ && consequent_deletable_ ) delete consequent_;
  4436. if (alternative_ && alternative_deletable_) delete alternative_;
  4437. }
  4438. inline T value() const
  4439. {
  4440. if (is_true(test_))
  4441. return consequent_->value();
  4442. else
  4443. return alternative_->value();
  4444. }
  4445. inline typename expression_node<T>::node_type type() const
  4446. {
  4447. return expression_node<T>::e_conditional;
  4448. }
  4449. private:
  4450. expression_ptr test_;
  4451. expression_ptr consequent_;
  4452. expression_ptr alternative_;
  4453. bool test_deletable_;
  4454. bool consequent_deletable_;
  4455. bool alternative_deletable_;
  4456. };
  4457. template <typename T>
  4458. class cons_conditional_node : public expression_node<T>
  4459. {
  4460. public:
  4461. // Consequent only conditional statement node
  4462. typedef expression_node<T>* expression_ptr;
  4463. cons_conditional_node(expression_ptr test,
  4464. expression_ptr consequent)
  4465. : test_(test),
  4466. consequent_(consequent),
  4467. test_deletable_(branch_deletable(test_)),
  4468. consequent_deletable_(branch_deletable(consequent_))
  4469. {}
  4470. ~cons_conditional_node()
  4471. {
  4472. if (test_ && test_deletable_ ) delete test_;
  4473. if (consequent_ && consequent_deletable_) delete consequent_;
  4474. }
  4475. inline T value() const
  4476. {
  4477. if (is_true(test_))
  4478. return consequent_->value();
  4479. else
  4480. return std::numeric_limits<T>::quiet_NaN();
  4481. }
  4482. inline typename expression_node<T>::node_type type() const
  4483. {
  4484. return expression_node<T>::e_conditional;
  4485. }
  4486. private:
  4487. expression_ptr test_;
  4488. expression_ptr consequent_;
  4489. bool test_deletable_;
  4490. bool consequent_deletable_;
  4491. };
  4492. #ifndef exprtk_disable_break_continue
  4493. template <typename T>
  4494. class break_exception
  4495. {
  4496. public:
  4497. break_exception(const T& v)
  4498. : value(v)
  4499. {}
  4500. T value;
  4501. };
  4502. class continue_exception
  4503. {};
  4504. template <typename T>
  4505. class break_node : public expression_node<T>
  4506. {
  4507. public:
  4508. typedef expression_node<T>* expression_ptr;
  4509. break_node(expression_ptr ret = expression_ptr(0))
  4510. : return_(ret),
  4511. return_deletable_(branch_deletable(return_))
  4512. {}
  4513. ~break_node()
  4514. {
  4515. if (return_deletable_)
  4516. {
  4517. delete return_;
  4518. }
  4519. }
  4520. inline T value() const
  4521. {
  4522. throw break_exception<T>(return_ ? return_->value() : std::numeric_limits<T>::quiet_NaN());
  4523. #ifndef _MSC_VER
  4524. return std::numeric_limits<T>::quiet_NaN();
  4525. #endif
  4526. }
  4527. inline typename expression_node<T>::node_type type() const
  4528. {
  4529. return expression_node<T>::e_break;
  4530. }
  4531. private:
  4532. expression_ptr return_;
  4533. bool return_deletable_;
  4534. };
  4535. template <typename T>
  4536. class continue_node : public expression_node<T>
  4537. {
  4538. public:
  4539. inline T value() const
  4540. {
  4541. throw continue_exception();
  4542. #ifndef _MSC_VER
  4543. return std::numeric_limits<T>::quiet_NaN();
  4544. #endif
  4545. }
  4546. inline typename expression_node<T>::node_type type() const
  4547. {
  4548. return expression_node<T>::e_break;
  4549. }
  4550. };
  4551. #endif
  4552. template <typename T>
  4553. class while_loop_node : public expression_node<T>
  4554. {
  4555. public:
  4556. typedef expression_node<T>* expression_ptr;
  4557. while_loop_node(expression_ptr condition, expression_ptr loop_body)
  4558. : condition_(condition),
  4559. loop_body_(loop_body),
  4560. condition_deletable_(branch_deletable(condition_)),
  4561. loop_body_deletable_(branch_deletable(loop_body_))
  4562. {}
  4563. ~while_loop_node()
  4564. {
  4565. if (condition_ && condition_deletable_)
  4566. {
  4567. delete condition_;
  4568. }
  4569. if (loop_body_ && loop_body_deletable_)
  4570. {
  4571. delete loop_body_;
  4572. }
  4573. }
  4574. inline T value() const
  4575. {
  4576. T result = T(0);
  4577. while (is_true(condition_))
  4578. {
  4579. result = loop_body_->value();
  4580. }
  4581. return result;
  4582. }
  4583. inline typename expression_node<T>::node_type type() const
  4584. {
  4585. return expression_node<T>::e_while;
  4586. }
  4587. private:
  4588. expression_ptr condition_;
  4589. expression_ptr loop_body_;
  4590. bool condition_deletable_;
  4591. bool loop_body_deletable_;
  4592. };
  4593. template <typename T>
  4594. class repeat_until_loop_node : public expression_node<T>
  4595. {
  4596. public:
  4597. typedef expression_node<T>* expression_ptr;
  4598. repeat_until_loop_node(expression_ptr condition, expression_ptr loop_body)
  4599. : condition_(condition),
  4600. loop_body_(loop_body),
  4601. condition_deletable_(branch_deletable(condition_)),
  4602. loop_body_deletable_(branch_deletable(loop_body_))
  4603. {}
  4604. ~repeat_until_loop_node()
  4605. {
  4606. if (condition_ && condition_deletable_)
  4607. {
  4608. delete condition_;
  4609. }
  4610. if (loop_body_ && loop_body_deletable_)
  4611. {
  4612. delete loop_body_;
  4613. }
  4614. }
  4615. inline T value() const
  4616. {
  4617. T result = T(0);
  4618. do
  4619. {
  4620. result = loop_body_->value();
  4621. }
  4622. while (is_false(condition_));
  4623. return result;
  4624. }
  4625. inline typename expression_node<T>::node_type type() const
  4626. {
  4627. return expression_node<T>::e_repeat;
  4628. }
  4629. private:
  4630. expression_ptr condition_;
  4631. expression_ptr loop_body_;
  4632. bool condition_deletable_;
  4633. bool loop_body_deletable_;
  4634. };
  4635. template <typename T>
  4636. class for_loop_node : public expression_node<T>
  4637. {
  4638. public:
  4639. typedef expression_node<T>* expression_ptr;
  4640. for_loop_node(expression_ptr initialiser,
  4641. expression_ptr condition,
  4642. expression_ptr incrementor,
  4643. expression_ptr loop_body)
  4644. : initialiser_(initialiser),
  4645. condition_ (condition),
  4646. incrementor_(incrementor),
  4647. loop_body_ (loop_body),
  4648. initialiser_deletable_(branch_deletable(initialiser_)),
  4649. condition_deletable_ (branch_deletable(condition_ )),
  4650. incrementor_deletable_(branch_deletable(incrementor_)),
  4651. loop_body_deletable_ (branch_deletable(loop_body_ ))
  4652. {}
  4653. ~for_loop_node()
  4654. {
  4655. if (initialiser_ && initialiser_deletable_)
  4656. {
  4657. delete initialiser_;
  4658. }
  4659. if (condition_ && condition_deletable_)
  4660. {
  4661. delete condition_;
  4662. }
  4663. if (incrementor_ && incrementor_deletable_)
  4664. {
  4665. delete incrementor_;
  4666. }
  4667. if (loop_body_ && loop_body_deletable_)
  4668. {
  4669. delete loop_body_;
  4670. }
  4671. }
  4672. inline T value() const
  4673. {
  4674. T result = T(0);
  4675. if (initialiser_)
  4676. initialiser_->value();
  4677. if (incrementor_)
  4678. {
  4679. while (is_true(condition_))
  4680. {
  4681. result = loop_body_->value();
  4682. incrementor_->value();
  4683. }
  4684. }
  4685. else
  4686. {
  4687. while (is_true(condition_))
  4688. {
  4689. result = loop_body_->value();
  4690. }
  4691. }
  4692. return result;
  4693. }
  4694. inline typename expression_node<T>::node_type type() const
  4695. {
  4696. return expression_node<T>::e_for;
  4697. }
  4698. private:
  4699. expression_ptr initialiser_;
  4700. expression_ptr condition_ ;
  4701. expression_ptr incrementor_;
  4702. expression_ptr loop_body_ ;
  4703. bool initialiser_deletable_;
  4704. bool condition_deletable_ ;
  4705. bool incrementor_deletable_;
  4706. bool loop_body_deletable_ ;
  4707. };
  4708. #ifndef exprtk_disable_break_continue
  4709. template <typename T>
  4710. class while_loop_bc_node : public expression_node<T>
  4711. {
  4712. public:
  4713. typedef expression_node<T>* expression_ptr;
  4714. while_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
  4715. : condition_(condition),
  4716. loop_body_(loop_body),
  4717. condition_deletable_(branch_deletable(condition_)),
  4718. loop_body_deletable_(branch_deletable(loop_body_))
  4719. {}
  4720. ~while_loop_bc_node()
  4721. {
  4722. if (condition_ && condition_deletable_)
  4723. {
  4724. delete condition_;
  4725. }
  4726. if (loop_body_ && loop_body_deletable_)
  4727. {
  4728. delete loop_body_;
  4729. }
  4730. }
  4731. inline T value() const
  4732. {
  4733. T result = T(0);
  4734. while (is_true(condition_))
  4735. {
  4736. try
  4737. {
  4738. result = loop_body_->value();
  4739. }
  4740. catch(const break_exception<T>& e)
  4741. {
  4742. return e.value;
  4743. }
  4744. catch(const continue_exception&)
  4745. {}
  4746. }
  4747. return result;
  4748. }
  4749. inline typename expression_node<T>::node_type type() const
  4750. {
  4751. return expression_node<T>::e_while;
  4752. }
  4753. private:
  4754. expression_ptr condition_;
  4755. expression_ptr loop_body_;
  4756. bool condition_deletable_;
  4757. bool loop_body_deletable_;
  4758. };
  4759. template <typename T>
  4760. class repeat_until_loop_bc_node : public expression_node<T>
  4761. {
  4762. public:
  4763. typedef expression_node<T>* expression_ptr;
  4764. repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
  4765. : condition_(condition),
  4766. loop_body_(loop_body),
  4767. condition_deletable_(branch_deletable(condition_)),
  4768. loop_body_deletable_(branch_deletable(loop_body_))
  4769. {}
  4770. ~repeat_until_loop_bc_node()
  4771. {
  4772. if (condition_ && condition_deletable_)
  4773. {
  4774. delete condition_;
  4775. }
  4776. if (loop_body_ && loop_body_deletable_)
  4777. {
  4778. delete loop_body_;
  4779. }
  4780. }
  4781. inline T value() const
  4782. {
  4783. T result = T(0);
  4784. do
  4785. {
  4786. try
  4787. {
  4788. result = loop_body_->value();
  4789. }
  4790. catch(const break_exception<T>& e)
  4791. {
  4792. return e.value;
  4793. }
  4794. catch(const continue_exception&)
  4795. {}
  4796. }
  4797. while (is_false(condition_));
  4798. return result;
  4799. }
  4800. inline typename expression_node<T>::node_type type() const
  4801. {
  4802. return expression_node<T>::e_repeat;
  4803. }
  4804. private:
  4805. expression_ptr condition_;
  4806. expression_ptr loop_body_;
  4807. bool condition_deletable_;
  4808. bool loop_body_deletable_;
  4809. };
  4810. template <typename T>
  4811. class for_loop_bc_node : public expression_node<T>
  4812. {
  4813. public:
  4814. typedef expression_node<T>* expression_ptr;
  4815. for_loop_bc_node(expression_ptr initialiser,
  4816. expression_ptr condition,
  4817. expression_ptr incrementor,
  4818. expression_ptr loop_body)
  4819. : initialiser_(initialiser),
  4820. condition_ (condition ),
  4821. incrementor_(incrementor),
  4822. loop_body_ (loop_body ),
  4823. initialiser_deletable_(branch_deletable(initialiser_)),
  4824. condition_deletable_ (branch_deletable(condition_ )),
  4825. incrementor_deletable_(branch_deletable(incrementor_)),
  4826. loop_body_deletable_ (branch_deletable(loop_body_ ))
  4827. {}
  4828. ~for_loop_bc_node()
  4829. {
  4830. if (initialiser_ && initialiser_deletable_)
  4831. {
  4832. delete initialiser_;
  4833. }
  4834. if (condition_ && condition_deletable_)
  4835. {
  4836. delete condition_;
  4837. }
  4838. if (incrementor_ && incrementor_deletable_)
  4839. {
  4840. delete incrementor_;
  4841. }
  4842. if (loop_body_ && loop_body_deletable_)
  4843. {
  4844. delete loop_body_;
  4845. }
  4846. }
  4847. inline T value() const
  4848. {
  4849. T result = T(0);
  4850. if (initialiser_)
  4851. initialiser_->value();
  4852. if (incrementor_)
  4853. {
  4854. while (is_true(condition_))
  4855. {
  4856. try
  4857. {
  4858. result = loop_body_->value();
  4859. }
  4860. catch(const break_exception<T>& e)
  4861. {
  4862. return e.value;
  4863. }
  4864. catch(const continue_exception&)
  4865. {}
  4866. incrementor_->value();
  4867. }
  4868. }
  4869. else
  4870. {
  4871. while (is_true(condition_))
  4872. {
  4873. try
  4874. {
  4875. result = loop_body_->value();
  4876. }
  4877. catch(const break_exception<T>& e)
  4878. {
  4879. return e.value;
  4880. }
  4881. catch(const continue_exception&)
  4882. {}
  4883. }
  4884. }
  4885. return result;
  4886. }
  4887. inline typename expression_node<T>::node_type type() const
  4888. {
  4889. return expression_node<T>::e_for;
  4890. }
  4891. private:
  4892. expression_ptr initialiser_;
  4893. expression_ptr condition_ ;
  4894. expression_ptr incrementor_;
  4895. expression_ptr loop_body_ ;
  4896. bool initialiser_deletable_;
  4897. bool condition_deletable_ ;
  4898. bool incrementor_deletable_;
  4899. bool loop_body_deletable_ ;
  4900. };
  4901. #endif
  4902. template <typename T>
  4903. class switch_node : public expression_node<T>
  4904. {
  4905. public:
  4906. typedef expression_node<T>* expression_ptr;
  4907. template <typename Allocator,
  4908. template <typename,typename> class Sequence>
  4909. switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
  4910. {
  4911. if (1 != (arg_list.size() & 1))
  4912. return;
  4913. arg_list_.resize(arg_list.size());
  4914. delete_branch_.resize(arg_list.size());
  4915. for (std::size_t i = 0; i < arg_list.size(); ++i)
  4916. {
  4917. if (arg_list[i])
  4918. {
  4919. arg_list_[i] = arg_list[i];
  4920. delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
  4921. }
  4922. else
  4923. {
  4924. arg_list_.clear();
  4925. delete_branch_.clear();
  4926. return;
  4927. }
  4928. }
  4929. }
  4930. ~switch_node()
  4931. {
  4932. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  4933. {
  4934. if (arg_list_[i] && delete_branch_[i])
  4935. {
  4936. delete arg_list_[i];
  4937. arg_list_[i] = 0;
  4938. }
  4939. }
  4940. }
  4941. inline T value() const
  4942. {
  4943. if (!arg_list_.empty())
  4944. {
  4945. const std::size_t upper_bound = (arg_list_.size() - 1);
  4946. for (std::size_t i = 0; i < upper_bound; i += 2)
  4947. {
  4948. expression_ptr condition = arg_list_[i ];
  4949. expression_ptr consequent = arg_list_[i + 1];
  4950. if (is_true(condition))
  4951. {
  4952. return consequent->value();
  4953. }
  4954. }
  4955. return arg_list_[upper_bound]->value();
  4956. }
  4957. else
  4958. return std::numeric_limits<T>::quiet_NaN();
  4959. }
  4960. inline typename expression_node<T>::node_type type() const
  4961. {
  4962. return expression_node<T>::e_switch;
  4963. }
  4964. protected:
  4965. std::vector<expression_ptr> arg_list_;
  4966. std::vector<unsigned char> delete_branch_;
  4967. };
  4968. template <typename T, typename Switch_N>
  4969. class switch_n_node : public switch_node<T>
  4970. {
  4971. public:
  4972. typedef expression_node<T>* expression_ptr;
  4973. template <typename Allocator,
  4974. template <typename,typename> class Sequence>
  4975. switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
  4976. : switch_node<T>(arg_list)
  4977. {}
  4978. inline T value() const
  4979. {
  4980. return Switch_N::process(switch_node<T>::arg_list_);
  4981. }
  4982. };
  4983. template <typename T>
  4984. class multi_switch_node : public expression_node<T>
  4985. {
  4986. public:
  4987. typedef expression_node<T>* expression_ptr;
  4988. template <typename Allocator,
  4989. template <typename,typename> class Sequence>
  4990. multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
  4991. {
  4992. if (0 != (arg_list.size() & 1))
  4993. return;
  4994. arg_list_.resize(arg_list.size());
  4995. delete_branch_.resize(arg_list.size());
  4996. for (std::size_t i = 0; i < arg_list.size(); ++i)
  4997. {
  4998. if (arg_list[i])
  4999. {
  5000. arg_list_[i] = arg_list[i];
  5001. delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
  5002. }
  5003. else
  5004. {
  5005. arg_list_.clear();
  5006. delete_branch_.clear();
  5007. return;
  5008. }
  5009. }
  5010. }
  5011. ~multi_switch_node()
  5012. {
  5013. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  5014. {
  5015. if (arg_list_[i] && delete_branch_[i])
  5016. {
  5017. delete arg_list_[i];
  5018. arg_list_[i] = 0;
  5019. }
  5020. }
  5021. }
  5022. inline T value() const
  5023. {
  5024. T result = T(0);
  5025. if (arg_list_.empty())
  5026. {
  5027. return std::numeric_limits<T>::quiet_NaN();
  5028. }
  5029. const std::size_t upper_bound = (arg_list_.size() - 1);
  5030. for (std::size_t i = 0; i < upper_bound; i += 2)
  5031. {
  5032. expression_ptr condition = arg_list_[i ];
  5033. expression_ptr consequent = arg_list_[i + 1];
  5034. if (is_true(condition))
  5035. {
  5036. result = consequent->value();
  5037. }
  5038. }
  5039. return result;
  5040. }
  5041. inline typename expression_node<T>::node_type type() const
  5042. {
  5043. return expression_node<T>::e_mswitch;
  5044. }
  5045. private:
  5046. std::vector<expression_ptr> arg_list_;
  5047. std::vector<unsigned char> delete_branch_;
  5048. };
  5049. template <typename T>
  5050. class ivariable
  5051. {
  5052. public:
  5053. virtual T& ref() = 0;
  5054. virtual const T& ref() const = 0;
  5055. };
  5056. template <typename T>
  5057. class variable_node : public expression_node<T>,
  5058. public ivariable <T>
  5059. {
  5060. public:
  5061. static T null_value;
  5062. explicit variable_node()
  5063. : value_(&null_value),
  5064. delete_value_(false)
  5065. {}
  5066. variable_node(T& v)
  5067. : value_(&v),
  5068. delete_value_(false)
  5069. {}
  5070. ~variable_node()
  5071. {
  5072. if (delete_value_)
  5073. {
  5074. delete value_;
  5075. }
  5076. }
  5077. inline bool operator <(const variable_node<T>& v) const
  5078. {
  5079. return this < (&v);
  5080. }
  5081. inline T value() const
  5082. {
  5083. return (*value_);
  5084. }
  5085. inline T& ref()
  5086. {
  5087. return (*value_);
  5088. }
  5089. inline const T& ref() const
  5090. {
  5091. return (*value_);
  5092. }
  5093. inline typename expression_node<T>::node_type type() const
  5094. {
  5095. return expression_node<T>::e_variable;
  5096. }
  5097. inline bool& delete_value()
  5098. {
  5099. return delete_value_;
  5100. }
  5101. private:
  5102. T* value_;
  5103. bool delete_value_;
  5104. };
  5105. template <typename T>
  5106. T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
  5107. template <typename T>
  5108. struct range_pack
  5109. {
  5110. typedef expression_node<T>* expression_node_ptr;
  5111. typedef std::pair<std::size_t,std::size_t> cached_range_t;
  5112. range_pack()
  5113. : n0_e (std::make_pair(false,expression_node_ptr(0))),
  5114. n1_e (std::make_pair(false,expression_node_ptr(0))),
  5115. n0_c (std::make_pair(false,0)),
  5116. n1_c (std::make_pair(false,0)),
  5117. cache(std::make_pair(0,0))
  5118. {}
  5119. void clear()
  5120. {
  5121. n0_e = std::make_pair(false,expression_node_ptr(0));
  5122. n1_e = std::make_pair(false,expression_node_ptr(0));
  5123. n0_c = std::make_pair(false,0);
  5124. n1_c = std::make_pair(false,0);
  5125. cache = std::make_pair(0,0);
  5126. }
  5127. void free()
  5128. {
  5129. if (n0_e.first && n0_e.second)
  5130. {
  5131. n0_e.first = false;
  5132. if (
  5133. !is_variable_node(n0_e.second) &&
  5134. !is_string_node (n0_e.second)
  5135. )
  5136. {
  5137. delete n0_e.second;
  5138. n0_e.second = expression_node_ptr(0);
  5139. }
  5140. }
  5141. if (n1_e.first && n1_e.second)
  5142. {
  5143. n1_e.first = false;
  5144. if (
  5145. !is_variable_node(n1_e.second) &&
  5146. !is_string_node (n1_e.second)
  5147. )
  5148. {
  5149. delete n1_e.second;
  5150. n1_e.second = expression_node_ptr(0);
  5151. }
  5152. }
  5153. }
  5154. bool const_range()
  5155. {
  5156. return ( n0_c.first && n1_c.first) &&
  5157. (!n0_e.first && !n1_e.first);
  5158. }
  5159. bool var_range()
  5160. {
  5161. return ( n0_e.first && n1_e.first) &&
  5162. (!n0_c.first && !n1_c.first);
  5163. }
  5164. bool operator()(std::size_t& r0, std::size_t& r1, const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
  5165. {
  5166. if (n0_c.first)
  5167. r0 = n0_c.second;
  5168. else if (n0_e.first)
  5169. {
  5170. T r0_value = n0_e.second->value();
  5171. if (r0_value < 0)
  5172. return false;
  5173. else
  5174. r0 = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
  5175. }
  5176. else
  5177. return false;
  5178. if (n1_c.first)
  5179. r1 = n1_c.second;
  5180. else if (n1_e.first)
  5181. {
  5182. T r1_value = n1_e.second->value();
  5183. if (r1_value < 0)
  5184. return false;
  5185. else
  5186. r1 = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
  5187. }
  5188. else
  5189. return false;
  5190. if (
  5191. (std::numeric_limits<std::size_t>::max() != size) &&
  5192. (std::numeric_limits<std::size_t>::max() == r1 )
  5193. )
  5194. {
  5195. r1 = size - 1;
  5196. }
  5197. cache.first = r0;
  5198. cache.second = r1;
  5199. return (r0 <= r1);
  5200. }
  5201. inline std::size_t const_size() const
  5202. {
  5203. return (n1_c.second - n0_c.second + 1);
  5204. }
  5205. inline std::size_t cache_size() const
  5206. {
  5207. return (cache.second - cache.first + 1);
  5208. }
  5209. std::pair<bool,expression_node_ptr> n0_e;
  5210. std::pair<bool,expression_node_ptr> n1_e;
  5211. std::pair<bool,std::size_t > n0_c;
  5212. std::pair<bool,std::size_t > n1_c;
  5213. mutable cached_range_t cache;
  5214. };
  5215. template <typename T>
  5216. class string_base_node;
  5217. template <typename T>
  5218. struct range_data_type
  5219. {
  5220. typedef range_pack<T> range_t;
  5221. typedef string_base_node<T>* strbase_ptr_t;
  5222. range_data_type()
  5223. : range(0),
  5224. data (0),
  5225. size (0),
  5226. type_size(0),
  5227. str_node (0)
  5228. {}
  5229. range_t* range;
  5230. void* data;
  5231. std::size_t size;
  5232. std::size_t type_size;
  5233. strbase_ptr_t str_node;
  5234. };
  5235. template <typename T> class vector_node;
  5236. template <typename T>
  5237. class vector_interface
  5238. {
  5239. public:
  5240. typedef vector_node<T>* vector_node_ptr;
  5241. virtual ~vector_interface()
  5242. {}
  5243. virtual vector_node_ptr vec() const = 0;
  5244. virtual vector_node_ptr vec() = 0;
  5245. virtual std::size_t size() const = 0;
  5246. };
  5247. template <typename T>
  5248. class vector_node : public expression_node <T>,
  5249. public vector_interface<T>
  5250. {
  5251. public:
  5252. typedef expression_node<T>* expression_ptr;
  5253. typedef vector_holder<T> vector_holder_t;
  5254. typedef vector_node<T>* vector_node_ptr;
  5255. vector_node(vector_holder_t* vh)
  5256. : vector_holder_(vh)
  5257. {}
  5258. inline T value() const
  5259. {
  5260. return *(ref()[0]);
  5261. }
  5262. inline const vector_holder_t& ref() const
  5263. {
  5264. return (*vector_holder_);
  5265. }
  5266. inline vector_holder_t& ref()
  5267. {
  5268. return (*vector_holder_);
  5269. }
  5270. vector_node_ptr vec() const
  5271. {
  5272. return const_cast<vector_node_ptr>(this);
  5273. }
  5274. vector_node_ptr vec()
  5275. {
  5276. return this;
  5277. }
  5278. inline typename expression_node<T>::node_type type() const
  5279. {
  5280. return expression_node<T>::e_vector;
  5281. }
  5282. std::size_t size() const
  5283. {
  5284. return ref().size();
  5285. }
  5286. private:
  5287. vector_holder_t* vector_holder_;
  5288. };
  5289. template <typename T>
  5290. class vector_elem_node : public expression_node<T>,
  5291. public ivariable <T>
  5292. {
  5293. public:
  5294. typedef expression_node<T>* expression_ptr;
  5295. vector_elem_node(expression_ptr index, T* vector_base)
  5296. : index_(index),
  5297. vector_base_(vector_base),
  5298. index_deletable_(branch_deletable(index_))
  5299. {}
  5300. ~vector_elem_node()
  5301. {
  5302. if (index_ && index_deletable_)
  5303. {
  5304. delete index_;
  5305. }
  5306. }
  5307. inline T value() const
  5308. {
  5309. return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
  5310. }
  5311. inline T& ref()
  5312. {
  5313. return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
  5314. }
  5315. inline const T& ref() const
  5316. {
  5317. return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
  5318. }
  5319. inline typename expression_node<T>::node_type type() const
  5320. {
  5321. return expression_node<T>::e_vecelem;
  5322. }
  5323. private:
  5324. expression_ptr index_;
  5325. T* vector_base_;
  5326. bool index_deletable_;
  5327. };
  5328. template <typename T>
  5329. class vector_assignment_node : public expression_node<T>
  5330. {
  5331. public:
  5332. typedef expression_node<T>* expression_ptr;
  5333. vector_assignment_node(T* vector_base,
  5334. const std::size_t& size,
  5335. const std::vector<expression_ptr>& initialiser_list,
  5336. const bool single_value_initialse)
  5337. : vector_base_(vector_base),
  5338. initialiser_list_(initialiser_list),
  5339. size_(size),
  5340. single_value_initialse_(single_value_initialse)
  5341. {}
  5342. ~vector_assignment_node()
  5343. {
  5344. for (std::size_t i = 0; i < initialiser_list_.size(); ++i)
  5345. {
  5346. if (branch_deletable(initialiser_list_[i]))
  5347. {
  5348. delete initialiser_list_[i];
  5349. }
  5350. }
  5351. }
  5352. inline T value() const
  5353. {
  5354. if (single_value_initialse_)
  5355. {
  5356. for (std::size_t i = 0; i < size_; ++i)
  5357. {
  5358. *(vector_base_ + i) = initialiser_list_[0]->value();
  5359. }
  5360. }
  5361. else
  5362. {
  5363. std::size_t il_size = initialiser_list_.size();
  5364. for (std::size_t i = 0; i < il_size; ++i)
  5365. {
  5366. *(vector_base_ + i) = initialiser_list_[i]->value();
  5367. }
  5368. if (il_size < size_)
  5369. {
  5370. for (std::size_t i = il_size; i < size_; ++i)
  5371. {
  5372. *(vector_base_ + i) = T(0);
  5373. }
  5374. }
  5375. }
  5376. return *(vector_base_);
  5377. }
  5378. inline typename expression_node<T>::node_type type() const
  5379. {
  5380. return expression_node<T>::e_vecdefass;
  5381. }
  5382. private:
  5383. vector_assignment_node<T>& operator=(const vector_assignment_node<T>&);
  5384. mutable T* vector_base_;
  5385. std::vector<expression_ptr> initialiser_list_;
  5386. const std::size_t size_;
  5387. const bool single_value_initialse_;
  5388. };
  5389. template <typename T>
  5390. class swap_node : public expression_node<T>
  5391. {
  5392. public:
  5393. typedef expression_node<T>* expression_ptr;
  5394. typedef variable_node<T>* variable_node_ptr;
  5395. swap_node(variable_node_ptr var0, variable_node_ptr var1)
  5396. : var0_(var0),
  5397. var1_(var1)
  5398. {}
  5399. inline T value() const
  5400. {
  5401. std::swap(var0_->ref(),var1_->ref());
  5402. return var1_->ref();
  5403. }
  5404. inline typename expression_node<T>::node_type type() const
  5405. {
  5406. return expression_node<T>::e_swap;
  5407. }
  5408. private:
  5409. variable_node_ptr var0_;
  5410. variable_node_ptr var1_;
  5411. };
  5412. template <typename T>
  5413. class swap_generic_node : public binary_node<T>
  5414. {
  5415. public:
  5416. typedef expression_node<T>* expression_ptr;
  5417. typedef ivariable<T>* ivariable_ptr;
  5418. swap_generic_node(expression_ptr var0, expression_ptr var1)
  5419. : binary_node<T>(details::e_swap,var0,var1),
  5420. var0_(dynamic_cast<ivariable_ptr>(var0)),
  5421. var1_(dynamic_cast<ivariable_ptr>(var1))
  5422. {}
  5423. inline T value() const
  5424. {
  5425. std::swap(var0_->ref(),var1_->ref());
  5426. return var1_->ref();
  5427. }
  5428. inline typename expression_node<T>::node_type type() const
  5429. {
  5430. return expression_node<T>::e_swap;
  5431. }
  5432. private:
  5433. ivariable_ptr var0_;
  5434. ivariable_ptr var1_;
  5435. };
  5436. template <typename T>
  5437. class swap_vecvec_node : public binary_node <T>,
  5438. public vector_interface<T>
  5439. {
  5440. public:
  5441. typedef expression_node<T>* expression_ptr;
  5442. typedef vector_node<T>* vector_node_ptr;
  5443. swap_vecvec_node(expression_ptr branch0,
  5444. expression_ptr branch1)
  5445. : binary_node<T>(details::e_swap,branch0,branch1),
  5446. vec0_node_ptr_(0),
  5447. vec1_node_ptr_(0),
  5448. vec_size_ (0),
  5449. initialised_(false)
  5450. {
  5451. if (is_ivector_node(binary_node<T>::branch_[0].first))
  5452. {
  5453. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  5454. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  5455. {
  5456. vec0_node_ptr_ = vi->vec();
  5457. }
  5458. }
  5459. if (is_ivector_node(binary_node<T>::branch_[1].first))
  5460. {
  5461. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  5462. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  5463. {
  5464. vec1_node_ptr_ = vi->vec();
  5465. }
  5466. }
  5467. if (vec0_node_ptr_ && vec1_node_ptr_)
  5468. {
  5469. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  5470. vec1_node_ptr_->ref().size());
  5471. initialised_ = true;
  5472. }
  5473. }
  5474. inline T value() const
  5475. {
  5476. if (initialised_)
  5477. {
  5478. binary_node<T>::branch_[0].first->value();
  5479. binary_node<T>::branch_[1].first->value();
  5480. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  5481. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  5482. for (std::size_t i = 0; i < vec_size_; ++i)
  5483. {
  5484. std::swap((*vec0[i]),(*vec1[i]));
  5485. }
  5486. return vec1_node_ptr_->value();
  5487. }
  5488. else
  5489. return std::numeric_limits<T>::quiet_NaN();
  5490. }
  5491. vector_node_ptr vec() const
  5492. {
  5493. return vec0_node_ptr_;
  5494. }
  5495. vector_node_ptr vec()
  5496. {
  5497. return vec0_node_ptr_;
  5498. }
  5499. inline typename expression_node<T>::node_type type() const
  5500. {
  5501. return expression_node<T>::e_vecvecswap;
  5502. }
  5503. std::size_t size() const
  5504. {
  5505. return vec_size_;
  5506. }
  5507. private:
  5508. vector_node<T>* vec0_node_ptr_;
  5509. vector_node<T>* vec1_node_ptr_;
  5510. std::size_t vec_size_;
  5511. bool initialised_;
  5512. };
  5513. #ifndef exprtk_disable_string_capabilities
  5514. template <typename T>
  5515. class stringvar_node : public expression_node <T>,
  5516. public string_base_node<T>,
  5517. public range_interface <T>
  5518. {
  5519. public:
  5520. typedef range_pack<T> range_t;
  5521. static std::string null_value;
  5522. explicit stringvar_node()
  5523. : value_(&null_value)
  5524. {}
  5525. explicit stringvar_node(std::string& v)
  5526. : value_(&v)
  5527. {
  5528. rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  5529. rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
  5530. rp_.cache.first = rp_.n0_c.second;
  5531. rp_.cache.second = rp_.n1_c.second;
  5532. }
  5533. inline bool operator <(const stringvar_node<T>& v) const
  5534. {
  5535. return this < (&v);
  5536. }
  5537. inline T value() const
  5538. {
  5539. rp_.n1_c.second = (*value_).size() - 1;
  5540. rp_.cache.second = rp_.n1_c.second;
  5541. return std::numeric_limits<T>::quiet_NaN();
  5542. }
  5543. std::string str() const
  5544. {
  5545. return ref();
  5546. }
  5547. const char* base() const
  5548. {
  5549. return (*value_).data();
  5550. }
  5551. std::size_t size() const
  5552. {
  5553. return ref().size();
  5554. }
  5555. std::string& ref()
  5556. {
  5557. return (*value_);
  5558. }
  5559. const std::string& ref() const
  5560. {
  5561. return (*value_);
  5562. }
  5563. range_t& range_ref()
  5564. {
  5565. return rp_;
  5566. }
  5567. const range_t& range_ref() const
  5568. {
  5569. return rp_;
  5570. }
  5571. inline typename expression_node<T>::node_type type() const
  5572. {
  5573. return expression_node<T>::e_stringvar;
  5574. }
  5575. private:
  5576. std::string* value_;
  5577. mutable range_t rp_;
  5578. };
  5579. template <typename T>
  5580. std::string stringvar_node<T>::null_value = std::string("");
  5581. template <typename T>
  5582. class string_range_node : public expression_node <T>,
  5583. public string_base_node<T>,
  5584. public range_interface <T>
  5585. {
  5586. public:
  5587. typedef range_pack<T> range_t;
  5588. static std::string null_value;
  5589. explicit string_range_node(std::string& v, range_t rp)
  5590. : value_(&v),
  5591. rp_(rp)
  5592. {}
  5593. ~string_range_node()
  5594. {
  5595. rp_.free();
  5596. }
  5597. inline bool operator <(const string_range_node<T>& v) const
  5598. {
  5599. return this < (&v);
  5600. }
  5601. inline T value() const
  5602. {
  5603. return std::numeric_limits<T>::quiet_NaN();
  5604. }
  5605. inline std::string str() const
  5606. {
  5607. return (*value_);
  5608. }
  5609. const char* base() const
  5610. {
  5611. return (*value_).data();
  5612. }
  5613. std::size_t size() const
  5614. {
  5615. return ref().size();
  5616. }
  5617. inline range_t range() const
  5618. {
  5619. return rp_;
  5620. }
  5621. inline virtual std::string& ref()
  5622. {
  5623. return (*value_);
  5624. }
  5625. inline virtual const std::string& ref() const
  5626. {
  5627. return (*value_);
  5628. }
  5629. inline range_t& range_ref()
  5630. {
  5631. return rp_;
  5632. }
  5633. inline const range_t& range_ref() const
  5634. {
  5635. return rp_;
  5636. }
  5637. inline typename expression_node<T>::node_type type() const
  5638. {
  5639. return expression_node<T>::e_stringvarrng;
  5640. }
  5641. private:
  5642. std::string* value_;
  5643. range_t rp_;
  5644. };
  5645. template <typename T>
  5646. std::string string_range_node<T>::null_value = std::string("");
  5647. template <typename T>
  5648. class const_string_range_node : public expression_node <T>,
  5649. public string_base_node<T>,
  5650. public range_interface <T>
  5651. {
  5652. public:
  5653. typedef range_pack<T> range_t;
  5654. explicit const_string_range_node(const std::string& v, range_t rp)
  5655. : value_(v),
  5656. rp_(rp)
  5657. {}
  5658. ~const_string_range_node()
  5659. {
  5660. rp_.free();
  5661. }
  5662. inline T value() const
  5663. {
  5664. return std::numeric_limits<T>::quiet_NaN();
  5665. }
  5666. std::string str() const
  5667. {
  5668. return value_;
  5669. }
  5670. const char* base() const
  5671. {
  5672. return value_.data();
  5673. }
  5674. std::size_t size() const
  5675. {
  5676. return value_.size();
  5677. }
  5678. range_t range() const
  5679. {
  5680. return rp_;
  5681. }
  5682. range_t& range_ref()
  5683. {
  5684. return rp_;
  5685. }
  5686. const range_t& range_ref() const
  5687. {
  5688. return rp_;
  5689. }
  5690. inline typename expression_node<T>::node_type type() const
  5691. {
  5692. return expression_node<T>::e_cstringvarrng;
  5693. }
  5694. private:
  5695. const_string_range_node<T>& operator=(const const_string_range_node<T>&);
  5696. const std::string value_;
  5697. range_t rp_;
  5698. };
  5699. template <typename T>
  5700. class generic_string_range_node : public expression_node <T>,
  5701. public string_base_node<T>,
  5702. public range_interface <T>
  5703. {
  5704. public:
  5705. typedef expression_node <T>* expression_ptr;
  5706. typedef stringvar_node <T>* strvar_node_ptr;
  5707. typedef string_base_node<T>* str_base_ptr;
  5708. typedef range_pack <T> range_t;
  5709. typedef range_t* range_ptr;
  5710. typedef range_interface<T> irange_t;
  5711. typedef irange_t* irange_ptr;
  5712. generic_string_range_node(expression_ptr str_branch, range_t brange)
  5713. : initialised_(false),
  5714. branch_(str_branch),
  5715. branch_deletable_(branch_deletable(branch_)),
  5716. str_base_ptr_ (0),
  5717. str_range_ptr_(0),
  5718. base_range_(brange)
  5719. {
  5720. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  5721. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  5722. range_.cache.first = range_.n0_c.second;
  5723. range_.cache.second = range_.n1_c.second;
  5724. if (is_generally_string_node(branch_))
  5725. {
  5726. str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
  5727. if (0 == str_base_ptr_)
  5728. return;
  5729. str_range_ptr_ = dynamic_cast<irange_ptr>(branch_);
  5730. if (0 == str_range_ptr_)
  5731. return;
  5732. }
  5733. initialised_ = (str_base_ptr_ && str_range_ptr_);
  5734. }
  5735. ~generic_string_range_node()
  5736. {
  5737. base_range_.free();
  5738. if (branch_ && branch_deletable_)
  5739. {
  5740. delete branch_;
  5741. branch_ = 0;
  5742. }
  5743. }
  5744. inline T value() const
  5745. {
  5746. if (initialised_)
  5747. {
  5748. branch_->value();
  5749. std::size_t str_r0 = 0;
  5750. std::size_t str_r1 = 0;
  5751. std::size_t r0 = 0;
  5752. std::size_t r1 = 0;
  5753. range_t& range = str_range_ptr_->range_ref();
  5754. const std::size_t base_str_size = str_base_ptr_->size();
  5755. if (
  5756. range (str_r0,str_r1,base_str_size) &&
  5757. base_range_( r0, r1,base_str_size)
  5758. )
  5759. {
  5760. const std::size_t size = (r1 - r0) + 1;
  5761. range_.n1_c.second = size - 1;
  5762. range_.cache.second = range_.n1_c.second;
  5763. value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
  5764. }
  5765. }
  5766. return std::numeric_limits<T>::quiet_NaN();
  5767. }
  5768. std::string str() const
  5769. {
  5770. return value_;
  5771. }
  5772. const char* base() const
  5773. {
  5774. return value_.data();
  5775. }
  5776. std::size_t size() const
  5777. {
  5778. return value_.size();
  5779. }
  5780. range_t& range_ref()
  5781. {
  5782. return range_;
  5783. }
  5784. const range_t& range_ref() const
  5785. {
  5786. return range_;
  5787. }
  5788. inline typename expression_node<T>::node_type type() const
  5789. {
  5790. return expression_node<T>::e_strgenrange;
  5791. }
  5792. private:
  5793. bool initialised_;
  5794. expression_ptr branch_;
  5795. bool branch_deletable_;
  5796. str_base_ptr str_base_ptr_;
  5797. irange_ptr str_range_ptr_;
  5798. mutable range_t base_range_;
  5799. mutable range_t range_;
  5800. mutable std::string value_;
  5801. };
  5802. template <typename T>
  5803. class string_concat_node : public binary_node <T>,
  5804. public string_base_node<T>,
  5805. public range_interface <T>
  5806. {
  5807. public:
  5808. typedef expression_node <T>* expression_ptr;
  5809. typedef string_base_node<T>* str_base_ptr;
  5810. typedef range_pack <T> range_t;
  5811. typedef range_t* range_ptr;
  5812. typedef range_interface<T> irange_t;
  5813. typedef irange_t* irange_ptr;
  5814. string_concat_node(const operator_type& opr,
  5815. expression_ptr branch0,
  5816. expression_ptr branch1)
  5817. : binary_node<T>(opr,branch0,branch1),
  5818. initialised_(false),
  5819. str0_base_ptr_ (0),
  5820. str1_base_ptr_ (0),
  5821. str0_range_ptr_(0),
  5822. str1_range_ptr_(0)
  5823. {
  5824. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  5825. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  5826. range_.cache.first = range_.n0_c.second;
  5827. range_.cache.second = range_.n1_c.second;
  5828. if (is_generally_string_node(binary_node<T>::branch_[0].first))
  5829. {
  5830. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  5831. if (0 == str0_base_ptr_)
  5832. return;
  5833. str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  5834. if (0 == str0_range_ptr_)
  5835. return;
  5836. }
  5837. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  5838. {
  5839. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  5840. if (0 == str1_base_ptr_)
  5841. return;
  5842. str1_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  5843. if (0 == str1_range_ptr_)
  5844. return;
  5845. }
  5846. initialised_ = str0_base_ptr_ &&
  5847. str1_base_ptr_ &&
  5848. str0_range_ptr_ &&
  5849. str1_range_ptr_ ;
  5850. }
  5851. inline T value() const
  5852. {
  5853. if (initialised_)
  5854. {
  5855. binary_node<T>::branch_[0].first->value();
  5856. binary_node<T>::branch_[1].first->value();
  5857. std::size_t str0_r0 = 0;
  5858. std::size_t str0_r1 = 0;
  5859. std::size_t str1_r0 = 0;
  5860. std::size_t str1_r1 = 0;
  5861. range_t& range0 = str0_range_ptr_->range_ref();
  5862. range_t& range1 = str1_range_ptr_->range_ref();
  5863. if (
  5864. range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
  5865. range1(str1_r0,str1_r1,str1_base_ptr_->size())
  5866. )
  5867. {
  5868. const std::size_t size0 = (str0_r1 - str0_r0) + 1;
  5869. const std::size_t size1 = (str1_r1 - str1_r0) + 1;
  5870. value_.assign(str0_base_ptr_->base() + str0_r0, size0);
  5871. value_.append(str1_base_ptr_->base() + str1_r0, size1);
  5872. range_.n1_c.second = value_.size() - 1;
  5873. range_.cache.second = range_.n1_c.second;
  5874. }
  5875. }
  5876. return std::numeric_limits<T>::quiet_NaN();
  5877. }
  5878. std::string str() const
  5879. {
  5880. return value_;
  5881. }
  5882. const char* base() const
  5883. {
  5884. return value_.data();
  5885. }
  5886. std::size_t size() const
  5887. {
  5888. return value_.size();
  5889. }
  5890. range_t& range_ref()
  5891. {
  5892. return range_;
  5893. }
  5894. const range_t& range_ref() const
  5895. {
  5896. return range_;
  5897. }
  5898. inline typename expression_node<T>::node_type type() const
  5899. {
  5900. return expression_node<T>::e_strconcat;
  5901. }
  5902. private:
  5903. bool initialised_;
  5904. str_base_ptr str0_base_ptr_;
  5905. str_base_ptr str1_base_ptr_;
  5906. irange_ptr str0_range_ptr_;
  5907. irange_ptr str1_range_ptr_;
  5908. mutable range_t range_;
  5909. mutable std::string value_;
  5910. };
  5911. template <typename T>
  5912. class swap_string_node : public binary_node <T>,
  5913. public string_base_node<T>,
  5914. public range_interface <T>
  5915. {
  5916. public:
  5917. typedef expression_node <T>* expression_ptr;
  5918. typedef stringvar_node <T>* strvar_node_ptr;
  5919. typedef string_base_node<T>* str_base_ptr;
  5920. typedef range_pack <T> range_t;
  5921. typedef range_t* range_ptr;
  5922. typedef range_interface<T> irange_t;
  5923. typedef irange_t* irange_ptr;
  5924. swap_string_node(expression_ptr branch0, expression_ptr branch1)
  5925. : binary_node<T>(details::e_swap,branch0,branch1),
  5926. initialised_(false),
  5927. str0_node_ptr_(0),
  5928. str1_node_ptr_(0)
  5929. {
  5930. if (is_string_node(binary_node<T>::branch_[0].first))
  5931. {
  5932. str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
  5933. }
  5934. if (is_string_node(binary_node<T>::branch_[1].first))
  5935. {
  5936. str1_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[1].first);
  5937. }
  5938. initialised_ = (str0_node_ptr_ && str1_node_ptr_);
  5939. }
  5940. inline T value() const
  5941. {
  5942. if (initialised_)
  5943. {
  5944. binary_node<T>::branch_[0].first->value();
  5945. binary_node<T>::branch_[1].first->value();
  5946. std::swap(str0_node_ptr_->ref(),str1_node_ptr_->ref());
  5947. }
  5948. return std::numeric_limits<T>::quiet_NaN();
  5949. }
  5950. std::string str() const
  5951. {
  5952. return str0_node_ptr_->str();
  5953. }
  5954. const char* base() const
  5955. {
  5956. return str0_node_ptr_->base();
  5957. }
  5958. std::size_t size() const
  5959. {
  5960. return str0_node_ptr_->size();
  5961. }
  5962. range_t& range_ref()
  5963. {
  5964. return str0_node_ptr_->range_ref();
  5965. }
  5966. const range_t& range_ref() const
  5967. {
  5968. return str0_node_ptr_->range_ref();
  5969. }
  5970. inline typename expression_node<T>::node_type type() const
  5971. {
  5972. return expression_node<T>::e_strswap;
  5973. }
  5974. private:
  5975. bool initialised_;
  5976. strvar_node_ptr str0_node_ptr_;
  5977. strvar_node_ptr str1_node_ptr_;
  5978. };
  5979. template <typename T>
  5980. class stringvar_size_node : public expression_node<T>
  5981. {
  5982. public:
  5983. static std::string null_value;
  5984. explicit stringvar_size_node()
  5985. : value_(&null_value)
  5986. {}
  5987. explicit stringvar_size_node(std::string& v)
  5988. : value_(&v)
  5989. {}
  5990. inline T value() const
  5991. {
  5992. return T((*value_).size());
  5993. }
  5994. inline typename expression_node<T>::node_type type() const
  5995. {
  5996. return expression_node<T>::e_stringvarsize;
  5997. }
  5998. private:
  5999. std::string* value_;
  6000. };
  6001. template <typename T>
  6002. std::string stringvar_size_node<T>::null_value = std::string("");
  6003. template <typename T>
  6004. class string_size_node : public expression_node<T>
  6005. {
  6006. public:
  6007. typedef expression_node <T>* expression_ptr;
  6008. typedef string_base_node<T>* str_base_ptr;
  6009. string_size_node(expression_ptr brnch)
  6010. : branch_(brnch),
  6011. branch_deletable_(branch_deletable(branch_)),
  6012. str_base_ptr_(0)
  6013. {
  6014. if (is_generally_string_node(branch_))
  6015. {
  6016. str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
  6017. if (0 == str_base_ptr_)
  6018. return;
  6019. }
  6020. }
  6021. ~string_size_node()
  6022. {
  6023. if (branch_ && branch_deletable_)
  6024. {
  6025. delete branch_;
  6026. branch_ = 0;
  6027. }
  6028. }
  6029. inline T value() const
  6030. {
  6031. T result = std::numeric_limits<T>::quiet_NaN();
  6032. if (str_base_ptr_)
  6033. {
  6034. branch_->value();
  6035. result = T(str_base_ptr_->size());
  6036. }
  6037. return result;
  6038. }
  6039. inline typename expression_node<T>::node_type type() const
  6040. {
  6041. return expression_node<T>::e_stringsize;
  6042. }
  6043. private:
  6044. expression_ptr branch_;
  6045. bool branch_deletable_;
  6046. str_base_ptr str_base_ptr_;
  6047. };
  6048. struct asn_assignment
  6049. {
  6050. static inline void execute(std::string& s, const char* data, const std::size_t size)
  6051. { s.assign(data,size); }
  6052. };
  6053. struct asn_addassignment
  6054. {
  6055. static inline void execute(std::string& s, const char* data, const std::size_t size)
  6056. { s.append(data,size); }
  6057. };
  6058. template <typename T, typename AssignmentProcess = asn_assignment>
  6059. class assignment_string_node : public binary_node <T>,
  6060. public string_base_node<T>,
  6061. public range_interface <T>
  6062. {
  6063. public:
  6064. typedef expression_node <T>* expression_ptr;
  6065. typedef stringvar_node <T>* strvar_node_ptr;
  6066. typedef string_base_node<T>* str_base_ptr;
  6067. typedef range_pack <T> range_t;
  6068. typedef range_t* range_ptr;
  6069. typedef range_interface<T> irange_t;
  6070. typedef irange_t* irange_ptr;
  6071. assignment_string_node(const operator_type& opr,
  6072. expression_ptr branch0,
  6073. expression_ptr branch1)
  6074. : binary_node<T>(opr,branch0,branch1),
  6075. initialised_(false),
  6076. str0_base_ptr_ (0),
  6077. str1_base_ptr_ (0),
  6078. str0_node_ptr_ (0),
  6079. str1_range_ptr_(0)
  6080. {
  6081. if (is_string_node(binary_node<T>::branch_[0].first))
  6082. {
  6083. str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
  6084. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  6085. }
  6086. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  6087. {
  6088. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  6089. if (0 == str1_base_ptr_)
  6090. return;
  6091. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  6092. if (0 == range_ptr)
  6093. return;
  6094. str1_range_ptr_ = &(range_ptr->range_ref());
  6095. }
  6096. initialised_ = str0_base_ptr_ &&
  6097. str1_base_ptr_ &&
  6098. str0_node_ptr_ &&
  6099. str1_range_ptr_ ;
  6100. }
  6101. inline T value() const
  6102. {
  6103. if (initialised_)
  6104. {
  6105. binary_node<T>::branch_[1].first->value();
  6106. std::size_t r0 = 0;
  6107. std::size_t r1 = 0;
  6108. range_t& range = (*str1_range_ptr_);
  6109. if (range(r0,r1,str1_base_ptr_->size()))
  6110. {
  6111. AssignmentProcess::execute(str0_node_ptr_->ref(),
  6112. str1_base_ptr_->base() + r0,
  6113. (r1 - r0) + 1);
  6114. binary_node<T>::branch_[0].first->value();
  6115. }
  6116. }
  6117. return std::numeric_limits<T>::quiet_NaN();
  6118. }
  6119. std::string str() const
  6120. {
  6121. return str0_node_ptr_->str();
  6122. }
  6123. const char* base() const
  6124. {
  6125. return str0_node_ptr_->base();
  6126. }
  6127. std::size_t size() const
  6128. {
  6129. return str0_node_ptr_->size();
  6130. }
  6131. range_t& range_ref()
  6132. {
  6133. return str0_node_ptr_->range_ref();
  6134. }
  6135. const range_t& range_ref() const
  6136. {
  6137. return str0_node_ptr_->range_ref();
  6138. }
  6139. inline typename expression_node<T>::node_type type() const
  6140. {
  6141. return expression_node<T>::e_strass;
  6142. }
  6143. private:
  6144. bool initialised_;
  6145. str_base_ptr str0_base_ptr_;
  6146. str_base_ptr str1_base_ptr_;
  6147. strvar_node_ptr str0_node_ptr_;
  6148. range_ptr str1_range_ptr_;
  6149. };
  6150. template <typename T, typename AssignmentProcess = asn_assignment>
  6151. class assignment_string_range_node : public binary_node <T>,
  6152. public string_base_node<T>,
  6153. public range_interface <T>
  6154. {
  6155. public:
  6156. typedef expression_node <T>* expression_ptr;
  6157. typedef stringvar_node <T>* strvar_node_ptr;
  6158. typedef string_base_node<T>* str_base_ptr;
  6159. typedef range_pack <T> range_t;
  6160. typedef range_t* range_ptr;
  6161. typedef range_interface<T> irange_t;
  6162. typedef irange_t* irange_ptr;
  6163. assignment_string_range_node(const operator_type& opr,
  6164. expression_ptr branch0,
  6165. expression_ptr branch1)
  6166. : binary_node<T>(opr,branch0,branch1),
  6167. initialised_(false),
  6168. str0_base_ptr_ (0),
  6169. str1_base_ptr_ (0),
  6170. str0_node_ptr_ (0),
  6171. str0_range_ptr_(0),
  6172. str1_range_ptr_(0)
  6173. {
  6174. if (is_string_range_node(binary_node<T>::branch_[0].first))
  6175. {
  6176. str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
  6177. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  6178. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  6179. if (0 == range_ptr)
  6180. return;
  6181. str0_range_ptr_ = &(range_ptr->range_ref());
  6182. }
  6183. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  6184. {
  6185. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  6186. if (0 == str1_base_ptr_)
  6187. return;
  6188. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  6189. if (0 == range_ptr)
  6190. return;
  6191. str1_range_ptr_ = &(range_ptr->range_ref());
  6192. }
  6193. initialised_ = str0_base_ptr_ &&
  6194. str1_base_ptr_ &&
  6195. str0_node_ptr_ &&
  6196. str0_range_ptr_ &&
  6197. str1_range_ptr_ ;
  6198. }
  6199. inline T value() const
  6200. {
  6201. if (initialised_)
  6202. {
  6203. binary_node<T>::branch_[0].first->value();
  6204. binary_node<T>::branch_[1].first->value();
  6205. std::size_t s0_r0 = 0;
  6206. std::size_t s0_r1 = 0;
  6207. std::size_t s1_r0 = 0;
  6208. std::size_t s1_r1 = 0;
  6209. range_t& range0 = (*str0_range_ptr_);
  6210. range_t& range1 = (*str1_range_ptr_);
  6211. if (
  6212. range0(s0_r0,s0_r1,str0_base_ptr_->size()) &&
  6213. range1(s1_r0,s1_r1,str1_base_ptr_->size())
  6214. )
  6215. {
  6216. std::size_t size = std::min((s0_r1 - s0_r0),(s1_r1 - s1_r0)) + 1;
  6217. std::copy(str1_base_ptr_->base() + s1_r0,
  6218. str1_base_ptr_->base() + s1_r0 + size,
  6219. const_cast<char*>(base() + s0_r0));
  6220. }
  6221. }
  6222. return std::numeric_limits<T>::quiet_NaN();
  6223. }
  6224. std::string str() const
  6225. {
  6226. return str0_node_ptr_->str();
  6227. }
  6228. const char* base() const
  6229. {
  6230. return str0_node_ptr_->base();
  6231. }
  6232. std::size_t size() const
  6233. {
  6234. return str0_node_ptr_->size();
  6235. }
  6236. range_t& range_ref()
  6237. {
  6238. return str0_node_ptr_->range_ref();
  6239. }
  6240. const range_t& range_ref() const
  6241. {
  6242. return str0_node_ptr_->range_ref();
  6243. }
  6244. inline typename expression_node<T>::node_type type() const
  6245. {
  6246. return expression_node<T>::e_strass;
  6247. }
  6248. private:
  6249. bool initialised_;
  6250. str_base_ptr str0_base_ptr_;
  6251. str_base_ptr str1_base_ptr_;
  6252. strvar_node_ptr str0_node_ptr_;
  6253. range_ptr str0_range_ptr_;
  6254. range_ptr str1_range_ptr_;
  6255. };
  6256. template <typename T>
  6257. class conditional_string_node : public trinary_node <T>,
  6258. public string_base_node<T>,
  6259. public range_interface <T>
  6260. {
  6261. public:
  6262. typedef expression_node <T>* expression_ptr;
  6263. typedef string_base_node<T>* str_base_ptr;
  6264. typedef range_pack <T> range_t;
  6265. typedef range_t* range_ptr;
  6266. typedef range_interface<T> irange_t;
  6267. typedef irange_t* irange_ptr;
  6268. conditional_string_node(expression_ptr test,
  6269. expression_ptr consequent,
  6270. expression_ptr alternative)
  6271. : trinary_node<T>(details::e_default,consequent,alternative,test),
  6272. initialised_(false),
  6273. str0_base_ptr_ (0),
  6274. str1_base_ptr_ (0),
  6275. str0_range_ptr_(0),
  6276. str1_range_ptr_(0),
  6277. test_ (test),
  6278. consequent_ (consequent),
  6279. alternative_(alternative)
  6280. {
  6281. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  6282. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  6283. range_.cache.first = range_.n0_c.second;
  6284. range_.cache.second = range_.n1_c.second;
  6285. if (is_generally_string_node(trinary_node<T>::branch_[0].first))
  6286. {
  6287. str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first);
  6288. if (0 == str0_base_ptr_)
  6289. return;
  6290. str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first);
  6291. if (0 == str0_range_ptr_)
  6292. return;
  6293. }
  6294. if (is_generally_string_node(trinary_node<T>::branch_[1].first))
  6295. {
  6296. str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first);
  6297. if (0 == str1_base_ptr_)
  6298. return;
  6299. str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first);
  6300. if (0 == str1_range_ptr_)
  6301. return;
  6302. }
  6303. initialised_ = str0_base_ptr_ &&
  6304. str1_base_ptr_ &&
  6305. str0_range_ptr_ &&
  6306. str1_range_ptr_ ;
  6307. }
  6308. inline T value() const
  6309. {
  6310. if (initialised_)
  6311. {
  6312. std::size_t r0 = 0;
  6313. std::size_t r1 = 0;
  6314. if (is_true(test_))
  6315. {
  6316. consequent_->value();
  6317. range_t& range = str0_range_ptr_->range_ref();
  6318. if (range(r0,r1,str0_base_ptr_->size()))
  6319. {
  6320. const std::size_t size = (r1 - r0) + 1;
  6321. value_.assign(str0_base_ptr_->base() + r0, size);
  6322. range_.n1_c.second = value_.size() - 1;
  6323. range_.cache.second = range_.n1_c.second;
  6324. return T(1);
  6325. }
  6326. }
  6327. else
  6328. {
  6329. alternative_->value();
  6330. range_t& range = str1_range_ptr_->range_ref();
  6331. if (range(r0,r1,str1_base_ptr_->size()))
  6332. {
  6333. const std::size_t size = (r1 - r0) + 1;
  6334. value_.assign(str1_base_ptr_->base() + r0, size);
  6335. range_.n1_c.second = value_.size() - 1;
  6336. range_.cache.second = range_.n1_c.second;
  6337. return T(0);
  6338. }
  6339. }
  6340. }
  6341. return std::numeric_limits<T>::quiet_NaN();
  6342. }
  6343. std::string str() const
  6344. {
  6345. return value_;
  6346. }
  6347. const char* base() const
  6348. {
  6349. return value_.data();
  6350. }
  6351. std::size_t size() const
  6352. {
  6353. return value_.size();
  6354. }
  6355. range_t& range_ref()
  6356. {
  6357. return range_;
  6358. }
  6359. const range_t& range_ref() const
  6360. {
  6361. return range_;
  6362. }
  6363. inline typename expression_node<T>::node_type type() const
  6364. {
  6365. return expression_node<T>::e_strcondition;
  6366. }
  6367. private:
  6368. bool initialised_;
  6369. str_base_ptr str0_base_ptr_;
  6370. str_base_ptr str1_base_ptr_;
  6371. irange_ptr str0_range_ptr_;
  6372. irange_ptr str1_range_ptr_;
  6373. mutable range_t range_;
  6374. mutable std::string value_;
  6375. expression_ptr test_;
  6376. expression_ptr consequent_;
  6377. expression_ptr alternative_;
  6378. };
  6379. template <typename T>
  6380. class cons_conditional_str_node : public binary_node <T>,
  6381. public string_base_node<T>,
  6382. public range_interface <T>
  6383. {
  6384. public:
  6385. typedef expression_node <T>* expression_ptr;
  6386. typedef string_base_node<T>* str_base_ptr;
  6387. typedef range_pack <T> range_t;
  6388. typedef range_t* range_ptr;
  6389. typedef range_interface<T> irange_t;
  6390. typedef irange_t* irange_ptr;
  6391. cons_conditional_str_node(expression_ptr test,
  6392. expression_ptr consequent)
  6393. : binary_node<T>(details::e_default,consequent,test),
  6394. initialised_(false),
  6395. str0_base_ptr_ (0),
  6396. str0_range_ptr_(0),
  6397. test_ (test),
  6398. consequent_(consequent)
  6399. {
  6400. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  6401. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  6402. range_.cache.first = range_.n0_c.second;
  6403. range_.cache.second = range_.n1_c.second;
  6404. if (is_generally_string_node(binary_node<T>::branch_[0].first))
  6405. {
  6406. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  6407. if (0 == str0_base_ptr_)
  6408. return;
  6409. str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  6410. if (0 == str0_range_ptr_)
  6411. return;
  6412. }
  6413. initialised_ = str0_base_ptr_ && str0_range_ptr_ ;
  6414. }
  6415. inline T value() const
  6416. {
  6417. if (initialised_)
  6418. {
  6419. std::size_t r0 = 0;
  6420. std::size_t r1 = 0;
  6421. if (is_true(test_))
  6422. {
  6423. consequent_->value();
  6424. range_t& range = str0_range_ptr_->range_ref();
  6425. if (range(r0,r1,str0_base_ptr_->size()))
  6426. {
  6427. const std::size_t size = (r1 - r0) + 1;
  6428. value_.assign(str0_base_ptr_->base() + r0, size);
  6429. range_.n1_c.second = value_.size() - 1;
  6430. range_.cache.second = range_.n1_c.second;
  6431. return T(1);
  6432. }
  6433. }
  6434. }
  6435. return std::numeric_limits<T>::quiet_NaN();
  6436. }
  6437. std::string str() const
  6438. {
  6439. return value_;
  6440. }
  6441. const char* base() const
  6442. {
  6443. return value_.data();
  6444. }
  6445. std::size_t size() const
  6446. {
  6447. return value_.size();
  6448. }
  6449. range_t& range_ref()
  6450. {
  6451. return range_;
  6452. }
  6453. const range_t& range_ref() const
  6454. {
  6455. return range_;
  6456. }
  6457. inline typename expression_node<T>::node_type type() const
  6458. {
  6459. return expression_node<T>::e_strccondition;
  6460. }
  6461. private:
  6462. bool initialised_;
  6463. str_base_ptr str0_base_ptr_;
  6464. irange_ptr str0_range_ptr_;
  6465. mutable range_t range_;
  6466. mutable std::string value_;
  6467. expression_ptr test_;
  6468. expression_ptr consequent_;
  6469. };
  6470. #endif
  6471. template <typename T, std::size_t N>
  6472. inline T axn(T a, T x)
  6473. {
  6474. // a*x^n
  6475. return a * exprtk::details::numeric::fast_exp<T,N>::result(x);
  6476. }
  6477. template <typename T, std::size_t N>
  6478. inline T axnb(T a, T x, T b)
  6479. {
  6480. // a*x^n+b
  6481. return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b;
  6482. }
  6483. template <typename T>
  6484. struct sf_base
  6485. {
  6486. typedef typename details::functor_t<T>::Type Type;
  6487. typedef typename details::functor_t<T> functor_t;
  6488. typedef typename functor_t::qfunc_t quaternary_functor_t;
  6489. typedef typename functor_t::tfunc_t trinary_functor_t;
  6490. typedef typename functor_t::bfunc_t binary_functor_t;
  6491. typedef typename functor_t::ufunc_t unary_functor_t;
  6492. };
  6493. #define define_sfop3(NN,OP0,OP1) \
  6494. template <typename T> \
  6495. struct sf##NN##_op : public sf_base<T> \
  6496. { \
  6497. typedef typename sf_base<T>::Type Type; \
  6498. static inline T process(Type x, Type y, Type z) \
  6499. { \
  6500. return (OP0); \
  6501. } \
  6502. static inline std::string id() \
  6503. { \
  6504. return OP1; \
  6505. } \
  6506. }; \
  6507. define_sfop3(00,(x + y) / z ,"(t+t)/t")
  6508. define_sfop3(01,(x + y) * z ,"(t+t)*t")
  6509. define_sfop3(02,(x + y) - z ,"(t+t)-t")
  6510. define_sfop3(03,(x + y) + z ,"(t+t)+t")
  6511. define_sfop3(04,(x - y) + z ,"(t-t)+t")
  6512. define_sfop3(05,(x - y) / z ,"(t-t)/t")
  6513. define_sfop3(06,(x - y) * z ,"(t-t)*t")
  6514. define_sfop3(07,(x * y) + z ,"(t*t)+t")
  6515. define_sfop3(08,(x * y) - z ,"(t*t)-t")
  6516. define_sfop3(09,(x * y) / z ,"(t*t)/t")
  6517. define_sfop3(10,(x * y) * z ,"(t*t)*t")
  6518. define_sfop3(11,(x / y) + z ,"(t/t)+t")
  6519. define_sfop3(12,(x / y) - z ,"(t/t)-t")
  6520. define_sfop3(13,(x / y) / z ,"(t/t)/t")
  6521. define_sfop3(14,(x / y) * z ,"(t/t)*t")
  6522. define_sfop3(15,x / (y + z) ,"t/(t+t)")
  6523. define_sfop3(16,x / (y - z) ,"t/(t-t)")
  6524. define_sfop3(17,x / (y * z) ,"t/(t*t)")
  6525. define_sfop3(18,x / (y / z) ,"t/(t/t)")
  6526. define_sfop3(19,x * (y + z) ,"t*(t+t)")
  6527. define_sfop3(20,x * (y - z) ,"t*(t-t)")
  6528. define_sfop3(21,x * (y * z) ,"t*(t*t)")
  6529. define_sfop3(22,x * (y / z) ,"t*(t/t)")
  6530. define_sfop3(23,x - (y + z) ,"t-(t+t)")
  6531. define_sfop3(24,x - (y - z) ,"t-(t-t)")
  6532. define_sfop3(25,x - (y / z) ,"t-(t/t)")
  6533. define_sfop3(26,x - (y * z) ,"t-(t*t)")
  6534. define_sfop3(27,x + (y * z) ,"t+(t*t)")
  6535. define_sfop3(28,x + (y / z) ,"t+(t/t)")
  6536. define_sfop3(29,x + (y + z) ,"t+(t+t)")
  6537. define_sfop3(30,x + (y - z) ,"t+(t-t)")
  6538. define_sfop3(31,(axnb<T,2>(x,y,z))," ")
  6539. define_sfop3(32,(axnb<T,3>(x,y,z))," ")
  6540. define_sfop3(33,(axnb<T,4>(x,y,z))," ")
  6541. define_sfop3(34,(axnb<T,5>(x,y,z))," ")
  6542. define_sfop3(35,(axnb<T,6>(x,y,z))," ")
  6543. define_sfop3(36,(axnb<T,7>(x,y,z))," ")
  6544. define_sfop3(37,(axnb<T,8>(x,y,z))," ")
  6545. define_sfop3(38,(axnb<T,9>(x,y,z))," ")
  6546. define_sfop3(39,x * numeric::log(y) + z,"")
  6547. define_sfop3(40,x * numeric::log(y) - z,"")
  6548. define_sfop3(41,x * numeric::log10(y) + z,"")
  6549. define_sfop3(42,x * numeric::log10(y) - z,"")
  6550. define_sfop3(43,x * numeric::sin(y) + z ,"")
  6551. define_sfop3(44,x * numeric::sin(y) - z ,"")
  6552. define_sfop3(45,x * numeric::cos(y) + z ,"")
  6553. define_sfop3(46,x * numeric::cos(y) - z ,"")
  6554. define_sfop3(47,details::is_true(x) ? y : z,"")
  6555. #define define_sfop4(NN,OP0,OP1) \
  6556. template <typename T> \
  6557. struct sf##NN##_op : public sf_base<T> \
  6558. { \
  6559. typedef typename sf_base<T>::Type Type; \
  6560. static inline T process(Type x, Type y, Type z, Type w) \
  6561. { \
  6562. return (OP0); \
  6563. } \
  6564. static inline std::string id() { return OP1; } \
  6565. }; \
  6566. define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
  6567. define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)")
  6568. define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)")
  6569. define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)")
  6570. define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)")
  6571. define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)")
  6572. define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)")
  6573. define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)")
  6574. define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)")
  6575. define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)")
  6576. define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)")
  6577. define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)")
  6578. define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)")
  6579. define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)")
  6580. define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)")
  6581. define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)")
  6582. define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)")
  6583. define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t")
  6584. define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t")
  6585. define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t")
  6586. define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t")
  6587. define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t")
  6588. define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t")
  6589. define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t")
  6590. define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t")
  6591. define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)")
  6592. define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)")
  6593. define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)")
  6594. define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)")
  6595. define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)")
  6596. define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)")
  6597. define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)")
  6598. define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))")
  6599. define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))")
  6600. define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))")
  6601. define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))")
  6602. define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"")
  6603. define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"")
  6604. define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"")
  6605. define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"")
  6606. define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"")
  6607. define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"")
  6608. define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"")
  6609. define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"")
  6610. define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"")
  6611. define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"")
  6612. define_sfop4(94,((x < y) ? z : w),"")
  6613. define_sfop4(95,((x <= y) ? z : w),"")
  6614. define_sfop4(96,((x > y) ? z : w),"")
  6615. define_sfop4(97,((x >= y) ? z : w),"")
  6616. define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"")
  6617. define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"")
  6618. define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)")
  6619. define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)")
  6620. define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)")
  6621. define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)")
  6622. define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)")
  6623. define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)")
  6624. define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)")
  6625. define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)")
  6626. define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)")
  6627. define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)")
  6628. define_sfop4(ext10,((x + y) * (z - w)),"(t+t)*(t-t)")
  6629. define_sfop4(ext11,((x + y) / (z - w)),"(t+t)/(t-t)")
  6630. define_sfop4(ext12,((x - y) - (z + w)),"(t-t)-(t+t)")
  6631. define_sfop4(ext13,((x - y) + (z + w)),"(t-t)+(t+t)")
  6632. define_sfop4(ext14,((x - y) * (z + w)),"(t-t)*(t+t)")
  6633. define_sfop4(ext15,((x - y) / (z + w)),"(t-t)/(t+t)")
  6634. define_sfop4(ext16,((x * y) - (z + w)),"(t*t)-(t+t)")
  6635. define_sfop4(ext17,((x / y) - (z + w)),"(t/t)-(t+t)")
  6636. define_sfop4(ext18,((x * y) + (z + w)),"(t*t)+(t+t)")
  6637. define_sfop4(ext19,((x / y) + (z + w)),"(t/t)+(t+t)")
  6638. define_sfop4(ext20,((x * y) + (z - w)),"(t*t)+(t-t)")
  6639. define_sfop4(ext21,((x / y) + (z - w)),"(t/t)+(t-t)")
  6640. define_sfop4(ext22,((x * y) - (z - w)),"(t*t)-(t-t)")
  6641. define_sfop4(ext23,((x / y) - (z - w)),"(t/t)-(t-t)")
  6642. define_sfop4(ext24,((x + y) * (z * w)),"(t+t)*(t*t)")
  6643. define_sfop4(ext25,((x + y) * (z / w)),"(t+t)*(t/t)")
  6644. define_sfop4(ext26,((x + y) / (z * w)),"(t+t)/(t*t)")
  6645. define_sfop4(ext27,((x + y) / (z / w)),"(t+t)/(t/t)")
  6646. define_sfop4(ext28,((x - y) / (z * w)),"(t-t)/(t*t)")
  6647. define_sfop4(ext29,((x - y) / (z / w)),"(t-t)/(t/t)")
  6648. define_sfop4(ext30,((x - y) * (z * w)),"(t-t)*(t*t)")
  6649. define_sfop4(ext31,((x - y) * (z / w)),"(t-t)*(t/t)")
  6650. define_sfop4(ext32,((x * y) * (z + w)),"(t*t)*(t+t)")
  6651. define_sfop4(ext33,((x / y) * (z + w)),"(t/t)*(t+t)")
  6652. define_sfop4(ext34,((x * y) / (z + w)),"(t*t)/(t+t)")
  6653. define_sfop4(ext35,((x / y) / (z + w)),"(t/t)/(t+t)")
  6654. define_sfop4(ext36,((x * y) / (z - w)),"(t*t)/(t-t)")
  6655. define_sfop4(ext37,((x / y) / (z - w)),"(t/t)/(t-t)")
  6656. define_sfop4(ext38,((x * y) * (z - w)),"(t*t)*(t-t)")
  6657. define_sfop4(ext39,((x * y) / (z * w)),"(t*t)/(t*t)")
  6658. define_sfop4(ext40,((x / y) * (z / w)),"(t/t)*(t/t)")
  6659. define_sfop4(ext41,((x / y) * (z - w)),"(t/t)*(t-t)")
  6660. define_sfop4(ext42,((x * y) * (z * w)),"(t*t)*(t*t)")
  6661. define_sfop4(ext43,(x + (y * (z / w))),"t+(t*(t/t))")
  6662. define_sfop4(ext44,(x - (y * (z / w))),"t-(t*(t/t))")
  6663. define_sfop4(ext45,(x + (y / (z * w))),"t+(t/(t*t))")
  6664. define_sfop4(ext46,(x - (y / (z * w))),"t-(t/(t*t))")
  6665. define_sfop4(ext47,(((x - y) - z) * w),"((t-t)-t)*t")
  6666. define_sfop4(ext48,(((x - y) - z) / w),"((t-t)-t)/t")
  6667. define_sfop4(ext49,(((x - y) + z) * w),"((t-t)+t)*t")
  6668. define_sfop4(ext50,(((x - y) + z) / w),"((t-t)+t)/t")
  6669. define_sfop4(ext51,((x + (y - z)) * w),"(t+(t-t))*t")
  6670. define_sfop4(ext52,((x + (y - z)) / w),"(t+(t-t))/t")
  6671. define_sfop4(ext53,((x + y) / (z + w)),"(t+t)/(t+t)")
  6672. define_sfop4(ext54,((x - y) / (z - w)),"(t-t)/(t-t)")
  6673. define_sfop4(ext55,((x + y) * (z + w)),"(t+t)*(t+t)")
  6674. define_sfop4(ext56,((x - y) * (z - w)),"(t-t)*(t-t)")
  6675. define_sfop4(ext57,((x - y) + (z - w)),"(t-t)+(t-t)")
  6676. define_sfop4(ext58,((x - y) - (z - w)),"(t-t)-(t-t)")
  6677. define_sfop4(ext59,((x / y) + (z * w)),"(t/t)+(t*t)")
  6678. #undef define_sfop3
  6679. #undef define_sfop4
  6680. template <typename T, typename SpecialFunction>
  6681. class sf3_node : public trinary_node<T>
  6682. {
  6683. public:
  6684. typedef expression_node<T>* expression_ptr;
  6685. sf3_node(const operator_type& opr,
  6686. expression_ptr branch0,
  6687. expression_ptr branch1,
  6688. expression_ptr branch2)
  6689. : trinary_node<T>(opr,branch0,branch1,branch2)
  6690. {}
  6691. inline T value() const
  6692. {
  6693. const T x = trinary_node<T>::branch_[0].first->value();
  6694. const T y = trinary_node<T>::branch_[1].first->value();
  6695. const T z = trinary_node<T>::branch_[2].first->value();
  6696. return SpecialFunction::process(x,y,z);
  6697. }
  6698. };
  6699. template <typename T, typename SpecialFunction>
  6700. class sf4_node : public quaternary_node<T>
  6701. {
  6702. public:
  6703. typedef expression_node<T>* expression_ptr;
  6704. sf4_node(const operator_type& opr,
  6705. expression_ptr branch0,
  6706. expression_ptr branch1,
  6707. expression_ptr branch2,
  6708. expression_ptr branch3)
  6709. : quaternary_node<T>(opr,branch0,branch1,branch2,branch3)
  6710. {}
  6711. inline T value() const
  6712. {
  6713. const T x = quaternary_node<T>::branch_[0].first->value();
  6714. const T y = quaternary_node<T>::branch_[1].first->value();
  6715. const T z = quaternary_node<T>::branch_[2].first->value();
  6716. const T w = quaternary_node<T>::branch_[3].first->value();
  6717. return SpecialFunction::process(x,y,z,w);
  6718. }
  6719. };
  6720. template <typename T, typename SpecialFunction>
  6721. class sf3_var_node : public expression_node<T>
  6722. {
  6723. public:
  6724. typedef expression_node<T>* expression_ptr;
  6725. sf3_var_node(const T& v0, const T& v1, const T& v2)
  6726. : v0_(v0),
  6727. v1_(v1),
  6728. v2_(v2)
  6729. {}
  6730. inline T value() const
  6731. {
  6732. return SpecialFunction::process(v0_,v1_,v2_);
  6733. }
  6734. inline typename expression_node<T>::node_type type() const
  6735. {
  6736. return expression_node<T>::e_trinary;
  6737. }
  6738. private:
  6739. sf3_var_node(sf3_var_node<T,SpecialFunction>&);
  6740. sf3_var_node<T,SpecialFunction>& operator=(sf3_var_node<T,SpecialFunction>&);
  6741. const T& v0_;
  6742. const T& v1_;
  6743. const T& v2_;
  6744. };
  6745. template <typename T, typename SpecialFunction>
  6746. class sf4_var_node : public expression_node<T>
  6747. {
  6748. public:
  6749. typedef expression_node<T>* expression_ptr;
  6750. sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
  6751. : v0_(v0),
  6752. v1_(v1),
  6753. v2_(v2),
  6754. v3_(v3)
  6755. {}
  6756. inline T value() const
  6757. {
  6758. return SpecialFunction::process(v0_,v1_,v2_,v3_);
  6759. }
  6760. inline typename expression_node<T>::node_type type() const
  6761. {
  6762. return expression_node<T>::e_trinary;
  6763. }
  6764. private:
  6765. sf4_var_node(sf4_var_node<T,SpecialFunction>&);
  6766. sf4_var_node<T,SpecialFunction>& operator=(sf4_var_node<T,SpecialFunction>&);
  6767. const T& v0_;
  6768. const T& v1_;
  6769. const T& v2_;
  6770. const T& v3_;
  6771. };
  6772. template <typename T, typename VarArgFunction>
  6773. class vararg_node : public expression_node<T>
  6774. {
  6775. public:
  6776. typedef expression_node<T>* expression_ptr;
  6777. template <typename Allocator,
  6778. template <typename,typename> class Sequence>
  6779. vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
  6780. {
  6781. arg_list_.resize(arg_list.size());
  6782. delete_branch_.resize(arg_list.size());
  6783. for (std::size_t i = 0; i < arg_list.size(); ++i)
  6784. {
  6785. if (arg_list[i])
  6786. {
  6787. arg_list_[i] = arg_list[i];
  6788. delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
  6789. }
  6790. else
  6791. {
  6792. arg_list_.clear();
  6793. delete_branch_.clear();
  6794. return;
  6795. }
  6796. }
  6797. }
  6798. ~vararg_node()
  6799. {
  6800. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  6801. {
  6802. if (arg_list_[i] && delete_branch_[i])
  6803. {
  6804. delete arg_list_[i];
  6805. arg_list_[i] = 0;
  6806. }
  6807. }
  6808. }
  6809. inline T value() const
  6810. {
  6811. if (!arg_list_.empty())
  6812. return VarArgFunction::process(arg_list_);
  6813. else
  6814. return std::numeric_limits<T>::quiet_NaN();
  6815. }
  6816. inline typename expression_node<T>::node_type type() const
  6817. {
  6818. return expression_node<T>::e_vararg;
  6819. }
  6820. private:
  6821. std::vector<expression_ptr> arg_list_;
  6822. std::vector<unsigned char> delete_branch_;
  6823. };
  6824. template <typename T, typename VarArgFunction>
  6825. class vararg_varnode : public expression_node<T>
  6826. {
  6827. public:
  6828. typedef expression_node<T>* expression_ptr;
  6829. template <typename Allocator,
  6830. template <typename,typename> class Sequence>
  6831. vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
  6832. {
  6833. arg_list_.resize(arg_list.size());
  6834. for (std::size_t i = 0; i < arg_list.size(); ++i)
  6835. {
  6836. if (arg_list[i] && is_variable_node(arg_list[i]))
  6837. {
  6838. variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]);
  6839. arg_list_[i] = (&var_node_ptr->ref());
  6840. }
  6841. else
  6842. {
  6843. arg_list_.clear();
  6844. return;
  6845. }
  6846. }
  6847. }
  6848. inline T value() const
  6849. {
  6850. if (!arg_list_.empty())
  6851. return VarArgFunction::process(arg_list_);
  6852. else
  6853. return std::numeric_limits<T>::quiet_NaN();
  6854. }
  6855. inline typename expression_node<T>::node_type type() const
  6856. {
  6857. return expression_node<T>::e_vararg;
  6858. }
  6859. private:
  6860. std::vector<const T*> arg_list_;
  6861. };
  6862. template <typename T, typename VecFunction>
  6863. class vectorize_node : public expression_node<T>
  6864. {
  6865. public:
  6866. typedef expression_node<T>* expression_ptr;
  6867. vectorize_node(const expression_ptr v)
  6868. : ivec_ptr_(0),
  6869. v_(v),
  6870. v_deletable_(branch_deletable(v_))
  6871. {
  6872. if (is_ivector_node(v))
  6873. {
  6874. ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v);
  6875. }
  6876. else
  6877. ivec_ptr_ = 0;
  6878. }
  6879. ~vectorize_node()
  6880. {
  6881. if (v_ && v_deletable_)
  6882. {
  6883. delete v_;
  6884. }
  6885. }
  6886. inline T value() const
  6887. {
  6888. if (ivec_ptr_)
  6889. {
  6890. v_->value();
  6891. return VecFunction::process(ivec_ptr_);
  6892. }
  6893. else
  6894. return std::numeric_limits<T>::quiet_NaN();
  6895. }
  6896. inline typename expression_node<T>::node_type type() const
  6897. {
  6898. return expression_node<T>::e_vecfunc;
  6899. }
  6900. private:
  6901. vector_interface<T>* ivec_ptr_;
  6902. expression_ptr v_;
  6903. bool v_deletable_;
  6904. };
  6905. template <typename T>
  6906. class assignment_node : public binary_node<T>
  6907. {
  6908. public:
  6909. typedef expression_node<T>* expression_ptr;
  6910. assignment_node(const operator_type& opr,
  6911. expression_ptr branch0,
  6912. expression_ptr branch1)
  6913. : binary_node<T>(opr,branch0,branch1),
  6914. var_node_ptr_(0)
  6915. {
  6916. if (is_variable_node(binary_node<T>::branch_[0].first))
  6917. {
  6918. var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
  6919. }
  6920. }
  6921. inline T value() const
  6922. {
  6923. if (var_node_ptr_)
  6924. {
  6925. T& result = var_node_ptr_->ref();
  6926. result = binary_node<T>::branch_[1].first->value();
  6927. return result;
  6928. }
  6929. else
  6930. return std::numeric_limits<T>::quiet_NaN();
  6931. }
  6932. private:
  6933. variable_node<T>* var_node_ptr_;
  6934. };
  6935. template <typename T>
  6936. class assignment_vec_elem_node : public binary_node<T>
  6937. {
  6938. public:
  6939. typedef expression_node<T>* expression_ptr;
  6940. assignment_vec_elem_node(const operator_type& opr,
  6941. expression_ptr branch0,
  6942. expression_ptr branch1)
  6943. : binary_node<T>(opr,branch0,branch1),
  6944. vec_node_ptr_(0)
  6945. {
  6946. if (is_vector_elem_node(binary_node<T>::branch_[0].first))
  6947. {
  6948. vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
  6949. }
  6950. }
  6951. inline T value() const
  6952. {
  6953. if (vec_node_ptr_)
  6954. {
  6955. T& result = vec_node_ptr_->ref();
  6956. result = binary_node<T>::branch_[1].first->value();
  6957. return result;
  6958. }
  6959. else
  6960. return std::numeric_limits<T>::quiet_NaN();
  6961. }
  6962. private:
  6963. vector_elem_node<T>* vec_node_ptr_;
  6964. };
  6965. template <typename T>
  6966. class assignment_vec_node : public binary_node <T>,
  6967. public vector_interface<T>
  6968. {
  6969. public:
  6970. typedef expression_node<T>* expression_ptr;
  6971. typedef vector_node<T>* vector_node_ptr;
  6972. assignment_vec_node(const operator_type& opr,
  6973. expression_ptr branch0,
  6974. expression_ptr branch1)
  6975. : binary_node<T>(opr,branch0,branch1),
  6976. vec_node_ptr_(0),
  6977. vec_size_ (0)
  6978. {
  6979. if (is_vector_node(binary_node<T>::branch_[0].first))
  6980. {
  6981. vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  6982. vec_size_ = vec_node_ptr_->ref().size();
  6983. }
  6984. }
  6985. inline T value() const
  6986. {
  6987. if (vec_node_ptr_)
  6988. {
  6989. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  6990. const T v = binary_node<T>::branch_[1].first->value();
  6991. for (std::size_t i = 0; i < vec_size_; ++i)
  6992. {
  6993. (*vec_hldr[i]) = v;
  6994. }
  6995. return vec_node_ptr_->value();
  6996. }
  6997. else
  6998. return std::numeric_limits<T>::quiet_NaN();
  6999. }
  7000. vector_node_ptr vec() const
  7001. {
  7002. return vec_node_ptr_;
  7003. }
  7004. vector_node_ptr vec()
  7005. {
  7006. return vec_node_ptr_;
  7007. }
  7008. inline typename expression_node<T>::node_type type() const
  7009. {
  7010. return expression_node<T>::e_vecvalass;
  7011. }
  7012. std::size_t size() const
  7013. {
  7014. return vec_size_;
  7015. }
  7016. private:
  7017. vector_node<T>* vec_node_ptr_;
  7018. std::size_t vec_size_;
  7019. };
  7020. template <typename T>
  7021. class assignment_vecvec_node : public binary_node <T>,
  7022. public vector_interface<T>
  7023. {
  7024. public:
  7025. typedef expression_node<T>* expression_ptr;
  7026. typedef vector_node<T>* vector_node_ptr;
  7027. assignment_vecvec_node(const operator_type& opr,
  7028. expression_ptr branch0,
  7029. expression_ptr branch1)
  7030. : binary_node<T>(opr,branch0,branch1),
  7031. vec0_node_ptr_(0),
  7032. vec1_node_ptr_(0),
  7033. vec_size_ (0)
  7034. {
  7035. if (is_vector_node(binary_node<T>::branch_[0].first))
  7036. {
  7037. vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  7038. }
  7039. if (is_vector_node(binary_node<T>::branch_[1].first))
  7040. {
  7041. vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
  7042. }
  7043. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7044. {
  7045. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7046. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7047. {
  7048. vec1_node_ptr_ = vi->vec();
  7049. }
  7050. }
  7051. if (vec0_node_ptr_ && vec1_node_ptr_)
  7052. {
  7053. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  7054. vec1_node_ptr_->ref().size());
  7055. }
  7056. }
  7057. inline T value() const
  7058. {
  7059. binary_node<T>::branch_[1].first->value();
  7060. if (vec0_node_ptr_ && vec1_node_ptr_)
  7061. {
  7062. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7063. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7064. for (std::size_t i = 0; i < vec_size_; ++i)
  7065. {
  7066. (*vec0[i]) = (*vec1[i]);
  7067. }
  7068. return vec0_node_ptr_->value();
  7069. }
  7070. else
  7071. return std::numeric_limits<T>::quiet_NaN();
  7072. }
  7073. vector_node_ptr vec() const
  7074. {
  7075. return vec0_node_ptr_;
  7076. }
  7077. vector_node_ptr vec()
  7078. {
  7079. return vec0_node_ptr_;
  7080. }
  7081. inline typename expression_node<T>::node_type type() const
  7082. {
  7083. return expression_node<T>::e_vecvecass;
  7084. }
  7085. std::size_t size() const
  7086. {
  7087. return vec_size_;
  7088. }
  7089. private:
  7090. vector_node<T>* vec0_node_ptr_;
  7091. vector_node<T>* vec1_node_ptr_;
  7092. std::size_t vec_size_;
  7093. };
  7094. template <typename T, typename Operation>
  7095. class assignment_op_node : public binary_node<T>
  7096. {
  7097. public:
  7098. typedef expression_node<T>* expression_ptr;
  7099. assignment_op_node(const operator_type& opr,
  7100. expression_ptr branch0,
  7101. expression_ptr branch1)
  7102. : binary_node<T>(opr,branch0,branch1),
  7103. var_node_ptr_(0)
  7104. {
  7105. if (is_variable_node(binary_node<T>::branch_[0].first))
  7106. {
  7107. var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
  7108. }
  7109. }
  7110. inline T value() const
  7111. {
  7112. if (var_node_ptr_)
  7113. {
  7114. T& v = var_node_ptr_->ref();
  7115. v = Operation::process(v,binary_node<T>::branch_[1].first->value());
  7116. return v;
  7117. }
  7118. else
  7119. return std::numeric_limits<T>::quiet_NaN();
  7120. }
  7121. private:
  7122. variable_node<T>* var_node_ptr_;
  7123. };
  7124. template <typename T, typename Operation>
  7125. class assignment_vec_elem_op_node : public binary_node<T>
  7126. {
  7127. public:
  7128. typedef expression_node<T>* expression_ptr;
  7129. assignment_vec_elem_op_node(const operator_type& opr,
  7130. expression_ptr branch0,
  7131. expression_ptr branch1)
  7132. : binary_node<T>(opr,branch0,branch1),
  7133. vec_node_ptr_(0)
  7134. {
  7135. if (is_vector_elem_node(binary_node<T>::branch_[0].first))
  7136. {
  7137. vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
  7138. }
  7139. }
  7140. inline T value() const
  7141. {
  7142. if (vec_node_ptr_)
  7143. {
  7144. T& v = vec_node_ptr_->ref();
  7145. v = Operation::process(v,binary_node<T>::branch_[1].first->value());
  7146. return v;
  7147. }
  7148. else
  7149. return std::numeric_limits<T>::quiet_NaN();
  7150. }
  7151. private:
  7152. vector_elem_node<T>* vec_node_ptr_;
  7153. };
  7154. template <typename T, typename Operation>
  7155. class assignment_vec_op_node : public binary_node <T>,
  7156. public vector_interface<T>
  7157. {
  7158. public:
  7159. typedef expression_node<T>* expression_ptr;
  7160. typedef vector_node<T>* vector_node_ptr;
  7161. assignment_vec_op_node(const operator_type& opr,
  7162. expression_ptr branch0,
  7163. expression_ptr branch1)
  7164. : binary_node<T>(opr,branch0,branch1),
  7165. vec_node_ptr_(0),
  7166. vec_size_ (0)
  7167. {
  7168. if (is_vector_node(binary_node<T>::branch_[0].first))
  7169. {
  7170. vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  7171. vec_size_ = vec_node_ptr_->ref().size();
  7172. }
  7173. }
  7174. inline T value() const
  7175. {
  7176. if (vec_node_ptr_)
  7177. {
  7178. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  7179. const T v = binary_node<T>::branch_[1].first->value();
  7180. for (std::size_t i = 0; i < vec_size_; ++i)
  7181. {
  7182. T& vec_i = *vec_hldr[i];
  7183. vec_i = Operation::process(vec_i,v);
  7184. }
  7185. return vec_node_ptr_->value();
  7186. }
  7187. else
  7188. return std::numeric_limits<T>::quiet_NaN();
  7189. }
  7190. vector_node_ptr vec() const
  7191. {
  7192. return vec_node_ptr_;
  7193. }
  7194. vector_node_ptr vec()
  7195. {
  7196. return vec_node_ptr_;
  7197. }
  7198. inline typename expression_node<T>::node_type type() const
  7199. {
  7200. return expression_node<T>::e_vecopvalass;
  7201. }
  7202. std::size_t size() const
  7203. {
  7204. return vec_size_;
  7205. }
  7206. private:
  7207. vector_node<T>* vec_node_ptr_;
  7208. std::size_t vec_size_;
  7209. };
  7210. template <typename T, typename Operation>
  7211. class assignment_vecvec_op_node : public binary_node <T>,
  7212. public vector_interface<T>
  7213. {
  7214. public:
  7215. typedef expression_node<T>* expression_ptr;
  7216. typedef vector_node<T>* vector_node_ptr;
  7217. assignment_vecvec_op_node(const operator_type& opr,
  7218. expression_ptr branch0,
  7219. expression_ptr branch1)
  7220. : binary_node<T>(opr,branch0,branch1),
  7221. vec0_node_ptr_(0),
  7222. vec1_node_ptr_(0),
  7223. vec_size_ (0)
  7224. {
  7225. if (is_vector_node(binary_node<T>::branch_[0].first))
  7226. {
  7227. vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  7228. }
  7229. if (is_vector_node(binary_node<T>::branch_[1].first))
  7230. {
  7231. vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
  7232. }
  7233. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7234. {
  7235. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7236. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7237. {
  7238. vec1_node_ptr_ = vi->vec();
  7239. }
  7240. }
  7241. if (vec0_node_ptr_ && vec1_node_ptr_)
  7242. {
  7243. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  7244. vec1_node_ptr_->ref().size());
  7245. }
  7246. }
  7247. inline T value() const
  7248. {
  7249. if (vec0_node_ptr_ && vec1_node_ptr_)
  7250. {
  7251. binary_node<T>::branch_[0].first->value();
  7252. binary_node<T>::branch_[1].first->value();
  7253. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7254. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7255. for (std::size_t i = 0; i < vec_size_; ++i)
  7256. {
  7257. T& vec0_i = *vec0[i];
  7258. T& vec1_i = *vec1[i];
  7259. vec0_i = Operation::process(vec0_i,vec1_i);
  7260. }
  7261. return vec0_node_ptr_->value();
  7262. }
  7263. else
  7264. return std::numeric_limits<T>::quiet_NaN();
  7265. }
  7266. vector_node_ptr vec() const
  7267. {
  7268. return vec0_node_ptr_;
  7269. }
  7270. vector_node_ptr vec()
  7271. {
  7272. return vec0_node_ptr_;
  7273. }
  7274. inline typename expression_node<T>::node_type type() const
  7275. {
  7276. return expression_node<T>::e_vecopvecass;
  7277. }
  7278. std::size_t size() const
  7279. {
  7280. return vec_size_;
  7281. }
  7282. private:
  7283. vector_node<T>* vec0_node_ptr_;
  7284. vector_node<T>* vec1_node_ptr_;
  7285. std::size_t vec_size_;
  7286. };
  7287. template <typename T, typename Operation>
  7288. class eqineq_vecvec_node : public binary_node <T>,
  7289. public vector_interface<T>
  7290. {
  7291. public:
  7292. typedef expression_node<T>* expression_ptr;
  7293. typedef vector_node<T>* vector_node_ptr;
  7294. eqineq_vecvec_node(const operator_type& opr,
  7295. expression_ptr branch0,
  7296. expression_ptr branch1)
  7297. : binary_node<T>(opr,branch0,branch1),
  7298. vec0_node_ptr_(0),
  7299. vec1_node_ptr_(0),
  7300. vec_size_ (0)
  7301. {
  7302. if (is_vector_node(binary_node<T>::branch_[0].first))
  7303. {
  7304. vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
  7305. }
  7306. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  7307. {
  7308. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7309. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  7310. {
  7311. vec0_node_ptr_ = vi->vec();
  7312. }
  7313. }
  7314. if (is_vector_node(binary_node<T>::branch_[1].first))
  7315. {
  7316. vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
  7317. }
  7318. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7319. {
  7320. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7321. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7322. {
  7323. vec1_node_ptr_ = vi->vec();
  7324. }
  7325. }
  7326. if (vec0_node_ptr_ && vec1_node_ptr_)
  7327. {
  7328. vec_size_ = std::min(vec0_node_ptr_->ref().size(),
  7329. vec1_node_ptr_->ref().size());
  7330. }
  7331. }
  7332. inline T value() const
  7333. {
  7334. if (vec0_node_ptr_ && vec1_node_ptr_)
  7335. {
  7336. binary_node<T>::branch_[0].first->value();
  7337. binary_node<T>::branch_[1].first->value();
  7338. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7339. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7340. for (std::size_t i = 0; i < vec_size_; ++i)
  7341. {
  7342. if (std::equal_to<T>()(T(0),Operation::process(*vec0[i],*vec1[i])))
  7343. {
  7344. return T(0);
  7345. }
  7346. }
  7347. return T(1);
  7348. }
  7349. else
  7350. return std::numeric_limits<T>::quiet_NaN();
  7351. }
  7352. vector_node_ptr vec() const
  7353. {
  7354. return vec0_node_ptr_;
  7355. }
  7356. vector_node_ptr vec()
  7357. {
  7358. return vec0_node_ptr_;
  7359. }
  7360. inline typename expression_node<T>::node_type type() const
  7361. {
  7362. return expression_node<T>::e_vecvecineq;
  7363. }
  7364. std::size_t size() const
  7365. {
  7366. return vec_size_;
  7367. }
  7368. private:
  7369. vector_node<T>* vec0_node_ptr_;
  7370. vector_node<T>* vec1_node_ptr_;
  7371. std::size_t vec_size_;
  7372. };
  7373. template <typename T, typename Operation>
  7374. class eqineq_vecval_node : public binary_node <T>,
  7375. public vector_interface<T>
  7376. {
  7377. public:
  7378. typedef expression_node<T>* expression_ptr;
  7379. typedef vector_node<T>* vector_node_ptr;
  7380. eqineq_vecval_node(const operator_type& opr,
  7381. expression_ptr branch0,
  7382. expression_ptr branch1)
  7383. : binary_node<T>(opr,branch0,branch1),
  7384. vec_node_ptr_(0),
  7385. vec_size_ (0)
  7386. {
  7387. if (is_vector_node(binary_node<T>::branch_[0].first))
  7388. {
  7389. vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
  7390. }
  7391. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  7392. {
  7393. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7394. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  7395. {
  7396. vec_node_ptr_ = vi->vec();
  7397. }
  7398. }
  7399. if (vec_node_ptr_)
  7400. {
  7401. vec_size_ = vec_node_ptr_->ref().size();
  7402. }
  7403. }
  7404. inline T value() const
  7405. {
  7406. if (vec_node_ptr_)
  7407. {
  7408. binary_node<T>::branch_[0].first->value();
  7409. T v = binary_node<T>::branch_[1].first->value();
  7410. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  7411. for (std::size_t i = 0; i < vec_size_; ++i)
  7412. {
  7413. if (std::equal_to<T>()(T(0),Operation::process(*vec_hldr[i],v)))
  7414. {
  7415. return T(0);
  7416. }
  7417. }
  7418. return T(1);
  7419. }
  7420. else
  7421. return std::numeric_limits<T>::quiet_NaN();
  7422. }
  7423. vector_node_ptr vec() const
  7424. {
  7425. return vec_node_ptr_;
  7426. }
  7427. vector_node_ptr vec()
  7428. {
  7429. return vec_node_ptr_;
  7430. }
  7431. inline typename expression_node<T>::node_type type() const
  7432. {
  7433. return expression_node<T>::e_vecvalineq;
  7434. }
  7435. std::size_t size() const
  7436. {
  7437. return vec_size_;
  7438. }
  7439. private:
  7440. vector_node<T>* vec_node_ptr_;
  7441. std::size_t vec_size_;
  7442. };
  7443. template <typename T, typename Operation>
  7444. class eqineq_valvec_node : public binary_node <T>,
  7445. public vector_interface<T>
  7446. {
  7447. public:
  7448. typedef expression_node<T>* expression_ptr;
  7449. typedef vector_node<T>* vector_node_ptr;
  7450. eqineq_valvec_node(const operator_type& opr,
  7451. expression_ptr branch0,
  7452. expression_ptr branch1)
  7453. : binary_node<T>(opr,branch0,branch1),
  7454. vec_node_ptr_(0),
  7455. vec_size_ (0)
  7456. {
  7457. if (is_vector_node(binary_node<T>::branch_[1].first))
  7458. {
  7459. vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
  7460. }
  7461. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7462. {
  7463. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7464. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7465. {
  7466. vec_node_ptr_ = vi->vec();
  7467. }
  7468. }
  7469. if (vec_node_ptr_)
  7470. {
  7471. vec_size_ = vec_node_ptr_->ref().size();
  7472. }
  7473. }
  7474. inline T value() const
  7475. {
  7476. if (vec_node_ptr_)
  7477. {
  7478. T v = binary_node<T>::branch_[0].first->value();
  7479. binary_node<T>::branch_[1].first->value();
  7480. vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
  7481. for (std::size_t i = 0; i < vec_size_; ++i)
  7482. {
  7483. if (std::equal_to<T>()(T(0),Operation::process(v,*vec_hldr[i])))
  7484. {
  7485. return T(0);
  7486. }
  7487. }
  7488. return T(1);
  7489. }
  7490. else
  7491. return std::numeric_limits<T>::quiet_NaN();
  7492. }
  7493. vector_node_ptr vec() const
  7494. {
  7495. return vec_node_ptr_;
  7496. }
  7497. vector_node_ptr vec()
  7498. {
  7499. return vec_node_ptr_;
  7500. }
  7501. inline typename expression_node<T>::node_type type() const
  7502. {
  7503. return expression_node<T>::e_valvecineq;
  7504. }
  7505. std::size_t size() const
  7506. {
  7507. return vec_size_;
  7508. }
  7509. private:
  7510. vector_node<T>* vec_node_ptr_;
  7511. std::size_t vec_size_;
  7512. };
  7513. template <typename T, typename Operation>
  7514. class vecarith_vecvec_node : public binary_node <T>,
  7515. public vector_interface<T>
  7516. {
  7517. public:
  7518. typedef expression_node<T>* expression_ptr;
  7519. typedef vector_node<T>* vector_node_ptr;
  7520. typedef vector_holder<T>* vector_holder_ptr;
  7521. vecarith_vecvec_node(const operator_type& opr,
  7522. expression_ptr branch0,
  7523. expression_ptr branch1)
  7524. : binary_node<T>(opr,branch0,branch1),
  7525. vec0_node_ptr_(0),
  7526. vec1_node_ptr_(0),
  7527. vec_size_ (0),
  7528. data_ (0),
  7529. temp_ (0),
  7530. temp_vec_node_(0)
  7531. {
  7532. if (is_vector_node(binary_node<T>::branch_[0].first))
  7533. {
  7534. vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
  7535. }
  7536. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  7537. {
  7538. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7539. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  7540. {
  7541. vec0_node_ptr_ = vi->vec();
  7542. }
  7543. }
  7544. if (is_vector_node(binary_node<T>::branch_[1].first))
  7545. {
  7546. vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
  7547. }
  7548. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7549. {
  7550. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7551. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7552. {
  7553. vec1_node_ptr_ = vi->vec();
  7554. }
  7555. }
  7556. if (vec0_node_ptr_ && vec1_node_ptr_)
  7557. {
  7558. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7559. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7560. vec_size_ = std::min(vec0.size(),vec1.size());
  7561. data_ = new T[vec_size_];
  7562. temp_ = new vector_holder<T>(data_,vec_size_);
  7563. temp_vec_node_ = new vector_node<T> (temp_);
  7564. }
  7565. }
  7566. ~vecarith_vecvec_node()
  7567. {
  7568. delete[] data_;
  7569. delete temp_;
  7570. delete temp_vec_node_;
  7571. }
  7572. inline T value() const
  7573. {
  7574. if (vec0_node_ptr_ && vec1_node_ptr_)
  7575. {
  7576. binary_node<T>::branch_[0].first->value();
  7577. binary_node<T>::branch_[1].first->value();
  7578. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7579. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7580. vector_holder<T>& vec2 = *temp_;
  7581. for (std::size_t i = 0; i < vec_size_; ++i)
  7582. {
  7583. T& vec0_i = *vec0[i];
  7584. T& vec1_i = *vec1[i];
  7585. T& vec2_i = *vec2[i];
  7586. vec2_i = Operation::process(vec0_i,vec1_i);
  7587. }
  7588. return *vec2[0];
  7589. }
  7590. else
  7591. return std::numeric_limits<T>::quiet_NaN();
  7592. }
  7593. vector_node_ptr vec() const
  7594. {
  7595. return temp_vec_node_;
  7596. }
  7597. vector_node_ptr vec()
  7598. {
  7599. return temp_vec_node_;
  7600. }
  7601. inline typename expression_node<T>::node_type type() const
  7602. {
  7603. return expression_node<T>::e_vecvecarith;
  7604. }
  7605. std::size_t size() const
  7606. {
  7607. return vec_size_;
  7608. }
  7609. private:
  7610. vector_node_ptr vec0_node_ptr_;
  7611. vector_node_ptr vec1_node_ptr_;
  7612. std::size_t vec_size_;
  7613. T* data_;
  7614. vector_holder_ptr temp_;
  7615. vector_node_ptr temp_vec_node_;
  7616. };
  7617. template <typename T, typename Operation>
  7618. class vecarith_vecval_node : public binary_node <T>,
  7619. public vector_interface<T>
  7620. {
  7621. public:
  7622. typedef expression_node<T>* expression_ptr;
  7623. typedef vector_node<T>* vector_node_ptr;
  7624. typedef vector_holder<T>* vector_holder_ptr;
  7625. vecarith_vecval_node(const operator_type& opr,
  7626. expression_ptr branch0,
  7627. expression_ptr branch1)
  7628. : binary_node<T>(opr,branch0,branch1),
  7629. vec0_node_ptr_(0),
  7630. vec_size_ (0),
  7631. data_ (0),
  7632. temp_ (0),
  7633. temp_vec_node_(0)
  7634. {
  7635. if (is_vector_node(binary_node<T>::branch_[0].first))
  7636. {
  7637. vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
  7638. }
  7639. else if (is_ivector_node(binary_node<T>::branch_[0].first))
  7640. {
  7641. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7642. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
  7643. {
  7644. vec0_node_ptr_ = vi->vec();
  7645. }
  7646. }
  7647. if (vec0_node_ptr_)
  7648. {
  7649. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7650. vec_size_ = vec0.size();
  7651. data_ = new T[vec_size_];
  7652. temp_ = new vector_holder<T>(data_,vec_size_);
  7653. temp_vec_node_ = new vector_node<T> (temp_);
  7654. }
  7655. }
  7656. ~vecarith_vecval_node()
  7657. {
  7658. delete[] data_;
  7659. delete temp_;
  7660. delete temp_vec_node_;
  7661. }
  7662. inline T value() const
  7663. {
  7664. if (vec0_node_ptr_)
  7665. {
  7666. binary_node<T>::branch_[0].first->value();
  7667. const T v = binary_node<T>::branch_[1].first->value();
  7668. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7669. vector_holder<T>& vec1 = *temp_;
  7670. for (std::size_t i = 0; i < vec_size_; ++i)
  7671. {
  7672. T& vec0_i = *vec0[i];
  7673. T& vec1_i = *vec1[i];
  7674. vec1_i = Operation::process(vec0_i,v);
  7675. }
  7676. return *vec1[0];
  7677. }
  7678. else
  7679. return std::numeric_limits<T>::quiet_NaN();
  7680. }
  7681. vector_node_ptr vec() const
  7682. {
  7683. return temp_vec_node_;
  7684. }
  7685. vector_node_ptr vec()
  7686. {
  7687. return temp_vec_node_;
  7688. }
  7689. inline typename expression_node<T>::node_type type() const
  7690. {
  7691. return expression_node<T>::e_vecvalarith;
  7692. }
  7693. std::size_t size() const
  7694. {
  7695. return vec_size_;
  7696. }
  7697. private:
  7698. vector_node_ptr vec0_node_ptr_;
  7699. std::size_t vec_size_;
  7700. T* data_;
  7701. vector_holder_ptr temp_;
  7702. vector_node_ptr temp_vec_node_;
  7703. };
  7704. template <typename T, typename Operation>
  7705. class vecarith_valvec_node : public binary_node <T>,
  7706. public vector_interface<T>
  7707. {
  7708. public:
  7709. typedef expression_node<T>* expression_ptr;
  7710. typedef vector_node<T>* vector_node_ptr;
  7711. typedef vector_holder<T>* vector_holder_ptr;
  7712. vecarith_valvec_node(const operator_type& opr,
  7713. expression_ptr branch0,
  7714. expression_ptr branch1)
  7715. : binary_node<T>(opr,branch0,branch1),
  7716. vec1_node_ptr_(0),
  7717. vec_size_ (0),
  7718. data_ (0),
  7719. temp_ (0),
  7720. temp_vec_node_(0)
  7721. {
  7722. if (is_vector_node(binary_node<T>::branch_[1].first))
  7723. {
  7724. vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
  7725. }
  7726. else if (is_ivector_node(binary_node<T>::branch_[1].first))
  7727. {
  7728. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7729. if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
  7730. {
  7731. vec1_node_ptr_ = vi->vec();
  7732. }
  7733. }
  7734. if (vec1_node_ptr_)
  7735. {
  7736. vector_holder<T>& vec0 = vec1_node_ptr_->ref();
  7737. vec_size_ = vec0.size();
  7738. data_ = new T[vec_size_];
  7739. temp_ = new vector_holder<T>(data_,vec_size_);
  7740. temp_vec_node_ = new vector_node<T> (temp_);
  7741. }
  7742. }
  7743. ~vecarith_valvec_node()
  7744. {
  7745. delete[] data_;
  7746. delete temp_;
  7747. delete temp_vec_node_;
  7748. }
  7749. inline T value() const
  7750. {
  7751. if (vec1_node_ptr_)
  7752. {
  7753. const T v = binary_node<T>::branch_[0].first->value();
  7754. binary_node<T>::branch_[1].first->value();
  7755. vector_holder<T>& vec1 = vec1_node_ptr_->ref();
  7756. vector_holder<T>& vec2 = *temp_;
  7757. for (std::size_t i = 0; i < vec_size_; ++i)
  7758. {
  7759. T& vec1_i = *vec1[i];
  7760. T& vec2_i = *vec2[i];
  7761. vec2_i = Operation::process(v,vec1_i);
  7762. }
  7763. return *vec2[0];
  7764. }
  7765. else
  7766. return std::numeric_limits<T>::quiet_NaN();
  7767. }
  7768. vector_node_ptr vec() const
  7769. {
  7770. return temp_vec_node_;
  7771. }
  7772. vector_node_ptr vec()
  7773. {
  7774. return temp_vec_node_;
  7775. }
  7776. inline typename expression_node<T>::node_type type() const
  7777. {
  7778. return expression_node<T>::e_vecvalarith;
  7779. }
  7780. std::size_t size() const
  7781. {
  7782. return vec_size_;
  7783. }
  7784. private:
  7785. vector_node_ptr vec1_node_ptr_;
  7786. std::size_t vec_size_;
  7787. T* data_;
  7788. vector_holder_ptr temp_;
  7789. vector_node_ptr temp_vec_node_;
  7790. };
  7791. template <typename T, typename Operation>
  7792. class unary_vector_node : public unary_node <T>,
  7793. public vector_interface<T>
  7794. {
  7795. public:
  7796. typedef expression_node<T>* expression_ptr;
  7797. typedef vector_node<T>* vector_node_ptr;
  7798. typedef vector_holder<T>* vector_holder_ptr;
  7799. unary_vector_node(const operator_type& opr, expression_ptr branch0)
  7800. : unary_node<T>(opr,branch0),
  7801. vec0_node_ptr_(0),
  7802. vec_size_ (0),
  7803. data_ (0),
  7804. temp_ (0),
  7805. temp_vec_node_(0)
  7806. {
  7807. if (is_vector_node(unary_node<T>::branch_))
  7808. {
  7809. vec0_node_ptr_ = static_cast<vector_node_ptr>(unary_node<T>::branch_);
  7810. }
  7811. else if (is_ivector_node(unary_node<T>::branch_))
  7812. {
  7813. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  7814. if ((vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_)))
  7815. {
  7816. vec0_node_ptr_ = vi->vec();
  7817. }
  7818. }
  7819. if (vec0_node_ptr_)
  7820. {
  7821. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7822. vec_size_ = vec0.size();
  7823. data_ = new T[vec_size_];
  7824. temp_ = new vector_holder<T>(data_,vec_size_);
  7825. temp_vec_node_ = new vector_node<T> (temp_);
  7826. }
  7827. }
  7828. ~unary_vector_node()
  7829. {
  7830. delete[] data_;
  7831. delete temp_;
  7832. delete temp_vec_node_;
  7833. }
  7834. inline T value() const
  7835. {
  7836. unary_node<T>::branch_->value();
  7837. if (vec0_node_ptr_)
  7838. {
  7839. vector_holder<T>& vec0 = vec0_node_ptr_->ref();
  7840. vector_holder<T>& vec1 = *temp_;
  7841. for (std::size_t i = 0; i < vec_size_; ++i)
  7842. {
  7843. T& vec0_i = *vec0[i];
  7844. T& vec1_i = *vec1[i];
  7845. vec1_i = Operation::process(vec0_i);
  7846. }
  7847. return *vec1[0];
  7848. }
  7849. else
  7850. return std::numeric_limits<T>::quiet_NaN();
  7851. }
  7852. vector_node_ptr vec() const
  7853. {
  7854. return temp_vec_node_;
  7855. }
  7856. vector_node_ptr vec()
  7857. {
  7858. return temp_vec_node_;
  7859. }
  7860. inline typename expression_node<T>::node_type type() const
  7861. {
  7862. return expression_node<T>::e_vecunaryop;
  7863. }
  7864. std::size_t size() const
  7865. {
  7866. return vec_size_;
  7867. }
  7868. private:
  7869. vector_node_ptr vec0_node_ptr_;
  7870. std::size_t vec_size_;
  7871. T* data_;
  7872. vector_holder_ptr temp_;
  7873. vector_node_ptr temp_vec_node_;
  7874. };
  7875. template <typename T>
  7876. class scand_node : public binary_node<T>
  7877. {
  7878. public:
  7879. typedef expression_node<T>* expression_ptr;
  7880. scand_node(const operator_type& opr,
  7881. expression_ptr branch0,
  7882. expression_ptr branch1)
  7883. : binary_node<T>(opr,branch0,branch1)
  7884. {}
  7885. inline T value() const
  7886. {
  7887. return (
  7888. std::not_equal_to<T>()
  7889. (T(0),binary_node<T>::branch_[0].first->value()) &&
  7890. std::not_equal_to<T>()
  7891. (T(0),binary_node<T>::branch_[1].first->value())
  7892. ) ? T(1) : T(0);
  7893. }
  7894. };
  7895. template <typename T>
  7896. class scor_node : public binary_node<T>
  7897. {
  7898. public:
  7899. typedef expression_node<T>* expression_ptr;
  7900. scor_node(const operator_type& opr,
  7901. expression_ptr branch0,
  7902. expression_ptr branch1)
  7903. : binary_node<T>(opr,branch0,branch1)
  7904. {}
  7905. inline T value() const
  7906. {
  7907. return (
  7908. std::not_equal_to<T>()
  7909. (T(0),binary_node<T>::branch_[0].first->value()) ||
  7910. std::not_equal_to<T>()
  7911. (T(0),binary_node<T>::branch_[1].first->value())
  7912. ) ? T(1) : T(0);
  7913. }
  7914. };
  7915. template <typename T, typename IFunction, std::size_t N>
  7916. class function_N_node : public expression_node<T>
  7917. {
  7918. public:
  7919. // Function of N paramters.
  7920. typedef expression_node<T>* expression_ptr;
  7921. typedef std::pair<expression_ptr,bool> branch_t;
  7922. typedef IFunction ifunction;
  7923. function_N_node(ifunction* func)
  7924. : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
  7925. parameter_count_(func->param_count)
  7926. {}
  7927. ~function_N_node()
  7928. {
  7929. cleanup_branches::execute<T,N>(branch_);
  7930. }
  7931. template <std::size_t NumBranches>
  7932. bool init_branches(expression_ptr (&b)[NumBranches])
  7933. {
  7934. // Needed for incompetent and broken msvc compiler versions
  7935. #ifdef _MSC_VER
  7936. #pragma warning(push)
  7937. #pragma warning(disable: 4127)
  7938. #endif
  7939. if (N != NumBranches)
  7940. return false;
  7941. else
  7942. {
  7943. for (std::size_t i = 0; i < NumBranches; ++i)
  7944. {
  7945. if (b[i])
  7946. branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
  7947. else
  7948. return false;
  7949. }
  7950. return true;
  7951. }
  7952. #ifdef _MSC_VER
  7953. #pragma warning(pop)
  7954. #endif
  7955. }
  7956. inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
  7957. {
  7958. return this < (&fn);
  7959. }
  7960. inline T value() const
  7961. {
  7962. // Needed for incompetent and broken msvc compiler versions
  7963. #ifdef _MSC_VER
  7964. #pragma warning(push)
  7965. #pragma warning(disable: 4127)
  7966. #endif
  7967. if ((0 == function_) || (0 == N))
  7968. return std::numeric_limits<T>::quiet_NaN();
  7969. else
  7970. {
  7971. T v[N];
  7972. evaluate_branches<T,N>::execute(v,branch_);
  7973. return invoke<T,N>::execute(*function_,v);
  7974. }
  7975. #ifdef _MSC_VER
  7976. #pragma warning(pop)
  7977. #endif
  7978. }
  7979. template <typename T_, std::size_t BranchCount>
  7980. struct evaluate_branches
  7981. {
  7982. static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
  7983. {
  7984. for (std::size_t i = 0; i < BranchCount; ++i)
  7985. {
  7986. v[i] = b[i].first->value();
  7987. }
  7988. }
  7989. };
  7990. template <typename T_>
  7991. struct evaluate_branches <T_,5>
  7992. {
  7993. static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
  7994. {
  7995. v[0] = b[0].first->value();
  7996. v[1] = b[1].first->value();
  7997. v[2] = b[2].first->value();
  7998. v[3] = b[3].first->value();
  7999. v[4] = b[4].first->value();
  8000. }
  8001. };
  8002. template <typename T_>
  8003. struct evaluate_branches <T_,4>
  8004. {
  8005. static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
  8006. {
  8007. v[0] = b[0].first->value();
  8008. v[1] = b[1].first->value();
  8009. v[2] = b[2].first->value();
  8010. v[3] = b[3].first->value();
  8011. }
  8012. };
  8013. template <typename T_>
  8014. struct evaluate_branches <T_,3>
  8015. {
  8016. static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
  8017. {
  8018. v[0] = b[0].first->value();
  8019. v[1] = b[1].first->value();
  8020. v[2] = b[2].first->value();
  8021. }
  8022. };
  8023. template <typename T_>
  8024. struct evaluate_branches <T_,2>
  8025. {
  8026. static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
  8027. {
  8028. v[0] = b[0].first->value();
  8029. v[1] = b[1].first->value();
  8030. }
  8031. };
  8032. template <typename T_>
  8033. struct evaluate_branches <T_,1>
  8034. {
  8035. static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
  8036. {
  8037. v[0] = b[0].first->value();
  8038. }
  8039. };
  8040. template <typename T_, std::size_t ParamCount>
  8041. struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
  8042. template <typename T_>
  8043. struct invoke<T_,20>
  8044. {
  8045. static inline T_ execute(ifunction& f, T_ (&v)[20])
  8046. { 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]); }
  8047. };
  8048. template <typename T_>
  8049. struct invoke<T_,19>
  8050. {
  8051. static inline T_ execute(ifunction& f, T_ (&v)[19])
  8052. { 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]); }
  8053. };
  8054. template <typename T_>
  8055. struct invoke<T_,18>
  8056. {
  8057. static inline T_ execute(ifunction& f, T_ (&v)[18])
  8058. { 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]); }
  8059. };
  8060. template <typename T_>
  8061. struct invoke<T_,17>
  8062. {
  8063. static inline T_ execute(ifunction& f, T_ (&v)[17])
  8064. { 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]); }
  8065. };
  8066. template <typename T_>
  8067. struct invoke<T_,16>
  8068. {
  8069. static inline T_ execute(ifunction& f, T_ (&v)[16])
  8070. { 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]); }
  8071. };
  8072. template <typename T_>
  8073. struct invoke<T_,15>
  8074. {
  8075. static inline T_ execute(ifunction& f, T_ (&v)[15])
  8076. { 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]); }
  8077. };
  8078. template <typename T_>
  8079. struct invoke<T_,14>
  8080. {
  8081. static inline T_ execute(ifunction& f, T_ (&v)[14])
  8082. { 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]); }
  8083. };
  8084. template <typename T_>
  8085. struct invoke<T_,13>
  8086. {
  8087. static inline T_ execute(ifunction& f, T_ (&v)[13])
  8088. { 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]); }
  8089. };
  8090. template <typename T_>
  8091. struct invoke<T_,12>
  8092. {
  8093. static inline T_ execute(ifunction& f, T_ (&v)[12])
  8094. { 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]); }
  8095. };
  8096. template <typename T_>
  8097. struct invoke<T_,11>
  8098. {
  8099. static inline T_ execute(ifunction& f, T_ (&v)[11])
  8100. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10]); }
  8101. };
  8102. template <typename T_>
  8103. struct invoke<T_,10>
  8104. {
  8105. static inline T_ execute(ifunction& f, T_ (&v)[10])
  8106. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); }
  8107. };
  8108. template <typename T_>
  8109. struct invoke<T_,9>
  8110. {
  8111. static inline T_ execute(ifunction& f, T_ (&v)[9])
  8112. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); }
  8113. };
  8114. template <typename T_>
  8115. struct invoke<T_,8>
  8116. {
  8117. static inline T_ execute(ifunction& f, T_ (&v)[8])
  8118. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); }
  8119. };
  8120. template <typename T_>
  8121. struct invoke<T_,7>
  8122. {
  8123. static inline T_ execute(ifunction& f, T_ (&v)[7])
  8124. { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); }
  8125. };
  8126. template <typename T_>
  8127. struct invoke<T_,6>
  8128. {
  8129. static inline T_ execute(ifunction& f, T_ (&v)[6])
  8130. { return f(v[0],v[1],v[2],v[3],v[4],v[5]); }
  8131. };
  8132. template <typename T_>
  8133. struct invoke<T_,5>
  8134. {
  8135. static inline T_ execute(ifunction& f, T_ (&v)[5])
  8136. { return f(v[0],v[1],v[2],v[3],v[4]); }
  8137. };
  8138. template <typename T_>
  8139. struct invoke<T_,4>
  8140. {
  8141. static inline T_ execute(ifunction& f, T_ (&v)[4])
  8142. { return f(v[0],v[1],v[2],v[3]); }
  8143. };
  8144. template <typename T_>
  8145. struct invoke<T_,3>
  8146. {
  8147. static inline T_ execute(ifunction& f, T_ (&v)[3])
  8148. { return f(v[0],v[1],v[2]); }
  8149. };
  8150. template <typename T_>
  8151. struct invoke<T_,2>
  8152. {
  8153. static inline T_ execute(ifunction& f, T_ (&v)[2])
  8154. { return f(v[0],v[1]); }
  8155. };
  8156. template <typename T_>
  8157. struct invoke<T_,1>
  8158. {
  8159. static inline T_ execute(ifunction& f, T_ (&v)[1])
  8160. { return f(v[0]); }
  8161. };
  8162. inline typename expression_node<T>::node_type type() const
  8163. {
  8164. return expression_node<T>::e_function;
  8165. }
  8166. private:
  8167. ifunction* function_;
  8168. std::size_t parameter_count_;
  8169. branch_t branch_[N];
  8170. };
  8171. template <typename T, typename IFunction>
  8172. class function_N_node<T,IFunction,0> : public expression_node<T>
  8173. {
  8174. public:
  8175. typedef expression_node<T>* expression_ptr;
  8176. typedef IFunction ifunction;
  8177. function_N_node(ifunction* func)
  8178. : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
  8179. {}
  8180. inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
  8181. {
  8182. return this < (&fn);
  8183. }
  8184. inline T value() const
  8185. {
  8186. if (function_)
  8187. return (*function_)();
  8188. else
  8189. return std::numeric_limits<T>::quiet_NaN();
  8190. }
  8191. inline typename expression_node<T>::node_type type() const
  8192. {
  8193. return expression_node<T>::e_function;
  8194. }
  8195. private:
  8196. ifunction* function_;
  8197. };
  8198. template <typename T, typename VarArgFunction>
  8199. class vararg_function_node : public expression_node<T>
  8200. {
  8201. public:
  8202. typedef expression_node<T>* expression_ptr;
  8203. vararg_function_node(VarArgFunction* func,
  8204. const std::vector<expression_ptr>& arg_list)
  8205. : function_(func),
  8206. arg_list_(arg_list)
  8207. {
  8208. value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
  8209. }
  8210. ~vararg_function_node()
  8211. {
  8212. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  8213. {
  8214. if (arg_list_[i] && !details::is_variable_node(arg_list_[i]))
  8215. {
  8216. delete arg_list_[i];
  8217. arg_list_[i] = 0;
  8218. }
  8219. }
  8220. }
  8221. inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
  8222. {
  8223. return this < (&fn);
  8224. }
  8225. inline T value() const
  8226. {
  8227. if (function_)
  8228. {
  8229. populate_value_list();
  8230. return (*function_)(value_list_);
  8231. }
  8232. else
  8233. return std::numeric_limits<T>::quiet_NaN();
  8234. }
  8235. inline typename expression_node<T>::node_type type() const
  8236. {
  8237. return expression_node<T>::e_vafunction;
  8238. }
  8239. private:
  8240. inline void populate_value_list() const
  8241. {
  8242. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  8243. {
  8244. value_list_[i] = arg_list_[i]->value();
  8245. }
  8246. }
  8247. VarArgFunction* function_;
  8248. std::vector<expression_ptr> arg_list_;
  8249. mutable std::vector<T> value_list_;
  8250. };
  8251. template <typename T, typename GenericFunction>
  8252. class generic_function_node : public expression_node<T>
  8253. {
  8254. public:
  8255. typedef type_store<T> type_store_t;
  8256. typedef expression_node<T>* expression_ptr;
  8257. typedef variable_node<T> variable_node_t;
  8258. typedef vector_elem_node<T> vector_elem_node_t;
  8259. typedef vector_node<T> vector_node_t;
  8260. typedef variable_node_t* variable_node_ptr_t;
  8261. typedef vector_elem_node_t* vector_elem_node_ptr_t;
  8262. typedef vector_node_t* vector_node_ptr_t;
  8263. typedef range_interface<T> range_interface_t;
  8264. typedef range_data_type<T> range_data_type_t;
  8265. typedef range_pack<T> range_t;
  8266. typedef std::pair<expression_ptr,bool> branch_t;
  8267. typedef std::pair<void*,std::size_t> void_t;
  8268. typedef std::vector<T> tmp_vs_t;
  8269. typedef std::vector<type_store_t> typestore_list_t;
  8270. typedef std::vector<range_data_type_t> range_list_t;
  8271. generic_function_node(const std::vector<expression_ptr>& arg_list,
  8272. GenericFunction* func = (GenericFunction*)(0))
  8273. : function_(func),
  8274. arg_list_(arg_list)
  8275. {}
  8276. ~generic_function_node()
  8277. {
  8278. cleanup_branches::execute(branch_);
  8279. }
  8280. virtual bool init_branches()
  8281. {
  8282. expr_as_vec1_store_.resize(arg_list_.size(),T(0) );
  8283. typestore_list_ .resize(arg_list_.size(),type_store_t() );
  8284. range_list_ .resize(arg_list_.size(),range_data_type_t());
  8285. branch_ .resize(arg_list_.size(),branch_t((expression_ptr)0,false));
  8286. for (std::size_t i = 0; i < arg_list_.size(); ++i)
  8287. {
  8288. type_store_t& ts = typestore_list_[i];
  8289. if (0 == arg_list_[i])
  8290. return false;
  8291. else if (is_ivector_node(arg_list_[i]))
  8292. {
  8293. vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
  8294. if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i])))
  8295. return false;
  8296. ts.size = vi->size();
  8297. ts.data = vi->vec()->ref()[0];
  8298. ts.type = type_store_t::e_vector;
  8299. }
  8300. else if (is_generally_string_node(arg_list_[i]))
  8301. {
  8302. string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0);
  8303. if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i])))
  8304. return false;
  8305. ts.size = sbn->size();
  8306. ts.data = reinterpret_cast<void*>(const_cast<char*>(sbn->base()));
  8307. ts.type = type_store_t::e_string;
  8308. range_list_[i].data = ts.data;
  8309. range_list_[i].size = ts.size;
  8310. range_list_[i].type_size = sizeof(char);
  8311. range_list_[i].str_node = sbn;
  8312. range_interface_t* ri = reinterpret_cast<range_interface_t*>(0);
  8313. if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i])))
  8314. return false;
  8315. range_t& rp = ri->range_ref();
  8316. if (
  8317. rp.const_range() &&
  8318. is_const_string_range_node(arg_list_[i])
  8319. )
  8320. {
  8321. ts.size = rp.const_size();
  8322. ts.data = static_cast<char*>(ts.data) + rp.n0_c.second;
  8323. range_list_[i].range = reinterpret_cast<range_t*>(0);
  8324. }
  8325. else
  8326. range_list_[i].range = &(ri->range_ref());
  8327. }
  8328. else if (is_variable_node(arg_list_[i]))
  8329. {
  8330. variable_node_ptr_t var = variable_node_ptr_t(0);
  8331. if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i])))
  8332. return false;
  8333. ts.size = 1;
  8334. ts.data = &var->ref();
  8335. ts.type = type_store_t::e_scalar;
  8336. }
  8337. else if (is_vector_elem_node(arg_list_[i]))
  8338. {
  8339. vector_elem_node_ptr_t var = vector_elem_node_ptr_t(0);
  8340. if (0 == (var = dynamic_cast<vector_elem_node_ptr_t>(arg_list_[i])))
  8341. return false;
  8342. ts.size = 1;
  8343. ts.data = reinterpret_cast<void*>(&var->ref());
  8344. ts.type = type_store_t::e_scalar;
  8345. }
  8346. else
  8347. {
  8348. ts.size = 1;
  8349. ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]);
  8350. ts.type = type_store_t::e_scalar;
  8351. }
  8352. branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]));
  8353. }
  8354. return true;
  8355. }
  8356. inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const
  8357. {
  8358. return this < (&fn);
  8359. }
  8360. inline T value() const
  8361. {
  8362. if (function_)
  8363. {
  8364. if (populate_value_list())
  8365. {
  8366. typedef typename GenericFunction::parameter_list_t parameter_list_t;
  8367. return (*function_)(parameter_list_t(typestore_list_));
  8368. }
  8369. }
  8370. return std::numeric_limits<T>::quiet_NaN();
  8371. }
  8372. inline typename expression_node<T>::node_type type() const
  8373. {
  8374. return expression_node<T>::e_genfunction;
  8375. }
  8376. protected:
  8377. inline virtual bool populate_value_list() const
  8378. {
  8379. for (std::size_t i = 0; i < branch_.size(); ++i)
  8380. {
  8381. expr_as_vec1_store_[i] = branch_[i].first->value();
  8382. }
  8383. for (std::size_t i = 0; i < branch_.size(); ++i)
  8384. {
  8385. range_data_type_t& rdt = range_list_[i];
  8386. if (rdt.range)
  8387. {
  8388. range_t& rp = (*rdt.range);
  8389. std::size_t r0 = 0;
  8390. std::size_t r1 = 0;
  8391. if (rp(r0,r1,rdt.size))
  8392. {
  8393. type_store_t& ts = typestore_list_[i];
  8394. ts.size = rp.cache_size();
  8395. if (ts.type == type_store_t::e_string)
  8396. ts.data = const_cast<char*>(rdt.str_node->base()) + rp.cache.first;
  8397. else
  8398. ts.data = static_cast<char*>(rdt.data) + (rp.cache.first * rdt.type_size);
  8399. }
  8400. else
  8401. return false;
  8402. }
  8403. }
  8404. return true;
  8405. }
  8406. GenericFunction* function_;
  8407. mutable typestore_list_t typestore_list_;
  8408. private:
  8409. std::vector<expression_ptr> arg_list_;
  8410. std::vector<branch_t> branch_;
  8411. mutable tmp_vs_t expr_as_vec1_store_;
  8412. mutable range_list_t range_list_;
  8413. };
  8414. template <typename T, typename StringFunction>
  8415. class string_function_node : public generic_function_node<T,StringFunction>,
  8416. public string_base_node<T>,
  8417. public range_interface <T>
  8418. {
  8419. public:
  8420. typedef generic_function_node<T,StringFunction> gen_function_t;
  8421. typedef range_pack<T> range_t;
  8422. string_function_node(StringFunction* func,
  8423. const std::vector<typename gen_function_t::expression_ptr>& arg_list)
  8424. : gen_function_t(arg_list,func)
  8425. {
  8426. range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
  8427. range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
  8428. range_.cache.first = range_.n0_c.second;
  8429. range_.cache.second = range_.n1_c.second;
  8430. }
  8431. inline bool operator <(const string_function_node<T,StringFunction>& fn) const
  8432. {
  8433. return this < (&fn);
  8434. }
  8435. inline T value() const
  8436. {
  8437. T result = std::numeric_limits<T>::quiet_NaN();
  8438. if (gen_function_t::function_)
  8439. {
  8440. if (gen_function_t::populate_value_list())
  8441. {
  8442. typedef typename StringFunction::parameter_list_t parameter_list_t;
  8443. result = (*gen_function_t::function_)(ret_string_,
  8444. parameter_list_t(gen_function_t::typestore_list_));
  8445. range_.n1_c.second = ret_string_.size() - 1;
  8446. range_.cache.second = range_.n1_c.second;
  8447. return result;
  8448. }
  8449. }
  8450. return result;
  8451. }
  8452. inline typename expression_node<T>::node_type type() const
  8453. {
  8454. return expression_node<T>::e_strfunction;
  8455. }
  8456. std::string str() const
  8457. {
  8458. return ret_string_;
  8459. }
  8460. const char* base() const
  8461. {
  8462. return ret_string_.data();
  8463. }
  8464. std::size_t size() const
  8465. {
  8466. return ret_string_.size();
  8467. }
  8468. range_t& range_ref()
  8469. {
  8470. return range_;
  8471. }
  8472. const range_t& range_ref() const
  8473. {
  8474. return range_;
  8475. }
  8476. protected:
  8477. mutable range_t range_;
  8478. mutable std::string ret_string_;
  8479. };
  8480. template <typename T, typename GenericFunction>
  8481. class multimode_genfunction_node : public generic_function_node<T,GenericFunction>
  8482. {
  8483. public:
  8484. typedef generic_function_node<T,GenericFunction> gen_function_t;
  8485. typedef range_pack<T> range_t;
  8486. multimode_genfunction_node(GenericFunction* func,
  8487. const std::size_t& param_seq_index,
  8488. const std::vector<typename gen_function_t::expression_ptr>& arg_list)
  8489. : gen_function_t(arg_list,func),
  8490. param_seq_index_(param_seq_index)
  8491. {}
  8492. inline T value() const
  8493. {
  8494. T result = std::numeric_limits<T>::quiet_NaN();
  8495. if (gen_function_t::function_)
  8496. {
  8497. if (gen_function_t::populate_value_list())
  8498. {
  8499. typedef typename GenericFunction::parameter_list_t parameter_list_t;
  8500. return (*gen_function_t::function_)(param_seq_index_,
  8501. parameter_list_t(gen_function_t::typestore_list_));
  8502. }
  8503. }
  8504. return result;
  8505. }
  8506. inline typename expression_node<T>::node_type type() const
  8507. {
  8508. return expression_node<T>::e_genfunction;
  8509. }
  8510. private:
  8511. std::size_t param_seq_index_;
  8512. };
  8513. template <typename T, typename StringFunction>
  8514. class multimode_strfunction_node : public string_function_node<T,StringFunction>
  8515. {
  8516. public:
  8517. typedef string_function_node<T,StringFunction> str_function_t;
  8518. typedef range_pack<T> range_t;
  8519. multimode_strfunction_node(StringFunction* func,
  8520. const std::size_t& param_seq_index,
  8521. const std::vector<typename str_function_t::expression_ptr>& arg_list)
  8522. : str_function_t(func,arg_list),
  8523. param_seq_index_(param_seq_index)
  8524. {}
  8525. inline T value() const
  8526. {
  8527. T result = std::numeric_limits<T>::quiet_NaN();
  8528. if (str_function_t::function_)
  8529. {
  8530. if (str_function_t::populate_value_list())
  8531. {
  8532. typedef typename StringFunction::parameter_list_t parameter_list_t;
  8533. result = (*str_function_t::function_)(param_seq_index_,
  8534. str_function_t::ret_string_,
  8535. parameter_list_t(str_function_t::typestore_list_));
  8536. str_function_t::range_.n1_c.second = str_function_t::ret_string_.size() - 1;
  8537. str_function_t::range_.cache.second = str_function_t::range_.n1_c.second;
  8538. return result;
  8539. }
  8540. }
  8541. return result;
  8542. }
  8543. inline typename expression_node<T>::node_type type() const
  8544. {
  8545. return expression_node<T>::e_strfunction;
  8546. }
  8547. private:
  8548. std::size_t param_seq_index_;
  8549. };
  8550. class return_exception
  8551. {};
  8552. template <typename T>
  8553. class null_igenfunc
  8554. {
  8555. public:
  8556. typedef type_store<T> generic_type;
  8557. typedef typename generic_type::parameter_list parameter_list_t;
  8558. inline virtual T operator()(parameter_list_t)
  8559. {
  8560. return std::numeric_limits<T>::quiet_NaN();
  8561. }
  8562. };
  8563. template <typename T>
  8564. class return_node : public generic_function_node<T,null_igenfunc<T> >
  8565. {
  8566. public:
  8567. typedef null_igenfunc<T> igeneric_function_t;
  8568. typedef igeneric_function_t* igeneric_function_ptr;
  8569. typedef generic_function_node<T,igeneric_function_t> gen_function_t;
  8570. typedef results_context<T> results_context_t;
  8571. return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list,
  8572. results_context_t& rc)
  8573. : gen_function_t (arg_list),
  8574. results_context_(&rc)
  8575. {}
  8576. inline T value() const
  8577. {
  8578. if (
  8579. (0 != results_context_) &&
  8580. gen_function_t::populate_value_list()
  8581. )
  8582. {
  8583. typedef typename type_store<T>::parameter_list parameter_list_t;
  8584. results_context_->
  8585. assign(parameter_list_t(gen_function_t::typestore_list_));
  8586. throw return_exception();
  8587. }
  8588. return std::numeric_limits<T>::quiet_NaN();
  8589. }
  8590. inline typename expression_node<T>::node_type type() const
  8591. {
  8592. return expression_node<T>::e_return;
  8593. }
  8594. private:
  8595. results_context_t* results_context_;
  8596. };
  8597. template <typename T>
  8598. class return_envelope_node : public expression_node<T>
  8599. {
  8600. public:
  8601. typedef expression_node<T>* expression_ptr;
  8602. typedef results_context<T> results_context_t;
  8603. return_envelope_node(expression_ptr body, results_context_t& rc)
  8604. : results_context_(&rc),
  8605. return_invoked_ (false),
  8606. body_ (body),
  8607. body_deletable_ (branch_deletable(body_))
  8608. {}
  8609. ~return_envelope_node()
  8610. {
  8611. if (body_ && body_deletable_)
  8612. {
  8613. delete body_;
  8614. }
  8615. }
  8616. inline T value() const
  8617. {
  8618. try
  8619. {
  8620. return_invoked_ = false;
  8621. results_context_->clear();
  8622. return body_->value();
  8623. }
  8624. catch(const return_exception&)
  8625. {
  8626. return_invoked_ = true;
  8627. return std::numeric_limits<T>::quiet_NaN();
  8628. }
  8629. }
  8630. inline typename expression_node<T>::node_type type() const
  8631. {
  8632. return expression_node<T>::e_retenv;
  8633. }
  8634. inline bool* retinvk_ptr()
  8635. {
  8636. return &return_invoked_;
  8637. }
  8638. private:
  8639. results_context_t* results_context_;
  8640. mutable bool return_invoked_;
  8641. expression_ptr body_;
  8642. bool body_deletable_;
  8643. };
  8644. #define exprtk_define_unary_op(OpName) \
  8645. template <typename T> \
  8646. struct OpName##_op \
  8647. { \
  8648. typedef typename functor_t<T>::Type Type; \
  8649. \
  8650. static inline T process(Type v) \
  8651. { \
  8652. return numeric:: OpName (v); \
  8653. } \
  8654. \
  8655. static inline typename expression_node<T>::node_type type() \
  8656. { \
  8657. return expression_node<T>::e_##OpName; \
  8658. } \
  8659. \
  8660. static inline details::operator_type operation() \
  8661. { \
  8662. return details::e_##OpName; \
  8663. } \
  8664. }; \
  8665. exprtk_define_unary_op(abs )
  8666. exprtk_define_unary_op(acos )
  8667. exprtk_define_unary_op(acosh)
  8668. exprtk_define_unary_op(asin )
  8669. exprtk_define_unary_op(asinh)
  8670. exprtk_define_unary_op(atan )
  8671. exprtk_define_unary_op(atanh)
  8672. exprtk_define_unary_op(ceil )
  8673. exprtk_define_unary_op(cos )
  8674. exprtk_define_unary_op(cosh )
  8675. exprtk_define_unary_op(cot )
  8676. exprtk_define_unary_op(csc )
  8677. exprtk_define_unary_op(d2g )
  8678. exprtk_define_unary_op(d2r )
  8679. exprtk_define_unary_op(erf )
  8680. exprtk_define_unary_op(erfc )
  8681. exprtk_define_unary_op(exp )
  8682. exprtk_define_unary_op(expm1)
  8683. exprtk_define_unary_op(floor)
  8684. exprtk_define_unary_op(frac )
  8685. exprtk_define_unary_op(g2d )
  8686. exprtk_define_unary_op(log )
  8687. exprtk_define_unary_op(log10)
  8688. exprtk_define_unary_op(log2 )
  8689. exprtk_define_unary_op(log1p)
  8690. exprtk_define_unary_op(ncdf )
  8691. exprtk_define_unary_op(neg )
  8692. exprtk_define_unary_op(notl )
  8693. exprtk_define_unary_op(pos )
  8694. exprtk_define_unary_op(r2d )
  8695. exprtk_define_unary_op(round)
  8696. exprtk_define_unary_op(sec )
  8697. exprtk_define_unary_op(sgn )
  8698. exprtk_define_unary_op(sin )
  8699. exprtk_define_unary_op(sinc )
  8700. exprtk_define_unary_op(sinh )
  8701. exprtk_define_unary_op(sqrt )
  8702. exprtk_define_unary_op(tan )
  8703. exprtk_define_unary_op(tanh )
  8704. exprtk_define_unary_op(trunc)
  8705. #undef exprtk_define_unary_op
  8706. template <typename T>
  8707. struct opr_base
  8708. {
  8709. typedef typename details::functor_t<T>::Type Type;
  8710. typedef typename details::functor_t<T> functor_t;
  8711. typedef typename functor_t::qfunc_t quaternary_functor_t;
  8712. typedef typename functor_t::tfunc_t trinary_functor_t;
  8713. typedef typename functor_t::bfunc_t binary_functor_t;
  8714. typedef typename functor_t::ufunc_t unary_functor_t;
  8715. };
  8716. template <typename T>
  8717. struct add_op : public opr_base<T>
  8718. {
  8719. typedef typename opr_base<T>::Type Type;
  8720. static inline T process(Type t1, Type t2) { return t1 + t2; }
  8721. static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
  8722. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; }
  8723. static inline details::operator_type operation() { return details::e_add; }
  8724. };
  8725. template <typename T>
  8726. struct mul_op : public opr_base<T>
  8727. {
  8728. typedef typename opr_base<T>::Type Type;
  8729. static inline T process(Type t1, Type t2) { return t1 * t2; }
  8730. static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
  8731. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; }
  8732. static inline details::operator_type operation() { return details::e_mul; }
  8733. };
  8734. template <typename T>
  8735. struct sub_op : public opr_base<T>
  8736. {
  8737. typedef typename opr_base<T>::Type Type;
  8738. static inline T process(Type t1, Type t2) { return t1 - t2; }
  8739. static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
  8740. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; }
  8741. static inline details::operator_type operation() { return details::e_sub; }
  8742. };
  8743. template <typename T>
  8744. struct div_op : public opr_base<T>
  8745. {
  8746. typedef typename opr_base<T>::Type Type;
  8747. static inline T process(Type t1, Type t2) { return t1 / t2; }
  8748. static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
  8749. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; }
  8750. static inline details::operator_type operation() { return details::e_div; }
  8751. };
  8752. template <typename T>
  8753. struct mod_op : public opr_base<T>
  8754. {
  8755. typedef typename opr_base<T>::Type Type;
  8756. static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
  8757. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
  8758. static inline details::operator_type operation() { return details::e_mod; }
  8759. };
  8760. template <typename T>
  8761. struct pow_op : public opr_base<T>
  8762. {
  8763. typedef typename opr_base<T>::Type Type;
  8764. static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
  8765. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
  8766. static inline details::operator_type operation() { return details::e_pow; }
  8767. };
  8768. template <typename T>
  8769. struct lt_op : public opr_base<T>
  8770. {
  8771. typedef typename opr_base<T>::Type Type;
  8772. static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
  8773. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
  8774. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
  8775. static inline details::operator_type operation() { return details::e_lt; }
  8776. };
  8777. template <typename T>
  8778. struct lte_op : public opr_base<T>
  8779. {
  8780. typedef typename opr_base<T>::Type Type;
  8781. static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
  8782. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
  8783. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
  8784. static inline details::operator_type operation() { return details::e_lte; }
  8785. };
  8786. template <typename T>
  8787. struct gt_op : public opr_base<T>
  8788. {
  8789. typedef typename opr_base<T>::Type Type;
  8790. static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
  8791. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
  8792. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
  8793. static inline details::operator_type operation() { return details::e_gt; }
  8794. };
  8795. template <typename T>
  8796. struct gte_op : public opr_base<T>
  8797. {
  8798. typedef typename opr_base<T>::Type Type;
  8799. static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
  8800. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
  8801. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
  8802. static inline details::operator_type operation() { return details::e_gte; }
  8803. };
  8804. template <typename T>
  8805. struct eq_op : public opr_base<T>
  8806. {
  8807. typedef typename opr_base<T>::Type Type;
  8808. static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); }
  8809. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
  8810. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
  8811. static inline details::operator_type operation() { return details::e_eq; }
  8812. };
  8813. template <typename T>
  8814. struct ne_op : public opr_base<T>
  8815. {
  8816. typedef typename opr_base<T>::Type Type;
  8817. static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
  8818. static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
  8819. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
  8820. static inline details::operator_type operation() { return details::e_ne; }
  8821. };
  8822. template <typename T>
  8823. struct and_op : public opr_base<T>
  8824. {
  8825. typedef typename opr_base<T>::Type Type;
  8826. static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
  8827. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
  8828. static inline details::operator_type operation() { return details::e_and; }
  8829. };
  8830. template <typename T>
  8831. struct nand_op : public opr_base<T>
  8832. {
  8833. typedef typename opr_base<T>::Type Type;
  8834. static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
  8835. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; }
  8836. static inline details::operator_type operation() { return details::e_nand; }
  8837. };
  8838. template <typename T>
  8839. struct or_op : public opr_base<T>
  8840. {
  8841. typedef typename opr_base<T>::Type Type;
  8842. static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
  8843. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
  8844. static inline details::operator_type operation() { return details::e_or; }
  8845. };
  8846. template <typename T>
  8847. struct nor_op : public opr_base<T>
  8848. {
  8849. typedef typename opr_base<T>::Type Type;
  8850. static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
  8851. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  8852. static inline details::operator_type operation() { return details::e_nor; }
  8853. };
  8854. template <typename T>
  8855. struct xor_op : public opr_base<T>
  8856. {
  8857. typedef typename opr_base<T>::Type Type;
  8858. static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
  8859. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  8860. static inline details::operator_type operation() { return details::e_xor; }
  8861. };
  8862. template <typename T>
  8863. struct xnor_op : public opr_base<T>
  8864. {
  8865. typedef typename opr_base<T>::Type Type;
  8866. static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
  8867. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
  8868. static inline details::operator_type operation() { return details::e_xnor; }
  8869. };
  8870. template <typename T>
  8871. struct in_op : public opr_base<T>
  8872. {
  8873. typedef typename opr_base<T>::Type Type;
  8874. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  8875. static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
  8876. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
  8877. static inline details::operator_type operation() { return details::e_in; }
  8878. };
  8879. template <typename T>
  8880. struct like_op : public opr_base<T>
  8881. {
  8882. typedef typename opr_base<T>::Type Type;
  8883. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  8884. static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
  8885. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; }
  8886. static inline details::operator_type operation() { return details::e_like; }
  8887. };
  8888. template <typename T>
  8889. struct ilike_op : public opr_base<T>
  8890. {
  8891. typedef typename opr_base<T>::Type Type;
  8892. static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
  8893. static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
  8894. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; }
  8895. static inline details::operator_type operation() { return details::e_ilike; }
  8896. };
  8897. template <typename T>
  8898. struct inrange_op : public opr_base<T>
  8899. {
  8900. typedef typename opr_base<T>::Type Type;
  8901. static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
  8902. static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
  8903. {
  8904. return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
  8905. }
  8906. static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_inranges; }
  8907. static inline details::operator_type operation() { return details::e_inrange; }
  8908. };
  8909. template <typename T>
  8910. inline T value(details::expression_node<T>* n)
  8911. {
  8912. return n->value();
  8913. }
  8914. template <typename T>
  8915. inline T value(T* t)
  8916. {
  8917. return (*t);
  8918. }
  8919. template <typename T>
  8920. struct vararg_add_op : public opr_base<T>
  8921. {
  8922. typedef typename opr_base<T>::Type Type;
  8923. template <typename Type,
  8924. typename Allocator,
  8925. template <typename,typename> class Sequence>
  8926. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8927. {
  8928. switch (arg_list.size())
  8929. {
  8930. case 0 : return T(0);
  8931. case 1 : return process_1(arg_list);
  8932. case 2 : return process_2(arg_list);
  8933. case 3 : return process_3(arg_list);
  8934. case 4 : return process_4(arg_list);
  8935. case 5 : return process_5(arg_list);
  8936. default :
  8937. {
  8938. T result = T(0);
  8939. for (std::size_t i = 0; i < arg_list.size(); ++i)
  8940. {
  8941. result += value(arg_list[i]);
  8942. }
  8943. return result;
  8944. }
  8945. }
  8946. }
  8947. template <typename Sequence>
  8948. static inline T process_1(const Sequence& arg_list)
  8949. {
  8950. return value(arg_list[0]);
  8951. }
  8952. template <typename Sequence>
  8953. static inline T process_2(const Sequence& arg_list)
  8954. {
  8955. return value(arg_list[0]) + value(arg_list[1]);
  8956. }
  8957. template <typename Sequence>
  8958. static inline T process_3(const Sequence& arg_list)
  8959. {
  8960. return value(arg_list[0]) + value(arg_list[1]) +
  8961. value(arg_list[2]);
  8962. }
  8963. template <typename Sequence>
  8964. static inline T process_4(const Sequence& arg_list)
  8965. {
  8966. return value(arg_list[0]) + value(arg_list[1]) +
  8967. value(arg_list[2]) + value(arg_list[3]);
  8968. }
  8969. template <typename Sequence>
  8970. static inline T process_5(const Sequence& arg_list)
  8971. {
  8972. return value(arg_list[0]) + value(arg_list[1]) +
  8973. value(arg_list[2]) + value(arg_list[3]) +
  8974. value(arg_list[4]);
  8975. }
  8976. };
  8977. template <typename T>
  8978. struct vararg_mul_op : public opr_base<T>
  8979. {
  8980. typedef typename opr_base<T>::Type Type;
  8981. template <typename Type,
  8982. typename Allocator,
  8983. template <typename,typename> class Sequence>
  8984. static inline T process(const Sequence<Type,Allocator>& arg_list)
  8985. {
  8986. switch (arg_list.size())
  8987. {
  8988. case 0 : return T(0);
  8989. case 1 : return process_1(arg_list);
  8990. case 2 : return process_2(arg_list);
  8991. case 3 : return process_3(arg_list);
  8992. case 4 : return process_4(arg_list);
  8993. case 5 : return process_5(arg_list);
  8994. default :
  8995. {
  8996. T result = T(value(arg_list[0]));
  8997. for (std::size_t i = 1; i < arg_list.size(); ++i)
  8998. {
  8999. result *= value(arg_list[i]);
  9000. }
  9001. return result;
  9002. }
  9003. }
  9004. }
  9005. template <typename Sequence>
  9006. static inline T process_1(const Sequence& arg_list)
  9007. {
  9008. return value(arg_list[0]);
  9009. }
  9010. template <typename Sequence>
  9011. static inline T process_2(const Sequence& arg_list)
  9012. {
  9013. return value(arg_list[0]) * value(arg_list[1]);
  9014. }
  9015. template <typename Sequence>
  9016. static inline T process_3(const Sequence& arg_list)
  9017. {
  9018. return value(arg_list[0]) * value(arg_list[1]) *
  9019. value(arg_list[2]);
  9020. }
  9021. template <typename Sequence>
  9022. static inline T process_4(const Sequence& arg_list)
  9023. {
  9024. return value(arg_list[0]) * value(arg_list[1]) *
  9025. value(arg_list[2]) * value(arg_list[3]);
  9026. }
  9027. template <typename Sequence>
  9028. static inline T process_5(const Sequence& arg_list)
  9029. {
  9030. return value(arg_list[0]) * value(arg_list[1]) *
  9031. value(arg_list[2]) * value(arg_list[3]) *
  9032. value(arg_list[4]);
  9033. }
  9034. };
  9035. template <typename T>
  9036. struct vararg_avg_op : public opr_base<T>
  9037. {
  9038. typedef typename opr_base<T>::Type Type;
  9039. template <typename Type,
  9040. typename Allocator,
  9041. template <typename,typename> class Sequence>
  9042. static inline T process(const Sequence<Type,Allocator>& arg_list)
  9043. {
  9044. switch (arg_list.size())
  9045. {
  9046. case 0 : return T(0);
  9047. case 1 : return process_1(arg_list);
  9048. case 2 : return process_2(arg_list);
  9049. case 3 : return process_3(arg_list);
  9050. case 4 : return process_4(arg_list);
  9051. case 5 : return process_5(arg_list);
  9052. default : return vararg_add_op<T>::process(arg_list) / arg_list.size();
  9053. }
  9054. }
  9055. template <typename Sequence>
  9056. static inline T process_1(const Sequence& arg_list)
  9057. {
  9058. return value(arg_list[0]);
  9059. }
  9060. template <typename Sequence>
  9061. static inline T process_2(const Sequence& arg_list)
  9062. {
  9063. return (value(arg_list[0]) + value(arg_list[1])) / T(2);
  9064. }
  9065. template <typename Sequence>
  9066. static inline T process_3(const Sequence& arg_list)
  9067. {
  9068. return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3);
  9069. }
  9070. template <typename Sequence>
  9071. static inline T process_4(const Sequence& arg_list)
  9072. {
  9073. return (value(arg_list[0]) + value(arg_list[1]) +
  9074. value(arg_list[2]) + value(arg_list[3])) / T(4);
  9075. }
  9076. template <typename Sequence>
  9077. static inline T process_5(const Sequence& arg_list)
  9078. {
  9079. return (value(arg_list[0]) + value(arg_list[1]) +
  9080. value(arg_list[2]) + value(arg_list[3]) +
  9081. value(arg_list[4])) / T(5);
  9082. }
  9083. };
  9084. template <typename T>
  9085. struct vararg_min_op : public opr_base<T>
  9086. {
  9087. typedef typename opr_base<T>::Type Type;
  9088. template <typename Type,
  9089. typename Allocator,
  9090. template <typename,typename> class Sequence>
  9091. static inline T process(const Sequence<Type,Allocator>& arg_list)
  9092. {
  9093. switch (arg_list.size())
  9094. {
  9095. case 0 : return T(0);
  9096. case 1 : return process_1(arg_list);
  9097. case 2 : return process_2(arg_list);
  9098. case 3 : return process_3(arg_list);
  9099. case 4 : return process_4(arg_list);
  9100. case 5 : return process_5(arg_list);
  9101. default :
  9102. {
  9103. T result = T(value(arg_list[0]));
  9104. for (std::size_t i = 1; i < arg_list.size(); ++i)
  9105. {
  9106. const T v = value(arg_list[i]);
  9107. if (v < result)
  9108. result = v;
  9109. }
  9110. return result;
  9111. }
  9112. }
  9113. }
  9114. template <typename Sequence>
  9115. static inline T process_1(const Sequence& arg_list)
  9116. {
  9117. return value(arg_list[0]);
  9118. }
  9119. template <typename Sequence>
  9120. static inline T process_2(const Sequence& arg_list)
  9121. {
  9122. return std::min<T>(value(arg_list[0]),value(arg_list[1]));
  9123. }
  9124. template <typename Sequence>
  9125. static inline T process_3(const Sequence& arg_list)
  9126. {
  9127. return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
  9128. }
  9129. template <typename Sequence>
  9130. static inline T process_4(const Sequence& arg_list)
  9131. {
  9132. return std::min<T>(
  9133. std::min<T>(value(arg_list[0]),value(arg_list[1])),
  9134. std::min<T>(value(arg_list[2]),value(arg_list[3])));
  9135. }
  9136. template <typename Sequence>
  9137. static inline T process_5(const Sequence& arg_list)
  9138. {
  9139. return std::min<T>(
  9140. std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),
  9141. std::min<T>(value(arg_list[2]),value(arg_list[3]))),
  9142. value(arg_list[4]));
  9143. }
  9144. };
  9145. template <typename T>
  9146. struct vararg_max_op : public opr_base<T>
  9147. {
  9148. typedef typename opr_base<T>::Type Type;
  9149. template <typename Type,
  9150. typename Allocator,
  9151. template <typename,typename> class Sequence>
  9152. static inline T process(const Sequence<Type,Allocator>& arg_list)
  9153. {
  9154. switch (arg_list.size())
  9155. {
  9156. case 0 : return T(0);
  9157. case 1 : return process_1(arg_list);
  9158. case 2 : return process_2(arg_list);
  9159. case 3 : return process_3(arg_list);
  9160. case 4 : return process_4(arg_list);
  9161. case 5 : return process_5(arg_list);
  9162. default :
  9163. {
  9164. T result = T(value(arg_list[0]));
  9165. for (std::size_t i = 1; i < arg_list.size(); ++i)
  9166. {
  9167. const T v = value(arg_list[i]);
  9168. if (v > result)
  9169. result = v;
  9170. }
  9171. return result;
  9172. }
  9173. }
  9174. }
  9175. template <typename Sequence>
  9176. static inline T process_1(const Sequence& arg_list)
  9177. {
  9178. return value(arg_list[0]);
  9179. }
  9180. template <typename Sequence>
  9181. static inline T process_2(const Sequence& arg_list)
  9182. {
  9183. return std::max<T>(value(arg_list[0]),value(arg_list[1]));
  9184. }
  9185. template <typename Sequence>
  9186. static inline T process_3(const Sequence& arg_list)
  9187. {
  9188. return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
  9189. }
  9190. template <typename Sequence>
  9191. static inline T process_4(const Sequence& arg_list)
  9192. {
  9193. return std::max<T>(
  9194. std::max<T>(value(arg_list[0]),value(arg_list[1])),
  9195. std::max<T>(value(arg_list[2]),value(arg_list[3])));
  9196. }
  9197. template <typename Sequence>
  9198. static inline T process_5(const Sequence& arg_list)
  9199. {
  9200. return std::max<T>(
  9201. std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),
  9202. std::max<T>(value(arg_list[2]),value(arg_list[3]))),
  9203. value(arg_list[4]));
  9204. }
  9205. };
  9206. template <typename T>
  9207. struct vararg_mand_op : public opr_base<T>
  9208. {
  9209. typedef typename opr_base<T>::Type Type;
  9210. template <typename Type,
  9211. typename Allocator,
  9212. template <typename,typename> class Sequence>
  9213. static inline T process(const Sequence<Type,Allocator>& arg_list)
  9214. {
  9215. switch (arg_list.size())
  9216. {
  9217. case 1 : return process_1(arg_list);
  9218. case 2 : return process_2(arg_list);
  9219. case 3 : return process_3(arg_list);
  9220. case 4 : return process_4(arg_list);
  9221. case 5 : return process_5(arg_list);
  9222. default :
  9223. {
  9224. for (std::size_t i = 0; i < arg_list.size(); ++i)
  9225. {
  9226. if (std::equal_to<T>()(T(0),value(arg_list[i])))
  9227. return T(0);
  9228. }
  9229. return T(1);
  9230. }
  9231. }
  9232. }
  9233. template <typename Sequence>
  9234. static inline T process_1(const Sequence& arg_list)
  9235. {
  9236. return std::not_equal_to<T>()
  9237. (T(0),value(arg_list[0])) ? T(1) : T(0);
  9238. }
  9239. template <typename Sequence>
  9240. static inline T process_2(const Sequence& arg_list)
  9241. {
  9242. return (
  9243. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  9244. std::not_equal_to<T>()(T(0),value(arg_list[1]))
  9245. ) ? T(1) : T(0);
  9246. }
  9247. template <typename Sequence>
  9248. static inline T process_3(const Sequence& arg_list)
  9249. {
  9250. return (
  9251. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  9252. std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
  9253. std::not_equal_to<T>()(T(0),value(arg_list[2]))
  9254. ) ? T(1) : T(0);
  9255. }
  9256. template <typename Sequence>
  9257. static inline T process_4(const Sequence& arg_list)
  9258. {
  9259. return (
  9260. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  9261. std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
  9262. std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
  9263. std::not_equal_to<T>()(T(0),value(arg_list[3]))
  9264. ) ? T(1) : T(0);
  9265. }
  9266. template <typename Sequence>
  9267. static inline T process_5(const Sequence& arg_list)
  9268. {
  9269. return (
  9270. std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
  9271. std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
  9272. std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
  9273. std::not_equal_to<T>()(T(0),value(arg_list[3])) &&
  9274. std::not_equal_to<T>()(T(0),value(arg_list[4]))
  9275. ) ? T(1) : T(0);
  9276. }
  9277. };
  9278. template <typename T>
  9279. struct vararg_mor_op : public opr_base<T>
  9280. {
  9281. typedef typename opr_base<T>::Type Type;
  9282. template <typename Type,
  9283. typename Allocator,
  9284. template <typename,typename> class Sequence>
  9285. static inline T process(const Sequence<Type,Allocator>& arg_list)
  9286. {
  9287. switch (arg_list.size())
  9288. {
  9289. case 1 : return process_1(arg_list);
  9290. case 2 : return process_2(arg_list);
  9291. case 3 : return process_3(arg_list);
  9292. case 4 : return process_4(arg_list);
  9293. case 5 : return process_5(arg_list);
  9294. default :
  9295. {
  9296. for (std::size_t i = 0; i < arg_list.size(); ++i)
  9297. {
  9298. if (std::not_equal_to<T>()(T(0),value(arg_list[i])))
  9299. return T(1);
  9300. }
  9301. return T(0);
  9302. }
  9303. }
  9304. }
  9305. template <typename Sequence>
  9306. static inline T process_1(const Sequence& arg_list)
  9307. {
  9308. return std::not_equal_to<T>()
  9309. (T(0),value(arg_list[0])) ? T(1) : T(0);
  9310. }
  9311. template <typename Sequence>
  9312. static inline T process_2(const Sequence& arg_list)
  9313. {
  9314. return (
  9315. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  9316. std::not_equal_to<T>()(T(0),value(arg_list[1]))
  9317. ) ? T(1) : T(0);
  9318. }
  9319. template <typename Sequence>
  9320. static inline T process_3(const Sequence& arg_list)
  9321. {
  9322. return (
  9323. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  9324. std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
  9325. std::not_equal_to<T>()(T(0),value(arg_list[2]))
  9326. ) ? T(1) : T(0);
  9327. }
  9328. template <typename Sequence>
  9329. static inline T process_4(const Sequence& arg_list)
  9330. {
  9331. return (
  9332. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  9333. std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
  9334. std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
  9335. std::not_equal_to<T>()(T(0),value(arg_list[3]))
  9336. ) ? T(1) : T(0);
  9337. }
  9338. template <typename Sequence>
  9339. static inline T process_5(const Sequence& arg_list)
  9340. {
  9341. return (
  9342. std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
  9343. std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
  9344. std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
  9345. std::not_equal_to<T>()(T(0),value(arg_list[3])) ||
  9346. std::not_equal_to<T>()(T(0),value(arg_list[4]))
  9347. ) ? T(1) : T(0);
  9348. }
  9349. };
  9350. template <typename T>
  9351. struct vararg_multi_op : public opr_base<T>
  9352. {
  9353. typedef typename opr_base<T>::Type Type;
  9354. template <typename Type,
  9355. typename Allocator,
  9356. template <typename,typename> class Sequence>
  9357. static inline T process(const Sequence<Type,Allocator>& arg_list)
  9358. {
  9359. switch (arg_list.size())
  9360. {
  9361. case 0 : return std::numeric_limits<T>::quiet_NaN();
  9362. case 1 : return process_1(arg_list);
  9363. case 2 : return process_2(arg_list);
  9364. case 3 : return process_3(arg_list);
  9365. case 4 : return process_4(arg_list);
  9366. case 5 : return process_5(arg_list);
  9367. case 6 : return process_6(arg_list);
  9368. case 7 : return process_7(arg_list);
  9369. case 8 : return process_8(arg_list);
  9370. default :
  9371. {
  9372. for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
  9373. {
  9374. value(arg_list[i]);
  9375. }
  9376. return value(arg_list.back());
  9377. }
  9378. }
  9379. }
  9380. template <typename Sequence>
  9381. static inline T process_1(const Sequence& arg_list)
  9382. {
  9383. return value(arg_list[0]);
  9384. }
  9385. template <typename Sequence>
  9386. static inline T process_2(const Sequence& arg_list)
  9387. {
  9388. value(arg_list[0]);
  9389. return value(arg_list[1]);
  9390. }
  9391. template <typename Sequence>
  9392. static inline T process_3(const Sequence& arg_list)
  9393. {
  9394. value(arg_list[0]);
  9395. value(arg_list[1]);
  9396. return value(arg_list[2]);
  9397. }
  9398. template <typename Sequence>
  9399. static inline T process_4(const Sequence& arg_list)
  9400. {
  9401. value(arg_list[0]);
  9402. value(arg_list[1]);
  9403. value(arg_list[2]);
  9404. return value(arg_list[3]);
  9405. }
  9406. template <typename Sequence>
  9407. static inline T process_5(const Sequence& arg_list)
  9408. {
  9409. value(arg_list[0]);
  9410. value(arg_list[1]);
  9411. value(arg_list[2]);
  9412. value(arg_list[3]);
  9413. return value(arg_list[4]);
  9414. }
  9415. template <typename Sequence>
  9416. static inline T process_6(const Sequence& arg_list)
  9417. {
  9418. value(arg_list[0]);
  9419. value(arg_list[1]);
  9420. value(arg_list[2]);
  9421. value(arg_list[3]);
  9422. value(arg_list[4]);
  9423. return value(arg_list[5]);
  9424. }
  9425. template <typename Sequence>
  9426. static inline T process_7(const Sequence& arg_list)
  9427. {
  9428. value(arg_list[0]);
  9429. value(arg_list[1]);
  9430. value(arg_list[2]);
  9431. value(arg_list[3]);
  9432. value(arg_list[4]);
  9433. value(arg_list[5]);
  9434. return value(arg_list[6]);
  9435. }
  9436. template <typename Sequence>
  9437. static inline T process_8(const Sequence& arg_list)
  9438. {
  9439. value(arg_list[0]);
  9440. value(arg_list[1]);
  9441. value(arg_list[2]);
  9442. value(arg_list[3]);
  9443. value(arg_list[4]);
  9444. value(arg_list[5]);
  9445. value(arg_list[6]);
  9446. return value(arg_list[7]);
  9447. }
  9448. };
  9449. template <typename T>
  9450. struct vec_add_op
  9451. {
  9452. typedef vector_interface<T>* ivector_ptr;
  9453. static inline T process(const ivector_ptr v)
  9454. {
  9455. vector_holder<T>& vec = v->vec()->ref();
  9456. T result = T(0);
  9457. for (std::size_t i = 0; i < vec.size(); ++i)
  9458. {
  9459. result += (*vec[i]);
  9460. }
  9461. return result;
  9462. }
  9463. };
  9464. template <typename T>
  9465. struct vec_mul_op
  9466. {
  9467. typedef vector_interface<T>* ivector_ptr;
  9468. static inline T process(const ivector_ptr v)
  9469. {
  9470. vector_holder<T>& vec = v->vec()->ref();
  9471. T result = (*vec[0]);
  9472. for (std::size_t i = 1; i < vec.size(); ++i)
  9473. {
  9474. result *= (*vec[i]);
  9475. }
  9476. return result;
  9477. }
  9478. };
  9479. template <typename T>
  9480. struct vec_avg_op
  9481. {
  9482. typedef vector_interface<T>* ivector_ptr;
  9483. static inline T process(const ivector_ptr v)
  9484. {
  9485. vector_holder<T>& vec = v->vec()->ref();
  9486. T result = T(0);
  9487. for (std::size_t i = 0; i < vec.size(); ++i)
  9488. {
  9489. result += (*vec[i]);
  9490. }
  9491. return result / vec.size();
  9492. }
  9493. };
  9494. template <typename T>
  9495. struct vec_min_op
  9496. {
  9497. typedef vector_interface<T>* ivector_ptr;
  9498. static inline T process(const ivector_ptr v)
  9499. {
  9500. vector_holder<T>& vec = v->vec()->ref();
  9501. T result = (*vec[0]);
  9502. for (std::size_t i = 1; i < vec.size(); ++i)
  9503. {
  9504. T v_i = (*vec[i]);
  9505. if (v_i < result)
  9506. result = v_i;
  9507. }
  9508. return result;
  9509. }
  9510. };
  9511. template <typename T>
  9512. struct vec_max_op
  9513. {
  9514. typedef vector_interface<T>* ivector_ptr;
  9515. static inline T process(const ivector_ptr v)
  9516. {
  9517. vector_holder<T>& vec = v->vec()->ref();
  9518. T result = (*vec[0]);
  9519. for (std::size_t i = 1; i < vec.size(); ++i)
  9520. {
  9521. T v_i = (*vec[i]);
  9522. if (v_i > result)
  9523. result = v_i;
  9524. }
  9525. return result;
  9526. }
  9527. };
  9528. template <typename T>
  9529. class vov_base_node : public expression_node<T>
  9530. {
  9531. public:
  9532. inline virtual operator_type operation() const
  9533. {
  9534. return details::e_default;
  9535. }
  9536. virtual const T& v0() const = 0;
  9537. virtual const T& v1() const = 0;
  9538. };
  9539. template <typename T>
  9540. class cov_base_node : public expression_node<T>
  9541. {
  9542. public:
  9543. inline virtual operator_type operation() const
  9544. {
  9545. return details::e_default;
  9546. }
  9547. virtual const T c() const = 0;
  9548. virtual const T& v() const = 0;
  9549. };
  9550. template <typename T>
  9551. class voc_base_node : public expression_node<T>
  9552. {
  9553. public:
  9554. inline virtual operator_type operation() const
  9555. {
  9556. return details::e_default;
  9557. }
  9558. virtual const T c() const = 0;
  9559. virtual const T& v() const = 0;
  9560. };
  9561. template <typename T>
  9562. class vob_base_node : public expression_node<T>
  9563. {
  9564. public:
  9565. virtual const T& v() const = 0;
  9566. };
  9567. template <typename T>
  9568. class bov_base_node : public expression_node<T>
  9569. {
  9570. public:
  9571. virtual const T& v() const = 0;
  9572. };
  9573. template <typename T>
  9574. class cob_base_node : public expression_node<T>
  9575. {
  9576. public:
  9577. inline virtual operator_type operation() const
  9578. {
  9579. return details::e_default;
  9580. }
  9581. virtual const T c() const = 0;
  9582. virtual void set_c(const T) = 0;
  9583. virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
  9584. };
  9585. template <typename T>
  9586. class boc_base_node : public expression_node<T>
  9587. {
  9588. public:
  9589. inline virtual operator_type operation() const
  9590. {
  9591. return details::e_default;
  9592. }
  9593. virtual const T c() const = 0;
  9594. virtual void set_c(const T) = 0;
  9595. virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
  9596. };
  9597. template <typename T>
  9598. class uv_base_node : public expression_node<T>
  9599. {
  9600. public:
  9601. inline virtual operator_type operation() const
  9602. {
  9603. return details::e_default;
  9604. }
  9605. virtual const T& v() const = 0;
  9606. };
  9607. template <typename T>
  9608. class sos_base_node : public expression_node<T>
  9609. {
  9610. public:
  9611. inline virtual operator_type operation() const
  9612. {
  9613. return details::e_default;
  9614. }
  9615. };
  9616. template <typename T>
  9617. class sosos_base_node : public expression_node<T>
  9618. {
  9619. public:
  9620. inline virtual operator_type operation() const
  9621. {
  9622. return details::e_default;
  9623. }
  9624. };
  9625. template <typename T>
  9626. class T0oT1oT2_base_node : public expression_node<T>
  9627. {
  9628. public:
  9629. virtual std::string type_id() const = 0;
  9630. };
  9631. template <typename T>
  9632. class T0oT1oT2oT3_base_node : public expression_node<T>
  9633. {
  9634. public:
  9635. virtual std::string type_id() const = 0;
  9636. };
  9637. template <typename T, typename Operation>
  9638. class unary_variable_node : public uv_base_node<T>
  9639. {
  9640. public:
  9641. typedef expression_node<T>* expression_ptr;
  9642. typedef Operation operation_t;
  9643. explicit unary_variable_node(const T& var)
  9644. : v_(var)
  9645. {}
  9646. inline T value() const
  9647. {
  9648. return Operation::process(v_);
  9649. }
  9650. inline typename expression_node<T>::node_type type() const
  9651. {
  9652. return Operation::type();
  9653. }
  9654. inline operator_type operation() const
  9655. {
  9656. return Operation::operation();
  9657. }
  9658. inline const T& v() const
  9659. {
  9660. return v_;
  9661. }
  9662. private:
  9663. unary_variable_node(unary_variable_node<T,Operation>&);
  9664. unary_variable_node<T,Operation>& operator=(unary_variable_node<T,Operation>&);
  9665. const T& v_;
  9666. };
  9667. template <typename T>
  9668. class uvouv_node : public expression_node<T>
  9669. {
  9670. public:
  9671. // UOpr1(v0) Op UOpr2(v1)
  9672. typedef expression_node<T>* expression_ptr;
  9673. typedef typename details::functor_t<T> functor_t;
  9674. typedef typename functor_t::bfunc_t bfunc_t;
  9675. typedef typename functor_t::ufunc_t ufunc_t;
  9676. explicit uvouv_node(const T& var0,const T& var1,
  9677. ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
  9678. : v0_(var0),
  9679. v1_(var1),
  9680. u0_(uf0),
  9681. u1_(uf1),
  9682. f_ (bf)
  9683. {}
  9684. inline T value() const
  9685. {
  9686. return f_(u0_(v0_),u1_(v1_));
  9687. }
  9688. inline typename expression_node<T>::node_type type() const
  9689. {
  9690. return expression_node<T>::e_uvouv;
  9691. }
  9692. inline operator_type operation() const
  9693. {
  9694. return details::e_default;
  9695. }
  9696. inline const T& v0()
  9697. {
  9698. return v0_;
  9699. }
  9700. inline const T& v1()
  9701. {
  9702. return v1_;
  9703. }
  9704. inline ufunc_t u0()
  9705. {
  9706. return u0_;
  9707. }
  9708. inline ufunc_t u1()
  9709. {
  9710. return u1_;
  9711. }
  9712. inline ufunc_t f()
  9713. {
  9714. return f_;
  9715. }
  9716. private:
  9717. uvouv_node(uvouv_node<T>&);
  9718. uvouv_node<T>& operator=(uvouv_node<T>&);
  9719. const T& v0_;
  9720. const T& v1_;
  9721. const ufunc_t u0_;
  9722. const ufunc_t u1_;
  9723. const bfunc_t f_;
  9724. };
  9725. template <typename T, typename Operation>
  9726. class unary_branch_node : public expression_node<T>
  9727. {
  9728. public:
  9729. typedef expression_node<T>* expression_ptr;
  9730. typedef Operation operation_t;
  9731. explicit unary_branch_node(expression_ptr brnch)
  9732. : branch_(brnch),
  9733. branch_deletable_(branch_deletable(branch_))
  9734. {}
  9735. ~unary_branch_node()
  9736. {
  9737. if (branch_ && branch_deletable_)
  9738. {
  9739. delete branch_;
  9740. branch_ = 0;
  9741. }
  9742. }
  9743. inline T value() const
  9744. {
  9745. return Operation::process(branch_->value());
  9746. }
  9747. inline typename expression_node<T>::node_type type() const
  9748. {
  9749. return Operation::type();
  9750. }
  9751. inline operator_type operation() const
  9752. {
  9753. return Operation::operation();
  9754. }
  9755. inline expression_node<T>* branch(const std::size_t&) const
  9756. {
  9757. return branch_;
  9758. }
  9759. inline void release()
  9760. {
  9761. branch_deletable_ = false;
  9762. }
  9763. private:
  9764. unary_branch_node(unary_branch_node<T,Operation>&);
  9765. unary_branch_node<T,Operation>& operator=(unary_branch_node<T,Operation>&);
  9766. expression_ptr branch_;
  9767. bool branch_deletable_;
  9768. };
  9769. template <typename T> struct is_const { enum {result = 0}; };
  9770. template <typename T> struct is_const <const T> { enum {result = 1}; };
  9771. template <typename T> struct is_const_ref { enum {result = 0}; };
  9772. template <typename T> struct is_const_ref <const T&> { enum {result = 1}; };
  9773. template <typename T> struct is_ref { enum {result = 0}; };
  9774. template <typename T> struct is_ref<T&> { enum {result = 1}; };
  9775. template <typename T> struct is_ref<const T&> { enum {result = 0}; };
  9776. template <std::size_t State>
  9777. struct param_to_str { static std::string result() { static const std::string r("v"); return r; } };
  9778. template <>
  9779. struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } };
  9780. #define exprtk_crtype(Type) \
  9781. param_to_str<is_const_ref< Type >::result>::result() \
  9782. template <typename T>
  9783. struct T0oT1oT2process
  9784. {
  9785. typedef typename details::functor_t<T> functor_t;
  9786. typedef typename functor_t::bfunc_t bfunc_t;
  9787. struct mode0
  9788. {
  9789. static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
  9790. {
  9791. // (T0 o0 T1) o1 T2
  9792. return bf1(bf0(t0,t1),t2);
  9793. }
  9794. template <typename T0, typename T1, typename T2>
  9795. static inline std::string id()
  9796. {
  9797. static const std::string result = "(" + exprtk_crtype(T0) + "o" +
  9798. exprtk_crtype(T1) + ")o(" +
  9799. exprtk_crtype(T2) + ")" ;
  9800. return result;
  9801. }
  9802. };
  9803. struct mode1
  9804. {
  9805. static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
  9806. {
  9807. // T0 o0 (T1 o1 T2)
  9808. return bf0(t0,bf1(t1,t2));
  9809. }
  9810. template <typename T0, typename T1, typename T2>
  9811. static inline std::string id()
  9812. {
  9813. static const std::string result = "(" + exprtk_crtype(T0) + ")o(" +
  9814. exprtk_crtype(T1) + "o" +
  9815. exprtk_crtype(T2) + ")" ;
  9816. return result;
  9817. }
  9818. };
  9819. };
  9820. template <typename T>
  9821. struct T0oT1oT20T3process
  9822. {
  9823. typedef typename details::functor_t<T> functor_t;
  9824. typedef typename functor_t::bfunc_t bfunc_t;
  9825. struct mode0
  9826. {
  9827. static inline T process(const T& t0, const T& t1,
  9828. const T& t2, const T& t3,
  9829. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9830. {
  9831. // (T0 o0 T1) o1 (T2 o2 T3)
  9832. return bf1(bf0(t0,t1),bf2(t2,t3));
  9833. }
  9834. template <typename T0, typename T1, typename T2, typename T3>
  9835. static inline std::string id()
  9836. {
  9837. static const std::string result = "(" + exprtk_crtype(T0) + "o" +
  9838. exprtk_crtype(T1) + ")o" +
  9839. "(" + exprtk_crtype(T2) + "o" +
  9840. exprtk_crtype(T3) + ")" ;
  9841. return result;
  9842. }
  9843. };
  9844. struct mode1
  9845. {
  9846. static inline T process(const T& t0, const T& t1,
  9847. const T& t2, const T& t3,
  9848. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9849. {
  9850. // (T0 o0 (T1 o1 (T2 o2 T3))
  9851. return bf0(t0,bf1(t1,bf2(t2,t3)));
  9852. }
  9853. template <typename T0, typename T1, typename T2, typename T3>
  9854. static inline std::string id()
  9855. {
  9856. static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
  9857. exprtk_crtype(T1) + ")o(" +
  9858. exprtk_crtype(T2) + "o" +
  9859. exprtk_crtype(T3) + "))" ;
  9860. return result;
  9861. }
  9862. };
  9863. struct mode2
  9864. {
  9865. static inline T process(const T& t0, const T& t1,
  9866. const T& t2, const T& t3,
  9867. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9868. {
  9869. // (T0 o0 ((T1 o1 T2) o2 T3)
  9870. return bf0(t0,bf2(bf1(t1,t2),t3));
  9871. }
  9872. template <typename T0, typename T1, typename T2, typename T3>
  9873. static inline std::string id()
  9874. {
  9875. static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
  9876. exprtk_crtype(T1) + "o" +
  9877. exprtk_crtype(T2) + ")o(" +
  9878. exprtk_crtype(T3) + "))" ;
  9879. return result;
  9880. }
  9881. };
  9882. struct mode3
  9883. {
  9884. static inline T process(const T& t0, const T& t1,
  9885. const T& t2, const T& t3,
  9886. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9887. {
  9888. // (((T0 o0 T1) o1 T2) o2 T3)
  9889. return bf2(bf1(bf0(t0,t1),t2),t3);
  9890. }
  9891. template <typename T0, typename T1, typename T2, typename T3>
  9892. static inline std::string id()
  9893. {
  9894. static const std::string result = "((" + exprtk_crtype(T0) + "o" +
  9895. exprtk_crtype(T1) + ")o(" +
  9896. exprtk_crtype(T2) + "))o(" +
  9897. exprtk_crtype(T3) + ")";
  9898. return result;
  9899. }
  9900. };
  9901. struct mode4
  9902. {
  9903. static inline T process(const T& t0, const T& t1,
  9904. const T& t2, const T& t3,
  9905. const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
  9906. {
  9907. // ((T0 o0 (T1 o1 T2)) o2 T3
  9908. return bf2(bf0(t0,bf1(t1,t2)),t3);
  9909. }
  9910. template <typename T0, typename T1, typename T2, typename T3>
  9911. static inline std::string id()
  9912. {
  9913. static const std::string result = "((" + exprtk_crtype(T0) + ")o(" +
  9914. exprtk_crtype(T1) + "o" +
  9915. exprtk_crtype(T2) + "))o(" +
  9916. exprtk_crtype(T3) + ")" ;
  9917. return result;
  9918. }
  9919. };
  9920. };
  9921. #undef exprtk_crtype
  9922. template <typename T, typename T0, typename T1>
  9923. struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; };
  9924. template <typename T, typename T0, typename T1>
  9925. const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none;
  9926. #define synthesis_node_type_define(T0_,T1_,v_) \
  9927. template <typename T, typename T0, typename T1> \
  9928. struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
  9929. template <typename T, typename T0, typename T1> \
  9930. const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
  9931. synthesis_node_type_define(const T0&,const T1&, e_vov)
  9932. synthesis_node_type_define(const T0&,const T1 , e_voc)
  9933. synthesis_node_type_define(const T0 ,const T1&, e_cov)
  9934. synthesis_node_type_define( T0&, T1&,e_none)
  9935. synthesis_node_type_define(const T0 ,const T1 ,e_none)
  9936. synthesis_node_type_define( T0&,const T1 ,e_none)
  9937. synthesis_node_type_define(const T0 , T1&,e_none)
  9938. synthesis_node_type_define(const T0&, T1&,e_none)
  9939. synthesis_node_type_define( T0&,const T1&,e_none)
  9940. #undef synthesis_node_type_define
  9941. template <typename T, typename T0, typename T1, typename T2>
  9942. struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
  9943. template <typename T, typename T0, typename T1, typename T2>
  9944. const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none;
  9945. #define synthesis_node_type_define(T0_,T1_,T2_,v_) \
  9946. template <typename T, typename T0, typename T1, typename T2> \
  9947. struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
  9948. template <typename T, typename T0, typename T1, typename T2> \
  9949. const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
  9950. synthesis_node_type_define(const T0&,const T1&,const T2&, e_vovov)
  9951. synthesis_node_type_define(const T0&,const T1&,const T2 , e_vovoc)
  9952. synthesis_node_type_define(const T0&,const T1 ,const T2&, e_vocov)
  9953. synthesis_node_type_define(const T0 ,const T1&,const T2&, e_covov)
  9954. synthesis_node_type_define(const T0 ,const T1&,const T2 , e_covoc)
  9955. synthesis_node_type_define(const T0 ,const T1 ,const T2 , e_none )
  9956. synthesis_node_type_define(const T0 ,const T1 ,const T2&, e_none )
  9957. synthesis_node_type_define(const T0&,const T1 ,const T2 , e_none )
  9958. synthesis_node_type_define( T0&, T1&, T2&, e_none )
  9959. #undef synthesis_node_type_define
  9960. template <typename T, typename T0, typename T1, typename T2, typename T3>
  9961. struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; };
  9962. template <typename T, typename T0, typename T1, typename T2, typename T3>
  9963. const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none;
  9964. #define synthesis_node_type_define(T0_,T1_,T2_,T3_,v_) \
  9965. template <typename T, typename T0, typename T1, typename T2, typename T3> \
  9966. struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
  9967. template <typename T, typename T0, typename T1, typename T2, typename T3> \
  9968. const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
  9969. synthesis_node_type_define(const T0&,const T1&,const T2&, const T3&,e_vovovov)
  9970. synthesis_node_type_define(const T0&,const T1&,const T2&, const T3 ,e_vovovoc)
  9971. synthesis_node_type_define(const T0&,const T1&,const T2 , const T3&,e_vovocov)
  9972. synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3&,e_vocovov)
  9973. synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3&,e_covovov)
  9974. synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3&,e_covocov)
  9975. synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc)
  9976. synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3 ,e_covovoc)
  9977. synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3&,e_vococov)
  9978. synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3 ,e_none )
  9979. synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3&,e_none )
  9980. synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3 ,e_none )
  9981. synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3 ,e_none )
  9982. synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3 ,e_none )
  9983. synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3&,e_none )
  9984. synthesis_node_type_define(const T0&,const T1&,const T2 , const T3 ,e_none )
  9985. #undef synthesis_node_type_define
  9986. template <typename T, typename T0, typename T1>
  9987. class T0oT1 : public expression_node<T>
  9988. {
  9989. public:
  9990. typedef typename details::functor_t<T> functor_t;
  9991. typedef typename functor_t::bfunc_t bfunc_t;
  9992. typedef T value_type;
  9993. typedef T0oT1<T,T0,T1> node_type;
  9994. T0oT1(T0 p0, T1 p1, const bfunc_t p2)
  9995. : t0_(p0),
  9996. t1_(p1),
  9997. f_ (p2)
  9998. {}
  9999. inline typename expression_node<T>::node_type type() const
  10000. {
  10001. static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result;
  10002. return result;
  10003. }
  10004. inline operator_type operation() const
  10005. {
  10006. return e_default;
  10007. }
  10008. inline T value() const
  10009. {
  10010. return f_(t0_,t1_);
  10011. }
  10012. inline T0 t0() const
  10013. {
  10014. return t0_;
  10015. }
  10016. inline T1 t1() const
  10017. {
  10018. return t1_;
  10019. }
  10020. inline bfunc_t f() const
  10021. {
  10022. return f_;
  10023. }
  10024. template <typename Allocator>
  10025. static inline expression_node<T>* allocate(Allocator& allocator,
  10026. T0 p0, T1 p1,
  10027. bfunc_t p2)
  10028. {
  10029. return allocator.template allocate_type<node_type,T0,T1,bfunc_t&>(p0,p1,p2);
  10030. }
  10031. private:
  10032. T0oT1(T0oT1<T,T0,T1>&) {}
  10033. T0oT1<T,T0,T1>& operator=(T0oT1<T,T0,T1>&) { return *this; }
  10034. T0 t0_;
  10035. T1 t1_;
  10036. const bfunc_t f_;
  10037. };
  10038. template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
  10039. class T0oT1oT2 : public T0oT1oT2_base_node<T>
  10040. {
  10041. public:
  10042. typedef typename details::functor_t<T> functor_t;
  10043. typedef typename functor_t::bfunc_t bfunc_t;
  10044. typedef T value_type;
  10045. typedef T0oT1oT2<T,T0,T1,T2,ProcessMode> node_type;
  10046. typedef ProcessMode process_mode_t;
  10047. T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
  10048. : t0_(p0),
  10049. t1_(p1),
  10050. t2_(p2),
  10051. f0_(p3),
  10052. f1_(p4)
  10053. {}
  10054. inline typename expression_node<T>::node_type type() const
  10055. {
  10056. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
  10057. return result;
  10058. }
  10059. inline operator_type operation() const
  10060. {
  10061. return e_default;
  10062. }
  10063. inline T value() const
  10064. {
  10065. return ProcessMode::process(t0_,t1_,t2_,f0_,f1_);
  10066. }
  10067. inline T0 t0() const
  10068. {
  10069. return t0_;
  10070. }
  10071. inline T1 t1() const
  10072. {
  10073. return t1_;
  10074. }
  10075. inline T2 t2() const
  10076. {
  10077. return t2_;
  10078. }
  10079. bfunc_t f0() const
  10080. {
  10081. return f0_;
  10082. }
  10083. bfunc_t f1() const
  10084. {
  10085. return f1_;
  10086. }
  10087. std::string type_id() const
  10088. {
  10089. return id();
  10090. }
  10091. static inline std::string id()
  10092. {
  10093. return process_mode_t::template id<T0,T1,T2>();
  10094. }
  10095. template <typename Allocator>
  10096. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
  10097. {
  10098. return allocator.template allocate_type<node_type,T0,T1,T2,bfunc_t,bfunc_t>(p0,p1,p2,p3,p4);
  10099. }
  10100. private:
  10101. T0oT1oT2(node_type&) {}
  10102. node_type& operator=(node_type&) { return *this; }
  10103. T0 t0_;
  10104. T1 t1_;
  10105. T2 t2_;
  10106. const bfunc_t f0_;
  10107. const bfunc_t f1_;
  10108. };
  10109. template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode>
  10110. class T0oT1oT2oT3 : public T0oT1oT2oT3_base_node<T>
  10111. {
  10112. public:
  10113. typedef typename details::functor_t<T> functor_t;
  10114. typedef typename functor_t::bfunc_t bfunc_t;
  10115. typedef T value_type;
  10116. typedef T0_ T0;
  10117. typedef T1_ T1;
  10118. typedef T2_ T2;
  10119. typedef T3_ T3;
  10120. typedef T0oT1oT2oT3<T,T0,T1,T2,T3,ProcessMode> node_type;
  10121. typedef ProcessMode process_mode_t;
  10122. T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
  10123. : t0_(p0),
  10124. t1_(p1),
  10125. t2_(p2),
  10126. t3_(p3),
  10127. f0_(p4),
  10128. f1_(p5),
  10129. f2_(p6)
  10130. {}
  10131. inline T value() const
  10132. {
  10133. return ProcessMode::process(t0_,t1_,t2_,t3_,f0_,f1_,f2_);
  10134. }
  10135. inline T0 t0() const
  10136. {
  10137. return t0_;
  10138. }
  10139. inline T1 t1() const
  10140. {
  10141. return t1_;
  10142. }
  10143. inline T2 t2() const
  10144. {
  10145. return t2_;
  10146. }
  10147. inline T3 t3() const
  10148. {
  10149. return t3_;
  10150. }
  10151. inline bfunc_t f0() const
  10152. {
  10153. return f0_;
  10154. }
  10155. inline bfunc_t f1() const
  10156. {
  10157. return f1_;
  10158. }
  10159. inline bfunc_t f2() const
  10160. {
  10161. return f2_;
  10162. }
  10163. inline std::string type_id() const
  10164. {
  10165. return id();
  10166. }
  10167. static inline std::string id()
  10168. {
  10169. return process_mode_t::template id<T0,T1,T2,T3>();
  10170. }
  10171. template <typename Allocator>
  10172. static inline expression_node<T>* allocate(Allocator& allocator,
  10173. T0 p0, T1 p1, T2 p2, T3 p3,
  10174. bfunc_t p4, bfunc_t p5, bfunc_t p6)
  10175. {
  10176. return allocator.template allocate_type<node_type,T0,T1,T2,T3,bfunc_t,bfunc_t>(p0,p1,p2,p3,p4,p5,p6);
  10177. }
  10178. private:
  10179. T0oT1oT2oT3(node_type&) {}
  10180. node_type& operator=(node_type&) { return *this; }
  10181. T0 t0_;
  10182. T1 t1_;
  10183. T2 t2_;
  10184. T3 t3_;
  10185. const bfunc_t f0_;
  10186. const bfunc_t f1_;
  10187. const bfunc_t f2_;
  10188. };
  10189. template <typename T, typename T0, typename T1, typename T2>
  10190. class T0oT1oT2_sf3 : public T0oT1oT2_base_node<T>
  10191. {
  10192. public:
  10193. typedef typename details::functor_t<T> functor_t;
  10194. typedef typename functor_t::tfunc_t tfunc_t;
  10195. typedef T value_type;
  10196. typedef T0oT1oT2_sf3<T,T0,T1,T2> node_type;
  10197. T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
  10198. : t0_(p0),
  10199. t1_(p1),
  10200. t2_(p2),
  10201. f_ (p3)
  10202. {}
  10203. inline typename expression_node<T>::node_type type() const
  10204. {
  10205. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
  10206. return result;
  10207. }
  10208. inline operator_type operation() const
  10209. {
  10210. return e_default;
  10211. }
  10212. inline T value() const
  10213. {
  10214. return f_(t0_,t1_,t2_);
  10215. }
  10216. inline T0 t0() const
  10217. {
  10218. return t0_;
  10219. }
  10220. inline T1 t1() const
  10221. {
  10222. return t1_;
  10223. }
  10224. inline T2 t2() const
  10225. {
  10226. return t2_;
  10227. }
  10228. tfunc_t f() const
  10229. {
  10230. return f_;
  10231. }
  10232. std::string type_id() const
  10233. {
  10234. return id();
  10235. }
  10236. static inline std::string id()
  10237. {
  10238. return "sf3";
  10239. }
  10240. template <typename Allocator>
  10241. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
  10242. {
  10243. return allocator.template allocate_type<node_type,T0,T1,T2,tfunc_t>(p0,p1,p2,p3);
  10244. }
  10245. private:
  10246. T0oT1oT2_sf3(node_type&) {}
  10247. node_type& operator=(node_type&) { return *this; }
  10248. T0 t0_;
  10249. T1 t1_;
  10250. T2 t2_;
  10251. const tfunc_t f_;
  10252. };
  10253. template <typename T, typename T0, typename T1, typename T2>
  10254. class sf3ext_type_node : public T0oT1oT2_base_node<T>
  10255. {
  10256. public:
  10257. virtual T0 t0() const = 0;
  10258. virtual T1 t1() const = 0;
  10259. virtual T2 t2() const = 0;
  10260. };
  10261. template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
  10262. class T0oT1oT2_sf3ext : public sf3ext_type_node<T,T0,T1,T2>
  10263. {
  10264. public:
  10265. typedef typename details::functor_t<T> functor_t;
  10266. typedef typename functor_t::tfunc_t tfunc_t;
  10267. typedef T value_type;
  10268. typedef T0oT1oT2_sf3ext<T,T0,T1,T2,SF3Operation> node_type;
  10269. T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
  10270. : t0_(p0),
  10271. t1_(p1),
  10272. t2_(p2)
  10273. {}
  10274. inline typename expression_node<T>::node_type type() const
  10275. {
  10276. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
  10277. return result;
  10278. }
  10279. inline operator_type operation() const
  10280. {
  10281. return e_default;
  10282. }
  10283. inline T value() const
  10284. {
  10285. return SF3Operation::process(t0_,t1_,t2_);
  10286. }
  10287. T0 t0() const
  10288. {
  10289. return t0_;
  10290. }
  10291. T1 t1() const
  10292. {
  10293. return t1_;
  10294. }
  10295. T2 t2() const
  10296. {
  10297. return t2_;
  10298. }
  10299. std::string type_id() const
  10300. {
  10301. return id();
  10302. }
  10303. static inline std::string id()
  10304. {
  10305. return SF3Operation::id();
  10306. }
  10307. template <typename Allocator>
  10308. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2)
  10309. {
  10310. return allocator.template allocate_type<node_type,T0,T1,T2>(p0,p1,p2);
  10311. }
  10312. private:
  10313. T0oT1oT2_sf3ext(node_type&) {}
  10314. node_type& operator=(node_type&) { return *this; }
  10315. T0 t0_;
  10316. T1 t1_;
  10317. T2 t2_;
  10318. };
  10319. template <typename T>
  10320. inline bool is_sf3ext_node(const expression_node<T>* n)
  10321. {
  10322. switch (n->type())
  10323. {
  10324. case expression_node<T>::e_vovov : return true;
  10325. case expression_node<T>::e_vovoc : return true;
  10326. case expression_node<T>::e_vocov : return true;
  10327. case expression_node<T>::e_covov : return true;
  10328. case expression_node<T>::e_covoc : return true;
  10329. default : return false;
  10330. }
  10331. }
  10332. template <typename T, typename T0, typename T1, typename T2, typename T3>
  10333. class T0oT1oT2oT3_sf4 : public T0oT1oT2_base_node<T>
  10334. {
  10335. public:
  10336. typedef typename details::functor_t<T> functor_t;
  10337. typedef typename functor_t::qfunc_t qfunc_t;
  10338. typedef T value_type;
  10339. typedef T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> node_type;
  10340. T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
  10341. : t0_(p0),
  10342. t1_(p1),
  10343. t2_(p2),
  10344. t3_(p3),
  10345. f_ (p4)
  10346. {}
  10347. inline typename expression_node<T>::node_type type() const
  10348. {
  10349. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
  10350. return result;
  10351. }
  10352. inline operator_type operation() const
  10353. {
  10354. return e_default;
  10355. }
  10356. inline T value() const
  10357. {
  10358. return f_(t0_,t1_,t2_,t3_);
  10359. }
  10360. inline T0 t0() const
  10361. {
  10362. return t0_;
  10363. }
  10364. inline T1 t1() const
  10365. {
  10366. return t1_;
  10367. }
  10368. inline T2 t2() const
  10369. {
  10370. return t2_;
  10371. }
  10372. inline T3 t3() const
  10373. {
  10374. return t3_;
  10375. }
  10376. qfunc_t f() const
  10377. {
  10378. return f_;
  10379. }
  10380. std::string type_id() const
  10381. {
  10382. return id();
  10383. }
  10384. static inline std::string id()
  10385. {
  10386. return "sf4";
  10387. }
  10388. template <typename Allocator>
  10389. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
  10390. {
  10391. return allocator.template allocate_type<node_type,T0,T1,T2,T3,qfunc_t>(p0,p1,p2,p3,p4);
  10392. }
  10393. private:
  10394. T0oT1oT2oT3_sf4(node_type&) {}
  10395. node_type& operator=(node_type&) { return *this; }
  10396. T0 t0_;
  10397. T1 t1_;
  10398. T2 t2_;
  10399. T3 t3_;
  10400. const qfunc_t f_;
  10401. };
  10402. template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation>
  10403. class T0oT1oT2oT3_sf4ext : public T0oT1oT2oT3_base_node<T>
  10404. {
  10405. public:
  10406. typedef typename details::functor_t<T> functor_t;
  10407. typedef typename functor_t::tfunc_t tfunc_t;
  10408. typedef T value_type;
  10409. typedef T0oT1oT2oT3_sf4ext<T,T0,T1,T2,T3,SF4Operation> node_type;
  10410. T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
  10411. : t0_(p0),
  10412. t1_(p1),
  10413. t2_(p2),
  10414. t3_(p3)
  10415. {}
  10416. inline typename expression_node<T>::node_type type() const
  10417. {
  10418. static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
  10419. return result;
  10420. }
  10421. inline operator_type operation() const
  10422. {
  10423. return e_default;
  10424. }
  10425. inline T value() const
  10426. {
  10427. return SF4Operation::process(t0_,t1_,t2_,t3_);
  10428. }
  10429. inline T0 t0() const
  10430. {
  10431. return t0_;
  10432. }
  10433. inline T1 t1() const
  10434. {
  10435. return t1_;
  10436. }
  10437. inline T2 t2() const
  10438. {
  10439. return t2_;
  10440. }
  10441. inline T3 t3() const
  10442. {
  10443. return t2_;
  10444. }
  10445. std::string type_id() const
  10446. {
  10447. return id();
  10448. }
  10449. static inline std::string id()
  10450. {
  10451. return SF4Operation::id();
  10452. }
  10453. template <typename Allocator>
  10454. static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3)
  10455. {
  10456. return allocator.template allocate_type<node_type,T0,T1,T2,T3>(p0,p1,p2,p3);
  10457. }
  10458. private:
  10459. T0oT1oT2oT3_sf4ext(node_type&) {}
  10460. node_type& operator=(node_type&) { return *this; }
  10461. T0 t0_;
  10462. T1 t1_;
  10463. T2 t2_;
  10464. T3 t3_;
  10465. };
  10466. template <typename T>
  10467. inline bool is_sf4ext_node(const expression_node<T>* n)
  10468. {
  10469. switch (n->type())
  10470. {
  10471. case expression_node<T>::e_vovovov : return true;
  10472. case expression_node<T>::e_vovovoc : return true;
  10473. case expression_node<T>::e_vovocov : return true;
  10474. case expression_node<T>::e_vocovov : return true;
  10475. case expression_node<T>::e_covovov : return true;
  10476. case expression_node<T>::e_covocov : return true;
  10477. case expression_node<T>::e_vocovoc : return true;
  10478. case expression_node<T>::e_covovoc : return true;
  10479. case expression_node<T>::e_vococov : return true;
  10480. default : return false;
  10481. }
  10482. }
  10483. template <typename T, typename T0, typename T1>
  10484. struct T0oT1_define
  10485. {
  10486. typedef details::T0oT1<T,T0,T1> type0;
  10487. };
  10488. template <typename T, typename T0, typename T1, typename T2>
  10489. struct T0oT1oT2_define
  10490. {
  10491. typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode0> type0;
  10492. typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode1> type1;
  10493. typedef details::T0oT1oT2_sf3<T,T0,T1,T2> sf3_type;
  10494. typedef details::sf3ext_type_node<T,T0,T1,T2> sf3_type_node;
  10495. };
  10496. template <typename T, typename T0, typename T1, typename T2, typename T3>
  10497. struct T0oT1oT2oT3_define
  10498. {
  10499. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode0> type0;
  10500. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode1> type1;
  10501. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode2> type2;
  10502. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode3> type3;
  10503. typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode4> type4;
  10504. typedef details::T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> sf4_type;
  10505. };
  10506. template <typename T, typename Operation>
  10507. class vov_node : public vov_base_node<T>
  10508. {
  10509. public:
  10510. typedef expression_node<T>* expression_ptr;
  10511. typedef Operation operation_t;
  10512. // variable op variable node
  10513. explicit vov_node(const T& var0, const T& var1)
  10514. : v0_(var0),
  10515. v1_(var1)
  10516. {}
  10517. inline T value() const
  10518. {
  10519. return Operation::process(v0_,v1_);
  10520. }
  10521. inline typename expression_node<T>::node_type type() const
  10522. {
  10523. return Operation::type();
  10524. }
  10525. inline operator_type operation() const
  10526. {
  10527. return Operation::operation();
  10528. }
  10529. inline const T& v0() const
  10530. {
  10531. return v0_;
  10532. }
  10533. inline const T& v1() const
  10534. {
  10535. return v1_;
  10536. }
  10537. protected:
  10538. const T& v0_;
  10539. const T& v1_;
  10540. private:
  10541. vov_node(vov_node<T,Operation>&);
  10542. vov_node<T,Operation>& operator=(vov_node<T,Operation>&);
  10543. };
  10544. template <typename T, typename Operation>
  10545. class cov_node : public cov_base_node<T>
  10546. {
  10547. public:
  10548. typedef expression_node<T>* expression_ptr;
  10549. typedef Operation operation_t;
  10550. // constant op variable node
  10551. explicit cov_node(const T& const_var, const T& var)
  10552. : c_(const_var),
  10553. v_(var)
  10554. {}
  10555. inline T value() const
  10556. {
  10557. return Operation::process(c_,v_);
  10558. }
  10559. inline typename expression_node<T>::node_type type() const
  10560. {
  10561. return Operation::type();
  10562. }
  10563. inline operator_type operation() const
  10564. {
  10565. return Operation::operation();
  10566. }
  10567. inline const T c() const
  10568. {
  10569. return c_;
  10570. }
  10571. inline const T& v() const
  10572. {
  10573. return v_;
  10574. }
  10575. protected:
  10576. const T c_;
  10577. const T& v_;
  10578. private:
  10579. cov_node(const cov_node<T,Operation>&);
  10580. cov_node<T,Operation>& operator=(const cov_node<T,Operation>&);
  10581. };
  10582. template <typename T, typename Operation>
  10583. class voc_node : public voc_base_node<T>
  10584. {
  10585. public:
  10586. typedef expression_node<T>* expression_ptr;
  10587. typedef Operation operation_t;
  10588. // variable op constant node
  10589. explicit voc_node(const T& var, const T& const_var)
  10590. : v_(var),
  10591. c_(const_var)
  10592. {}
  10593. inline T value() const
  10594. {
  10595. return Operation::process(v_,c_);
  10596. }
  10597. inline operator_type operation() const
  10598. {
  10599. return Operation::operation();
  10600. }
  10601. inline const T c() const
  10602. {
  10603. return c_;
  10604. }
  10605. inline const T& v() const
  10606. {
  10607. return v_;
  10608. }
  10609. protected:
  10610. const T& v_;
  10611. const T c_;
  10612. private:
  10613. voc_node(const voc_node<T,Operation>&);
  10614. voc_node<T,Operation>& operator=(const voc_node<T,Operation>&);
  10615. };
  10616. template <typename T, typename Operation>
  10617. class vob_node : public vob_base_node<T>
  10618. {
  10619. public:
  10620. typedef expression_node<T>* expression_ptr;
  10621. typedef std::pair<expression_ptr,bool> branch_t;
  10622. typedef Operation operation_t;
  10623. // variable op constant node
  10624. explicit vob_node(const T& var, const expression_ptr brnch)
  10625. : v_(var)
  10626. {
  10627. init_branches<1>(branch_,brnch);
  10628. }
  10629. ~vob_node()
  10630. {
  10631. cleanup_branches::execute<T,1>(branch_);
  10632. }
  10633. inline T value() const
  10634. {
  10635. return Operation::process(v_,branch_[0].first->value());
  10636. }
  10637. inline operator_type operation() const
  10638. {
  10639. return Operation::operation();
  10640. }
  10641. inline const T& v() const
  10642. {
  10643. return v_;
  10644. }
  10645. inline expression_node<T>* branch(const std::size_t&) const
  10646. {
  10647. return branch_[0].first;
  10648. }
  10649. private:
  10650. vob_node(const vob_node<T,Operation>&);
  10651. vob_node<T,Operation>& operator=(const vob_node<T,Operation>&);
  10652. const T& v_;
  10653. branch_t branch_[1];
  10654. };
  10655. template <typename T, typename Operation>
  10656. class bov_node : public bov_base_node<T>
  10657. {
  10658. public:
  10659. typedef expression_node<T>* expression_ptr;
  10660. typedef std::pair<expression_ptr,bool> branch_t;
  10661. typedef Operation operation_t;
  10662. // variable op constant node
  10663. explicit bov_node(const expression_ptr brnch, const T& var)
  10664. : v_(var)
  10665. {
  10666. init_branches<1>(branch_,brnch);
  10667. }
  10668. ~bov_node()
  10669. {
  10670. cleanup_branches::execute<T,1>(branch_);
  10671. }
  10672. inline T value() const
  10673. {
  10674. return Operation::process(branch_[0].first->value(),v_);
  10675. }
  10676. inline operator_type operation() const
  10677. {
  10678. return Operation::operation();
  10679. }
  10680. inline const T& v() const
  10681. {
  10682. return v_;
  10683. }
  10684. inline expression_node<T>* branch(const std::size_t&) const
  10685. {
  10686. return branch_[0].first;
  10687. }
  10688. private:
  10689. bov_node(const bov_node<T,Operation>&);
  10690. bov_node<T,Operation>& operator=(const bov_node<T,Operation>&);
  10691. const T& v_;
  10692. branch_t branch_[1];
  10693. };
  10694. template <typename T, typename Operation>
  10695. class cob_node : public cob_base_node<T>
  10696. {
  10697. public:
  10698. typedef expression_node<T>* expression_ptr;
  10699. typedef std::pair<expression_ptr,bool> branch_t;
  10700. typedef Operation operation_t;
  10701. // variable op constant node
  10702. explicit cob_node(const T const_var, const expression_ptr brnch)
  10703. : c_(const_var)
  10704. {
  10705. init_branches<1>(branch_,brnch);
  10706. }
  10707. ~cob_node()
  10708. {
  10709. cleanup_branches::execute<T,1>(branch_);
  10710. }
  10711. inline T value() const
  10712. {
  10713. return Operation::process(c_,branch_[0].first->value());
  10714. }
  10715. inline operator_type operation() const
  10716. {
  10717. return Operation::operation();
  10718. }
  10719. inline const T c() const
  10720. {
  10721. return c_;
  10722. }
  10723. inline void set_c(const T new_c)
  10724. {
  10725. (*const_cast<T*>(&c_)) = new_c;
  10726. }
  10727. inline expression_node<T>* branch(const std::size_t&) const
  10728. {
  10729. return branch_[0].first;
  10730. }
  10731. inline expression_node<T>* move_branch(const std::size_t&)
  10732. {
  10733. branch_[0].second = false;
  10734. return branch_[0].first;
  10735. }
  10736. private:
  10737. cob_node(const cob_node<T,Operation>&);
  10738. cob_node<T,Operation>& operator=(const cob_node<T,Operation>&);
  10739. const T c_;
  10740. branch_t branch_[1];
  10741. };
  10742. template <typename T, typename Operation>
  10743. class boc_node : public boc_base_node<T>
  10744. {
  10745. public:
  10746. typedef expression_node<T>* expression_ptr;
  10747. typedef std::pair<expression_ptr,bool> branch_t;
  10748. typedef Operation operation_t;
  10749. // variable op constant node
  10750. explicit boc_node(const expression_ptr brnch, const T const_var)
  10751. : c_(const_var)
  10752. {
  10753. init_branches<1>(branch_,brnch);
  10754. }
  10755. ~boc_node()
  10756. {
  10757. cleanup_branches::execute<T,1>(branch_);
  10758. }
  10759. inline T value() const
  10760. {
  10761. return Operation::process(branch_[0].first->value(),c_);
  10762. }
  10763. inline operator_type operation() const
  10764. {
  10765. return Operation::operation();
  10766. }
  10767. inline const T c() const
  10768. {
  10769. return c_;
  10770. }
  10771. inline void set_c(const T new_c)
  10772. {
  10773. (*const_cast<T*>(&c_)) = new_c;
  10774. }
  10775. inline expression_node<T>* branch(const std::size_t&) const
  10776. {
  10777. return branch_[0].first;
  10778. }
  10779. inline expression_node<T>* move_branch(const std::size_t&)
  10780. {
  10781. branch_[0].second = false;
  10782. return branch_[0].first;
  10783. }
  10784. private:
  10785. boc_node(const boc_node<T,Operation>&);
  10786. boc_node<T,Operation>& operator=(const boc_node<T,Operation>&);
  10787. const T c_;
  10788. branch_t branch_[1];
  10789. };
  10790. #ifndef exprtk_disable_string_capabilities
  10791. template <typename T, typename SType0, typename SType1, typename Operation>
  10792. class sos_node : public sos_base_node<T>
  10793. {
  10794. public:
  10795. typedef expression_node<T>* expression_ptr;
  10796. typedef Operation operation_t;
  10797. // string op string node
  10798. explicit sos_node(SType0 p0, SType1 p1)
  10799. : s0_(p0),
  10800. s1_(p1)
  10801. {}
  10802. inline T value() const
  10803. {
  10804. return Operation::process(s0_,s1_);
  10805. }
  10806. inline typename expression_node<T>::node_type type() const
  10807. {
  10808. return Operation::type();
  10809. }
  10810. inline operator_type operation() const
  10811. {
  10812. return Operation::operation();
  10813. }
  10814. inline std::string& s0()
  10815. {
  10816. return s0_;
  10817. }
  10818. inline std::string& s1()
  10819. {
  10820. return s1_;
  10821. }
  10822. protected:
  10823. SType0 s0_;
  10824. SType1 s1_;
  10825. private:
  10826. sos_node(sos_node<T,SType0,SType1,Operation>&);
  10827. sos_node<T,SType0,SType1,Operation>& operator=(sos_node<T,SType0,SType1,Operation>&);
  10828. };
  10829. template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
  10830. class str_xrox_node : public sos_base_node<T>
  10831. {
  10832. public:
  10833. typedef expression_node<T>* expression_ptr;
  10834. typedef Operation operation_t;
  10835. // string-range op string node
  10836. explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
  10837. : s0_(p0),
  10838. s1_(p1),
  10839. rp0_(rp0)
  10840. {}
  10841. ~str_xrox_node()
  10842. {
  10843. rp0_.free();
  10844. }
  10845. inline T value() const
  10846. {
  10847. std::size_t r0 = 0;
  10848. std::size_t r1 = 0;
  10849. if (rp0_(r0,r1,s0_.size()))
  10850. return Operation::process(s0_.substr(r0,(r1 - r0) + 1),s1_);
  10851. else
  10852. return T(0);
  10853. }
  10854. inline typename expression_node<T>::node_type type() const
  10855. {
  10856. return Operation::type();
  10857. }
  10858. inline operator_type operation() const
  10859. {
  10860. return Operation::operation();
  10861. }
  10862. inline std::string& s0()
  10863. {
  10864. return s0_;
  10865. }
  10866. inline std::string& s1()
  10867. {
  10868. return s1_;
  10869. }
  10870. protected:
  10871. SType0 s0_;
  10872. SType1 s1_;
  10873. RangePack rp0_;
  10874. private:
  10875. str_xrox_node(str_xrox_node<T,SType0,SType1,RangePack,Operation>&);
  10876. str_xrox_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xrox_node<T,SType0,SType1,RangePack,Operation>&);
  10877. };
  10878. template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
  10879. class str_xoxr_node : public sos_base_node<T>
  10880. {
  10881. public:
  10882. typedef expression_node<T>* expression_ptr;
  10883. typedef Operation operation_t;
  10884. // string op string range node
  10885. explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
  10886. : s0_ (p0 ),
  10887. s1_ (p1 ),
  10888. rp1_(rp1)
  10889. {}
  10890. ~str_xoxr_node()
  10891. {
  10892. rp1_.free();
  10893. }
  10894. inline T value() const
  10895. {
  10896. std::size_t r0 = 0;
  10897. std::size_t r1 = 0;
  10898. if (rp1_(r0,r1,s1_.size()))
  10899. return Operation::process(s0_,s1_.substr(r0,(r1 - r0) + 1));
  10900. else
  10901. return T(0);
  10902. }
  10903. inline typename expression_node<T>::node_type type() const
  10904. {
  10905. return Operation::type();
  10906. }
  10907. inline operator_type operation() const
  10908. {
  10909. return Operation::operation();
  10910. }
  10911. inline std::string& s0()
  10912. {
  10913. return s0_;
  10914. }
  10915. inline std::string& s1()
  10916. {
  10917. return s1_;
  10918. }
  10919. protected:
  10920. SType0 s0_;
  10921. SType1 s1_;
  10922. RangePack rp1_;
  10923. private:
  10924. str_xoxr_node(str_xoxr_node<T,SType0,SType1,RangePack,Operation>&);
  10925. str_xoxr_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xoxr_node<T,SType0,SType1,RangePack,Operation>&);
  10926. };
  10927. template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
  10928. class str_xroxr_node : public sos_base_node<T>
  10929. {
  10930. public:
  10931. typedef expression_node<T>* expression_ptr;
  10932. typedef Operation operation_t;
  10933. // string-range op string-range node
  10934. explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
  10935. : s0_ (p0 ),
  10936. s1_ (p1 ),
  10937. rp0_(rp0),
  10938. rp1_(rp1)
  10939. {}
  10940. ~str_xroxr_node()
  10941. {
  10942. rp0_.free();
  10943. rp1_.free();
  10944. }
  10945. inline T value() const
  10946. {
  10947. std::size_t r0_0 = 0;
  10948. std::size_t r0_1 = 0;
  10949. std::size_t r1_0 = 0;
  10950. std::size_t r1_1 = 0;
  10951. if (
  10952. rp0_(r0_0,r1_0,s0_.size()) &&
  10953. rp1_(r0_1,r1_1,s1_.size())
  10954. )
  10955. {
  10956. return Operation::process(
  10957. s0_.substr(r0_0,(r1_0 - r0_0) + 1),
  10958. s1_.substr(r0_1,(r1_1 - r0_1) + 1)
  10959. );
  10960. }
  10961. else
  10962. return T(0);
  10963. }
  10964. inline typename expression_node<T>::node_type type() const
  10965. {
  10966. return Operation::type();
  10967. }
  10968. inline operator_type operation() const
  10969. {
  10970. return Operation::operation();
  10971. }
  10972. inline std::string& s0()
  10973. {
  10974. return s0_;
  10975. }
  10976. inline std::string& s1()
  10977. {
  10978. return s1_;
  10979. }
  10980. protected:
  10981. SType0 s0_;
  10982. SType1 s1_;
  10983. RangePack rp0_;
  10984. RangePack rp1_;
  10985. private:
  10986. str_xroxr_node(str_xroxr_node<T,SType0,SType1,RangePack,Operation>&);
  10987. str_xroxr_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xroxr_node<T,SType0,SType1,RangePack,Operation>&);
  10988. };
  10989. template <typename T, typename Operation>
  10990. class str_sogens_node : public binary_node<T>
  10991. {
  10992. public:
  10993. typedef expression_node <T>* expression_ptr;
  10994. typedef string_base_node<T>* str_base_ptr;
  10995. typedef range_pack <T> range_t;
  10996. typedef range_t* range_ptr;
  10997. typedef range_interface<T> irange_t;
  10998. typedef irange_t* irange_ptr;
  10999. str_sogens_node(const operator_type& opr,
  11000. expression_ptr branch0,
  11001. expression_ptr branch1)
  11002. : binary_node<T>(opr,branch0,branch1),
  11003. str0_base_ptr_ (0),
  11004. str1_base_ptr_ (0),
  11005. str0_range_ptr_(0),
  11006. str1_range_ptr_(0)
  11007. {
  11008. if (is_generally_string_node(binary_node<T>::branch_[0].first))
  11009. {
  11010. str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
  11011. if (0 == str0_base_ptr_)
  11012. return;
  11013. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
  11014. if (0 == range_ptr)
  11015. return;
  11016. str0_range_ptr_ = &(range_ptr->range_ref());
  11017. }
  11018. if (is_generally_string_node(binary_node<T>::branch_[1].first))
  11019. {
  11020. str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
  11021. if (0 == str1_base_ptr_)
  11022. return;
  11023. irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
  11024. if (0 == range_ptr)
  11025. return;
  11026. str1_range_ptr_ = &(range_ptr->range_ref());
  11027. }
  11028. }
  11029. inline T value() const
  11030. {
  11031. if (
  11032. str0_base_ptr_ &&
  11033. str1_base_ptr_ &&
  11034. str0_range_ptr_ &&
  11035. str1_range_ptr_
  11036. )
  11037. {
  11038. binary_node<T>::branch_[0].first->value();
  11039. binary_node<T>::branch_[1].first->value();
  11040. std::size_t str0_r0 = 0;
  11041. std::size_t str0_r1 = 0;
  11042. std::size_t str1_r0 = 0;
  11043. std::size_t str1_r1 = 0;
  11044. range_t& range0 = (*str0_range_ptr_);
  11045. range_t& range1 = (*str1_range_ptr_);
  11046. if (
  11047. range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
  11048. range1(str1_r0,str1_r1,str1_base_ptr_->size())
  11049. )
  11050. {
  11051. return Operation::process(
  11052. str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0) + 1),
  11053. str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0) + 1)
  11054. );
  11055. }
  11056. }
  11057. return std::numeric_limits<T>::quiet_NaN();
  11058. }
  11059. inline typename expression_node<T>::node_type type() const
  11060. {
  11061. return Operation::type();
  11062. }
  11063. inline operator_type operation() const
  11064. {
  11065. return Operation::operation();
  11066. }
  11067. private:
  11068. str_sogens_node(str_sogens_node<T,Operation>&);
  11069. str_sogens_node<T,Operation>& operator=(str_sogens_node<T,Operation>&);
  11070. str_base_ptr str0_base_ptr_;
  11071. str_base_ptr str1_base_ptr_;
  11072. range_ptr str0_range_ptr_;
  11073. range_ptr str1_range_ptr_;
  11074. };
  11075. template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
  11076. class sosos_node : public sosos_base_node<T>
  11077. {
  11078. public:
  11079. typedef expression_node<T>* expression_ptr;
  11080. typedef Operation operation_t;
  11081. // variable op variable node
  11082. explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
  11083. : s0_(p0),
  11084. s1_(p1),
  11085. s2_(p2)
  11086. {}
  11087. inline T value() const
  11088. {
  11089. return Operation::process(s0_,s1_,s2_);
  11090. }
  11091. inline typename expression_node<T>::node_type type() const
  11092. {
  11093. return Operation::type();
  11094. }
  11095. inline operator_type operation() const
  11096. {
  11097. return Operation::operation();
  11098. }
  11099. inline std::string& s0()
  11100. {
  11101. return s0_;
  11102. }
  11103. inline std::string& s1()
  11104. {
  11105. return s1_;
  11106. }
  11107. inline std::string& s2()
  11108. {
  11109. return s2_;
  11110. }
  11111. protected:
  11112. SType0 s0_;
  11113. SType1 s1_;
  11114. SType2 s2_;
  11115. private:
  11116. sosos_node(sosos_node<T,SType0,SType1,SType2,Operation>&);
  11117. sosos_node<T,SType0,SType1,SType2,Operation>& operator=(sosos_node<T,SType0,SType1,SType2,Operation>&);
  11118. };
  11119. #endif
  11120. template <typename T, typename PowOp>
  11121. class ipow_node : public expression_node<T>
  11122. {
  11123. public:
  11124. typedef expression_node<T>* expression_ptr;
  11125. typedef PowOp operation_t;
  11126. explicit ipow_node(const T& v)
  11127. : v_(v)
  11128. {}
  11129. inline T value() const
  11130. {
  11131. return PowOp::result(v_);
  11132. }
  11133. inline typename expression_node<T>::node_type type() const
  11134. {
  11135. return expression_node<T>::e_ipow;
  11136. }
  11137. private:
  11138. ipow_node(const ipow_node<T,PowOp>&);
  11139. ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&);
  11140. const T& v_;
  11141. };
  11142. template <typename T, typename PowOp>
  11143. class ipowinv_node : public expression_node<T>
  11144. {
  11145. public:
  11146. typedef expression_node<T>* expression_ptr;
  11147. typedef PowOp operation_t;
  11148. explicit ipowinv_node(const T& v)
  11149. : v_(v)
  11150. {}
  11151. inline T value() const
  11152. {
  11153. return (T(1) / PowOp::result(v_));
  11154. }
  11155. inline typename expression_node<T>::node_type type() const
  11156. {
  11157. return expression_node<T>::e_ipowinv;
  11158. }
  11159. private:
  11160. ipowinv_node(const ipowinv_node<T,PowOp>&);
  11161. ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&);
  11162. const T& v_;
  11163. };
  11164. template <typename T>
  11165. inline bool is_vov_node(const expression_node<T>* node)
  11166. {
  11167. return (0 != dynamic_cast<const vov_base_node<T>*>(node));
  11168. }
  11169. template <typename T>
  11170. inline bool is_cov_node(const expression_node<T>* node)
  11171. {
  11172. return (0 != dynamic_cast<const cov_base_node<T>*>(node));
  11173. }
  11174. template <typename T>
  11175. inline bool is_voc_node(const expression_node<T>* node)
  11176. {
  11177. return (0 != dynamic_cast<const voc_base_node<T>*>(node));
  11178. }
  11179. template <typename T>
  11180. inline bool is_cob_node(const expression_node<T>* node)
  11181. {
  11182. return (0 != dynamic_cast<const cob_base_node<T>*>(node));
  11183. }
  11184. template <typename T>
  11185. inline bool is_boc_node(const expression_node<T>* node)
  11186. {
  11187. return (0 != dynamic_cast<const boc_base_node<T>*>(node));
  11188. }
  11189. template <typename T>
  11190. inline bool is_t0ot1ot2_node(const expression_node<T>* node)
  11191. {
  11192. return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node));
  11193. }
  11194. template <typename T>
  11195. inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node)
  11196. {
  11197. return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node));
  11198. }
  11199. template <typename T>
  11200. inline bool is_uv_node(const expression_node<T>* node)
  11201. {
  11202. return (0 != dynamic_cast<const uv_base_node<T>*>(node));
  11203. }
  11204. template <typename T>
  11205. inline bool is_string_node(const expression_node<T>* node)
  11206. {
  11207. return node && (expression_node<T>::e_stringvar == node->type());
  11208. }
  11209. template <typename T>
  11210. inline bool is_string_range_node(const expression_node<T>* node)
  11211. {
  11212. return node && (expression_node<T>::e_stringvarrng == node->type());
  11213. }
  11214. template <typename T>
  11215. inline bool is_const_string_node(const expression_node<T>* node)
  11216. {
  11217. return node && (expression_node<T>::e_stringconst == node->type());
  11218. }
  11219. template <typename T>
  11220. inline bool is_const_string_range_node(const expression_node<T>* node)
  11221. {
  11222. return node && (expression_node<T>::e_cstringvarrng == node->type());
  11223. }
  11224. template <typename T>
  11225. inline bool is_string_assignment_node(const expression_node<T>* node)
  11226. {
  11227. return node && (expression_node<T>::e_strass == node->type());
  11228. }
  11229. template <typename T>
  11230. inline bool is_string_concat_node(const expression_node<T>* node)
  11231. {
  11232. return node && (expression_node<T>::e_strconcat == node->type());
  11233. }
  11234. template <typename T>
  11235. inline bool is_string_function_node(const expression_node<T>* node)
  11236. {
  11237. return node && (expression_node<T>::e_strfunction == node->type());
  11238. }
  11239. template <typename T>
  11240. inline bool is_string_condition_node(const expression_node<T>* node)
  11241. {
  11242. return node && (expression_node<T>::e_strcondition == node->type());
  11243. }
  11244. template <typename T>
  11245. inline bool is_string_ccondition_node(const expression_node<T>* node)
  11246. {
  11247. return node && (expression_node<T>::e_strccondition == node->type());
  11248. }
  11249. template <typename T>
  11250. inline bool is_genricstring_range_node(const expression_node<T>* node)
  11251. {
  11252. return node && (expression_node<T>::e_strgenrange == node->type());
  11253. }
  11254. template <typename T>
  11255. inline bool is_generally_string_node(const expression_node<T>* node)
  11256. {
  11257. if (node)
  11258. {
  11259. switch (node->type())
  11260. {
  11261. case expression_node<T>::e_stringvar :
  11262. case expression_node<T>::e_stringconst :
  11263. case expression_node<T>::e_stringvarrng :
  11264. case expression_node<T>::e_cstringvarrng :
  11265. case expression_node<T>::e_strgenrange :
  11266. case expression_node<T>::e_strass :
  11267. case expression_node<T>::e_strconcat :
  11268. case expression_node<T>::e_strfunction :
  11269. case expression_node<T>::e_strcondition :
  11270. case expression_node<T>::e_strccondition : return true;
  11271. default : return false;
  11272. }
  11273. }
  11274. return false;
  11275. }
  11276. class node_allocator
  11277. {
  11278. public:
  11279. template <typename ResultNode, typename OpType, typename ExprNode>
  11280. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1])
  11281. {
  11282. return allocate<ResultNode>(operation,branch[0]);
  11283. }
  11284. template <typename ResultNode, typename OpType, typename ExprNode>
  11285. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2])
  11286. {
  11287. return allocate<ResultNode>(operation,branch[0],branch[1]);
  11288. }
  11289. template <typename ResultNode, typename OpType, typename ExprNode>
  11290. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3])
  11291. {
  11292. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2]);
  11293. }
  11294. template <typename ResultNode, typename OpType, typename ExprNode>
  11295. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4])
  11296. {
  11297. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3]);
  11298. }
  11299. template <typename ResultNode, typename OpType, typename ExprNode>
  11300. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5])
  11301. {
  11302. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4]);
  11303. }
  11304. template <typename ResultNode, typename OpType, typename ExprNode>
  11305. inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6])
  11306. {
  11307. return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4],branch[5]);
  11308. }
  11309. template <typename node_type>
  11310. inline expression_node<typename node_type::value_type>* allocate() const
  11311. {
  11312. return new node_type();
  11313. }
  11314. template <typename node_type,
  11315. typename Type,
  11316. typename Allocator,
  11317. template <typename,typename> class Sequence>
  11318. inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const
  11319. {
  11320. return new node_type(seq);
  11321. }
  11322. template <typename node_type, typename T1>
  11323. inline expression_node<typename node_type::value_type>* allocate(T1& t1) const
  11324. {
  11325. return new node_type(t1);
  11326. }
  11327. template <typename node_type, typename T1>
  11328. inline expression_node<typename node_type::value_type>* allocate_c(const T1& t1) const
  11329. {
  11330. return new node_type(t1);
  11331. }
  11332. template <typename node_type,
  11333. typename T1, typename T2>
  11334. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
  11335. {
  11336. return new node_type(t1,t2);
  11337. }
  11338. template <typename node_type,
  11339. typename T1, typename T2>
  11340. inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const
  11341. {
  11342. return new node_type(t1,t2);
  11343. }
  11344. template <typename node_type,
  11345. typename T1, typename T2>
  11346. inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
  11347. {
  11348. return new node_type(t1,t2);
  11349. }
  11350. template <typename node_type,
  11351. typename T1, typename T2>
  11352. inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const
  11353. {
  11354. return new node_type(t1,t2);
  11355. }
  11356. template <typename node_type,
  11357. typename T1, typename T2>
  11358. inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const
  11359. {
  11360. return new node_type(t1,t2);
  11361. }
  11362. template <typename node_type,
  11363. typename T1, typename T2, typename T3>
  11364. inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const
  11365. {
  11366. return new node_type(t1,t2,t3);
  11367. }
  11368. template <typename node_type,
  11369. typename T1, typename T2, typename T3, typename T4>
  11370. inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
  11371. {
  11372. return new node_type(t1,t2,t3,t4);
  11373. }
  11374. template <typename node_type,
  11375. typename T1, typename T2, typename T3>
  11376. inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const
  11377. {
  11378. return new node_type(t1,t2,t3);
  11379. }
  11380. template <typename node_type,
  11381. typename T1, typename T2, typename T3, typename T4>
  11382. inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const
  11383. {
  11384. return new node_type(t1,t2,t3,t4);
  11385. }
  11386. template <typename node_type,
  11387. typename T1, typename T2, typename T3, typename T4, typename T5>
  11388. inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
  11389. {
  11390. return new node_type(t1,t2,t3,t4,t5);
  11391. }
  11392. template <typename node_type,
  11393. typename T1, typename T2, typename T3>
  11394. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11395. const T3& t3) const
  11396. {
  11397. return new node_type(t1,t2,t3);
  11398. }
  11399. template <typename node_type,
  11400. typename T1, typename T2,
  11401. typename T3, typename T4>
  11402. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11403. const T3& t3, const T4& t4) const
  11404. {
  11405. return new node_type(t1,t2,t3,t4);
  11406. }
  11407. template <typename node_type,
  11408. typename T1, typename T2,
  11409. typename T3, typename T4, typename T5>
  11410. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11411. const T3& t3, const T4& t4,
  11412. const T5& t5) const
  11413. {
  11414. return new node_type(t1,t2,t3,t4,t5);
  11415. }
  11416. template <typename node_type,
  11417. typename T1, typename T2,
  11418. typename T3, typename T4, typename T5, typename T6>
  11419. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11420. const T3& t3, const T4& t4,
  11421. const T5& t5, const T6& t6) const
  11422. {
  11423. return new node_type(t1,t2,t3,t4,t5,t6);
  11424. }
  11425. template <typename node_type,
  11426. typename T1, typename T2,
  11427. typename T3, typename T4,
  11428. typename T5, typename T6, typename T7>
  11429. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11430. const T3& t3, const T4& t4,
  11431. const T5& t5, const T6& t6,
  11432. const T7& t7) const
  11433. {
  11434. return new node_type(t1,t2,t3,t4,t5,t6,t7);
  11435. }
  11436. template <typename node_type,
  11437. typename T1, typename T2,
  11438. typename T3, typename T4,
  11439. typename T5, typename T6,
  11440. typename T7, typename T8>
  11441. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11442. const T3& t3, const T4& t4,
  11443. const T5& t5, const T6& t6,
  11444. const T7& t7, const T8& t8) const
  11445. {
  11446. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8);
  11447. }
  11448. template <typename node_type,
  11449. typename T1, typename T2,
  11450. typename T3, typename T4,
  11451. typename T5, typename T6,
  11452. typename T7, typename T8, typename T9>
  11453. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11454. const T3& t3, const T4& t4,
  11455. const T5& t5, const T6& t6,
  11456. const T7& t7, const T8& t8,
  11457. const T9& t9) const
  11458. {
  11459. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9);
  11460. }
  11461. template <typename node_type,
  11462. typename T1, typename T2,
  11463. typename T3, typename T4,
  11464. typename T5, typename T6,
  11465. typename T7, typename T8,
  11466. typename T9, typename T10>
  11467. inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
  11468. const T3& t3, const T4& t4,
  11469. const T5& t5, const T6& t6,
  11470. const T7& t7, const T8& t8,
  11471. const T9& t9, const T10& t10) const
  11472. {
  11473. return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
  11474. }
  11475. template <typename node_type,
  11476. typename T1, typename T2, typename T3>
  11477. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const
  11478. {
  11479. return new node_type(t1,t2,t3);
  11480. }
  11481. template <typename node_type,
  11482. typename T1, typename T2,
  11483. typename T3, typename T4>
  11484. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
  11485. T3 t3, T4 t4) const
  11486. {
  11487. return new node_type(t1,t2,t3,t4);
  11488. }
  11489. template <typename node_type,
  11490. typename T1, typename T2,
  11491. typename T3, typename T4,
  11492. typename T5>
  11493. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
  11494. T3 t3, T4 t4,
  11495. T5 t5) const
  11496. {
  11497. return new node_type(t1,t2,t3,t4,t5);
  11498. }
  11499. template <typename node_type,
  11500. typename T1, typename T2,
  11501. typename T3, typename T4,
  11502. typename T5, typename T6, typename T7>
  11503. inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
  11504. T3 t3, T4 t4,
  11505. T5 t5, T6 t6,
  11506. T7 t7) const
  11507. {
  11508. return new node_type(t1,t2,t3,t4,t5,t6,t7);
  11509. }
  11510. template <typename T>
  11511. void inline free(expression_node<T>*& e) const
  11512. {
  11513. delete e;
  11514. e = 0;
  11515. }
  11516. };
  11517. inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
  11518. {
  11519. #define register_op(Symbol,Type,Args) \
  11520. m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
  11521. register_op( "abs",e_abs , 1)
  11522. register_op( "acos",e_acos , 1)
  11523. register_op( "acosh",e_acosh , 1)
  11524. register_op( "asin",e_asin , 1)
  11525. register_op( "asinh",e_asinh , 1)
  11526. register_op( "atan",e_atan , 1)
  11527. register_op( "atanh",e_atanh , 1)
  11528. register_op( "ceil",e_ceil , 1)
  11529. register_op( "cos",e_cos , 1)
  11530. register_op( "cosh",e_cosh , 1)
  11531. register_op( "exp",e_exp , 1)
  11532. register_op( "expm1",e_expm1 , 1)
  11533. register_op( "floor",e_floor , 1)
  11534. register_op( "log",e_log , 1)
  11535. register_op( "log10",e_log10 , 1)
  11536. register_op( "log2",e_log2 , 1)
  11537. register_op( "log1p",e_log1p , 1)
  11538. register_op( "round",e_round , 1)
  11539. register_op( "sin",e_sin , 1)
  11540. register_op( "sinc",e_sinc , 1)
  11541. register_op( "sinh",e_sinh , 1)
  11542. register_op( "sec",e_sec , 1)
  11543. register_op( "csc",e_csc , 1)
  11544. register_op( "sqrt",e_sqrt , 1)
  11545. register_op( "tan",e_tan , 1)
  11546. register_op( "tanh",e_tanh , 1)
  11547. register_op( "cot",e_cot , 1)
  11548. register_op( "rad2deg",e_r2d , 1)
  11549. register_op( "deg2rad",e_d2r , 1)
  11550. register_op( "deg2grad",e_d2g , 1)
  11551. register_op( "grad2deg",e_g2d , 1)
  11552. register_op( "sgn",e_sgn , 1)
  11553. register_op( "not",e_notl , 1)
  11554. register_op( "erf",e_erf , 1)
  11555. register_op( "erfc",e_erfc , 1)
  11556. register_op( "ncdf",e_ncdf , 1)
  11557. register_op( "frac",e_frac , 1)
  11558. register_op( "trunc",e_trunc , 1)
  11559. register_op( "atan2",e_atan2 , 2)
  11560. register_op( "mod",e_mod , 2)
  11561. register_op( "logn",e_logn , 2)
  11562. register_op( "pow",e_pow , 2)
  11563. register_op( "root",e_root , 2)
  11564. register_op( "roundn",e_roundn , 2)
  11565. register_op( "equal",e_equal , 2)
  11566. register_op("not_equal",e_nequal , 2)
  11567. register_op( "hypot",e_hypot , 2)
  11568. register_op( "shr",e_shr , 2)
  11569. register_op( "shl",e_shl , 2)
  11570. register_op( "clamp",e_clamp , 3)
  11571. register_op( "iclamp",e_iclamp , 3)
  11572. register_op( "inrange",e_inrange , 3)
  11573. #undef register_op
  11574. }
  11575. } // namespace details
  11576. class function_traits
  11577. {
  11578. public:
  11579. function_traits()
  11580. : allow_zero_parameters_(false),
  11581. has_side_effects_(true)
  11582. {}
  11583. inline bool& allow_zero_parameters()
  11584. {
  11585. return allow_zero_parameters_;
  11586. }
  11587. inline bool& has_side_effects()
  11588. {
  11589. return has_side_effects_;
  11590. }
  11591. private:
  11592. bool allow_zero_parameters_;
  11593. bool has_side_effects_;
  11594. };
  11595. template <typename FunctionType>
  11596. void enable_zero_parameters(FunctionType& func)
  11597. {
  11598. func.allow_zero_parameters() = true;
  11599. }
  11600. template <typename FunctionType>
  11601. void disable_zero_parameters(FunctionType& func)
  11602. {
  11603. func.allow_zero_parameters() = false;
  11604. }
  11605. template <typename FunctionType>
  11606. void enable_has_side_effects(FunctionType& func)
  11607. {
  11608. func.has_side_effects() = true;
  11609. }
  11610. template <typename FunctionType>
  11611. void disable_has_side_effects(FunctionType& func)
  11612. {
  11613. func.has_side_effects() = false;
  11614. }
  11615. template <typename T>
  11616. class ifunction : public function_traits
  11617. {
  11618. public:
  11619. explicit ifunction(const std::size_t& pc)
  11620. : param_count(pc)
  11621. {}
  11622. virtual ~ifunction()
  11623. {}
  11624. inline virtual T operator()()
  11625. {
  11626. return std::numeric_limits<T>::quiet_NaN();
  11627. }
  11628. inline virtual T operator()(const T&)
  11629. {
  11630. return std::numeric_limits<T>::quiet_NaN();
  11631. }
  11632. inline virtual T operator()(const T&,const T&)
  11633. {
  11634. return std::numeric_limits<T>::quiet_NaN();
  11635. }
  11636. inline virtual T operator()(const T&, const T&, const T&)
  11637. {
  11638. return std::numeric_limits<T>::quiet_NaN();
  11639. }
  11640. inline virtual T operator()(const T&, const T&, const T&, const T&)
  11641. {
  11642. return std::numeric_limits<T>::quiet_NaN();
  11643. }
  11644. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&)
  11645. {
  11646. return std::numeric_limits<T>::quiet_NaN();
  11647. }
  11648. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&)
  11649. {
  11650. return std::numeric_limits<T>::quiet_NaN();
  11651. }
  11652. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11653. {
  11654. return std::numeric_limits<T>::quiet_NaN();
  11655. }
  11656. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11657. {
  11658. return std::numeric_limits<T>::quiet_NaN();
  11659. }
  11660. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11661. {
  11662. return std::numeric_limits<T>::quiet_NaN();
  11663. }
  11664. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11665. {
  11666. return std::numeric_limits<T>::quiet_NaN();
  11667. }
  11668. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11669. const T&)
  11670. {
  11671. return std::numeric_limits<T>::quiet_NaN();
  11672. }
  11673. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11674. const T&, const T&)
  11675. {
  11676. return std::numeric_limits<T>::quiet_NaN();
  11677. }
  11678. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11679. const T&, const T&, const T&)
  11680. {
  11681. return std::numeric_limits<T>::quiet_NaN();
  11682. }
  11683. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11684. const T&, const T&, const T&, const T&)
  11685. {
  11686. return std::numeric_limits<T>::quiet_NaN();
  11687. }
  11688. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11689. const T&, const T&, const T&, const T&, const T&)
  11690. {
  11691. return std::numeric_limits<T>::quiet_NaN();
  11692. }
  11693. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11694. const T&, const T&, const T&, const T&, const T&, const T&)
  11695. {
  11696. return std::numeric_limits<T>::quiet_NaN();
  11697. }
  11698. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11699. const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11700. {
  11701. return std::numeric_limits<T>::quiet_NaN();
  11702. }
  11703. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11704. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11705. {
  11706. return std::numeric_limits<T>::quiet_NaN();
  11707. }
  11708. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11709. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11710. {
  11711. return std::numeric_limits<T>::quiet_NaN();
  11712. }
  11713. inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
  11714. const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
  11715. {
  11716. return std::numeric_limits<T>::quiet_NaN();
  11717. }
  11718. std::size_t param_count;
  11719. };
  11720. template <typename T>
  11721. class ivararg_function : public function_traits
  11722. {
  11723. public:
  11724. virtual ~ivararg_function()
  11725. {}
  11726. inline virtual T operator()(const std::vector<T>&)
  11727. {
  11728. exprtk_debug(("ivararg_function::operator() - Operator has not been overridden.\n"));
  11729. return std::numeric_limits<T>::quiet_NaN();
  11730. }
  11731. };
  11732. template <typename T>
  11733. class igeneric_function : public function_traits
  11734. {
  11735. public:
  11736. typedef T type;
  11737. typedef type_store<T> generic_type;
  11738. typedef typename generic_type::parameter_list parameter_list_t;
  11739. igeneric_function(const std::string& param_seq = "")
  11740. : parameter_sequence(param_seq)
  11741. {}
  11742. virtual ~igeneric_function()
  11743. {}
  11744. // f(i_0,i_1,....,i_N) --> Number
  11745. inline virtual T operator()(parameter_list_t)
  11746. {
  11747. exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [1]\n"));
  11748. return std::numeric_limits<T>::quiet_NaN();
  11749. }
  11750. // f(i_0,i_1,....,i_N) --> String
  11751. inline virtual T operator()(std::string&, parameter_list_t)
  11752. {
  11753. exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [2]\n"));
  11754. return std::numeric_limits<T>::quiet_NaN();
  11755. }
  11756. // f(psi,i_0,i_1,....,i_N) --> Number
  11757. inline virtual T operator()(const std::size_t&, parameter_list_t)
  11758. {
  11759. exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [3]\n"));
  11760. return std::numeric_limits<T>::quiet_NaN();
  11761. }
  11762. // f(psi,i_0,i_1,....,i_N) --> String
  11763. inline virtual T operator()(const std::size_t&, std::string&, parameter_list_t)
  11764. {
  11765. exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [4]\n"));
  11766. return std::numeric_limits<T>::quiet_NaN();
  11767. }
  11768. std::string parameter_sequence;
  11769. };
  11770. template <typename T> class parser;
  11771. template <typename T> class expression_helper;
  11772. template <typename T>
  11773. class symbol_table
  11774. {
  11775. protected:
  11776. template <typename Type, typename RawType>
  11777. struct type_store
  11778. {
  11779. typedef details::expression_node<T>* expression_ptr;
  11780. typedef typename details::variable_node<T> variable_node_t;
  11781. typedef ifunction<T> ifunction_t;
  11782. typedef ivararg_function<T> ivararg_function_t;
  11783. typedef igeneric_function<T> igeneric_function_t;
  11784. typedef details::vector_holder<T> vector_t;
  11785. #ifndef exprtk_disable_string_capabilities
  11786. typedef typename details::stringvar_node<T> stringvar_node_t;
  11787. #endif
  11788. typedef Type type_t;
  11789. typedef type_t* type_ptr;
  11790. typedef std::pair<bool,type_ptr> type_pair_t;
  11791. typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
  11792. typedef typename type_map_t::iterator tm_itr_t;
  11793. typedef typename type_map_t::const_iterator tm_const_itr_t;
  11794. enum { lut_size = 256 };
  11795. type_map_t map;
  11796. std::size_t size;
  11797. type_store()
  11798. : size(0)
  11799. {}
  11800. inline bool symbol_exists(const std::string& symbol_name) const
  11801. {
  11802. if (symbol_name.empty())
  11803. return false;
  11804. else if (map.end() != map.find(symbol_name))
  11805. return true;
  11806. else
  11807. return false;
  11808. }
  11809. template <typename PtrType>
  11810. inline std::string entity_name(const PtrType& ptr) const
  11811. {
  11812. if (map.empty())
  11813. return std::string();
  11814. tm_const_itr_t itr = map.begin();
  11815. while (map.end() != itr)
  11816. {
  11817. if (itr->second.second == ptr)
  11818. {
  11819. return itr->first;
  11820. }
  11821. else
  11822. ++itr;
  11823. }
  11824. return std::string();
  11825. }
  11826. inline bool is_constant(const std::string& symbol_name) const
  11827. {
  11828. if (symbol_name.empty())
  11829. return false;
  11830. else
  11831. {
  11832. tm_const_itr_t itr = map.find(symbol_name);
  11833. if (map.end() == itr)
  11834. return false;
  11835. else
  11836. return (*itr).second.first;
  11837. }
  11838. }
  11839. template <typename Tie, typename RType>
  11840. inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const)
  11841. {
  11842. if (symbol_name.size() > 1)
  11843. {
  11844. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  11845. {
  11846. if (details::imatch(symbol_name,details::reserved_symbols[i]))
  11847. {
  11848. return false;
  11849. }
  11850. }
  11851. }
  11852. tm_itr_t itr = map.find(symbol_name);
  11853. if (map.end() == itr)
  11854. {
  11855. map[symbol_name] = Tie::make(t,is_const);
  11856. ++size;
  11857. }
  11858. return true;
  11859. }
  11860. struct tie_array
  11861. {
  11862. static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false)
  11863. {
  11864. return std::make_pair(is_const,new vector_t(v.first,v.second));
  11865. }
  11866. };
  11867. struct tie_stdvec
  11868. {
  11869. template <typename Allocator>
  11870. static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false)
  11871. {
  11872. return std::make_pair(is_const,new vector_t(v));
  11873. }
  11874. };
  11875. struct tie_stddeq
  11876. {
  11877. template <typename Allocator>
  11878. static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false)
  11879. {
  11880. return std::make_pair(is_const,new vector_t(v));
  11881. }
  11882. };
  11883. template <std::size_t v_size>
  11884. inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false)
  11885. {
  11886. return add_impl<tie_array,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_const);
  11887. }
  11888. inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false)
  11889. {
  11890. return add_impl<tie_array,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_const);
  11891. }
  11892. template <typename Allocator>
  11893. inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false)
  11894. {
  11895. return add_impl<tie_stdvec,std::vector<T,Allocator>&>(symbol_name,v,is_const);
  11896. }
  11897. template <typename Allocator>
  11898. inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
  11899. {
  11900. return add_impl<tie_stddeq,std::deque<T,Allocator>&>(symbol_name,v,is_const);
  11901. }
  11902. inline bool add(const std::string& symbol_name, RawType& t, const bool is_const = false)
  11903. {
  11904. struct tie
  11905. {
  11906. static inline std::pair<bool,variable_node_t*> make(T& t,const bool is_const = false)
  11907. {
  11908. return std::make_pair(is_const,new variable_node_t(t));
  11909. }
  11910. #ifndef exprtk_disable_string_capabilities
  11911. static inline std::pair<bool,stringvar_node_t*> make(std::string& t,const bool is_const = false)
  11912. {
  11913. return std::make_pair(is_const,new stringvar_node_t(t));
  11914. }
  11915. #endif
  11916. static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
  11917. {
  11918. return std::make_pair(is_constant,&t);
  11919. }
  11920. static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_const = false)
  11921. {
  11922. return std::make_pair(is_const,&t);
  11923. }
  11924. static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false)
  11925. {
  11926. return std::make_pair(is_constant,&t);
  11927. }
  11928. };
  11929. tm_itr_t itr = map.find(symbol_name);
  11930. if (map.end() == itr)
  11931. {
  11932. map[symbol_name] = tie::make(t,is_const);
  11933. ++size;
  11934. }
  11935. return true;
  11936. }
  11937. inline type_ptr get(const std::string& symbol_name) const
  11938. {
  11939. tm_const_itr_t itr = map.find(symbol_name);
  11940. if (map.end() == itr)
  11941. return reinterpret_cast<type_ptr>(0);
  11942. else
  11943. return itr->second.second;
  11944. }
  11945. template <typename TType, typename TRawType, typename PtrType>
  11946. struct ptr_match
  11947. {
  11948. static inline bool test(const PtrType, const void*)
  11949. {
  11950. return false;
  11951. }
  11952. };
  11953. template <typename TType, typename TRawType>
  11954. struct ptr_match<TType,TRawType,variable_node_t*>
  11955. {
  11956. static inline bool test(const variable_node_t* p, const void* ptr)
  11957. {
  11958. exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p->ref())),ptr));
  11959. return (&(p->ref()) == ptr);
  11960. }
  11961. };
  11962. inline type_ptr get_from_varptr(const void* ptr) const
  11963. {
  11964. tm_const_itr_t itr = map.begin();
  11965. while (map.end() != itr)
  11966. {
  11967. type_ptr ret_ptr = itr->second.second;
  11968. if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr))
  11969. {
  11970. return ret_ptr;
  11971. }
  11972. ++itr;
  11973. }
  11974. return type_ptr(0);
  11975. }
  11976. inline bool remove(const std::string& symbol_name, const bool delete_node = true)
  11977. {
  11978. tm_itr_t itr = map.find(symbol_name);
  11979. if (map.end() != itr)
  11980. {
  11981. struct deleter
  11982. {
  11983. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  11984. static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
  11985. #ifndef exprtk_disable_string_capabilities
  11986. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  11987. #endif
  11988. static inline void process(std::pair<bool,function_t*>&) { }
  11989. };
  11990. if (delete_node)
  11991. {
  11992. deleter::process((*itr).second);
  11993. }
  11994. map.erase(itr);
  11995. --size;
  11996. return true;
  11997. }
  11998. else
  11999. return false;
  12000. }
  12001. inline RawType& type_ref(const std::string& symbol_name)
  12002. {
  12003. struct init_type
  12004. {
  12005. static inline double set(double) { return (0.0); }
  12006. static inline double set(long double) { return (0.0); }
  12007. static inline float set(float) { return (0.0f); }
  12008. static inline std::string set(std::string) { return std::string(""); }
  12009. };
  12010. static RawType null_type = init_type::set(RawType());
  12011. tm_const_itr_t itr = map.find(symbol_name);
  12012. if (map.end() == itr)
  12013. return null_type;
  12014. else
  12015. return itr->second.second->ref();
  12016. }
  12017. inline void clear(const bool delete_node = true)
  12018. {
  12019. struct deleter
  12020. {
  12021. static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
  12022. static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
  12023. static inline void process(std::pair<bool,function_t*>&) { }
  12024. #ifndef exprtk_disable_string_capabilities
  12025. static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
  12026. #endif
  12027. };
  12028. if (!map.empty())
  12029. {
  12030. if (delete_node)
  12031. {
  12032. tm_itr_t itr = map.begin();
  12033. tm_itr_t end = map.end();
  12034. while (end != itr)
  12035. {
  12036. deleter::process((*itr).second);
  12037. ++itr;
  12038. }
  12039. }
  12040. map.clear();
  12041. }
  12042. size = 0;
  12043. }
  12044. template <typename Allocator,
  12045. template <typename, typename> class Sequence>
  12046. inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
  12047. {
  12048. std::size_t count = 0;
  12049. if (!map.empty())
  12050. {
  12051. tm_const_itr_t itr = map.begin();
  12052. tm_const_itr_t end = map.end();
  12053. while (end != itr)
  12054. {
  12055. list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
  12056. ++itr;
  12057. ++count;
  12058. }
  12059. }
  12060. return count;
  12061. }
  12062. template <typename Allocator,
  12063. template <typename, typename> class Sequence>
  12064. inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
  12065. {
  12066. std::size_t count = 0;
  12067. if (!map.empty())
  12068. {
  12069. tm_const_itr_t itr = map.begin();
  12070. tm_const_itr_t end = map.end();
  12071. while (end != itr)
  12072. {
  12073. vlist.push_back((*itr).first);
  12074. ++itr;
  12075. ++count;
  12076. }
  12077. }
  12078. return count;
  12079. }
  12080. };
  12081. typedef details::expression_node<T>* expression_ptr;
  12082. typedef typename details::variable_node<T> variable_t;
  12083. typedef typename details::vector_holder<T> vector_holder_t;
  12084. typedef variable_t* variable_ptr;
  12085. #ifndef exprtk_disable_string_capabilities
  12086. typedef typename details::stringvar_node<T> stringvar_t;
  12087. typedef stringvar_t* stringvar_ptr;
  12088. #endif
  12089. typedef ifunction <T> function_t;
  12090. typedef ivararg_function <T> vararg_function_t;
  12091. typedef igeneric_function<T> generic_function_t;
  12092. typedef function_t* function_ptr;
  12093. typedef vararg_function_t* vararg_function_ptr;
  12094. typedef generic_function_t* generic_function_ptr;
  12095. static const std::size_t lut_size = 256;
  12096. // Symbol Table Holder
  12097. struct st_holder
  12098. {
  12099. struct st_data
  12100. {
  12101. type_store<typename details::variable_node<T>,T> variable_store;
  12102. #ifndef exprtk_disable_string_capabilities
  12103. type_store<typename details::stringvar_node<T>,std::string> stringvar_store;
  12104. #endif
  12105. type_store<ifunction<T>,ifunction<T> > function_store;
  12106. type_store<ivararg_function <T>,ivararg_function <T> > vararg_function_store;
  12107. type_store<igeneric_function<T>,igeneric_function<T> > generic_function_store;
  12108. type_store<igeneric_function<T>,igeneric_function<T> > string_function_store;
  12109. type_store<vector_holder_t,vector_holder_t> vector_store;
  12110. st_data()
  12111. {
  12112. for (std::size_t i = 0; i < details::reserved_words_size; ++i)
  12113. {
  12114. reserved_symbol_table_.insert(details::reserved_words[i]);
  12115. }
  12116. for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
  12117. {
  12118. reserved_symbol_table_.insert(details::reserved_symbols[i]);
  12119. }
  12120. }
  12121. inline bool is_reserved_symbol(const std::string& symbol) const
  12122. {
  12123. return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
  12124. }
  12125. std::list<T> local_symbol_list_;
  12126. std::list<std::string> local_stringvar_list_;
  12127. std::set<std::string> reserved_symbol_table_;
  12128. };
  12129. st_holder()
  12130. : ref_count(1),
  12131. data_(new st_data)
  12132. {}
  12133. st_holder(st_data* data)
  12134. : ref_count(1),
  12135. data_(data)
  12136. {}
  12137. ~st_holder()
  12138. {
  12139. if (data_ && (0 == ref_count))
  12140. {
  12141. delete data_;
  12142. data_ = 0;
  12143. }
  12144. }
  12145. std::size_t ref_count;
  12146. st_data* data_;
  12147. };
  12148. public:
  12149. symbol_table()
  12150. : holder_(new st_holder)
  12151. {
  12152. clear();
  12153. }
  12154. ~symbol_table()
  12155. {
  12156. if (holder_)
  12157. {
  12158. if (0 == --holder_->ref_count)
  12159. {
  12160. clear();
  12161. delete holder_;
  12162. }
  12163. }
  12164. }
  12165. symbol_table(const symbol_table<T>& st)
  12166. {
  12167. holder_ = st.holder_;
  12168. holder_->ref_count++;
  12169. }
  12170. inline symbol_table<T>& operator=(const symbol_table<T>& st)
  12171. {
  12172. if (holder_)
  12173. {
  12174. if (0 == --holder_->ref_count)
  12175. {
  12176. delete holder_;
  12177. }
  12178. holder_ = 0;
  12179. }
  12180. holder_ = st.holder_;
  12181. holder_->ref_count++;
  12182. return *this;
  12183. }
  12184. inline bool operator==(const symbol_table<T>& st)
  12185. {
  12186. return (this == &st) || (holder_ == st.holder_);
  12187. }
  12188. inline void clear_variables(const bool delete_node = true)
  12189. {
  12190. local_data().variable_store.clear(delete_node);
  12191. }
  12192. inline void clear_functions()
  12193. {
  12194. local_data().function_store.clear();
  12195. }
  12196. inline void clear_strings()
  12197. {
  12198. #ifndef exprtk_disable_string_capabilities
  12199. local_data().stringvar_store.clear();
  12200. #endif
  12201. }
  12202. inline void clear_vectors()
  12203. {
  12204. local_data().vector_store.clear();
  12205. }
  12206. inline void clear()
  12207. {
  12208. if (!valid()) return;
  12209. clear_variables();
  12210. clear_functions();
  12211. clear_strings ();
  12212. clear_vectors ();
  12213. }
  12214. inline std::size_t variable_count() const
  12215. {
  12216. if (valid())
  12217. return local_data().variable_store.size;
  12218. else
  12219. return 0;
  12220. }
  12221. #ifndef exprtk_disable_string_capabilities
  12222. inline std::size_t stringvar_count() const
  12223. {
  12224. if (valid())
  12225. return local_data().stringvar_store.size;
  12226. else
  12227. return 0;
  12228. }
  12229. #endif
  12230. inline std::size_t function_count() const
  12231. {
  12232. if (valid())
  12233. return local_data().function_store.size;
  12234. else
  12235. return 0;
  12236. }
  12237. inline std::size_t vector_count() const
  12238. {
  12239. if (valid())
  12240. return local_data().vector_store.size;
  12241. else
  12242. return 0;
  12243. }
  12244. inline variable_ptr get_variable(const std::string& variable_name) const
  12245. {
  12246. if (!valid())
  12247. return reinterpret_cast<variable_ptr>(0);
  12248. else if (!valid_symbol(variable_name))
  12249. return reinterpret_cast<variable_ptr>(0);
  12250. else
  12251. return local_data().variable_store.get(variable_name);
  12252. }
  12253. inline variable_ptr get_variable(const T& var_ref) const
  12254. {
  12255. if (!valid())
  12256. return reinterpret_cast<variable_ptr>(0);
  12257. else
  12258. return local_data().variable_store.get_from_varptr(
  12259. reinterpret_cast<const void*>(&var_ref));
  12260. }
  12261. #ifndef exprtk_disable_string_capabilities
  12262. inline stringvar_ptr get_stringvar(const std::string& string_name) const
  12263. {
  12264. if (!valid())
  12265. return reinterpret_cast<stringvar_ptr>(0);
  12266. else if (!valid_symbol(string_name))
  12267. return reinterpret_cast<stringvar_ptr>(0);
  12268. else
  12269. return local_data().stringvar_store.get(string_name);
  12270. }
  12271. #endif
  12272. inline function_ptr get_function(const std::string& function_name) const
  12273. {
  12274. if (!valid())
  12275. return reinterpret_cast<function_ptr>(0);
  12276. else if (!valid_symbol(function_name))
  12277. return reinterpret_cast<function_ptr>(0);
  12278. else
  12279. return local_data().function_store.get(function_name);
  12280. }
  12281. inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
  12282. {
  12283. if (!valid())
  12284. return reinterpret_cast<vararg_function_ptr>(0);
  12285. else if (!valid_symbol(vararg_function_name))
  12286. return reinterpret_cast<vararg_function_ptr>(0);
  12287. else
  12288. return local_data().vararg_function_store.get(vararg_function_name);
  12289. }
  12290. inline generic_function_ptr get_generic_function(const std::string& function_name) const
  12291. {
  12292. if (!valid())
  12293. return reinterpret_cast<generic_function_ptr>(0);
  12294. else if (!valid_symbol(function_name))
  12295. return reinterpret_cast<generic_function_ptr>(0);
  12296. else
  12297. return local_data().generic_function_store.get(function_name);
  12298. }
  12299. inline generic_function_ptr get_string_function(const std::string& function_name) const
  12300. {
  12301. if (!valid())
  12302. return reinterpret_cast<generic_function_ptr>(0);
  12303. else if (!valid_symbol(function_name))
  12304. return reinterpret_cast<generic_function_ptr>(0);
  12305. else
  12306. return local_data().string_function_store.get(function_name);
  12307. }
  12308. typedef vector_holder_t* vector_holder_ptr;
  12309. inline vector_holder_ptr get_vector(const std::string& vector_name) const
  12310. {
  12311. if (!valid())
  12312. return reinterpret_cast<vector_holder_ptr>(0);
  12313. else if (!valid_symbol(vector_name))
  12314. return reinterpret_cast<vector_holder_ptr>(0);
  12315. else
  12316. return local_data().vector_store.get(vector_name);
  12317. }
  12318. inline T& variable_ref(const std::string& symbol_name)
  12319. {
  12320. static T null_var = T(0);
  12321. if (!valid())
  12322. return null_var;
  12323. else if (!valid_symbol(symbol_name))
  12324. return null_var;
  12325. else
  12326. return local_data().variable_store.type_ref(symbol_name);
  12327. }
  12328. #ifndef exprtk_disable_string_capabilities
  12329. inline std::string& stringvar_ref(const std::string& symbol_name)
  12330. {
  12331. static std::string null_stringvar;
  12332. if (!valid())
  12333. return null_stringvar;
  12334. else if (!valid_symbol(symbol_name))
  12335. return null_stringvar;
  12336. else
  12337. return local_data().stringvar_store.type_ref(symbol_name);
  12338. }
  12339. #endif
  12340. inline bool is_constant_node(const std::string& symbol_name) const
  12341. {
  12342. if (!valid())
  12343. return false;
  12344. else if (!valid_symbol(symbol_name))
  12345. return false;
  12346. else
  12347. return local_data().variable_store.is_constant(symbol_name);
  12348. }
  12349. #ifndef exprtk_disable_string_capabilities
  12350. inline bool is_constant_string(const std::string& symbol_name) const
  12351. {
  12352. if (!valid())
  12353. return false;
  12354. else if (!valid_symbol(symbol_name))
  12355. return false;
  12356. else if (!local_data().stringvar_store.symbol_exists(symbol_name))
  12357. return false;
  12358. else
  12359. return local_data().stringvar_store.is_constant(symbol_name);
  12360. }
  12361. #endif
  12362. inline bool create_variable(const std::string& variable_name, const T& value = T(0))
  12363. {
  12364. if (!valid())
  12365. return false;
  12366. else if (!valid_symbol(variable_name))
  12367. return false;
  12368. else if (symbol_exists(variable_name))
  12369. return false;
  12370. local_data().local_symbol_list_.push_back(value);
  12371. T& t = local_data().local_symbol_list_.back();
  12372. return add_variable(variable_name,t);
  12373. }
  12374. #ifndef exprtk_disable_string_capabilities
  12375. inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
  12376. {
  12377. if (!valid())
  12378. return false;
  12379. else if (!valid_symbol(stringvar_name))
  12380. return false;
  12381. else if (symbol_exists(stringvar_name))
  12382. return false;
  12383. local_data().local_stringvar_list_.push_back(value);
  12384. std::string& s = local_data().local_stringvar_list_.back();
  12385. return add_stringvar(stringvar_name,s);
  12386. }
  12387. #endif
  12388. inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
  12389. {
  12390. if (!valid())
  12391. return false;
  12392. else if (!valid_symbol(variable_name))
  12393. return false;
  12394. else if (symbol_exists(variable_name))
  12395. return false;
  12396. else
  12397. return local_data().variable_store.add(variable_name,t,is_constant);
  12398. }
  12399. inline bool add_constant(const std::string& constant_name, const T& value)
  12400. {
  12401. if (!valid())
  12402. return false;
  12403. else if (!valid_symbol(constant_name))
  12404. return false;
  12405. else if (symbol_exists(constant_name))
  12406. return false;
  12407. local_data().local_symbol_list_.push_back(value);
  12408. T& t = local_data().local_symbol_list_.back();
  12409. return add_variable(constant_name,t,true);
  12410. }
  12411. #ifndef exprtk_disable_string_capabilities
  12412. inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
  12413. {
  12414. if (!valid())
  12415. return false;
  12416. else if (!valid_symbol(stringvar_name))
  12417. return false;
  12418. else if (symbol_exists(stringvar_name))
  12419. return false;
  12420. else
  12421. return local_data().stringvar_store.add(stringvar_name,s,is_constant);
  12422. }
  12423. #endif
  12424. inline bool add_function(const std::string& function_name, function_t& function)
  12425. {
  12426. if (!valid())
  12427. return false;
  12428. else if (!valid_symbol(function_name))
  12429. return false;
  12430. else if (symbol_exists(function_name))
  12431. return false;
  12432. else
  12433. return local_data().function_store.add(function_name,function);
  12434. }
  12435. inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
  12436. {
  12437. if (!valid())
  12438. return false;
  12439. else if (!valid_symbol(vararg_function_name))
  12440. return false;
  12441. else if (symbol_exists(vararg_function_name))
  12442. return false;
  12443. else
  12444. return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
  12445. }
  12446. enum func_type
  12447. {
  12448. e_ft_unknown = 0,
  12449. e_ft_basicfunc = 1,
  12450. e_ft_strfunc = 2
  12451. };
  12452. inline bool add_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
  12453. {
  12454. if (!valid())
  12455. return false;
  12456. else if (!valid_symbol(function_name))
  12457. return false;
  12458. else if (symbol_exists(function_name))
  12459. return false;
  12460. else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
  12461. return false;
  12462. else if (e_ft_basicfunc == ft)
  12463. return local_data().generic_function_store.add(function_name,function);
  12464. else if (e_ft_strfunc == ft)
  12465. return local_data().string_function_store.add(function_name, function);
  12466. else
  12467. return false;
  12468. }
  12469. inline bool add_reserved_function(const std::string& function_name, function_t& function)
  12470. {
  12471. if (!valid())
  12472. return false;
  12473. else if (!valid_symbol(function_name,false))
  12474. return false;
  12475. else if (symbol_exists(function_name,false))
  12476. return false;
  12477. else
  12478. return local_data().function_store.add(function_name,function);
  12479. }
  12480. inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
  12481. {
  12482. if (!valid())
  12483. return false;
  12484. else if (!valid_symbol(vararg_function_name,false))
  12485. return false;
  12486. else if (symbol_exists(vararg_function_name,false))
  12487. return false;
  12488. else
  12489. return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
  12490. }
  12491. inline bool add_reserved_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
  12492. {
  12493. if (!valid())
  12494. return false;
  12495. else if (!valid_symbol(function_name,false))
  12496. return false;
  12497. else if (symbol_exists(function_name,false))
  12498. return false;
  12499. else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
  12500. return false;
  12501. else if (e_ft_basicfunc == ft)
  12502. return local_data().generic_function_store.add(function_name,function);
  12503. else if (e_ft_strfunc == ft)
  12504. return local_data().string_function_store.add(function_name, function);
  12505. else
  12506. return false;
  12507. }
  12508. template <std::size_t N>
  12509. inline bool add_vector(const std::string& vector_name, T (&v)[N])
  12510. {
  12511. if (!valid())
  12512. return false;
  12513. else if (!valid_symbol(vector_name))
  12514. return false;
  12515. else if (symbol_exists(vector_name))
  12516. return false;
  12517. else
  12518. return local_data().vector_store.add(vector_name,v);
  12519. }
  12520. inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
  12521. {
  12522. if (!valid())
  12523. return false;
  12524. else if (!valid_symbol(vector_name))
  12525. return false;
  12526. else if (symbol_exists(vector_name))
  12527. return false;
  12528. else
  12529. return local_data().vector_store.add(vector_name,v,v_size);
  12530. }
  12531. template <typename Allocator>
  12532. inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
  12533. {
  12534. if (!valid())
  12535. return false;
  12536. else if (!valid_symbol(vector_name))
  12537. return false;
  12538. else if (symbol_exists(vector_name))
  12539. return false;
  12540. else
  12541. return local_data().vector_store.add(vector_name,v);
  12542. }
  12543. template <typename Allocator>
  12544. inline bool add_vector(const std::string& vector_name, std::deque<T,Allocator>& v)
  12545. {
  12546. if (!valid())
  12547. return false;
  12548. else if (!valid_symbol(vector_name))
  12549. return false;
  12550. else if (symbol_exists(vector_name))
  12551. return false;
  12552. else
  12553. return local_data().vector_store.add(vector_name,v);
  12554. }
  12555. inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
  12556. {
  12557. if (!valid())
  12558. return false;
  12559. else
  12560. return local_data().variable_store.remove(variable_name, delete_node);
  12561. }
  12562. #ifndef exprtk_disable_string_capabilities
  12563. inline bool remove_stringvar(const std::string& string_name)
  12564. {
  12565. if (!valid())
  12566. return false;
  12567. else
  12568. return local_data().stringvar_store.remove(string_name);
  12569. }
  12570. #endif
  12571. inline bool remove_function(const std::string& function_name)
  12572. {
  12573. if (!valid())
  12574. return false;
  12575. else
  12576. return local_data().function_store.remove(function_name);
  12577. }
  12578. inline bool remove_vararg_function(const std::string& vararg_function_name)
  12579. {
  12580. if (!valid())
  12581. return false;
  12582. else
  12583. return local_data().vararg_function_store.remove(vararg_function_name);
  12584. }
  12585. inline bool remove_vector(const std::string& vector_name)
  12586. {
  12587. if (!valid())
  12588. return false;
  12589. else
  12590. return local_data().vector_store.remove(vector_name);
  12591. }
  12592. inline bool add_constants()
  12593. {
  12594. return add_pi () &&
  12595. add_epsilon () &&
  12596. add_infinity();
  12597. }
  12598. inline bool add_pi()
  12599. {
  12600. static const T local_pi = T(details::numeric::constant::pi);
  12601. return add_constant("pi",local_pi);
  12602. }
  12603. inline bool add_epsilon()
  12604. {
  12605. static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
  12606. return add_constant("epsilon",local_epsilon);
  12607. }
  12608. inline bool add_infinity()
  12609. {
  12610. static const T local_infinity = std::numeric_limits<T>::infinity();
  12611. return add_constant("inf",local_infinity);
  12612. }
  12613. template <typename Allocator,
  12614. template <typename, typename> class Sequence>
  12615. inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
  12616. {
  12617. if (!valid())
  12618. return 0;
  12619. else
  12620. return local_data().variable_store.get_list(vlist);
  12621. }
  12622. template <typename Allocator,
  12623. template <typename, typename> class Sequence>
  12624. inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
  12625. {
  12626. if (!valid())
  12627. return 0;
  12628. else
  12629. return local_data().variable_store.get_list(vlist);
  12630. }
  12631. #ifndef exprtk_disable_string_capabilities
  12632. template <typename Allocator,
  12633. template <typename, typename> class Sequence>
  12634. inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
  12635. {
  12636. if (!valid())
  12637. return 0;
  12638. else
  12639. return local_data().stringvar_store.get_list(svlist);
  12640. }
  12641. template <typename Allocator,
  12642. template <typename, typename> class Sequence>
  12643. inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
  12644. {
  12645. if (!valid())
  12646. return 0;
  12647. else
  12648. return local_data().stringvar_store.get_list(svlist);
  12649. }
  12650. #endif
  12651. template <typename Allocator,
  12652. template <typename, typename> class Sequence>
  12653. inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vlist) const
  12654. {
  12655. if (!valid())
  12656. return 0;
  12657. else
  12658. return local_data().vector_store.get_list(vlist);
  12659. }
  12660. inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const
  12661. {
  12662. /*
  12663. Will return true if symbol_name exists as either a reserved symbol,
  12664. variable, stringvar or function name in any of the type stores.
  12665. */
  12666. if (!valid())
  12667. return false;
  12668. else if (local_data().variable_store.symbol_exists(symbol_name))
  12669. return true;
  12670. #ifndef exprtk_disable_string_capabilities
  12671. else if (local_data().stringvar_store.symbol_exists(symbol_name))
  12672. return true;
  12673. #endif
  12674. else if (local_data().function_store.symbol_exists(symbol_name))
  12675. return true;
  12676. else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name))
  12677. return true;
  12678. else
  12679. return false;
  12680. }
  12681. inline bool is_variable(const std::string& variable_name) const
  12682. {
  12683. if (!valid())
  12684. return false;
  12685. else
  12686. return local_data().variable_store.symbol_exists(variable_name);
  12687. }
  12688. #ifndef exprtk_disable_string_capabilities
  12689. inline bool is_stringvar(const std::string& stringvar_name) const
  12690. {
  12691. if (!valid())
  12692. return false;
  12693. else
  12694. return local_data().stringvar_store.symbol_exists(stringvar_name);
  12695. }
  12696. inline bool is_conststr_stringvar(const std::string& symbol_name) const
  12697. {
  12698. if (!valid())
  12699. return false;
  12700. else if (!valid_symbol(symbol_name))
  12701. return false;
  12702. else if (!local_data().stringvar_store.symbol_exists(symbol_name))
  12703. return false;
  12704. return (
  12705. local_data().stringvar_store.symbol_exists(symbol_name) ||
  12706. local_data().stringvar_store.is_constant (symbol_name)
  12707. );
  12708. }
  12709. #endif
  12710. inline bool is_function(const std::string& function_name) const
  12711. {
  12712. if (!valid())
  12713. return false;
  12714. else
  12715. return local_data().function_store.symbol_exists(function_name);
  12716. }
  12717. inline bool is_vararg_function(const std::string& vararg_function_name) const
  12718. {
  12719. if (!valid())
  12720. return false;
  12721. else
  12722. return local_data().vararg_function_store.symbol_exists(vararg_function_name);
  12723. }
  12724. inline bool is_vector(const std::string& vector_name) const
  12725. {
  12726. if (!valid())
  12727. return false;
  12728. else
  12729. return local_data().vector_store.symbol_exists(vector_name);
  12730. }
  12731. inline std::string get_variable_name(const expression_ptr& ptr) const
  12732. {
  12733. return local_data().variable_store.entity_name(ptr);
  12734. }
  12735. inline std::string get_vector_name(const vector_holder_ptr& ptr) const
  12736. {
  12737. return local_data().vector_store.entity_name(ptr);
  12738. }
  12739. #ifndef exprtk_disable_string_capabilities
  12740. inline std::string get_stringvar_name(const expression_ptr& ptr) const
  12741. {
  12742. return local_data().stringvar_store.entity_name(ptr);
  12743. }
  12744. inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const
  12745. {
  12746. return local_data().stringvar_store.entity_name(ptr);
  12747. }
  12748. #endif
  12749. inline bool valid() const
  12750. {
  12751. // Symbol table sanity check.
  12752. return holder_ && holder_->data_;
  12753. }
  12754. inline void load_from(const symbol_table<T>& st)
  12755. {
  12756. {
  12757. std::vector<std::string> name_list;
  12758. st.local_data().function_store.get_list(name_list);
  12759. if (!name_list.empty())
  12760. {
  12761. for (std::size_t i = 0; i < name_list.size(); ++i)
  12762. {
  12763. exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]);
  12764. add_function(name_list[i],ifunc);
  12765. }
  12766. }
  12767. }
  12768. {
  12769. std::vector<std::string> name_list;
  12770. st.local_data().vararg_function_store.get_list(name_list);
  12771. if (!name_list.empty())
  12772. {
  12773. for (std::size_t i = 0; i < name_list.size(); ++i)
  12774. {
  12775. exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]);
  12776. add_function(name_list[i],ivafunc);
  12777. }
  12778. }
  12779. }
  12780. {
  12781. std::vector<std::string> name_list;
  12782. st.local_data().generic_function_store.get_list(name_list);
  12783. if (!name_list.empty())
  12784. {
  12785. for (std::size_t i = 0; i < name_list.size(); ++i)
  12786. {
  12787. exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]);
  12788. add_function(name_list[i],ifunc);
  12789. }
  12790. }
  12791. }
  12792. {
  12793. std::vector<std::string> name_list;
  12794. st.local_data().string_function_store.get_list(name_list);
  12795. if (!name_list.empty())
  12796. {
  12797. for (std::size_t i = 0; i < name_list.size(); ++i)
  12798. {
  12799. exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
  12800. add_function(name_list[i],ifunc,e_ft_strfunc);
  12801. }
  12802. }
  12803. }
  12804. }
  12805. private:
  12806. inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const
  12807. {
  12808. if (symbol.empty())
  12809. return false;
  12810. if (!details::is_letter(symbol[0]))
  12811. return false;
  12812. else if (symbol.size() > 1)
  12813. {
  12814. for (std::size_t i = 1; i < symbol.size(); ++i)
  12815. {
  12816. if (
  12817. (!details::is_letter(symbol[i])) &&
  12818. (!details:: is_digit(symbol[i])) &&
  12819. ('_' != symbol[i])
  12820. )
  12821. {
  12822. return false;
  12823. }
  12824. }
  12825. }
  12826. return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true;
  12827. }
  12828. inline bool valid_function(const std::string& symbol) const
  12829. {
  12830. if (symbol.empty())
  12831. return false;
  12832. if (!details::is_letter(symbol[0]))
  12833. return false;
  12834. else if (symbol.size() > 1)
  12835. {
  12836. for (std::size_t i = 1; i < symbol.size(); ++i)
  12837. {
  12838. if (
  12839. (!details::is_letter(symbol[i])) &&
  12840. (!details:: is_digit(symbol[i])) &&
  12841. ('_' != symbol[i])
  12842. )
  12843. {
  12844. return false;
  12845. }
  12846. }
  12847. }
  12848. return true;
  12849. }
  12850. typedef typename st_holder::st_data local_data_t;
  12851. inline local_data_t& local_data()
  12852. {
  12853. return *(holder_->data_);
  12854. }
  12855. inline const local_data_t& local_data() const
  12856. {
  12857. return *(holder_->data_);
  12858. }
  12859. st_holder* holder_;
  12860. friend class parser<T>;
  12861. };
  12862. template <typename T>
  12863. class function_compositor;
  12864. template <typename T>
  12865. class expression
  12866. {
  12867. private:
  12868. typedef details::expression_node<T>* expression_ptr;
  12869. typedef details::vector_holder<T>* vector_holder_ptr;
  12870. typedef std::vector<symbol_table<T> > symtab_list_t;
  12871. struct expression_holder
  12872. {
  12873. enum data_type
  12874. {
  12875. e_unknown ,
  12876. e_expr ,
  12877. e_vecholder,
  12878. e_data ,
  12879. e_vecdata ,
  12880. e_string
  12881. };
  12882. struct data_pack
  12883. {
  12884. data_pack()
  12885. : pointer(0),
  12886. type(e_unknown),
  12887. size(0)
  12888. {}
  12889. data_pack(void* ptr, data_type dt, std::size_t sz = 0)
  12890. : pointer(ptr),
  12891. type(dt),
  12892. size(sz)
  12893. {}
  12894. void* pointer;
  12895. data_type type;
  12896. std::size_t size;
  12897. };
  12898. typedef std::vector<data_pack> local_data_list_t;
  12899. typedef results_context<T> results_context_t;
  12900. expression_holder()
  12901. : ref_count(0),
  12902. expr (0),
  12903. results (0),
  12904. retinv_null(false),
  12905. return_invoked(&retinv_null)
  12906. {}
  12907. expression_holder(expression_ptr e)
  12908. : ref_count(1),
  12909. expr (e),
  12910. results (0),
  12911. retinv_null(false),
  12912. return_invoked(&retinv_null)
  12913. {}
  12914. ~expression_holder()
  12915. {
  12916. if (expr && details::branch_deletable(expr))
  12917. {
  12918. delete expr;
  12919. }
  12920. if (!local_data_list.empty())
  12921. {
  12922. for (std::size_t i = 0; i < local_data_list.size(); ++i)
  12923. {
  12924. switch (local_data_list[i].type)
  12925. {
  12926. case e_expr : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer);
  12927. break;
  12928. case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer);
  12929. break;
  12930. case e_data : delete (T*)(local_data_list[i].pointer);
  12931. break;
  12932. case e_vecdata : delete [] (T*)(local_data_list[i].pointer);
  12933. break;
  12934. case e_string : delete (std::string*)(local_data_list[i].pointer);
  12935. break;
  12936. default : break;
  12937. }
  12938. }
  12939. }
  12940. if (results)
  12941. {
  12942. delete results;
  12943. }
  12944. }
  12945. std::size_t ref_count;
  12946. expression_ptr expr;
  12947. local_data_list_t local_data_list;
  12948. results_context_t* results;
  12949. bool retinv_null;
  12950. bool* return_invoked;
  12951. friend class function_compositor<T>;
  12952. };
  12953. public:
  12954. expression()
  12955. : expression_holder_(0)
  12956. {
  12957. set_expression(new details::null_node<T>());
  12958. }
  12959. expression(const expression<T>& e)
  12960. : expression_holder_(e.expression_holder_),
  12961. symbol_table_list_(e.symbol_table_list_)
  12962. {
  12963. expression_holder_->ref_count++;
  12964. }
  12965. inline expression<T>& operator=(const expression<T>& e)
  12966. {
  12967. if (this != &e)
  12968. {
  12969. if (expression_holder_)
  12970. {
  12971. if (0 == --expression_holder_->ref_count)
  12972. {
  12973. delete expression_holder_;
  12974. }
  12975. expression_holder_ = 0;
  12976. }
  12977. expression_holder_ = e.expression_holder_;
  12978. expression_holder_->ref_count++;
  12979. symbol_table_list_ = e.symbol_table_list_;
  12980. }
  12981. return *this;
  12982. }
  12983. inline bool operator==(const expression<T>& e)
  12984. {
  12985. return (this == &e);
  12986. }
  12987. inline bool operator!() const
  12988. {
  12989. return (
  12990. (0 == expression_holder_ ) ||
  12991. (0 == expression_holder_->expr)
  12992. );
  12993. }
  12994. inline expression<T>& release()
  12995. {
  12996. if (expression_holder_)
  12997. {
  12998. if (0 == --expression_holder_->ref_count)
  12999. {
  13000. delete expression_holder_;
  13001. }
  13002. expression_holder_ = 0;
  13003. }
  13004. return *this;
  13005. }
  13006. ~expression()
  13007. {
  13008. if (expression_holder_)
  13009. {
  13010. if (0 == --expression_holder_->ref_count)
  13011. {
  13012. delete expression_holder_;
  13013. }
  13014. }
  13015. }
  13016. inline T value() const
  13017. {
  13018. return expression_holder_->expr->value();
  13019. }
  13020. inline T operator()() const
  13021. {
  13022. return value();
  13023. }
  13024. inline operator T() const
  13025. {
  13026. return value();
  13027. }
  13028. inline operator bool() const
  13029. {
  13030. return details::is_true(value());
  13031. }
  13032. inline void register_symbol_table(symbol_table<T>& st)
  13033. {
  13034. symbol_table_list_.push_back(st);
  13035. }
  13036. inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const
  13037. {
  13038. return symbol_table_list_[index];
  13039. }
  13040. inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0)
  13041. {
  13042. return symbol_table_list_[index];
  13043. }
  13044. typedef results_context<T> results_context_t;
  13045. inline const results_context_t& results() const
  13046. {
  13047. if (expression_holder_->results)
  13048. return (*expression_holder_->results);
  13049. else
  13050. {
  13051. static const results_context_t null_results;
  13052. return null_results;
  13053. }
  13054. }
  13055. inline bool return_invoked() const
  13056. {
  13057. return (*expression_holder_->return_invoked);
  13058. }
  13059. private:
  13060. inline symtab_list_t get_symbol_table_list() const
  13061. {
  13062. return symbol_table_list_;
  13063. }
  13064. inline void set_expression(const expression_ptr expr)
  13065. {
  13066. if (expr)
  13067. {
  13068. if (expression_holder_)
  13069. {
  13070. if (0 == --expression_holder_->ref_count)
  13071. {
  13072. delete expression_holder_;
  13073. }
  13074. }
  13075. expression_holder_ = new expression_holder(expr);
  13076. }
  13077. }
  13078. inline void register_local_var(expression_ptr expr)
  13079. {
  13080. if (expr)
  13081. {
  13082. if (expression_holder_)
  13083. {
  13084. expression_holder_->
  13085. local_data_list.push_back(
  13086. typename expression<T>::expression_holder::
  13087. data_pack(reinterpret_cast<void*>(expr),
  13088. expression_holder::e_expr));
  13089. }
  13090. }
  13091. }
  13092. inline void register_local_var(vector_holder_ptr vec_holder)
  13093. {
  13094. if (vec_holder)
  13095. {
  13096. if (expression_holder_)
  13097. {
  13098. expression_holder_->
  13099. local_data_list.push_back(
  13100. typename expression<T>::expression_holder::
  13101. data_pack(reinterpret_cast<void*>(vec_holder),
  13102. expression_holder::e_vecholder));
  13103. }
  13104. }
  13105. }
  13106. inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0)
  13107. {
  13108. if (data)
  13109. {
  13110. if (expression_holder_)
  13111. {
  13112. typename expression_holder::data_type dt = expression_holder::e_data;
  13113. switch(data_mode)
  13114. {
  13115. case 0 : dt = expression_holder::e_data; break;
  13116. case 1 : d