/exprtk.hpp
C++ Header | 10925 lines | 9219 code | 1577 blank | 129 comment | 1589 complexity | d77335b11214244e1477262350bde5de MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- ****************************************************************
- * C++ Mathematical Expression Toolkit Library *
- * *
- * Author: Arash Partow (1999-2013) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
- * *
- * Copyright notice: *
- * Free use of the C++ Mathematical Expression Toolkit Library *
- * is permitted under the guidelines and in accordance with the *
- * most current version of the Common Public License. *
- * http://www.opensource.org/licenses/cpl1.0.php *
- * *
- * Example expressions: *
- * (00) (y+x/y)*(x-y/x) *
- * (01) (x^2/sin(2*pi/y))-x/2 *
- * (02) sqrt(1-(x^2)) *
- * (03) 1-sin(2*x)+cos(pi/y) *
- * (04) a*exp(2*t)+c *
- * (05) if(((x+2)==3)and((y+5)<=9),1+w,2/z) *
- * (06) if(avg(x,y)<=x+y,x-y,x*y)+2*pi/x *
- * (07) z:=x+sin(2*pi/y) *
- * (08) u:=2*(pi*z)/(w:=x+cos(y/pi)) *
- * (09) clamp(-1,sin(2*pi*x)+cos(y/2*pi),+1) *
- * (10) inrange(-2,m,+2)==if(({-2<=m} and [m<=+2]),1,0) *
- * (11) (12.34sin(x)cos(2y)7+1)==(12.34*sin(x)*cos(2*y)*7+1) *
- * (12) (x ilike 's*ri?g') and [y<(3z^7+w)] *
- * *
- ****************************************************************
- */
- #ifndef INCLUDE_EXPRTK_HPP
- #define INCLUDE_EXPRTK_HPP
- #include <algorithm>
- #include <cctype>
- #include <cmath>
- #include <deque>
- #include <limits>
- #include <list>
- #include <map>
- #include <set>
- #include <stack>
- #include <stdexcept>
- #include <string>
- #ifndef exprtk_enable_all_optimizations
- # define exprtk_lean_and_mean
- # ifdef exprtk_lean_and_mean_numeric_only
- # ifndef exprtk_lean_and_mean
- # define exprtk_lean_and_mean
- # endif
- # ifndef exprtk_disable_string_capabilities
- # define exprtk_disable_string_capabilities
- # endif
- # endif
- # ifdef exprtk_lean_and_mean
- # ifndef exprtk_disable_extended_operator_optimizations
- # define exprtk_disable_extended_operator_optimizations
- # endif
- # ifndef exprtk_disable_extended_optimisations
- # define exprtk_disable_extended_optimisations
- # endif
- # endif
- #endif
- namespace exprtk
- {
- namespace details
- {
- inline bool is_whitespace(const char c)
- {
- return (' ' == c) || ('\n' == c) ||
- ('\r' == c) || ('\t' == c) ||
- ('\b' == c) || ('\v' == c) ||
- ('\f' == c) ;
- }
- inline bool is_operator_char(const char c)
- {
- return ('+' == c) || ('-' == c) ||
- ('*' == c) || ('/' == c) ||
- ('^' == c) || ('<' == c) ||
- ('>' == c) || ('=' == c) ||
- (',' == c) || ('!' == c) ||
- ('(' == c) || (')' == c) ||
- ('[' == c) || (']' == c) ||
- ('{' == c) || ('}' == c) ||
- ('%' == c) || (':' == c) ||
- ('?' == c);
- }
- inline bool is_letter(const char c)
- {
- return (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
- }
- inline bool is_digit(const char c)
- {
- return ('0' <= c) && (c <= '9');
- }
- inline bool is_letter_or_digit(const char c)
- {
- return is_letter(c) || is_digit(c);
- }
- inline bool is_left_bracket(const char c)
- {
- return ('(' == c) || ('[' == c) || ('{' == c);
- }
- inline bool is_right_bracket(const char c)
- {
- return (')' == c) || (']' == c) || ('}' == c);
- }
- inline bool is_bracket(const char c)
- {
- return is_left_bracket(c) || is_right_bracket(c);
- }
- inline bool is_sign(const char c)
- {
- return ('+' == c) || ('-' == c);
- }
- inline bool is_invalid(const char c)
- {
- return !is_whitespace(c) &&
- !is_operator_char(c) &&
- !is_letter(c) &&
- !is_digit(c) &&
- ('.' != c) &&
- ('_' != c) &&
- ('$' != c) &&
- ('\'' != c);
- }
- inline bool imatch(const char c1, const char c2)
- {
- return std::tolower(c1) == std::tolower(c2);
- }
- inline bool imatch(const std::string& s1, const std::string& s2)
- {
- if (s1.size() == s2.size())
- {
- for (std::size_t i = 0; i < s1.size(); ++i)
- {
- if (std::tolower(s1[i]) != std::tolower(s2[i]))
- {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- inline bool is_valid_sf_symbol(const std::string& symbol)
- {
- //Special function: $f12 or $F34
- return (symbol.size() == 4) &&
- ('$' == symbol[0]) &&
- imatch('f',symbol[1]) &&
- is_digit(symbol[2]) &&
- is_digit(symbol[3]);
- }
- inline std::string to_str(int i)
- {
- if (0 == i)
- return std::string("0");
- std::string result;
- bool negative = (i < 0);
- if (negative) i *= -1;
- while (i)
- {
- char digit = '0' + char(i % 10);
- result = (digit + result);
- i /= 10;
- }
- if (negative)
- result = "-" + result;
- return result;
- }
- struct ilesscompare
- {
- inline bool operator()(const std::string& s1, const std::string& s2) const
- {
- const std::size_t length = std::min(s1.size(),s2.size());
- for (std::size_t i = 0; i < length; ++i)
- {
- if (std::tolower(s1[i]) > std::tolower(s2[i]))
- return false;
- else if (std::tolower(s1[i]) < std::tolower(s2[i]))
- return true;
- }
- return s1.size() < s2.size();
- }
- };
- static const std::string reserved_words[] =
- {
- "and", "false", "for", "if", "ilike", "in", "like", "nand", "nor", "not",
- "or", "shl", "shr", "true", "while", "xor"
- };
- static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
- static const std::string reserved_symbols[] =
- {
- "abs", "acos", "and", "asin", "atan", "atan2", "avg", "ceil", "clamp",
- "cos", "cosh", "cot", "csc", "deg2grad", "deg2rad", "equal", "erf", "erfc",
- "exp", "false", "floor", "for", "frac", "grad2deg", "hyp", "if", "ilike",
- "in", "inrange", "like", "log", "log10", "logn", "max", "min", "mod", "mul",
- "nand", "nor", "not", "not_equal", "or", "pow", "rad2deg", "root", "round",
- "roundn", "sec", "sgn", "shl", "shr", "sin", "sinh", "sqrt", "sum", "tan",
- "tanh", "true", "trunc", "while", "xor"
- };
- static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
- inline bool is_reserved_word(const std::string& symbol)
- {
- for (std::size_t i = 0; i < reserved_words_size; ++i)
- {
- if (imatch(symbol,reserved_words[i]))
- {
- return true;
- }
- }
- return false;
- }
- inline bool is_reserved_symbol(const std::string& symbol)
- {
- for (std::size_t i = 0; i < reserved_symbols_size; ++i)
- {
- if (imatch(symbol,reserved_symbols[i]))
- {
- return true;
- }
- }
- return false;
- }
- struct cs_match { static inline bool cmp(const char c0, const char c1) { return c0 == c1; } };
- struct cis_match { static inline bool cmp(const char c0, const char c1) { return std::tolower(c0) == std::tolower(c1); } };
- template <typename Iterator, typename Compare>
- inline bool match_impl(const Iterator pattern_begin,
- const Iterator pattern_end,
- const Iterator data_begin,
- const Iterator data_end,
- const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
- const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
- {
- if (0 == std::distance(data_begin,data_end)) return false;
- Iterator d_itr = data_begin;
- Iterator p_itr = pattern_begin;
- Iterator c_itr = data_begin;
- Iterator m_itr = data_begin;
- while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
- {
- if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr)))
- {
- return false;
- }
- ++p_itr;
- ++d_itr;
- }
- while (data_end != d_itr)
- {
- if (zero_or_more == (*p_itr))
- {
- if (pattern_end == (++p_itr))
- {
- return true;
- }
- m_itr = p_itr;
- c_itr = d_itr;
- ++c_itr;
- }
- else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr)))
- {
- ++p_itr;
- ++d_itr;
- }
- else
- {
- p_itr = m_itr;
- d_itr = c_itr++;
- }
- }
- while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr;
- return (p_itr == pattern_end);
- }
- inline bool wc_match(const std::string& wild_card,
- const std::string& str)
- {
- return match_impl<const char*,cs_match>(wild_card.data(),
- wild_card.data() + wild_card.size(),
- str.data(),
- str.data() + str.size(),
- '*',
- '?');
- }
- inline bool wc_imatch(const std::string& wild_card,
- const std::string& str)
- {
- return match_impl<const char*,cis_match>(wild_card.data(),
- wild_card.data() + wild_card.size(),
- str.data(),
- str.data() + str.size(),
- '*',
- '?');
- }
- static const double pow10[] = {
- 1.0,
- 10.0,
- 100.0,
- 1000.0,
- 10000.0,
- 100000.0,
- 1000000.0,
- 10000000.0,
- 100000000.0,
- 1000000000.0,
- 10000000000.0,
- 100000000000.0,
- 1000000000000.0,
- 10000000000000.0,
- 100000000000000.0,
- 1000000000000000.0,
- 10000000000000000.0,
- };
- namespace numeric
- {
- namespace constant
- {
- static const double e = 2.718281828459045235360;
- static const double pi = 3.141592653589793238462;
- static const double pi_2 = 1.570796326794896619231;
- static const double pi_4 = 0.785398163397448309616;
- static const double pi_180 = 0.017453292519943295769;
- static const double _1_pi = 0.318309886183790671538;
- static const double _2_pi = 0.636619772367581343076;
- static const double _180_pi = 57.295779513082320876798;
- }
- namespace details
- {
- struct unknown_type_tag {};
- struct real_type_tag {};
- struct int_type_tag {};
- template <typename T>
- struct number_type { typedef unknown_type_tag type; };
- #define exprtk_register_real_type_tag(T)\
- template<> struct number_type<T> { typedef real_type_tag type; };
- #define exprtk_register_int_type_tag(T)\
- template<> struct number_type<T> { typedef int_type_tag type; };
- exprtk_register_real_type_tag(double)
- exprtk_register_real_type_tag(long double)
- exprtk_register_real_type_tag(float)
- exprtk_register_int_type_tag(short)
- exprtk_register_int_type_tag(int)
- exprtk_register_int_type_tag(long long int)
- exprtk_register_int_type_tag(unsigned short)
- exprtk_register_int_type_tag(unsigned int)
- exprtk_register_int_type_tag(unsigned long long int)
- #undef exprtk_register_real_type_tag
- #undef exprtk_register_int_type_tag
- template <typename T>
- inline T equal_impl(const T& v0, const T& v1, real_type_tag)
- {
- static const T epsilon = T(0.00000000001);
- return (std::abs(v0 - v1) <= (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? T(1) : T(0);
- }
- template <typename T>
- inline T equal_impl(const T& v0, const T& v1, int_type_tag)
- {
- return (v0 == v1) ? 1 : 0;
- }
- template <typename T>
- inline T nequal_impl(const T& v0, const T& v1, real_type_tag)
- {
- static const T epsilon = T(0.0000000001);
- return (std::abs(v0 - v1) > (std::max(T(1),std::max(std::abs(v0),std::abs(v1))) * epsilon)) ? T(1) : T(0);
- }
- template <typename T>
- inline T nequal_impl(const T& v0, const T& v1, int_type_tag)
- {
- return (v0 != v1) ? 1 : 0;
- }
- template <typename T>
- inline T modulus_impl(const T& v0, const T& v1, real_type_tag)
- {
- return std::fmod(v0,v1);
- }
- template <typename T>
- inline T modulus_impl(const T& v0, const T& v1, int_type_tag)
- {
- return v0 % v1;
- }
- template <typename T>
- inline T pow_impl(const T& v0, const T& v1, real_type_tag)
- {
- return std::pow(v0,v1);
- }
- template <typename T>
- inline T pow_impl(const T& v0, const T& v1, int_type_tag)
- {
- return std::pow(static_cast<double>(v0),static_cast<double>(v1));
- }
- template <typename T>
- inline T logn_impl(const T& v0, const T& v1, real_type_tag)
- {
- return std::log(v0) / std::log(v1);
- }
- template <typename T>
- inline T logn_impl(const T& v0, const T& v1, int_type_tag)
- {
- return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
- }
- template <typename T>
- inline T root_impl(const T& v0, const T& v1, real_type_tag)
- {
- return std::pow(v0,T(1)/v1);
- }
- template <typename T>
- inline T root_impl(const T& v0, const T& v1, int_type_tag)
- {
- return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
- }
- template <typename T>
- inline T roundn_impl(const T& v0, const T& v1, real_type_tag)
- {
- return T(std::floor((v0 * pow10[(int)std::floor(v1)]) + T(0.5)) / T(pow10[(int)std::floor(v1)]));
- }
- template <typename T>
- inline T roundn_impl(const T& v0, const T&, int_type_tag)
- {
- return v0;
- }
- template <typename T>
- inline T hyp_impl(const T& v0, const T& v1, real_type_tag)
- {
- return std::sqrt((v0 * v0) + (v1 * v1));
- }
- template <typename T>
- inline T hyp_impl(const T& v0, const T& v1, int_type_tag)
- {
- return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
- }
- template <typename T>
- inline T atan2_impl(const T& v0, const T& v1, real_type_tag)
- {
- return std::atan2(v0,v1);
- }
- template <typename T>
- inline T atan2_impl(const T&, const T&, int_type_tag)
- {
- return 0;
- }
- template <typename T>
- inline T shr_impl(const T& v0, const T& v1, real_type_tag)
- {
- return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
- }
- template <typename T>
- inline T shr_impl(const T& v0, const T& v1, int_type_tag)
- {
- return v0 >> v1;
- }
- template <typename T>
- inline T shl_impl(const T& v0, const T& v1, real_type_tag)
- {
- return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
- }
- template <typename T>
- inline T shl_impl(const T& v0, const T& v1, int_type_tag)
- {
- return v0 << v1;
- }
- template <typename T>
- inline T sgn_impl(const T& v, real_type_tag)
- {
- if (v > T(0.0)) return T(+1.0);
- else if (v < T(0.0)) return T(-1.0);
- else return T( 0.0);
- }
- template <typename T>
- inline T sgn_impl(const T& v, int_type_tag)
- {
- if (v > T(0)) return T(+1);
- else if (v < T(0)) return T(-1);
- else return T( 0);
- }
- template <typename T>
- inline T xor_impl(const T& v0, const T& v1, real_type_tag)
- {
- return v0 != v1;
- }
- template <typename T>
- inline T xor_impl(const T& v0, const T& v1, int_type_tag)
- {
- return v0 ^ v1;
- }
- template <typename T>
- inline T erf_impl(T v, real_type_tag)
- {
- #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
- //Note: This should not be required for mscv 11.+
- T a1 = T(+0.254829592);
- T a2 = T(-0.284496736);
- T a3 = T(+1.421413741);
- T a4 = T(-1.453152027);
- T a5 = T(+1.061405429);
- T p = T( 0.327591100);
- T sign = T(1.0);
- if (v < 0)
- {
- sign = -1;
- v = abs(v);
- }
- T t = T(1.0) / (T(1.0) + p * v);
- T y = T(1.0) - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * std::exp(-v * v);
- return sign * y;
- #else
- return ::erf(v);
- #endif
- }
- template <typename T>
- inline T erf_impl(T v, int_type_tag)
- {
- return erf_impl(static_cast<double>(v),real_type_tag());
- }
- template <typename T>
- inline T erfc_impl(T v, real_type_tag)
- {
- #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
- return T(1.0) - erf_impl(v,real_type_tag());
- #else
- return ::erfc(v);
- #endif
- }
- template <typename T>
- inline T erfc_impl(T v, int_type_tag)
- {
- return erfc_impl(static_cast<double>(v),real_type_tag());
- }
- template <typename T> inline T abs_impl(const T v, real_type_tag) { return std::abs (v); }
- template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
- template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
- template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
- template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
- template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
- template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
- template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
- template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
- template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
- template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
- template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
- template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
- template <typename T> inline T round_impl(const T v, real_type_tag) { return std::floor(v + T(0.5)); }
- template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
- template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
- template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
- template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
- template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
- template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
- template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
- template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
- template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
- template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
- template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); }
- template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); }
- template <typename T> inline T notl_impl(const T v, real_type_tag) { return (v != T(0) ? T(0) : T(1)); }
- template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
- template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
- template <typename T> inline T abs_impl(const T v, int_type_tag) { return std::abs (v); }
- template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
- template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
- template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
- template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
- template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
- template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
- template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
- template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
- template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
- template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
- template <typename T> inline T frac_impl(const T v, int_type_tag) { return T(0); }
- template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
- template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
- template <typename T>
- inline bool is_integer_impl(const T& v, real_type_tag)
- {
- return (T(0.0) == std::fmod(v,T(1.0)));
- }
- template <typename T>
- inline bool is_integer_impl(const T&, int_type_tag)
- {
- return true;
- }
- }
- template <typename Type>
- struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
- template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
- template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
- template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
- template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
- template <typename T>
- inline T equal(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::equal_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T nequal(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::nequal_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T modulus(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::modulus_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T pow(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::pow_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T logn(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::logn_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T root(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::root_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T roundn(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::roundn_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T hyp(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::hyp_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T atan2(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::atan2_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T shr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::shr_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T shl(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::shl_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T xor_opr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return details::xor_impl(v0,v1,num_type);
- }
- template <typename T>
- inline bool is_integer(const T v)
- {
- typename details::number_type<T>::type num_type;
- return details::is_integer_impl(v,num_type);
- }
- template <typename T, unsigned int N>
- struct fast_exp
- {
- static inline T result(T v)
- {
- unsigned int k = N;
- T l = T(1);
- while (k)
- {
- if (k & 1)
- {
- l *= v;
- --k;
- }
- v *= v;
- k >>= 1;
- }
- return l;
- }
- };
- 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; } };
- template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
- 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; } };
- template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
- 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; } };
- template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
- template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
- template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
- template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v; } };
- template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } };
- template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } };
- #define exprtk_define_unary_function(FunctionName) \
- template <typename T> \
- inline T FunctionName (const T v) \
- { \
- typename details::number_type<T>::type num_type; \
- return details:: FunctionName##_impl(v,num_type); \
- }
- exprtk_define_unary_function(abs )
- exprtk_define_unary_function(acos )
- exprtk_define_unary_function(asin )
- exprtk_define_unary_function(atan )
- exprtk_define_unary_function(ceil )
- exprtk_define_unary_function(cos )
- exprtk_define_unary_function(cosh )
- exprtk_define_unary_function(exp )
- exprtk_define_unary_function(floor)
- exprtk_define_unary_function(log )
- exprtk_define_unary_function(log10)
- exprtk_define_unary_function(neg )
- exprtk_define_unary_function(pos )
- exprtk_define_unary_function(round)
- exprtk_define_unary_function(sin )
- exprtk_define_unary_function(sinh )
- exprtk_define_unary_function(sqrt )
- exprtk_define_unary_function(tan )
- exprtk_define_unary_function(tanh )
- exprtk_define_unary_function(cot )
- exprtk_define_unary_function(sec )
- exprtk_define_unary_function(csc )
- exprtk_define_unary_function(r2d )
- exprtk_define_unary_function(d2r )
- exprtk_define_unary_function(d2g )
- exprtk_define_unary_function(g2d )
- exprtk_define_unary_function(notl )
- exprtk_define_unary_function(sgn )
- exprtk_define_unary_function(erf )
- exprtk_define_unary_function(erfc )
- exprtk_define_unary_function(frac )
- exprtk_define_unary_function(trunc)
- #undef exprtk_define_unary_function
- }
- template <typename Iterator, typename Type>
- static inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, Type& result)
- {
- if (end == itr) return false;
- Type t = 0;
- bool negative = false;
- if ('+' == (*itr))
- ++itr;
- else if ('-' == (*itr))
- {
- ++itr;
- negative = true;
- }
- if (end == itr)
- return false;
- unsigned int digit_count = 0;
- while ((end != itr) && ('0' == (*itr))) ++itr;
- bool return_result = true;
- while (end != itr)
- {
- const unsigned char digit = (*itr - '0');
- if (digit > 9)
- {
- return_result = false;
- break;
- }
- if ((++digit_count) <= numeric::numeric_info<Type>::bound_length)
- {
- t *= 10;
- t += digit;
- }
- else
- {
- typedef unsigned long long int base_type;
- static const base_type max_limit = +std::numeric_limits<Type>::max();
- static const base_type min_limit = -std::numeric_limits<Type>::min();
- base_type tmp = static_cast<base_type>(t) * 10 + digit;
- if (negative && static_cast<base_type>(tmp) > min_limit)
- return_result = false;
- else if (static_cast<base_type>(tmp) > max_limit)
- return_result = false;
- t = static_cast<Type>(tmp);
- }
- ++itr;
- }
- result = static_cast<Type>((negative) ? -t : t);
- return return_result;
- }
- template <typename Iterator, typename T>
- static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
- {
- typedef typename std::iterator_traits<Iterator>::value_type type;
- static const std::size_t nan_length = 3;
- if (std::distance(itr,end) != static_cast<int>(nan_length))
- return false;
- if (static_cast<type>('n') == (*itr))
- {
- if ((static_cast<type>('a') != *(itr + 1)) || (static_cast<type>('n') != *(itr + 2)))
- {
- return false;
- }
- }
- else if ((static_cast<type>('A') != *(itr + 1)) || (static_cast<type>('N') != *(itr + 2)))
- {
- return false;
- }
- t = std::numeric_limits<T>::quiet_NaN();
- return true;
- }
- template <typename Iterator, typename T>
- static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
- {
- static const char inf_uc[] = "INFINITY";
- static const char inf_lc[] = "infinity";
- static const std::size_t inf_length = 8;
- const std::size_t length = std::distance(itr,end);
- if ((3 != length) && (inf_length != length))
- return false;
- const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
- while (end != itr)
- {
- if (*inf_itr == static_cast<char>(*itr))
- {
- ++itr;
- ++inf_itr;
- continue;
- }
- else
- return false;
- }
- if (negative)
- t = -std::numeric_limits<T>::infinity();
- else
- t = std::numeric_limits<T>::infinity();
- return true;
- }
- template <typename Iterator, typename T>
- inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t)
- {
- if (end == itr_external)
- return false;
- Iterator itr = itr_external;
- double d = 0.0;
- bool negative = false;
- if ('+' == (*itr))
- ++itr;
- else if ('-' == (*itr))
- {
- ++itr;
- negative = true;
- }
- if (end == itr)
- return false;
- if (('I' <= (*itr)) && ((*itr) <= 'n'))
- {
- if (('i' == (*itr)) || ('I' == (*itr)))
- {
- return parse_inf(itr,end,t,negative);
- }
- else if (('n' == (*itr)) || ('N' == (*itr)))
- {
- return parse_nan(itr,end,t);
- }
- else
- return false;
- }
- bool instate = false;
- int pre_decimal = 0;
- if ('.' != (*itr))
- {
- const Iterator curr = itr;
- while ((end != itr) && ('0' == (*itr))) ++itr;
- const Iterator post_zero_cull_itr = itr;
- unsigned char digit = 0;
- #define parse_digit_1 \
- if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; if (end == ++itr) break; \
- #define parse_digit_2 \
- if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; ++itr;\
- while (end != itr)
- {
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_2
- }
- #undef parse_digit_1
- #undef parse_digit_2
- if (curr != itr) instate = true;
- pre_decimal = static_cast<int>(std::distance(post_zero_cull_itr,itr));
- }
- int exponent = 0;
- if (end != itr)
- {
- if ('.' == (*itr))
- {
- ++itr;
- const Iterator curr = itr;
- unsigned char digit = 0;
- #define parse_digit_1 \
- if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; if (end == ++itr) break; \
- #define parse_digit_2 \
- if ((digit = static_cast<unsigned char>((*itr) - '0')) < 10) { d *= 10.0; d += digit; } else break; ++itr;\
- while (end != itr)
- {
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_1
- parse_digit_2
- }
- #undef parse_digit_1
- #undef parse_digit_2
- if (curr != itr) instate = true;
- exponent -= static_cast<int>(std::distance(curr,itr));
- }
- if (end != itr)
- {
- typename std::iterator_traits<Iterator>::value_type c = (*itr);
- if (('e' == c) || ('E' == c))
- {
- ++itr;
- int exp = 0;
- if (!string_to_type_converter_impl_ref(itr,end,exp))
- {
- if (end == itr)
- return false;
- else
- c = (*itr);
- }
- if (
- (exp < numeric::numeric_info<T>::min_exp) ||
- (numeric::numeric_info<T>::max_exp < exp)
- )
- return false;
- exponent += exp;
- }
- if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
- ++itr;
- else if ('#' == c)
- {
- ++itr;
- if (end == itr)
- return false;
- if ((10.0 != d) || (exponent != -1))
- return false;
- if (('I' <= (*itr)) && ((*itr) <= 'n'))
- {
- if (('i' == (*itr)) || ('I' == (*itr)))
- {
- return parse_inf(itr,end,t,negative);
- }
- else if (('n' == (*itr)) || ('N' == (*itr)))
- {
- return parse_nan(itr,end,t);
- }
- else
- return false;
- }
- return false;
- }
- }
- }
- if ((end != itr) || (!instate))
- return false;
- if (0 != exponent)
- {
- if (
- (std::numeric_limits<T>::max_exponent10 < (exponent + pre_decimal)) ||
- (std::numeric_limits<T>::min_exponent10 > (exponent + pre_decimal))
- )
- {
- return false;
- }
- const int e = std::abs(exponent);
- static const double fract10[] =
- {
- 0.0,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
- };
- static const std::size_t fract10_size = sizeof(fract10) / sizeof(double);
- if (d != 0.0)
- {
- if (static_cast<std::size_t>(e) < fract10_size)
- {
- if (exponent > 0)
- d *= fract10[e];
- else
- d /= fract10[e];
- }
- else
- d *= std::pow(10.0, 1.0 * exponent);
- }
- }
- t = static_cast<T>((negative) ? -d : d);
- return true;
- }
- template <typename T>
- inline bool string_to_real(const std::string& s, T& t)
- {
- const char* begin = s.data();
- const char* end = s.data() + s.size();
- return string_to_real(begin,end,t);
- }
- } // namespace details
- namespace lexer
- {
- struct token
- {
- enum token_type
- {
- e_none = 0,
- e_error = 1,
- e_err_symbol = 2,
- e_err_number = 3,
- e_err_string = 4,
- e_err_sfunc = 5,
- e_eof = 6,
- e_number = 7,
- e_symbol = 8,
- e_string = 9,
- e_assign = 10,
- e_shr = 11,
- e_shl = 12,
- e_lte = 13,
- e_ne = 14,
- e_gte = 15,
- e_lt = '<',
- e_gt = '>',
- e_eq = '=',
- e_rbracket = ')',
- e_lbracket = '(',
- e_rsqrbracket = ']',
- e_lsqrbracket = '[',
- e_rcrlbracket = '}',
- e_lcrlbracket = '{',
- e_comma = ',',
- e_add = '+',
- e_sub = '-',
- e_div = '/',
- e_mul = '*',
- e_mod = '%',
- e_pow = '^',
- e_colon = ':'
- };
- token()
- : type(e_none),
- value(""),
- position(std::numeric_limits<std::size_t>::max())
- {}
- void clear()
- {
- type = e_none;
- value = "";
- position = std::numeric_limits<std::size_t>::max();
- }
- template <typename Iterator>
- inline token& set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
- {
- type = tt;
- value.assign(begin,end);
- if (base_begin)
- position = std::distance(base_begin,begin);
- return *this;
- }
- template <typename Iterator>
- inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
- {
- type = e_symbol;
- value.assign(begin,end);
- if (base_begin)
- position = std::distance(base_begin,begin);
- …
Large files files are truncated, but you can click here to view the full file