PageRenderTime 53ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 2ms

/exprtk.hpp

http://fastmathparser.codeplex.com
C++ Header | 8207 lines | 7224 code | 873 blank | 110 comment | 1334 complexity | c5a4ad74bc8e61645a0da25ec83d8579 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. ****************************************************************
  3. * C++ Mathematical Expression Toolkit Library *
  4. * *
  5. * Author: Arash Partow (1999-2012) *
  6. * URL: http://www.partow.net/programming/exprtk/index.html *
  7. * *
  8. * Copyright notice: *
  9. * Free use of the C++ Mathematical Expression Toolkit Library *
  10. * is permitted under the guidelines and in accordance with the *
  11. * most current version of the Common Public License. *
  12. * http://www.opensource.org/licenses/cpl1.0.php *
  13. * *
  14. * Example expressions: *
  15. * (00) (y+x/y)*(x-y/x) *
  16. * (01) (x^2/sin(2*pi/y))-x/2 *
  17. * (02) sqrt(1-(x^2)) *
  18. * (03) 1-sin(2*x)+cos(pi/y) *
  19. * (04) a*exp(2*t)+c *
  20. * (05) if(((x+2)==3)and((y+5)<=9),1+w,2/z) *
  21. * (06) if(avg(x,y)<=x+y,x-y,x*y)+2*pi/x *
  22. * (07) z:=x+sin(2*pi/y) *
  23. * (08) u:=2*(pi*z)/(w:=x+cos(y/pi)) *
  24. * (09) clamp(-1,sin(2*pi*x)+cos(y/2*pi),+1) *
  25. * (10) inrange(-2,m,+2)==if(({-2<=m}and[m<=+2]),1,0) *
  26. * (11) (12.34sin(x)cos(2y)7+1)==(12.34*sin(x)*cos(2*y)*7+1) *
  27. * (12) (x ilike 's*ri?g') and [y<(3z^7+w)] *
  28. * *
  29. ****************************************************************
  30. */
  31. #ifndef INCLUDE_EXPRTK_HPP
  32. #define INCLUDE_EXPRTK_HPP
  33. #include <cctype>
  34. #include <iostream>
  35. #include <string>
  36. #include <algorithm>
  37. #include <cmath>
  38. #include <limits>
  39. #include <deque>
  40. #include <list>
  41. #include <map>
  42. #include <set>
  43. #include <stack>
  44. #define exprtk_lean_and_mean
  45. #ifdef exprtk_lean_and_mean_numeric_only
  46. #ifndef exprtk_lean_and_mean
  47. #define exprtk_lean_and_mean
  48. #endif
  49. #ifndef exprtk_disable_string_capabilities
  50. #define exprtk_disable_string_capabilities
  51. #endif
  52. #endif
  53. #ifdef exprtk_lean_and_mean
  54. #ifndef exprtk_disable_extended_operator_optimizations
  55. #define exprtk_disable_extended_operator_optimizations
  56. #endif
  57. #ifndef exprtk_disable_extended_optimisations
  58. #define exprtk_disable_extended_optimisations
  59. #endif
  60. #endif
  61. namespace exprtk
  62. {
  63. namespace details
  64. {
  65. inline bool is_whitespace(const char& c)
  66. {
  67. return (' ' == c) ||
  68. ('\n' == c) ||
  69. ('\r' == c) ||
  70. ('\t' == c) ||
  71. ('\b' == c);
  72. }
  73. inline bool is_operator_char(const char& c)
  74. {
  75. return ('+' == c) || ('-' == c) ||
  76. ('*' == c) || ('/' == c) ||
  77. ('^' == c) || ('<' == c) ||
  78. ('>' == c) || ('=' == c) ||
  79. (',' == c) || ('!' == c) ||
  80. ('(' == c) || (')' == c) ||
  81. ('[' == c) || (']' == c) ||
  82. ('{' == c) || ('}' == c) ||
  83. ('%' == c) || (':' == c) ||
  84. ('?' == c);
  85. }
  86. inline bool is_letter(const char c)
  87. {
  88. return (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
  89. }
  90. inline bool is_digit(const char c)
  91. {
  92. return ('0' <= c) && (c <= '9');
  93. }
  94. inline bool is_left_bracket(const char c)
  95. {
  96. return ('(' == c) || ('[' == c) || ('{' == c);
  97. }
  98. inline bool is_right_bracket(const char c)
  99. {
  100. return (')' == c) || (']' == c) || ('}' == c);
  101. }
  102. inline bool is_sign(const char c)
  103. {
  104. return ('+' == c) || ('-' == c);
  105. }
  106. inline bool is_invalid(const char& c)
  107. {
  108. return !is_whitespace(c) &&
  109. !is_operator_char(c) &&
  110. !is_letter(c) &&
  111. !is_digit(c) &&
  112. ('.' != c) &&
  113. ('_' != c) &&
  114. ('$' != c) &&
  115. ('\'' != c);
  116. }
  117. inline bool imatch(const char& c1, const char& c2)
  118. {
  119. return std::tolower(c1) == std::tolower(c2);
  120. }
  121. inline bool imatch(const std::string& s1, const std::string& s2)
  122. {
  123. if (s1.size() == s2.size())
  124. {
  125. for (std::size_t i = 0; i < s1.size(); ++i)
  126. {
  127. if (std::tolower(s1[i]) != std::tolower(s2[i]))
  128. {
  129. return false;
  130. }
  131. }
  132. return true;
  133. }
  134. return false;
  135. }
  136. static const std::string reserved_words[] =
  137. {
  138. "and", "false", "for", "if", "ilike", "in", "like", "nand", "nor", "not",
  139. "or", "true", "while", "xor"
  140. };
  141. static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
  142. static const std::string reserved_symbols[] =
  143. {
  144. "abs", "acos", "and", "asin", "atan", "atan2", "avg", "ceil", "clamp",
  145. "cos", "cosh", "cot", "csc", "deg2grad", "deg2rad", "equal", "erf", "erfc",
  146. "exp", "false", "floor", "for", "grad2deg", "hyp", "if", "ilike", "in",
  147. "inrange", "like", "log", "log10", "logn", "max", "min", "mod", "mul",
  148. "nand", "nor", "not", "not_equal", "or", "rad2deg", "root", "round",
  149. "roundn", "sec", "sgn", "shl", "shr", "sin", "sinh", "sqrt", "sum",
  150. "tan", "tanh", "true", "while", "xor"
  151. };
  152. static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
  153. inline bool is_reserved_word(const std::string& symbol)
  154. {
  155. for (std::size_t i = 0; i < reserved_words_size; ++i)
  156. {
  157. if (imatch(symbol,reserved_words[i]))
  158. {
  159. return true;
  160. }
  161. }
  162. return false;
  163. }
  164. inline bool is_reserved_symbol(const std::string& symbol)
  165. {
  166. for (std::size_t i = 0; i < reserved_symbols_size; ++i)
  167. {
  168. if (imatch(symbol,reserved_symbols[i]))
  169. {
  170. return true;
  171. }
  172. }
  173. return false;
  174. }
  175. struct cs_match { static inline bool cmp(const char c0, const char c1) { return c0 == c1; } };
  176. struct cis_match { static inline bool cmp(const char c0, const char c1) { return std::tolower(c0) == std::tolower(c1); } };
  177. template <typename Iterator, typename Compare>
  178. inline bool match_impl(const Iterator pattern_begin,
  179. const Iterator pattern_end,
  180. const Iterator data_begin,
  181. const Iterator data_end,
  182. const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
  183. const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
  184. {
  185. if (0 == std::distance(data_begin,data_end)) return false;
  186. Iterator d_itr = data_begin;
  187. Iterator p_itr = pattern_begin;
  188. Iterator c_itr = data_begin;
  189. Iterator m_itr = data_begin;
  190. while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
  191. {
  192. if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr)))
  193. {
  194. return false;
  195. }
  196. ++p_itr;
  197. ++d_itr;
  198. }
  199. while (data_end != d_itr)
  200. {
  201. if (zero_or_more == (*p_itr))
  202. {
  203. if (pattern_end == (++p_itr))
  204. {
  205. return true;
  206. }
  207. m_itr = p_itr;
  208. c_itr = d_itr;
  209. ++c_itr;
  210. }
  211. else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr)))
  212. {
  213. ++p_itr;
  214. ++d_itr;
  215. }
  216. else
  217. {
  218. p_itr = m_itr;
  219. d_itr = c_itr++;
  220. }
  221. }
  222. while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr;
  223. return (p_itr == pattern_end);
  224. }
  225. inline bool wc_match(const std::string& wild_card,
  226. const std::string& str)
  227. {
  228. return match_impl<const char*,cs_match>(wild_card.data(),
  229. wild_card.data() + wild_card.size(),
  230. str.data(),
  231. str.data() + str.size(),
  232. '*',
  233. '?');
  234. }
  235. inline bool wc_imatch(const std::string& wild_card,
  236. const std::string& str)
  237. {
  238. return match_impl<const char*,cis_match>(wild_card.data(),
  239. wild_card.data() + wild_card.size(),
  240. str.data(),
  241. str.data() + str.size(),
  242. '*',
  243. '?');
  244. }
  245. static const double pow10[] = {
  246. 1.0,
  247. 10.0,
  248. 100.0,
  249. 1000.0,
  250. 10000.0,
  251. 100000.0,
  252. 1000000.0,
  253. 10000000.0,
  254. 100000000.0,
  255. 1000000000.0,
  256. 10000000000.0,
  257. 100000000000.0,
  258. 1000000000000.0,
  259. 10000000000000.0,
  260. 100000000000000.0,
  261. 1000000000000000.0,
  262. 10000000000000000.0,
  263. };
  264. namespace numeric
  265. {
  266. namespace constant
  267. {
  268. static const double e = 2.718281828459045235360;
  269. static const double pi = 3.141592653589793238462;
  270. static const double pi_2 = 1.570796326794896619231;
  271. static const double pi_4 = 0.785398163397448309616;
  272. static const double pi_180 = 0.017453292519943295769;
  273. static const double _1_pi = 0.318309886183790671538;
  274. static const double _2_pi = 0.636619772367581343076;
  275. static const double _180_pi = 57.295779513082320876798;
  276. }
  277. namespace details
  278. {
  279. struct unknown_type_tag {};
  280. struct real_type_tag {};
  281. struct int_type_tag {};
  282. template <typename T>
  283. struct number_type { typedef unknown_type_tag type; };
  284. #define exprtk_register_real_type_tag(T)\
  285. template<> struct number_type<T> { typedef real_type_tag type; };
  286. #define exprtk_register_int_type_tag(T)\
  287. template<> struct number_type<T> { typedef int_type_tag type; };
  288. exprtk_register_real_type_tag(double)
  289. exprtk_register_real_type_tag(long double)
  290. exprtk_register_real_type_tag(float)
  291. exprtk_register_int_type_tag(short)
  292. exprtk_register_int_type_tag(int)
  293. exprtk_register_int_type_tag(long long int)
  294. exprtk_register_int_type_tag(unsigned short)
  295. exprtk_register_int_type_tag(unsigned int)
  296. exprtk_register_int_type_tag(unsigned long long int)
  297. #undef exprtk_register_real_type_tag
  298. #undef exprtk_register_int_type_tag
  299. template <typename T>
  300. inline T equal_impl(const T& v0, const T& v1, real_type_tag)
  301. {
  302. static const T epsilon = T(0.0000000001);
  303. return (std::abs(v0 - v1) <= (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? T(1) : T(0);
  304. }
  305. template <typename T>
  306. inline T equal_impl(const T& v0, const T& v1, int_type_tag)
  307. {
  308. return (v0 == v1) ? 1 : 0;
  309. }
  310. template <typename T>
  311. inline T nequal_impl(const T& v0, const T& v1, real_type_tag)
  312. {
  313. static const T epsilon = T(0.0000000001);
  314. return (std::abs(v0 - v1) > (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? T(1) : T(0);
  315. }
  316. template <typename T>
  317. inline T nequal_impl(const T& v0, const T& v1, int_type_tag)
  318. {
  319. return (v0 != v1) ? 1 : 0;
  320. }
  321. template <typename T>
  322. inline T modulus_impl(const T& v0, const T& v1, real_type_tag)
  323. {
  324. return std::fmod(v0,v1);
  325. }
  326. template <typename T>
  327. inline T modulus_impl(const T& v0, const T& v1, int_type_tag)
  328. {
  329. return v0 % v1;
  330. }
  331. template <typename T>
  332. inline T pow_impl(const T& v0, const T& v1, real_type_tag)
  333. {
  334. return std::pow(v0,v1);
  335. }
  336. template <typename T>
  337. inline T pow_impl(const T& v0, const T& v1, int_type_tag)
  338. {
  339. return std::pow(static_cast<double>(v0),static_cast<double>(v1));
  340. }
  341. template <typename T>
  342. inline T logn_impl(const T& v0, const T& v1, real_type_tag)
  343. {
  344. return std::log(v0) / std::log(v1);
  345. }
  346. template <typename T>
  347. inline T logn_impl(const T& v0, const T& v1, int_type_tag)
  348. {
  349. return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
  350. }
  351. template <typename T>
  352. inline T root_impl(const T& v0, const T& v1, real_type_tag)
  353. {
  354. return std::pow(v0,T(1)/v1);
  355. }
  356. template <typename T>
  357. inline T root_impl(const T& v0, const T& v1, int_type_tag)
  358. {
  359. return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
  360. }
  361. template <typename T>
  362. inline T roundn_impl(const T& v0, const T& v1, real_type_tag)
  363. {
  364. return T(std::floor((v0 * pow10[(int)std::floor(v1)]) + T(0.5)) / T(pow10[(int)std::floor(v1)]));
  365. }
  366. template <typename T>
  367. inline T roundn_impl(const T& v0, const T&, int_type_tag)
  368. {
  369. return v0;
  370. }
  371. template <typename T>
  372. inline T hyp_impl(const T& v0, const T& v1, real_type_tag)
  373. {
  374. return std::sqrt((v0 * v0) + (v1 * v1));
  375. }
  376. template <typename T>
  377. inline T hyp_impl(const T& v0, const T& v1, int_type_tag)
  378. {
  379. return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
  380. }
  381. template <typename T>
  382. inline T atan2_impl(const T& v0, const T& v1, real_type_tag)
  383. {
  384. return std::atan2(v0,v1);
  385. }
  386. template <typename T>
  387. inline T atan2_impl(const T&, const T&, int_type_tag)
  388. {
  389. return 0;
  390. }
  391. template <typename T>
  392. inline T shr_impl(const T& v0, const T& v1, real_type_tag)
  393. {
  394. return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
  395. }
  396. template <typename T>
  397. inline T shr_impl(const T& v0, const T& v1, int_type_tag)
  398. {
  399. return v0 >> v1;
  400. }
  401. template <typename T>
  402. inline T shl_impl(const T& v0, const T& v1, real_type_tag)
  403. {
  404. return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
  405. }
  406. template <typename T>
  407. inline T shl_impl(const T& v0, const T& v1, int_type_tag)
  408. {
  409. return v0 << v1;
  410. }
  411. template <typename T>
  412. inline T sgn_impl(const T& v, real_type_tag)
  413. {
  414. if (v > T(0.0)) return T(+1.0);
  415. else if (v < T(0.0)) return T(-1.0);
  416. else return T( 0.0);
  417. }
  418. template <typename T>
  419. inline T sgn_impl(const T& v, int_type_tag)
  420. {
  421. if (v > T(0)) return T(+1);
  422. else if (v < T(0)) return T(-1);
  423. else return T( 0);
  424. }
  425. template <typename T>
  426. inline T xor_impl(const T& v0, const T& v1, real_type_tag)
  427. {
  428. return v0 != v1;
  429. }
  430. template <typename T>
  431. inline T xor_impl(const T& v0, const T& v1, int_type_tag)
  432. {
  433. return v0 ^ v1;
  434. }
  435. template <typename T>
  436. inline T erf_impl(T v, real_type_tag)
  437. {
  438. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  439. //Note: This should not be required for mscv 11.+
  440. T a1 = T(+0.254829592);
  441. T a2 = T(-0.284496736);
  442. T a3 = T(+1.421413741);
  443. T a4 = T(-1.453152027);
  444. T a5 = T(+1.061405429);
  445. T p = T( 0.327591100);
  446. T sign = T(1.0);
  447. if (v < 0)
  448. {
  449. sign = -1;
  450. v = abs(v);
  451. }
  452. T t = T(1.0) / (T(1.0) + p * v);
  453. T y = T(1.0) - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * std::exp(-v * v);
  454. return sign * y;
  455. #else
  456. return ::erf(v);
  457. #endif
  458. }
  459. template <typename T>
  460. inline T erf_impl(T v, int_type_tag)
  461. {
  462. return erf_impl(static_cast<double>(v),real_type_tag());
  463. }
  464. template <typename T>
  465. inline T erfc_impl(T v, real_type_tag)
  466. {
  467. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  468. return T(1.0) - erf_impl(v,real_type_tag());
  469. #else
  470. return ::erfc(v);
  471. #endif
  472. }
  473. template <typename T>
  474. inline T erfc_impl(T v, int_type_tag)
  475. {
  476. return erfc_impl(static_cast<double>(v),real_type_tag());
  477. }
  478. template <typename T> inline T abs_impl(const T& v, real_type_tag) { return std::abs (v); }
  479. template <typename T> inline T acos_impl(const T& v, real_type_tag) { return std::acos (v); }
  480. template <typename T> inline T asin_impl(const T& v, real_type_tag) { return std::asin (v); }
  481. template <typename T> inline T atan_impl(const T& v, real_type_tag) { return std::atan (v); }
  482. template <typename T> inline T ceil_impl(const T& v, real_type_tag) { return std::ceil (v); }
  483. template <typename T> inline T cos_impl(const T& v, real_type_tag) { return std::cos (v); }
  484. template <typename T> inline T cosh_impl(const T& v, real_type_tag) { return std::cosh (v); }
  485. template <typename T> inline T exp_impl(const T& v, real_type_tag) { return std::exp (v); }
  486. template <typename T> inline T floor_impl(const T& v, real_type_tag) { return std::floor(v); }
  487. template <typename T> inline T log_impl(const T& v, real_type_tag) { return std::log (v); }
  488. template <typename T> inline T log10_impl(const T& v, real_type_tag) { return std::log10(v); }
  489. template <typename T> inline T neg_impl(const T& v, real_type_tag) { return -v; }
  490. template <typename T> inline T pos_impl(const T& v, real_type_tag) { return +v; }
  491. template <typename T> inline T round_impl(const T& v, real_type_tag) { return std::floor(v + T(0.5)); }
  492. template <typename T> inline T sin_impl(const T& v, real_type_tag) { return std::sin (v); }
  493. template <typename T> inline T sinh_impl(const T& v, real_type_tag) { return std::sinh (v); }
  494. template <typename T> inline T sqrt_impl(const T& v, real_type_tag) { return std::sqrt (v); }
  495. template <typename T> inline T tan_impl(const T& v, real_type_tag) { return std::tan (v); }
  496. template <typename T> inline T tanh_impl(const T& v, real_type_tag) { return std::tanh (v); }
  497. template <typename T> inline T cot_impl(const T& v, real_type_tag) { return T(1) / std::tan(v); }
  498. template <typename T> inline T sec_impl(const T& v, real_type_tag) { return T(1) / std::cos(v); }
  499. template <typename T> inline T csc_impl(const T& v, real_type_tag) { return T(1) / std::sin(v); }
  500. template <typename T> inline T r2d_impl(const T& v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
  501. template <typename T> inline T d2r_impl(const T& v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
  502. template <typename T> inline T d2g_impl(const T& v, real_type_tag) { return (v * T(20.0/9.0)); }
  503. template <typename T> inline T g2d_impl(const T& v, real_type_tag) { return (v * T(9.0/20.0)); }
  504. template <typename T> inline T notl_impl(const T& v, real_type_tag) { return (v != T(0) ? T(0) : T(1)); }
  505. template <typename T> inline T abs_impl(const T& v, int_type_tag) { return std::abs (v); }
  506. template <typename T> inline T exp_impl(const T& v, int_type_tag) { return std::exp (v); }
  507. template <typename T> inline T log_impl(const T& v, int_type_tag) { return std::log (v); }
  508. template <typename T> inline T log10_impl(const T& v, int_type_tag) { return std::log10(v); }
  509. template <typename T> inline T neg_impl(const T& v, int_type_tag) { return -v; }
  510. template <typename T> inline T pos_impl(const T& v, int_type_tag) { return +v; }
  511. template <typename T> inline T ceil_impl(const T& v, int_type_tag) { return v; }
  512. template <typename T> inline T floor_impl(const T& v, int_type_tag) { return v; }
  513. template <typename T> inline T round_impl(const T& v, int_type_tag) { return v; }
  514. template <typename T> inline T notl_impl(const T& v, int_type_tag) { return !v; }
  515. template <typename T> inline T sqrt_impl(const T& v, int_type_tag) { return std::sqrt (v); }
  516. template <typename T> inline T acos_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  517. template <typename T> inline T asin_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  518. template <typename T> inline T atan_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  519. template <typename T> inline T cos_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  520. template <typename T> inline T cosh_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  521. template <typename T> inline T sin_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  522. template <typename T> inline T sinh_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  523. template <typename T> inline T tan_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  524. template <typename T> inline T tanh_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  525. template <typename T> inline T cot_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  526. template <typename T> inline T sec_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  527. template <typename T> inline T csc_impl(const T& , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
  528. template <typename T>
  529. inline bool is_integer_impl(const T& v, real_type_tag)
  530. {
  531. return (T(0.0) == std::fmod(v,T(1.0)));
  532. }
  533. template <typename T>
  534. inline bool is_integer_impl(const T&, int_type_tag)
  535. {
  536. return true;
  537. }
  538. }
  539. template <typename Type>
  540. struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
  541. template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
  542. template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
  543. template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
  544. template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
  545. template <typename T>
  546. inline T equal(const T& v0, const T& v1)
  547. {
  548. typename details::number_type<T>::type num_type;
  549. return details::equal_impl(v0,v1,num_type);
  550. }
  551. template <typename T>
  552. inline T nequal(const T& v0, const T& v1)
  553. {
  554. typename details::number_type<T>::type num_type;
  555. return details::nequal_impl(v0,v1,num_type);
  556. }
  557. template <typename T>
  558. inline T modulus(const T& v0, const T& v1)
  559. {
  560. typename details::number_type<T>::type num_type;
  561. return details::modulus_impl(v0,v1,num_type);
  562. }
  563. template <typename T>
  564. inline T pow(const T& v0, const T& v1)
  565. {
  566. typename details::number_type<T>::type num_type;
  567. return details::pow_impl(v0,v1,num_type);
  568. }
  569. template <typename T>
  570. inline T logn(const T& v0, const T& v1)
  571. {
  572. typename details::number_type<T>::type num_type;
  573. return details::logn_impl(v0,v1,num_type);
  574. }
  575. template <typename T>
  576. inline T root(const T& v0, const T& v1)
  577. {
  578. typename details::number_type<T>::type num_type;
  579. return details::root_impl(v0,v1,num_type);
  580. }
  581. template <typename T>
  582. inline T roundn(const T& v0, const T& v1)
  583. {
  584. typename details::number_type<T>::type num_type;
  585. return details::roundn_impl(v0,v1,num_type);
  586. }
  587. template <typename T>
  588. inline T hyp(const T& v0, const T& v1)
  589. {
  590. typename details::number_type<T>::type num_type;
  591. return details::hyp_impl(v0,v1,num_type);
  592. }
  593. template <typename T>
  594. inline T atan2(const T& v0, const T& v1)
  595. {
  596. typename details::number_type<T>::type num_type;
  597. return details::atan2_impl(v0,v1,num_type);
  598. }
  599. template <typename T>
  600. inline T shr(const T& v0, const T& v1)
  601. {
  602. typename details::number_type<T>::type num_type;
  603. return details::shr_impl(v0,v1,num_type);
  604. }
  605. template <typename T>
  606. inline T shl(const T& v0, const T& v1)
  607. {
  608. typename details::number_type<T>::type num_type;
  609. return details::shl_impl(v0,v1,num_type);
  610. }
  611. template <typename T>
  612. inline T xor_opr(const T& v0, const T& v1)
  613. {
  614. typename details::number_type<T>::type num_type;
  615. return details::xor_impl(v0,v1,num_type);
  616. }
  617. template <typename T>
  618. inline bool is_integer(const T& v)
  619. {
  620. typename details::number_type<T>::type num_type;
  621. return details::is_integer_impl(v,num_type);
  622. }
  623. template <typename T, unsigned int N>
  624. struct fast_exp
  625. {
  626. static inline T result(T v)
  627. {
  628. unsigned int k = N;
  629. T l = T(1);
  630. while (k)
  631. {
  632. if (k & 1)
  633. {
  634. l *= v;
  635. --k;
  636. }
  637. v *= v;
  638. k >>= 1;
  639. }
  640. return l;
  641. }
  642. };
  643. 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; } };
  644. template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
  645. 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; } };
  646. template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
  647. 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; } };
  648. template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
  649. template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
  650. template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
  651. template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v; } };
  652. template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } };
  653. template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } };
  654. #define exprtk_define_unary_function(FunctionName) \
  655. template <typename T> \
  656. inline T FunctionName (const T& v) \
  657. { \
  658. typename details::number_type<T>::type num_type; \
  659. return details:: FunctionName##_impl(v,num_type); \
  660. }
  661. exprtk_define_unary_function(abs )
  662. exprtk_define_unary_function(acos )
  663. exprtk_define_unary_function(asin )
  664. exprtk_define_unary_function(atan )
  665. exprtk_define_unary_function(ceil )
  666. exprtk_define_unary_function(cos )
  667. exprtk_define_unary_function(cosh )
  668. exprtk_define_unary_function(exp )
  669. exprtk_define_unary_function(floor)
  670. exprtk_define_unary_function(log )
  671. exprtk_define_unary_function(log10)
  672. exprtk_define_unary_function(neg )
  673. exprtk_define_unary_function(pos )
  674. exprtk_define_unary_function(round)
  675. exprtk_define_unary_function(sin )
  676. exprtk_define_unary_function(sinh )
  677. exprtk_define_unary_function(sqrt )
  678. exprtk_define_unary_function(tan )
  679. exprtk_define_unary_function(tanh )
  680. exprtk_define_unary_function(cot )
  681. exprtk_define_unary_function(sec )
  682. exprtk_define_unary_function(csc )
  683. exprtk_define_unary_function(r2d )
  684. exprtk_define_unary_function(d2r )
  685. exprtk_define_unary_function(d2g )
  686. exprtk_define_unary_function(g2d )
  687. exprtk_define_unary_function(notl )
  688. exprtk_define_unary_function(sgn )
  689. exprtk_define_unary_function(erf )
  690. exprtk_define_unary_function(erfc )
  691. #undef exprtk_define_unary_function
  692. }
  693. template <typename T>
  694. struct token
  695. {
  696. enum token_type
  697. {
  698. none = 0,
  699. error = 1,
  700. eof = 2,
  701. number = 3,
  702. symbol = 4,
  703. string = 5,
  704. assign = 6,
  705. shr = 7,
  706. shl = 8,
  707. lte = 9,
  708. ne = 10,
  709. gte = 11,
  710. lt = '<',
  711. gt = '>',
  712. eq = '=',
  713. rbracket = ')',
  714. lbracket = '(',
  715. rsqrbracket = ']',
  716. lsqrbracket = '[',
  717. rcrlbracket = '}',
  718. lcrlbracket = '{',
  719. comma = ',',
  720. add = '+',
  721. sub = '-',
  722. div = '/',
  723. mul = '*',
  724. mod = '%',
  725. pow = '^'
  726. };
  727. token() {}
  728. explicit token(token_type ttype)
  729. : type(ttype)
  730. {}
  731. token(token_type ttype,
  732. const char* begin, const char* end)
  733. : type(ttype),
  734. value(std::string(begin,end)),
  735. numeric_value(T(0))
  736. {}
  737. token(token_type ttype, const std::string& v)
  738. : type(ttype),
  739. value(v),
  740. numeric_value(T(0))
  741. {}
  742. token(token_type ttype, const T& num_val)
  743. : type(ttype),
  744. numeric_value(num_val)
  745. {}
  746. token_type type;
  747. std::string value;
  748. T numeric_value;
  749. };
  750. template <typename T>
  751. class lexer
  752. {
  753. public:
  754. typedef token<T> token_t;
  755. inline bool process(const std::string& str)
  756. {
  757. error_description_ = "";
  758. s_itr = str.data();
  759. s_end = str.data() + str.size();
  760. eof_token_ = token_t(token_t::eof,s_end,s_end);
  761. token_list_.clear();
  762. while (s_end != s_itr)
  763. {
  764. scan_token();
  765. if (!error_description_.empty())
  766. {
  767. return false;
  768. }
  769. }
  770. process_commutative_symbols();
  771. token_itr_ = token_list_.begin();
  772. store_token_itr_ = token_list_.begin();
  773. return true;
  774. }
  775. inline void store()
  776. {
  777. store_token_itr_ = token_itr_;
  778. }
  779. inline void restore()
  780. {
  781. token_itr_ = store_token_itr_;
  782. }
  783. inline token_t& next_token()
  784. {
  785. if (token_list_.end() != token_itr_)
  786. {
  787. return *token_itr_++;
  788. }
  789. else
  790. return eof_token_;
  791. }
  792. inline std::string error() const
  793. {
  794. return error_description_;
  795. }
  796. private:
  797. inline void skip_whitespace()
  798. {
  799. while ((s_end != s_itr) && is_whitespace(*s_itr))
  800. {
  801. ++s_itr;
  802. }
  803. }
  804. inline void scan_token()
  805. {
  806. skip_whitespace();
  807. if (s_end == s_itr)
  808. {
  809. return;
  810. }
  811. else if (is_operator_char(*s_itr))
  812. {
  813. scan_operator();
  814. return;
  815. }
  816. else if (is_letter(*s_itr))
  817. {
  818. scan_symbol();
  819. return;
  820. }
  821. else if (is_digit((*s_itr)) || ('.' == (*s_itr)))
  822. {
  823. scan_number();
  824. return;
  825. }
  826. else if ('$' == (*s_itr))
  827. {
  828. scan_special_function();
  829. return;
  830. }
  831. #ifndef exprtk_disable_string_capabilities
  832. else if ('\'' == (*s_itr))
  833. {
  834. scan_string();
  835. return;
  836. }
  837. #endif
  838. else
  839. {
  840. set_error(std::string("scan_token() - error invalid token: ") + std::string(s_itr,s_itr + 2));
  841. token_list_.push_back(error(s_itr,s_itr + 1));
  842. ++s_itr;
  843. }
  844. }
  845. inline void scan_operator()
  846. {
  847. if ((s_itr + 1) != s_end)
  848. {
  849. typename token_t::token_type ttype = token_t::none;
  850. char c0 = s_itr[0];
  851. char c1 = s_itr[1];
  852. if ((c0 == '<') && (c1 == '=')) ttype = token_t::lte;
  853. else if ((c0 == '>') && (c1 == '=')) ttype = token_t::gte;
  854. else if ((c0 == '<') && (c1 == '>')) ttype = token_t::ne;
  855. else if ((c0 == '!') && (c1 == '=')) ttype = token_t::ne;
  856. else if ((c0 == '=') && (c1 == '=')) ttype = token_t::eq;
  857. else if ((c0 == ':') && (c1 == '=')) ttype = token_t::assign;
  858. else if ((c0 == '<') && (c1 == '<')) ttype = token_t::shl;
  859. else if ((c0 == '>') && (c1 == '>')) ttype = token_t::shr;
  860. if (token_t::none != ttype)
  861. {
  862. token_list_.push_back(token_t(ttype));
  863. s_itr += 2;
  864. return;
  865. }
  866. }
  867. if ('<' == *s_itr) token_list_.push_back(token_t(token_t::lt));
  868. else if ('>' == *s_itr) token_list_.push_back(token_t(token_t::gt));
  869. else
  870. token_list_.push_back(token_t(typename token_t::token_type((*s_itr))));
  871. ++s_itr;
  872. }
  873. inline void scan_symbol()
  874. {
  875. const char* begin = s_itr;
  876. while ((s_end != s_itr) &&
  877. (is_letter((*s_itr)) || is_digit ((*s_itr)) || ((*s_itr) == '_')))
  878. {
  879. ++s_itr;
  880. }
  881. static const std::string true_string = "true";
  882. static const std::string false_string = "false";
  883. if (details::imatch(std::string(begin,s_itr),true_string))
  884. token_list_.push_back(token_t(token_t::number,T(1)));
  885. else if (details::imatch(std::string(begin,s_itr),false_string))
  886. token_list_.push_back(token_t(token_t::number,T(0)));
  887. else
  888. token_list_.push_back(token_t(token_t::symbol,begin,s_itr));
  889. }
  890. inline void scan_number()
  891. {
  892. /*
  893. Attempt to match a valid numeric value in one of the following formats:
  894. 1. 123456
  895. 2. 123.456
  896. 3. 123.456e3
  897. 4. 123.456E3
  898. 5. 123.456e+3
  899. 6. 123.456E+3
  900. 7. 123.456e-3
  901. 8. 123.456E-3
  902. */
  903. const char* begin = s_itr;
  904. bool dot_found = false;
  905. bool e_found = false;
  906. bool post_e_sign_found = false;
  907. while (s_end != s_itr)
  908. {
  909. if ('.' == (*s_itr))
  910. {
  911. if (dot_found)
  912. {
  913. set_error(std::string("scan_number() - error invalid numeric token[1]: ") + std::string(begin,s_itr));
  914. token_list_.push_back(error(begin,s_itr));
  915. return;
  916. }
  917. dot_found = true;
  918. ++s_itr;
  919. continue;
  920. }
  921. else if (imatch('e',(*s_itr)))
  922. {
  923. const char& c = *(s_itr + 1);
  924. if (s_end == (s_itr + 1))
  925. {
  926. set_error(std::string("scan_number() - error invalid numeric token[2]: ") + std::string(begin,s_itr));
  927. token_list_.push_back(error(begin,s_itr));
  928. return;
  929. }
  930. else if (('+' != c) && ('-' != c) && !is_digit(c))
  931. {
  932. set_error(std::string("scan_number() - error invalid numeric token[3]: ") + std::string(begin,s_itr));
  933. token_list_.push_back(error(begin,s_itr));
  934. return;
  935. }
  936. e_found = true;
  937. ++s_itr;
  938. continue;
  939. }
  940. else if (e_found && is_sign(*s_itr))
  941. {
  942. if (post_e_sign_found)
  943. {
  944. set_error(std::string("scan_number() - error invalid numeric token[4]: ") + std::string(begin,s_itr));
  945. token_list_.push_back(error(begin,s_itr));
  946. return;
  947. }
  948. post_e_sign_found = true;
  949. ++s_itr;
  950. continue;
  951. }
  952. else if (('.' != (*s_itr)) && !is_digit(*s_itr))
  953. break;
  954. else
  955. ++s_itr;
  956. }
  957. T value = T(0.0);
  958. if (string_to_real(begin,s_itr,value))
  959. token_list_.push_back(token_t(token_t::number,value));
  960. else
  961. {
  962. set_error(std::string("scan_number() - error failed to parse token to real type. ") + std::string(begin,s_itr));
  963. token_list_.push_back(error(begin,s_itr));
  964. }
  965. return;
  966. }
  967. inline void scan_special_function()
  968. {
  969. const char* begin = s_itr;
  970. //$fdd(x,x,x) = 11 chars
  971. if (std::distance(s_itr,s_end) < 11)
  972. {
  973. set_error(std::string("scan_special_function() - error invalid special function [1]: ") + std::string(begin,s_itr));
  974. token_list_.push_back(error(begin,s_itr));
  975. return;
  976. }
  977. if (!(('$' == *s_itr) &&
  978. (imatch('f',*(s_itr + 1))) &&
  979. ('(' == *(s_itr + 4)) &&
  980. (is_digit(*(s_itr + 2))) &&
  981. (is_digit(*(s_itr + 3)))))
  982. {
  983. set_error(std::string("scan_special_function() - error invalid special function [2]: ") + std::string(begin,s_itr));
  984. token_list_.push_back(error(begin,s_itr));
  985. return;
  986. }
  987. s_itr += 4;
  988. token_list_.push_back(token_t(token_t::symbol,begin,s_itr));
  989. return;
  990. }
  991. #ifndef exprtk_disable_string_capabilities
  992. inline void scan_string()
  993. {
  994. const char* begin = s_itr + 1;
  995. if (std::distance(s_itr,s_end) < 2)
  996. {
  997. set_error(std::string("scan_string() - error invalid string [1]: ") + std::string(begin,s_itr));
  998. token_list_.push_back(error(begin,s_itr));
  999. return;
  1000. }
  1001. ++s_itr;
  1002. bool escaped = false;
  1003. std::string result_string;
  1004. while (s_end != s_itr)
  1005. {
  1006. if ('\\' == *s_itr)
  1007. {
  1008. escaped = true;
  1009. ++s_itr;
  1010. continue;
  1011. }
  1012. else if (!escaped)
  1013. {
  1014. if ('\'' == *s_itr)
  1015. break;
  1016. }
  1017. else if (escaped)
  1018. escaped = false;
  1019. result_string += *s_itr;
  1020. ++s_itr;
  1021. }
  1022. if (s_end == s_itr)
  1023. {
  1024. set_error(std::string("scan_string() - error string has not been terminated: ") + std::string(begin,s_itr));
  1025. token_list_.push_back(error(begin,s_itr));
  1026. return;
  1027. }
  1028. token_list_.push_back(token_t(token_t::string,result_string));
  1029. ++s_itr;
  1030. return;
  1031. }
  1032. #endif
  1033. inline void process_commutative_symbols()
  1034. {
  1035. if (token_list_.size() < 2)
  1036. return;
  1037. typename std::deque<token_t>::iterator itr = token_list_.begin() + 1;
  1038. typename std::deque<token_t>::iterator prev_itr = token_list_.begin();
  1039. while (token_list_.end() != itr)
  1040. {
  1041. token_t& curr_token = *itr;
  1042. token_t& prev_token = *prev_itr;
  1043. bool curr_token_not_reserved = !is_reserved_word(curr_token.value);
  1044. if (
  1045. //3x -> 3*x
  1046. ((token_t::symbol == curr_token.type) && (token_t::number == prev_token.type) && curr_token_not_reserved) ||
  1047. //3(x+1) -> 3*(x+1)
  1048. (is_left_bracket (static_cast<char>(curr_token.type)) && (token_t::number == prev_token.type)) ||
  1049. //(x+1)3 -> (x+1)*3
  1050. (is_right_bracket(static_cast<char>(prev_token.type)) && (token_t::number == curr_token.type)) ||
  1051. //(x+1)y -> (x+1)*y
  1052. (is_right_bracket(static_cast<char>(prev_token.type)) && (token_t::symbol == curr_token.type) && curr_token_not_reserved)
  1053. )
  1054. {
  1055. prev_itr = itr = token_list_.insert(itr,token_t(token_t::mul));
  1056. ++itr;
  1057. continue;
  1058. }
  1059. ++itr;
  1060. ++prev_itr;
  1061. }
  1062. }
  1063. inline void set_error(const std::string& s)
  1064. {
  1065. if (error_description_.empty())
  1066. {
  1067. error_description_ = s;
  1068. }
  1069. }
  1070. inline token_t error(const char* begin, const char* end) const
  1071. {
  1072. return token_t(token_t::error,begin,end);
  1073. }
  1074. private:
  1075. template <typename Iterator, typename Type>
  1076. static inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, Type& result)
  1077. {
  1078. if (end == itr) return false;
  1079. Type t = 0;
  1080. bool negative = false;
  1081. if ('+' == (*itr))
  1082. ++itr;
  1083. else if ('-' == (*itr))
  1084. {
  1085. ++itr;
  1086. negative = true;
  1087. }
  1088. if (end == itr)
  1089. return false;
  1090. unsigned int digit_count = 0;
  1091. while ((end != itr) && ('0' == (*itr))) ++itr;
  1092. bool return_result = true;
  1093. while (end != itr)
  1094. {
  1095. const unsigned char digit = (*itr - '0');
  1096. if (digit > 9)
  1097. {
  1098. return_result = false;
  1099. break;
  1100. }
  1101. if ((++digit_count) <= numeric::numeric_info<Type>::bound_length)
  1102. {
  1103. t *= 10;
  1104. t += digit;
  1105. }
  1106. else
  1107. {
  1108. typedef unsigned long long int base_type;
  1109. static const base_type max_limit = +std::numeric_limits<Type>::max();
  1110. static const base_type min_limit = -std::numeric_limits<Type>::min();
  1111. base_type tmp = static_cast<base_type>(t) * 10 + digit;
  1112. if (negative && static_cast<base_type>(tmp) > min_limit)
  1113. return_result = false;
  1114. else if (static_cast<base_type>(tmp) > max_limit)
  1115. return_result = false;
  1116. t = static_cast<Type>(tmp);
  1117. }
  1118. ++itr;
  1119. }
  1120. result = static_cast<Type>((negative) ? -t : t);
  1121. return return_result;
  1122. }
  1123. template <typename Iterator>
  1124. static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
  1125. {
  1126. typedef typename std::iterator_traits<Iterator>::value_type type;
  1127. static const std::size_t nan_length = 3;
  1128. if (std::distance(itr,end) != static_cast<int>(nan_length))
  1129. return false;
  1130. if (static_cast<type>('n') == (*itr))
  1131. {
  1132. if ((static_cast<type>('a') != *(itr + 1)) || (static_cast<type>('n') != *(itr + 2)))
  1133. {
  1134. return false;
  1135. }
  1136. }
  1137. else if ((static_cast<type>('A') != *(itr + 1)) || (static_cast<type>('N') != *(itr + 2)))
  1138. {
  1139. return false;
  1140. }
  1141. t = std::numeric_limits<T>::quiet_NaN();
  1142. return true;
  1143. }
  1144. template <typename Iterator>
  1145. static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
  1146. {
  1147. static const char inf_uc[] = "INFINITY";
  1148. static const char inf_lc[] = "infinity";
  1149. static const std::size_t inf_length = 8;
  1150. const std::size_t length = std::distance(itr,end);
  1151. if ((3 != length) && (inf_length != length))
  1152. return false;
  1153. const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
  1154. while (end != itr)
  1155. {
  1156. if (*inf_itr == static_cast<char>(*itr))
  1157. {
  1158. ++itr;
  1159. ++inf_itr;
  1160. continue;
  1161. }
  1162. else
  1163. return false;
  1164. }
  1165. if (negative)
  1166. t = -std::numeric_limits<T>::infinity();
  1167. else
  1168. t = std::numeric_limits<T>::infinity();
  1169. return true;
  1170. }
  1171. template <typename Iterator>
  1172. inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t)
  1173. {
  1174. if (end == itr_external) return false;
  1175. Iterator itr = itr_external;
  1176. double d = 0.0;
  1177. bool negative = false;
  1178. if ('+' == (*itr))
  1179. ++itr;
  1180. else if ('-' == (*itr))

Large files files are truncated, but you can click here to view the full file