/exprtk.hpp
C++ Header | 15710 lines | 13003 code | 2594 blank | 113 comment | 1608 complexity | 304dd65fa1664a3781c0e72ef5a01b4d 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-2015) *
- * 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) (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) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
- * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
- * *
- ******************************************************************
- */
- #ifndef INCLUDE_EXPRTK_HPP
- #define INCLUDE_EXPRTK_HPP
- #include <algorithm>
- #include <cctype>
- #include <cmath>
- #include <complex>
- #include <cstdio>
- #include <cstdlib>
- #include <deque>
- #include <exception>
- #include <functional>
- #include <iterator>
- #include <limits>
- #include <list>
- #include <map>
- #include <set>
- #include <stack>
- #include <stdexcept>
- #include <string>
- #include <utility>
- #include <vector>
- namespace exprtk
- {
- #if exprtk_enable_debugging
- #define exprtk_debug(params) printf params
- #else
- #define exprtk_debug(params) (void)0
- #endif
- 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) || ('&' == 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) &&
- ('\'' != 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 (4 == symbol.size()) &&
- ('$' == symbol[0]) &&
- imatch('f',symbol[1]) &&
- is_digit(symbol[2]) &&
- is_digit(symbol[3]);
- }
- inline const char& front(const std::string& s)
- {
- return s[0];
- }
- inline const char& back(const std::string& s)
- {
- return s[s.size() - 1];
- }
- inline std::string to_str(int i)
- {
- if (0 == i)
- return std::string("0");
- std::string result;
- if (i < 0)
- {
- for ( ; i; i /= 10)
- {
- result += '0' + char(-(i % 10));
- }
- result += '-';
- }
- else
- {
- for ( ; i; i /= 10)
- {
- result += '0' + char(i % 10);
- }
- }
- std::reverse(result.begin(), result.end());
- return result;
- }
- inline bool is_hex_digit(const std::string::value_type digit)
- {
- return (('0' <= digit) && (digit <= '9')) ||
- (('A' <= digit) && (digit <= 'F')) ||
- (('a' <= digit) && (digit <= 'f')) ;
- }
- inline unsigned char hex_to_bin(unsigned char h)
- {
- if (('0' <= h) && (h <= '9'))
- return (h - '0');
- else
- return (std::toupper(h) - 'A');
- }
- template <typename Iterator>
- inline void parse_hex(Iterator& itr, Iterator end, std::string::value_type& result)
- {
- if (
- (end != (itr )) &&
- (end != (itr + 1)) &&
- (end != (itr + 2)) &&
- (end != (itr + 3)) &&
- ('0' == *(itr )) &&
- (
- ('x' == *(itr + 1)) ||
- ('X' == *(itr + 1))
- ) &&
- (is_hex_digit(*(itr + 2))) &&
- (is_hex_digit(*(itr + 3)))
- )
- {
- result = hex_to_bin(*(itr + 2)) << 4 | hex_to_bin(*(itr + 3));
- itr += 3;
- }
- else
- result = '\0';
- }
- inline void cleanup_escapes(std::string& s)
- {
- typedef std::string::iterator str_itr_t;
- str_itr_t itr1 = s.begin();
- str_itr_t itr2 = s.begin();
- str_itr_t end = s.end ();
- std::size_t removal_count = 0;
- while (end != itr1)
- {
- if ('\\' == (*itr1))
- {
- ++removal_count;
- if (end == ++itr1)
- break;
- else if ('\\' != (*itr1))
- {
- switch (*itr1)
- {
- case 'n' : (*itr1) = '\n'; break;
- case 'r' : (*itr1) = '\r'; break;
- case 't' : (*itr1) = '\t'; break;
- case '0' : parse_hex(itr1, end, (*itr1));
- removal_count += 3;
- break;
- }
- continue;
- }
- }
- if (itr1 != itr2)
- {
- (*itr2) = (*itr1);
- }
- ++itr1;
- ++itr2;
- }
- s.resize(s.size() - removal_count);
- }
- class build_string
- {
- public:
- build_string(const std::size_t& initial_size = 64)
- {
- data_.reserve(initial_size);
- }
- inline build_string& operator << (const std::string& s)
- {
- data_ += s;
- return (*this);
- }
- inline build_string& operator << (const char* s)
- {
- data_ += std::string(s);
- return (*this);
- }
- inline operator std::string () const
- {
- return data_;
- }
- inline std::string as_string() const
- {
- return data_;
- }
- private:
- std::string data_;
- };
- 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)
- {
- const char c1 = static_cast<char>(std::tolower(s1[i]));
- const char c2 = static_cast<char>(std::tolower(s2[i]));
- if (c1 > c2)
- return false;
- else if (c1 < c2)
- return true;
- }
- return s1.size() < s2.size();
- }
- };
- static const std::string reserved_words[] =
- {
- "break", "case", "continue", "default", "false", "for",
- "if", "else", "ilike", "in", "like", "and", "nand", "nor",
- "not", "null", "or", "repeat", "return", "shl", "shr",
- "swap", "switch", "true", "until", "var", "while", "xnor",
- "xor", "&", "|"
- };
- static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
- static const std::string reserved_symbols[] =
- {
- "abs", "acos", "acosh", "and", "asin", "asinh", "atan",
- "atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
- "continue", "cos", "cosh", "cot", "csc", "default",
- "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp",
- "expm1", "false", "floor", "for", "frac", "grad2deg",
- "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
- "like", "log", "log10", "log2", "logn", "log1p", "mand",
- "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
- "not", "not_equal", "null", "or", "pow", "rad2deg",
- "repeat", "return", "root", "round", "roundn", "sec", "sgn",
- "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
- "switch", "tan", "tanh", "true", "trunc", "until", "var",
- "while", "xnor", "xor", "&", "|"
- };
- static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
- static const std::string base_function_list[] =
- {
- "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
- "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
- "csc", "equal", "erf", "erfc", "exp", "expm1", "floor",
- "frac", "hypot", "iclamp", "like", "log", "log10", "log2",
- "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul",
- "ncdf", "pow", "root", "round", "roundn", "sec", "sgn",
- "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
- "trunc", "not_equal", "inrange", "deg2grad", "deg2rad",
- "rad2deg", "grad2deg"
- };
- static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
- static const std::string logic_ops_list[] =
- {
- "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
- };
- static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
- static const std::string cntrl_struct_list[] =
- {
- "for", "if", "repeat", "switch", "while"
- };
- static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / 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;
- }
- inline bool is_base_function(const std::string& function_name)
- {
- for (std::size_t i = 0; i < base_function_list_size; ++i)
- {
- if (imatch(function_name,base_function_list[i]))
- {
- return true;
- }
- }
- return false;
- }
- inline bool is_control_struct(const std::string& cntrl_strct)
- {
- for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
- {
- if (imatch(cntrl_strct,cntrl_struct_list[i]))
- {
- return true;
- }
- }
- return false;
- }
- inline bool is_logic_opr(const std::string& lgc_opr)
- {
- for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
- {
- if (imatch(lgc_opr,logic_ops_list[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(),
- '*',
- '?');
- }
- inline bool sequence_match(const std::string& pattern,
- const std::string& str,
- std::size_t& diff_index,
- char& diff_value)
- {
- if (str.empty() || pattern.empty())
- return false;
- else if ('*' == pattern[0])
- return false;
- typedef std::string::const_iterator itr_t;
- itr_t p_itr = pattern.begin();
- itr_t s_itr = str .begin();
- itr_t p_end = pattern.end();
- itr_t s_end = str .end();
- while ((s_end != s_itr) && (p_end != p_itr))
- {
- if ('*' == (*p_itr))
- {
- const char target = std::toupper(*(p_itr - 1));
- if ('*' == target)
- {
- diff_index = std::distance(str.begin(),s_itr);
- diff_value = std::toupper(*p_itr);
- return false;
- }
- else
- ++p_itr;
- while (s_itr != s_end)
- {
- if (target != std::toupper(*s_itr))
- break;
- else
- ++s_itr;
- }
- continue;
- }
- else if (
- ('?' != *p_itr) &&
- std::toupper(*p_itr) != std::toupper(*s_itr)
- )
- {
- diff_index = std::distance(str.begin(),s_itr);
- diff_value = std::toupper(*p_itr);
- return false;
- }
- ++p_itr;
- ++s_itr;
- }
- return (
- (s_end == s_itr) &&
- (
- (p_end == p_itr) ||
- ('*' == *p_itr)
- )
- );
- }
- static const double pow10[] = {
- 1.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
- };
- static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
- 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;
- static const double log2 = 0.693147180559945309417;
- static const double sqrt2 = 1.414213562373095048801;
- }
- namespace details
- {
- struct unknown_type_tag {};
- struct real_type_tag {};
- struct complex_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_complex_type_tag(T) \
- template<> struct number_type<std::complex<T> > \
- { typedef complex_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_complex_type_tag(double )
- exprtk_register_complex_type_tag(long double)
- exprtk_register_complex_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>
- struct epsilon_type
- {
- static inline T value()
- {
- const T epsilon = T(0.0000000001);
- return epsilon;
- }
- };
- template <>
- struct epsilon_type <float>
- {
- static inline float value()
- {
- const float epsilon = float(0.000001f);
- return epsilon;
- }
- };
- template <>
- struct epsilon_type <long double>
- {
- static inline long double value()
- {
- const long double epsilon = (long double)(0.000000000001);
- return epsilon;
- }
- };
- template <typename T>
- inline bool is_nan_impl(const T v, real_type_tag)
- {
- return std::not_equal_to<T>()(v,v);
- }
- template <typename T>
- inline int to_int32_impl(const T v, real_type_tag)
- {
- return static_cast<int>(v);
- }
- template <typename T>
- inline long long int to_int64_impl(const T v, real_type_tag)
- {
- return static_cast<long long int>(v);
- }
- template <typename T>
- inline bool is_true_impl(const T v)
- {
- return std::not_equal_to<T>()(T(0),v);
- }
- template <typename T>
- inline bool is_false_impl(const T v)
- {
- return std::equal_to<T>()(T(0),v);
- }
- template <typename T>
- inline T abs_impl(const T v, real_type_tag)
- {
- return ((v >= T(0)) ? v : -v);
- }
- template <typename T>
- inline T min_impl(const T v0, const T v1, real_type_tag)
- {
- return std::min<T>(v0,v1);
- }
- template <typename T>
- inline T max_impl(const T v0, const T v1, real_type_tag)
- {
- return std::max<T>(v0,v1);
- }
- template <typename T>
- inline T equal_impl(const T v0, const T v1, real_type_tag)
- {
- const T epsilon = epsilon_type<T>::value();
- 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);
- }
- inline float equal_impl(const float v0, const float v1, real_type_tag)
- {
- const float epsilon = epsilon_type<float>::value();
- 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;
- }
- 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 expm1_impl(const T v, real_type_tag)
- {
- // return std::expm1<T>(v);
- if (abs_impl(v,real_type_tag()) < T(0.00001))
- return v + (T(0.5) * v * v);
- else
- return std::exp(v) - T(1);
- }
- template <typename T>
- inline T expm1_impl(const T v, int_type_tag)
- {
- return T(std::exp<double>(v)) - T(1);
- }
- template <typename T>
- inline T nequal_impl(const T v0, const T v1, real_type_tag)
- {
- typedef real_type_tag rtg;
- const T epsilon = epsilon_type<T>::value();
- 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);
- }
- inline float nequal_impl(const float v0, const float v1, real_type_tag)
- {
- typedef real_type_tag rtg;
- const float epsilon = epsilon_type<float>::value();
- 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;
- }
- 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 log1p_impl(const T v, real_type_tag)
- {
- if (v > T(-1))
- {
- if (abs_impl(v,real_type_tag()) > T(0.0001))
- {
- return std::log(T(1) + v);
- }
- else
- return (T(-0.5) * v + T(1)) * v;
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- template <typename T>
- inline T log1p_impl(const T v, int_type_tag)
- {
- if (v > T(-1))
- {
- return std::log(T(1) + v);
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- 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 round_impl(const T v, real_type_tag)
- {
- return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
- }
- template <typename T>
- inline T roundn_impl(const T v0, const T v1, real_type_tag)
- {
- const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1)));
- const T p10 = T(pow10[index]);
- if (v0 < T(0))
- return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
- else
- return T(std::floor((v0 * p10) + T(0.5)) / p10);
- }
- template <typename T>
- inline T roundn_impl(const T v0, const T, int_type_tag)
- {
- return v0;
- }
- template <typename T>
- inline T hypot_impl(const T v0, const T v1, real_type_tag)
- {
- return std::sqrt((v0 * v0) + (v1 * v1));
- }
- template <typename T>
- inline T hypot_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)) return T(+1);
- else if (v < T(0)) return T(-1);
- else return T( 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 and_impl(const T v0, const T v1, real_type_tag)
- {
- return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
- }
- template <typename T>
- inline T and_impl(const T v0, const T v1, int_type_tag)
- {
- return v0 && v1;
- }
- template <typename T>
- inline T nand_impl(const T v0, const T v1, real_type_tag)
- {
- return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
- }
- template <typename T>
- inline T nand_impl(const T v0, const T v1, int_type_tag)
- {
- return !(v0 && v1);
- }
- template <typename T>
- inline T or_impl(const T v0, const T v1, real_type_tag)
- {
- return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
- }
- template <typename T>
- inline T or_impl(const T v0, const T v1, int_type_tag)
- {
- return (v0 || v1);
- }
- template <typename T>
- inline T nor_impl(const T v0, const T v1, real_type_tag)
- {
- return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
- }
- template <typename T>
- inline T nor_impl(const T v0, const T v1, int_type_tag)
- {
- return !(v0 || v1);
- }
- template <typename T>
- inline T xor_impl(const T v0, const T v1, real_type_tag)
- {
- return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
- }
- template <typename T>
- inline T xor_impl(const T v0, const T v1, int_type_tag)
- {
- return v0 ^ v1;
- }
- template <typename T>
- inline T xnor_impl(const T v0, const T v1, real_type_tag)
- {
- const bool v0_true = is_true_impl(v0);
- const bool v1_true = is_true_impl(v1);
- if ((v0_true && v1_true) || (!v0_true && !v1_true))
- return T(1);
- else
- return T(0);
- }
- template <typename T>
- inline T xnor_impl(const T v0, const T v1, int_type_tag)
- {
- const bool v0_true = is_true_impl(v0);
- const bool v1_true = is_true_impl(v1);
- if ((v0_true && v1_true) || (!v0_true && !v1_true))
- return T(1);
- else
- return T(0);
- }
- template <typename T>
- inline T erf_impl(T v, real_type_tag)
- {
- #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
- // Credits: Abramowitz & Stegun Equations 7.1.25-28
- const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
- static const T c[] = {
- T( 1.26551223), T(1.00002368),
- T( 0.37409196), T(0.09678418),
- T(-0.18628806), T(0.27886807),
- T(-1.13520398), T(1.48851587),
- T(-0.82215223), T(0.17087277)
- };
- T result = T(1) - t * std::exp((-v * v) -
- c[0] + t * (c[1] + t *
- (c[2] + t * (c[3] + t *
- (c[4] + t * (c[5] + t *
- (c[6] + t * (c[7] + t *
- (c[8] + t * (c[9]))))))))));
- return (v >= T(0)) ? result : -result;
- #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) - 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 ncdf_impl(T v, real_type_tag)
- {
- T cnd = T(0.5) * (T(1) + erf_impl(
- abs_impl(v,real_type_tag()) /
- T(numeric::constant::sqrt2),real_type_tag()));
- return (v < T(0)) ? (T(1) - cnd) : cnd;
- }
- template <typename T>
- inline T ncdf_impl(T v, int_type_tag)
- {
- return ncdf_impl(static_cast<double>(v),real_type_tag());
- }
- template <typename T>
- inline T sinc_impl(T v, real_type_tag)
- {
- if (std::abs(v) >= std::numeric_limits<T>::epsilon())
- return(std::sin(v) / v);
- else
- return T(1);
- }
- template <typename T>
- inline T sinc_impl(T v, int_type_tag)
- {
- return sinc_impl(static_cast<double>(v),real_type_tag());
- }
- template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
- template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
- template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
- template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
- template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
- 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); }
- 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 log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
- 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 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 (std::not_equal_to<T>()(T(0),v) ? 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 ((v >= T(0)) ? v : -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 log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
- 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 , 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 acosh_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 asinh_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 atanh_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 std::equal_to<T>()(T(0),std::fmod(v,T(1)));
- }
- 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 int to_int32(const T v)
- {
- typename details::number_type<T>::type num_type;
- return to_int32_impl(v,num_type);
- }
- template <typename T>
- inline long long int to_int64(const T v)
- {
- typename details::number_type<T>::type num_type;
- return to_int64_impl(v,num_type);
- }
- template <typename T>
- inline bool is_nan(const T v)
- {
- typename details::number_type<T>::type num_type;
- return is_nan_impl(v,num_type);
- }
- template <typename T>
- inline T min(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return min_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T max(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return max_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T equal(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return 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 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 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 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 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 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 roundn_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T hypot(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return hypot_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 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 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 shl_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T and_opr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return and_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T nand_opr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return nand_impl(v0,v1,num_type);
- }
- template <typename T>
- …
Large files files are truncated, but you can click here to view the full file