/exprtk.hpp
C++ Header | 15710 lines | 13003 code | 2594 blank | 113 comment | 1608 complexity | 304dd65fa1664a3781c0e72ef5a01b4d MD5 | raw 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>
- inline T or_opr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return or_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T nor_opr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return nor_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 xor_impl(v0,v1,num_type);
- }
- template <typename T>
- inline T xnor_opr(const T v0, const T v1)
- {
- typename details::number_type<T>::type num_type;
- return xnor_impl(v0,v1,num_type);
- }
- template <typename T>
- inline bool is_integer(const T v)
- {
- typename details::number_type<T>::type num_type;
- return 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 FunctionName##_impl(v,num_type); \
- } \
- exprtk_define_unary_function(abs )
- exprtk_define_unary_function(acos )
- exprtk_define_unary_function(acosh)
- exprtk_define_unary_function(asin )
- exprtk_define_unary_function(asinh)
- exprtk_define_unary_function(atan )
- exprtk_define_unary_function(atanh)
- exprtk_define_unary_function(ceil )
- exprtk_define_unary_function(cos )
- exprtk_define_unary_function(cosh )
- exprtk_define_unary_function(exp )
- exprtk_define_unary_function(expm1)
- exprtk_define_unary_function(floor)
- exprtk_define_unary_function(log )
- exprtk_define_unary_function(log10)
- exprtk_define_unary_function(log2 )
- exprtk_define_unary_function(log1p)
- exprtk_define_unary_function(neg )
- exprtk_define_unary_function(pos )
- exprtk_define_unary_function(round)
- exprtk_define_unary_function(sin )
- exprtk_define_unary_function(sinc )
- 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(ncdf )
- exprtk_define_unary_function(frac )
- exprtk_define_unary_function(trunc)
- #undef exprtk_define_unary_function
- }
- template <typename T>
- inline T compute_pow10(T d, const int 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+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
- 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
- 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 int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
- const int e = std::abs(exponent);
- if (exponent >= std::numeric_limits<T>::min_exponent10)
- {
- if (e < fract10_size)
- {
- if (exponent > 0)
- return T(d * fract10[e]);
- else
- return T(d / fract10[e]);
- }
- else
- return T(d * std::pow(10.0, 10.0 * exponent));
- }
- else
- {
- d /= T(fract10[ -std::numeric_limits<T>::min_exponent10]);
- return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
- }
- }
- template <typename Iterator, typename T>
- inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result)
- {
- if (itr == end)
- return false;
- bool negative = ('-' == (*itr));
- if (negative || ('+' == (*itr)))
- {
- if (end == ++itr)
- return false;
- }
- while ((end != itr) && ('0' == (*itr))) ++itr;
- bool return_result = true;
- unsigned int digit = 0;
- const std::size_t length = std::distance(itr,end);
- if (length <= 4)
- {
- switch (length)
- {
- #ifdef exprtk_use_lut
- #define exprtk_process_digit \
- if ((digit = details::digit_table[(int)*itr++]) < 10) result = result * 10 + (digit); else { return_result = false; break; }
- #else
- #define exprtk_process_digit \
- if ((digit = (*itr++ - '0')) < 10) result = result * 10 + (digit); else { return_result = false; break; }
- #endif
- case 4 : exprtk_process_digit
- case 3 : exprtk_process_digit
- case 2 : exprtk_process_digit
- case 1 : if ((digit = (*itr - '0'))>= 10) { digit = 0; return_result = false; }
- #undef exprtk_process_digit
- }
- }
- else
- return_result = false;
- if (length && return_result)
- {
- result = result * 10 + static_cast<T>(digit);
- ++itr;
- }
- result = negative ? -result : result;
- 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, numeric::details::real_type_tag)
- {
- if (end == itr_external) return false;
- Iterator itr = itr_external;
- T d = T(0);
- bool negative = ('-' == (*itr));
- if (negative || '+' == (*itr))
- {
- if (end == ++itr)
- return false;
- }
- bool instate = false;
- #define parse_digit_1(d) \
- if ((digit = (*itr - '0')) < 10) { d = d * T(10) + digit; } else break; if (end == ++itr) break; \
- #define parse_digit_2(d) \
- if ((digit = (*itr - '0')) < 10) { d = d * T(10) + digit; } else break; ++itr; \
- if ('.' != (*itr))
- {
- const Iterator curr = itr;
- while ((end != itr) && ('0' == (*itr))) ++itr;
- unsigned int digit;
- while (end != itr)
- {
- // Note: For 'physical' superscalar architectures it
- // is advised that the following loop be: 4xPD1 and 1xPD2
- #ifdef exprtk_enable_superscalar
- parse_digit_1(d)
- parse_digit_1(d)
- #endif
- parse_digit_1(d)
- parse_digit_1(d)
- parse_digit_2(d)
- }
- if (curr != itr) instate = true;
- }
- int exponent = 0;
- if (end != itr)
- {
- if ('.' == (*itr))
- {
- const Iterator curr = ++itr;
- unsigned int digit;
- T tmp_d = T(0);
- while (end != itr)
- {
- #ifdef exprtk_enable_superscalar
- parse_digit_1(tmp_d)
- parse_digit_1(tmp_d)
- parse_digit_1(tmp_d)
- #endif
- parse_digit_1(tmp_d)
- parse_digit_1(tmp_d)
- parse_digit_2(tmp_d)
- }
- if (curr != itr)
- {
- instate = true;
- d += compute_pow10(tmp_d,-std::distance(curr,itr));
- }
- #undef parse_digit_1
- #undef parse_digit_2
- }
- if (end != itr)
- {
- typename std::iterator_traits<Iterator>::value_type c = (*itr);
- if (('e' == c) || ('E' == c))
- {
- int exp = 0;
- if (!details::string_to_type_converter_impl_ref(++itr,end,exp))
- {
- if (end == itr)
- return false;
- else
- c = (*itr);
- }
- exponent += exp;
- }
- if (end != itr)
- {
- if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
- ++itr;
- else if ('#' == c)
- {
- if (end == ++itr)
- return false;
- else 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;
- }
- else
- return false;
- }
- else 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;
- }
- else
- return false;
- }
- }
- }
- if ((end != itr) || (!instate))
- return false;
- else if (exponent)
- d = compute_pow10(d,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();
- typename numeric::details::number_type<T>::type num_type;
- return string_to_real(begin,end,t,num_type);
- }
- template <typename T>
- struct functor_t
- {
- /*
- Note: The following definitions for Type, may require tweaking
- based on the compiler and target architecture. The benchmark
- should provide enough information to make the right choice.
- */
- //typedef T Type;
- //typedef const T Type;
- typedef const T& Type;
- typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3);
- typedef T (*tfunc_t)(Type t0, Type t1, Type t2);
- typedef T (*bfunc_t)(Type t0, Type t1);
- typedef T (*ufunc_t)(Type t0);
- };
- } // 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_addass = 11,
- e_subass = 12, e_mulass = 13, e_divass = 14,
- e_modass = 15, e_shr = 16, e_shl = 17,
- e_lte = 18, e_ne = 19, e_gte = 20,
- e_swap = 21, 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 = ':',
- e_ternary = '?'
- };
- 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);
- return *this;
- }
- template <typename Iterator>
- inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
- {
- type = e_number;
- value.assign(begin,end);
- if (base_begin)
- position = std::distance(base_begin,begin);
- return *this;
- }
- template <typename Iterator>
- inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
- {
- type = e_string;
- value.assign(begin,end);
- if (base_begin)
- position = std::distance(base_begin,begin);
- return *this;
- }
- inline token& set_string(const std::string& s, const std::size_t p)
- {
- type = e_string;
- value = s;
- position = p;
- return *this;
- }
- template <typename Iterator>
- inline token& set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
- {
- if (
- (e_error == et) ||
- (e_err_symbol == et) ||
- (e_err_number == et) ||
- (e_err_string == et) ||
- (e_err_sfunc == et)
- )
- {
- type = et;
- }
- else
- type = e_error;
- value.assign(begin,end);
- if (base_begin)
- position = std::distance(base_begin,begin);
- return *this;
- }
- static inline std::string to_str(token_type t)
- {
- switch (t)
- {
- case e_none : return "NONE";
- case e_error : return "ERROR";
- case e_err_symbol : return "ERROR_SYMBOL";
- case e_err_number : return "ERROR_NUMBER";
- case e_err_string : return "ERROR_STRING";
- case e_eof : return "EOF";
- case e_number : return "NUMBER";
- case e_symbol : return "SYMBOL";
- case e_string : return "STRING";
- case e_assign : return ":=";
- case e_addass : return "+=";
- case e_subass : return "-=";
- case e_mulass : return "*=";
- case e_divass : return "/=";
- case e_modass : return "%=";
- case e_shr : return ">>";
- case e_shl : return "<<";
- case e_lte : return "<=";
- case e_ne : return "!=";
- case e_gte : return ">=";
- case e_lt : return "<";
- case e_gt : return ">";
- case e_eq : return "=";
- case e_rbracket : return ")";
- case e_lbracket : return "(";
- case e_rsqrbracket : return "]";
- case e_lsqrbracket : return "[";
- case e_rcrlbracket : return "}";
- case e_lcrlbracket : return "{";
- case e_comma : return ",";
- case e_add : return "+";
- case e_sub : return "-";
- case e_div : return "/";
- case e_mul : return "*";
- case e_mod : return "%";
- case e_pow : return "^";
- case e_colon : return ":";
- case e_ternary : return "?";
- case e_swap : return "<=>";
- default : return "UNKNOWN";
- }
- }
- inline bool is_error() const
- {
- return (
- (e_error == type) ||
- (e_err_symbol == type) ||
- (e_err_number == type) ||
- (e_err_string == type) ||
- (e_err_sfunc == type)
- );
- }
- token_type type;
- std::string value;
- std::size_t position;
- };
- class generator
- {
- public:
- typedef token token_t;
- typedef std::vector<token_t> token_list_t;
- typedef std::vector<token_t>::iterator token_list_itr_t;
- generator()
- : base_itr_(0),
- s_itr_ (0),
- s_end_ (0)
- {
- clear();
- }
- inline void clear()
- {
- base_itr_ = 0;
- s_itr_ = 0;
- s_end_ = 0;
- token_list_.clear();
- token_itr_ = token_list_.end();
- store_token_itr_ = token_list_.end();
- }
- inline bool process(const std::string& str)
- {
- base_itr_ = str.data();
- s_itr_ = str.data();
- s_end_ = str.data() + str.size();
- eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
- token_list_.clear();
- while (!is_end(s_itr_))
- {
- scan_token();
- if (token_list_.empty())
- return true;
- else if (token_list_.back().is_error())
- {
- return false;
- }
- }
- return true;
- }
- inline bool empty() const
- {
- return token_list_.empty();
- }
- inline std::size_t size() const
- {
- return token_list_.size();
- }
- inline void begin()
- {
- token_itr_ = token_list_.begin();
- store_token_itr_ = token_list_.begin();
- }
- inline void store()
- {
- store_token_itr_ = token_itr_;
- }
- inline void restore()
- {
- token_itr_ = store_token_itr_;
- }
- inline token_t& next_token()
- {
- if (token_list_.end() != token_itr_)
- {
- return *token_itr_++;
- }
- else
- return eof_token_;
- }
- inline token_t& peek_next_token()
- {
- if (token_list_.end() != token_itr_)
- {
- return *token_itr_;
- }
- else
- return eof_token_;
- }
- inline token_t& operator[](const std::size_t& index)
- {
- if (index < token_list_.size())
- return token_list_[index];
- else
- return eof_token_;
- }
- inline token_t operator[](const std::size_t& index) const
- {
- if (index < token_list_.size())
- return token_list_[index];
- else
- return eof_token_;
- }
- inline bool finished() const
- {
- return (token_list_.end() == token_itr_);
- }
- inline void insert_front(token_t::token_type tk_type)
- {
- if (
- !token_list_.empty() &&
- (token_list_.end() != token_itr_)
- )
- {
- token_t t = *token_itr_;
- t.type = tk_type;
- token_itr_ = token_list_.insert(token_itr_,t);
- }
- }
- inline std::string substr(const std::size_t& begin, const std::size_t& end)
- {
- const char* begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
- const char* end_itr = ((base_itr_ + end) < s_end_) ? (base_itr_ + end) : s_end_;
- return std::string(begin_itr,end_itr);
- }
- inline std::string remaining() const
- {
- if (finished())
- return "";
- else if (token_list_.begin() != token_itr_)
- return std::string(base_itr_ + (token_itr_ - 1)->position,s_end_);
- else
- return std::string(base_itr_ + token_itr_->position,s_end_);
- }
- private:
- inline bool is_end(const char* itr)
- {
- return (s_end_ == itr);
- }
- inline void skip_whitespace()
- {
- while (!is_end(s_itr_) && details::is_whitespace(*s_itr_))
- {
- ++s_itr_;
- }
- }
- inline void skip_comments()
- {
- #ifndef exprtk_disable_comments
- // The following comment styles are supported:
- // 1. // .... \n
- // 2. # .... \n
- // 3. /* .... */
- struct test
- {
- static inline bool comment_start(const char c0, const char c1, int& mode, int& incr)
- {
- mode = 0;
- if ('#' == c0) { mode = 1; incr = 1; }
- else if ('/' == c0)
- {
- if ('/' == c1) { mode = 1; incr = 2; }
- else if ('*' == c1) { mode = 2; incr = 2; }
- }
- return (0 != mode);
- }
- static inline bool comment_end(const char c0, const char c1, const int mode)
- {
- return (
- ((1 == mode) && ('\n' == c0)) ||
- ((2 == mode) && ( '*' == c0) && ('/' == c1))
- );
- }
- };
- int mode = 0;
- int increment = 0;
- if (is_end(s_itr_) || is_end((s_itr_ + 1)))
- return;
- else if (!test::comment_start(*s_itr_,*(s_itr_ + 1),mode,increment))
- return;
- s_itr_ += increment;
- while (!is_end(s_itr_) && !test::comment_end(*s_itr_,*(s_itr_ + 1),mode))
- {
- ++s_itr_;
- }
- if (!is_end(s_itr_))
- {
- s_itr_ += mode;
- skip_whitespace();
- skip_comments();
- }
- #endif
- }
- inline void scan_token()
- {
- skip_whitespace();
- skip_comments();
- if (is_end(s_itr_))
- {
- return;
- }
- else if (details::is_operator_char(*s_itr_))
- {
- scan_operator();
- return;
- }
- else if (details::is_letter(*s_itr_))
- {
- scan_symbol();
- return;
- }
- else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_)))
- {
- scan_number();
- return;
- }
- else if ('$' == (*s_itr_))
- {
- scan_special_function();
- return;
- }
- #ifndef exprtk_disable_string_capabilities
- else if ('\'' == (*s_itr_))
- {
- scan_string();
- return;
- }
- #endif
- else if ('~' == (*s_itr_))
- {
- token_t t;
- t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
- token_list_.push_back(t);
- ++s_itr_;
- return;
- }
- else
- {
- token_t t;
- t.set_error(token::e_error,s_itr_,s_itr_ + 2,base_itr_);
- token_list_.push_back(t);
- ++s_itr_;
- }
- }
- inline void scan_operator()
- {
- token_t t;
- const char c0 = s_itr_[0];
- if (!is_end(s_itr_ + 1))
- {
- const char c1 = s_itr_[1];
- if (!is_end(s_itr_ + 2))
- {
- const char c2 = s_itr_[2];
- if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
- {
- t.set_operator(token_t::e_swap,s_itr_,s_itr_ + 3,base_itr_);
- token_list_.push_back(t);
- s_itr_ += 3;
- return;
- }
- }
- token_t::token_type ttype = token_t::e_none;
- if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
- else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
- else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
- else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
- else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
- else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
- else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
- else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
- else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass;
- else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass;
- else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass;
- else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass;
- else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass;
- if (token_t::e_none != ttype)
- {
- t.set_operator(ttype,s_itr_,s_itr_ + 2,base_itr_);
- token_list_.push_back(t);
- s_itr_ += 2;
- return;
- }
- }
- if ('<' == c0)
- t.set_operator(token_t::e_lt ,s_itr_,s_itr_ + 1,base_itr_);
- else if ('>' == c0)
- t.set_operator(token_t::e_gt ,s_itr_,s_itr_ + 1,base_itr_);
- else if (';' == c0)
- t.set_operator(token_t::e_eof,s_itr_,s_itr_ + 1,base_itr_);
- else if ('&' == c0)
- t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
- else if ('|' == c0)
- t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
- else
- t.set_operator(token_t::token_type(c0),s_itr_,s_itr_ + 1,base_itr_);
- token_list_.push_back(t);
- ++s_itr_;
- }
- inline void scan_symbol()
- {
- const char* initial_itr = s_itr_;
- while (
- (!is_end(s_itr_)) &&
- (details::is_letter_or_digit(*s_itr_) || ((*s_itr_) == '_'))
- )
- {
- ++s_itr_;
- }
- token_t t;
- t.set_symbol(initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- }
- inline void scan_number()
- {
- /*
- Attempt to match a valid numeric value in one of the following formats:
- 1. 123456
- 2. 123.456
- 3. 123.456e3
- 4. 123.456E3
- 5. 123.456e+3
- 6. 123.456E+3
- 7. 123.456e-3
- 8. 123.456E-3
- */
- const char* initial_itr = s_itr_;
- bool dot_found = false;
- bool e_found = false;
- bool post_e_sign_found = false;
- token_t t;
- while (!is_end(s_itr_))
- {
- if ('.' == (*s_itr_))
- {
- if (dot_found)
- {
- t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- dot_found = true;
- ++s_itr_;
- continue;
- }
- else if (details::imatch('e',(*s_itr_)))
- {
- const char& c = *(s_itr_ + 1);
- if (is_end(s_itr_ + 1))
- {
- t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- else if (
- ('+' != c) &&
- ('-' != c) &&
- !details::is_digit(c)
- )
- {
- t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- e_found = true;
- ++s_itr_;
- continue;
- }
- else if (e_found && details::is_sign(*s_itr_))
- {
- if (post_e_sign_found)
- {
- t.set_error(token::e_err_number,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- post_e_sign_found = true;
- ++s_itr_;
- continue;
- }
- else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
- break;
- else
- ++s_itr_;
- }
- t.set_numeric(initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- inline void scan_special_function()
- {
- const char* initial_itr = s_itr_;
- token_t t;
- // $fdd(x,x,x) = at least 11 chars
- if (std::distance(s_itr_,s_end_) < 11)
- {
- t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- if (
- !(('$' == *s_itr_) &&
- (details::imatch ('f',*(s_itr_ + 1))) &&
- (details::is_digit(*(s_itr_ + 2))) &&
- (details::is_digit(*(s_itr_ + 3))))
- )
- {
- t.set_error(token::e_err_sfunc,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- s_itr_ += 4; // $fdd = 4chars
- t.set_symbol(initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- #ifndef exprtk_disable_string_capabilities
- inline void scan_string()
- {
- const char* initial_itr = s_itr_ + 1;
- token_t t;
- if (std::distance(s_itr_,s_end_) < 2)
- {
- t.set_error(token::e_err_string,s_itr_,s_end_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- ++s_itr_;
- bool escaped_found = false;
- bool escaped = false;
- while (!is_end(s_itr_))
- {
- if (!escaped && ('\\' == *s_itr_))
- {
- escaped_found = true;
- escaped = true;
- ++s_itr_;
- continue;
- }
- else if (!escaped)
- {
- if ('\'' == *s_itr_)
- break;
- }
- else if (escaped)
- {
- if (!is_end(s_itr_) && ('0' == *(s_itr_)))
- {
- /*
- Note: The following 'awkward' conditional is
- due to various broken msvc compilers.
- */
- #if _MSC_VER == 1600
- const bool within_range = !is_end(s_itr_ + 2) &&
- !is_end(s_itr_ + 3) ;
- #else
- const bool within_range = !is_end(s_itr_ + 1) &&
- !is_end(s_itr_ + 2) &&
- !is_end(s_itr_ + 3) ;
- #endif
- const bool x_seperator = ('x' == *(s_itr_ + 1)) ||
- ('X' == *(s_itr_ + 1)) ;
- const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
- details::is_hex_digit(*(s_itr_ + 3)) ;
- if (!within_range || !x_seperator || !both_digits)
- {
- t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- else
- s_itr_ += 3;
- }
- escaped = false;
- }
- ++s_itr_;
- }
- if (is_end(s_itr_))
- {
- t.set_error(token::e_err_string,initial_itr,s_itr_,base_itr_);
- token_list_.push_back(t);
- return;
- }
- if (!escaped_found)
- t.set_string(initial_itr,s_itr_,base_itr_);
- else
- {
- std::string parsed_string(initial_itr,s_itr_);
- details::cleanup_escapes(parsed_string);
- t.set_string(parsed_string, std::distance(base_itr_,initial_itr));
- }
- token_list_.push_back(t);
- ++s_itr_;
- return;
- }
- #endif
- private:
- token_list_t token_list_;
- token_list_itr_t token_itr_;
- token_list_itr_t store_token_itr_;
- token_t eof_token_;
- const char* base_itr_;
- const char* s_itr_;
- const char* s_end_;
- friend class token_scanner;
- friend class token_modifier;
- friend class token_inserter;
- friend class token_joiner;
- };
- class helper_interface
- {
- public:
- virtual void init() { }
- virtual void reset() { }
- virtual bool result() { return true; }
- virtual std::size_t process(generator&) { return 0; }
- virtual ~helper_interface() { }
- };
- class token_scanner : public helper_interface
- {
- public:
- virtual ~token_scanner()
- {}
- explicit token_scanner(const std::size_t& stride)
- : stride_(stride)
- {
- if (stride > 4)
- {
- throw std::invalid_argument("token_scanner() - Invalid stride value");
- }
- }
- inline std::size_t process(generator& g)
- {
- if (g.token_list_.size() >= stride_)
- {
- for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
- {
- token t;
- switch (stride_)
- {
- case 1 :
- {
- const token& t0 = g.token_list_[i];
- if (!operator()(t0))
- {
- return i;
- }
- }
- break;
- case 2 :
- {
- const token& t0 = g.token_list_[i ];
- const token& t1 = g.token_list_[i + 1];
- if (!operator()(t0,t1))
- {
- return i;
- }
- }
- break;
- case 3 :
- {
- const token& t0 = g.token_list_[i ];
- const token& t1 = g.token_list_[i + 1];
- const token& t2 = g.token_list_[i + 2];
- if (!operator()(t0,t1,t2))
- {
- return i;
- }
- }
- break;
- case 4 :
- {
- const token& t0 = g.token_list_[i ];
- const token& t1 = g.token_list_[i + 1];
- const token& t2 = g.token_list_[i + 2];
- const token& t3 = g.token_list_[i + 3];
- if (!operator()(t0,t1,t2,t3))
- {
- return i;
- }
- }
- break;
- }
- }
- }
- return (g.token_list_.size() - stride_ + 1);
- }
- virtual bool operator()(const token&)
- {
- return false;
- }
- virtual bool operator()(const token&, const token&)
- {
- return false;
- }
- virtual bool operator()(const token&, const token&, const token&)
- {
- return false;
- }
- virtual bool operator()(const token&, const token&, const token&, const token&)
- {
- return false;
- }
- private:
- std::size_t stride_;
- };
- class token_modifier : public helper_interface
- {
- public:
- inline std::size_t process(generator& g)
- {
- std::size_t changes = 0;
- for (std::size_t i = 0; i < g.token_list_.size(); ++i)
- {
- if (modify(g.token_list_[i])) changes++;
- }
- return changes;
- }
- virtual bool modify(token& t) = 0;
- };
- class token_inserter : public helper_interface
- {
- public:
- explicit token_inserter(const std::size_t& stride)
- : stride_(stride)
- {
- if (stride > 5)
- {
- throw std::invalid_argument("token_inserter() - Invalid stride value");
- }
- }
- inline std::size_t process(generator& g)
- {
- if (g.token_list_.empty())
- return 0;
- else if (g.token_list_.size() < stride_)
- return 0;
- std::size_t changes = 0;
- for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
- {
- int insert_index = -1;
- token t;
- switch (stride_)
- {
- case 1 : insert_index = insert(g.token_list_[i],t);
- break;
- case 2 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],t);
- break;
- case 3 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t);
- break;
- case 4 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],g.token_list_[i + 3],t);
- break;
- case 5 : insert_index = insert(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],g.token_list_[i + 3],g.token_list_[i + 4],t);
- break;
- }
- if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
- {
- g.token_list_.insert(g.token_list_.begin() + (i + insert_index),t);
- changes++;
- }
- }
- return changes;
- }
- inline virtual int insert(const token&, token& )
- {
- return -1;
- }
- inline virtual int insert(const token&, const token&, token&)
- {
- return -1;
- }
- inline virtual int insert(const token&, const token&, const token&, token&)
- {
- return -1;
- }
- inline virtual int insert(const token&, const token&, const token&, const token&, token&)
- {
- return -1;
- }
- inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
- {
- return -1;
- }
- private:
- std::size_t stride_;
- };
- class token_joiner : public helper_interface
- {
- public:
- token_joiner(const std::size_t& stride)
- : stride_(stride)
- {}
- inline std::size_t process(generator& g)
- {
- if (g.token_list_.empty())
- return 0;
- switch (stride_)
- {
- case 2 : return process_stride_2(g);
- case 3 : return process_stride_3(g);
- default : return 0;
- }
- }
- virtual bool join(const token&, const token&, token&) { return false; }
- virtual bool join(const token&, const token&, const token&, token&) { return false; }
- private:
- inline std::size_t process_stride_2(generator& g)
- {
- if (g.token_list_.size() < 2)
- return 0;
- std::size_t changes = 0;
- for (std::size_t i = 0; i < g.token_list_.size() - 1; ++i)
- {
- token t;
- while (join(g.token_list_[i],g.token_list_[i + 1],t))
- {
- g.token_list_[i] = t;
- g.token_list_.erase(g.token_list_.begin() + (i + 1));
- ++changes;
- }
- }
- return changes;
- }
- inline std::size_t process_stride_3(generator& g)
- {
- if (g.token_list_.size() < 3)
- return 0;
- std::size_t changes = 0;
- for (std::size_t i = 0; i < g.token_list_.size() - 2; ++i)
- {
- token t;
- while (join(g.token_list_[i],g.token_list_[i + 1],g.token_list_[i + 2],t))
- {
- g.token_list_[i] = t;
- g.token_list_.erase(g.token_list_.begin() + (i + 1),
- g.token_list_.begin() + (i + 3));
- ++changes;
- }
- }
- return changes;
- }
- std::size_t stride_;
- };
- namespace helper
- {
- inline void dump(lexer::generator& generator)
- {
- for (std::size_t i = 0; i < generator.size(); ++i)
- {
- lexer::token t = generator[i];
- printf("Token[%02d] @ %03d %6s --> '%s'\n",
- static_cast<int>(i),
- static_cast<int>(t.position),
- t.to_str(t.type).c_str(),
- t.value.c_str());
- }
- }
- class commutative_inserter : public lexer::token_inserter
- {
- public:
- commutative_inserter()
- : lexer::token_inserter(2)
- {}
- inline void ignore_symbol(const std::string& symbol)
- {
- ignore_set_.insert(symbol);
- }
- inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token)
- {
- bool match = false;
- new_token.type = lexer::token::e_mul;
- new_token.value = "*";
- new_token.position = t1.position;
- if (t0.type == lexer::token::e_symbol)
- {
- if (ignore_set_.end() != ignore_set_.find(t0.value))
- {
- return -1;
- }
- else if (!t0.value.empty() && ('$' == t0.value[0]))
- {
- return -1;
- }
- }
- if (t1.type == lexer::token::e_symbol)
- {
- if (ignore_set_.end() != ignore_set_.find(t1.value))
- {
- return -1;
- }
- }
- if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
- else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
- else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
- else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
- else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
- else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
- else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
- else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
- else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
- else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
- else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
- return (match) ? 1 : -1;
- }
- private:
- std::set<std::string,details::ilesscompare> ignore_set_;
- };
- class operator_joiner : public token_joiner
- {
- public:
- operator_joiner(const std::size_t& stride)
- : token_joiner(stride)
- {}
- inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t)
- {
- // ': =' --> ':='
- if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_assign;
- t.value = ":=";
- t.position = t0.position;
- return true;
- }
- // '+ =' --> '+='
- else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_addass;
- t.value = "+=";
- t.position = t0.position;
- return true;
- }
- // '- =' --> '-='
- else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_subass;
- t.value = "-=";
- t.position = t0.position;
- return true;
- }
- // '* =' --> '*='
- else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_mulass;
- t.value = "*=";
- t.position = t0.position;
- return true;
- }
- // '/ =' --> '/='
- else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_divass;
- t.value = "/=";
- t.position = t0.position;
- return true;
- }
- // '% =' --> '%='
- else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_modass;
- t.value = "%=";
- t.position = t0.position;
- return true;
- }
- // '> =' --> '>='
- else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_gte;
- t.value = ">=";
- t.position = t0.position;
- return true;
- }
- // '< =' --> '<='
- else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_lte;
- t.value = "<=";
- t.position = t0.position;
- return true;
- }
- // '= =' --> '=='
- else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_eq;
- t.value = "==";
- t.position = t0.position;
- return true;
- }
- // '! =' --> '!='
- else if ((static_cast<char>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
- {
- t.type = lexer::token::e_ne;
- t.value = "!=";
- t.position = t0.position;
- return true;
- }
- // '< >' --> '<>'
- else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
- {
- t.type = lexer::token::e_ne;
- t.value = "<>";
- t.position = t0.position;
- return true;
- }
- // '<= >' --> '<=>'
- else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt))
- {
- t.type = lexer::token::e_swap;
- t.value = "<=>";
- t.position = t0.position;
- return true;
- }
- else
- return false;
- }
- inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, lexer::token& t)
- {
- // '[ * ]' --> '[*]'
- if (
- (t0.type == lexer::token::e_lsqrbracket) &&
- (t1.type == lexer::token::e_mul ) &&
- (t2.type == lexer::token::e_rsqrbracket)
- )
- {
- t.type = lexer::token::e_symbol;
- t.value = "[*]";
- t.position = t0.position;
- return true;
- }
- else
- return false;
- }
- };
- class bracket_checker : public lexer::token_scanner
- {
- public:
- bracket_checker()
- : token_scanner(1),
- state_(true)
- {}
- bool result()
- {
- if (!stack_.empty())
- {
- lexer::token t;
- t.value = stack_.top().first;
- t.position = stack_.top().second;
- error_token_ = t;
- state_ = false;
- return false;
- }
- else
- return state_;
- }
- lexer::token error_token()
- {
- return error_token_;
- }
- void reset()
- {
- // Why? because msvc doesn't support swap properly.
- stack_ = std::stack<std::pair<char,std::size_t> >();
- state_ = true;
- error_token_.clear();
- }
- bool operator()(const lexer::token& t)
- {
- if (
- !t.value.empty() &&
- (lexer::token::e_string != t.type) &&
- (lexer::token::e_symbol != t.type) &&
- exprtk::details::is_bracket(t.value[0])
- )
- {
- char c = t.value[0];
- if (t.type == lexer::token::e_lbracket) stack_.push(std::make_pair(')',t.position));
- else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
- else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
- else if (exprtk::details::is_right_bracket(c))
- {
- if (stack_.empty())
- {
- state_ = false;
- error_token_ = t;
- return false;
- }
- else if (c != stack_.top().first)
- {
- state_ = false;
- error_token_ = t;
- return false;
- }
- else
- stack_.pop();
- }
- }
- return true;
- }
- private:
- bool state_;
- std::stack<std::pair<char,std::size_t> > stack_;
- lexer::token error_token_;
- };
- class numeric_checker : public lexer::token_scanner
- {
- public:
- numeric_checker()
- : token_scanner (1),
- current_index_(0)
- {}
- bool result()
- {
- return error_list_.empty();
- }
- void reset()
- {
- error_list_.clear();
- current_index_ = 0;
- }
- bool operator()(const lexer::token& t)
- {
- if (token::e_number == t.type)
- {
- double v;
- if (!exprtk::details::string_to_real(t.value,v))
- {
- error_list_.push_back(current_index_);
- }
- }
- ++current_index_;
- return true;
- }
- std::size_t error_count() const
- {
- return error_list_.size();
- }
- std::size_t error_index(const std::size_t& i)
- {
- if (i < error_list_.size())
- return error_list_[i];
- else
- return std::numeric_limits<std::size_t>::max();
- }
- void clear_errors()
- {
- error_list_.clear();
- }
- private:
- std::size_t current_index_;
- std::vector<std::size_t> error_list_;
- };
- class symbol_replacer : public lexer::token_modifier
- {
- private:
- typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
- public:
- bool remove(const std::string& target_symbol)
- {
- replace_map_t::iterator itr = replace_map_.find(target_symbol);
- if (replace_map_.end() == itr)
- return false;
- replace_map_.erase(itr);
- return true;
- }
- bool add_replace(const std::string& target_symbol,
- const std::string& replace_symbol,
- const lexer::token::token_type token_type = lexer::token::e_symbol)
- {
- replace_map_t::iterator itr = replace_map_.find(target_symbol);
- if (replace_map_.end() != itr)
- {
- return false;
- }
- replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
- return true;
- }
- void clear()
- {
- replace_map_.clear();
- }
- private:
- bool modify(lexer::token& t)
- {
- if (lexer::token::e_symbol == t.type)
- {
- if (replace_map_.empty())
- return false;
- replace_map_t::iterator itr = replace_map_.find(t.value);
- if (replace_map_.end() != itr)
- {
- t.value = itr->second.first;
- t.type = itr->second.second;
- return true;
- }
- }
- return false;
- }
- replace_map_t replace_map_;
- };
- class sequence_validator : public lexer::token_scanner
- {
- private:
- typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
- typedef std::set<token_pair_t> set_t;
- public:
- sequence_validator()
- : lexer::token_scanner(2)
- {
- add_invalid(lexer::token::e_number ,lexer::token::e_number );
- add_invalid(lexer::token::e_string ,lexer::token::e_string );
- add_invalid(lexer::token::e_number ,lexer::token::e_string );
- add_invalid(lexer::token::e_string ,lexer::token::e_number );
- add_invalid(lexer::token::e_string ,lexer::token::e_ternary);
- add_invalid_set1(lexer::token::e_assign );
- add_invalid_set1(lexer::token::e_shr );
- add_invalid_set1(lexer::token::e_shl );
- add_invalid_set1(lexer::token::e_lte );
- add_invalid_set1(lexer::token::e_ne );
- add_invalid_set1(lexer::token::e_gte );
- add_invalid_set1(lexer::token::e_lt );
- add_invalid_set1(lexer::token::e_gt );
- add_invalid_set1(lexer::token::e_eq );
- add_invalid_set1(lexer::token::e_comma );
- add_invalid_set1(lexer::token::e_add );
- add_invalid_set1(lexer::token::e_sub );
- add_invalid_set1(lexer::token::e_div );
- add_invalid_set1(lexer::token::e_mul );
- add_invalid_set1(lexer::token::e_mod );
- add_invalid_set1(lexer::token::e_pow );
- add_invalid_set1(lexer::token::e_colon );
- add_invalid_set1(lexer::token::e_ternary);
- }
- bool result()
- {
- return error_list_.empty();
- }
- bool operator()(const lexer::token& t0, const lexer::token& t1)
- {
- set_t::value_type p = std::make_pair(t0.type,t1.type);
- if (invalid_bracket_check(t0.type,t1.type))
- {
- error_list_.push_back(std::make_pair(t0,t1));
- }
- else if (invalid_comb_.find(p) != invalid_comb_.end())
- {
- error_list_.push_back(std::make_pair(t0,t1));
- }
- return true;
- }
- std::size_t error_count()
- {
- return error_list_.size();
- }
- std::pair<lexer::token,lexer::token> error(const std::size_t index)
- {
- if (index < error_list_.size())
- {
- return error_list_[index];
- }
- else
- {
- static const lexer::token error_token;
- return std::make_pair(error_token,error_token);
- }
- }
- void clear_errors()
- {
- error_list_.clear();
- }
- private:
- void add_invalid(lexer::token::token_type base, lexer::token::token_type t)
- {
- invalid_comb_.insert(std::make_pair(base,t));
- }
- void add_invalid_set1(lexer::token::token_type t)
- {
- add_invalid(t,lexer::token::e_assign);
- add_invalid(t,lexer::token::e_shr );
- add_invalid(t,lexer::token::e_shl );
- add_invalid(t,lexer::token::e_lte );
- add_invalid(t,lexer::token::e_ne );
- add_invalid(t,lexer::token::e_gte );
- add_invalid(t,lexer::token::e_lt );
- add_invalid(t,lexer::token::e_gt );
- add_invalid(t,lexer::token::e_eq );
- add_invalid(t,lexer::token::e_comma );
- add_invalid(t,lexer::token::e_div );
- add_invalid(t,lexer::token::e_mul );
- add_invalid(t,lexer::token::e_mod );
- add_invalid(t,lexer::token::e_pow );
- add_invalid(t,lexer::token::e_colon );
- }
- bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
- {
- if (details::is_right_bracket(static_cast<char>(base)))
- {
- switch (t)
- {
- case lexer::token::e_assign : return (']' != base);
- case lexer::token::e_string : return true;
- default : return false;
- }
- }
- else if (details::is_left_bracket(static_cast<char>(base)))
- {
- if (details::is_right_bracket(static_cast<char>(t)))
- return false;
- else if (details::is_left_bracket(static_cast<char>(t)))
- return false;
- else
- {
- switch (t)
- {
- case lexer::token::e_number : return false;
- case lexer::token::e_symbol : return false;
- case lexer::token::e_string : return false;
- case lexer::token::e_add : return false;
- case lexer::token::e_sub : return false;
- case lexer::token::e_colon : return false;
- case lexer::token::e_ternary : return false;
- default : return true;
- }
- }
- }
- else if (details::is_right_bracket(static_cast<char>(t)))
- {
- switch (base)
- {
- case lexer::token::e_number : return false;
- case lexer::token::e_symbol : return false;
- case lexer::token::e_string : return false;
- case lexer::token::e_eof : return false;
- case lexer::token::e_colon : return false;
- case lexer::token::e_ternary : return false;
- default : return true;
- }
- }
- else if (details::is_left_bracket(static_cast<char>(t)))
- {
- switch (base)
- {
- case lexer::token::e_rbracket : return true;
- case lexer::token::e_rsqrbracket : return true;
- case lexer::token::e_rcrlbracket : return true;
- default : return false;
- }
- }
- return false;
- }
- set_t invalid_comb_;
- std::vector<std::pair<lexer::token,lexer::token> > error_list_;
- };
- struct helper_assembly
- {
- inline bool register_scanner(lexer::token_scanner* scanner)
- {
- if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
- token_scanner_list.end(),
- scanner))
- {
- return false;
- }
- token_scanner_list.push_back(scanner);
- return true;
- }
- inline bool register_modifier(lexer::token_modifier* modifier)
- {
- if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
- token_modifier_list.end(),
- modifier))
- {
- return false;
- }
- token_modifier_list.push_back(modifier);
- return true;
- }
- inline bool register_joiner(lexer::token_joiner* joiner)
- {
- if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
- token_joiner_list.end(),
- joiner))
- {
- return false;
- }
- token_joiner_list.push_back(joiner);
- return true;
- }
- inline bool register_inserter(lexer::token_inserter* inserter)
- {
- if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
- token_inserter_list.end(),
- inserter))
- {
- return false;
- }
- token_inserter_list.push_back(inserter);
- return true;
- }
- inline bool run_modifiers(lexer::generator& g)
- {
- error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
- bool result = true;
- for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
- {
- lexer::token_modifier& modifier = (*token_modifier_list[i]);
- modifier.reset();
- modifier.process(g);
- if (!modifier.result())
- {
- error_token_modifier = token_modifier_list[i];
- return false;
- }
- }
- return result;
- }
- inline bool run_joiners(lexer::generator& g)
- {
- error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
- bool result = true;
- for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
- {
- lexer::token_joiner& joiner = (*token_joiner_list[i]);
- joiner.reset();
- joiner.process(g);
- if (!joiner.result())
- {
- error_token_joiner = token_joiner_list[i];
- return false;
- }
- }
- return result;
- }
- inline bool run_inserters(lexer::generator& g)
- {
- error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
- bool result = true;
- for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
- {
- lexer::token_inserter& inserter = (*token_inserter_list[i]);
- inserter.reset();
- inserter.process(g);
- if (!inserter.result())
- {
- error_token_inserter = token_inserter_list[i];
- return false;
- }
- }
- return result;
- }
- inline bool run_scanners(lexer::generator& g)
- {
- error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
- bool result = true;
- for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
- {
- lexer::token_scanner& scanner = (*token_scanner_list[i]);
- scanner.reset();
- scanner.process(g);
- if (!scanner.result())
- {
- error_token_scanner = token_scanner_list[i];
- return false;
- }
- }
- return result;
- }
- std::vector<lexer::token_scanner*> token_scanner_list;
- std::vector<lexer::token_modifier*> token_modifier_list;
- std::vector<lexer::token_joiner*> token_joiner_list;
- std::vector<lexer::token_inserter*> token_inserter_list;
- lexer::token_scanner* error_token_scanner;
- lexer::token_modifier* error_token_modifier;
- lexer::token_joiner* error_token_joiner;
- lexer::token_inserter* error_token_inserter;
- };
- }
- class parser_helper
- {
- public:
- typedef token token_t;
- typedef generator generator_t;
- inline bool init(const std::string& str)
- {
- if (!lexer_.process(str))
- {
- return false;
- }
- lexer_.begin();
- next_token();
- return true;
- }
- inline generator_t& lexer()
- {
- return lexer_;
- }
- inline const generator_t& lexer() const
- {
- return lexer_;
- }
- inline void store_token()
- {
- lexer_.store();
- store_current_token_ = current_token_;
- }
- inline void restore_token()
- {
- lexer_.restore();
- current_token_ = store_current_token_;
- }
- inline void next_token()
- {
- current_token_ = lexer_.next_token();
- }
- inline const token_t& current_token() const
- {
- return current_token_;
- }
- inline bool token_is(const token_t::token_type& ttype, const bool advance_token = true)
- {
- if (current_token().type != ttype)
- {
- return false;
- }
- if (advance_token)
- {
- next_token();
- }
- return true;
- }
- inline bool token_is(const token_t::token_type& ttype,
- const std::string& value,
- const bool advance_token = true)
- {
- if (
- (current_token().type != ttype) ||
- !exprtk::details::imatch(value,current_token().value)
- )
- {
- return false;
- }
- if (advance_token)
- {
- next_token();
- }
- return true;
- }
- inline bool token_is_then_assign(const token_t::token_type& ttype,
- std::string& token,
- const bool advance_token = true)
- {
- if (current_token_.type != ttype)
- {
- return false;
- }
- token = current_token_.value;
- if (advance_token)
- {
- next_token();
- }
- return true;
- }
- template <typename Allocator,
- template <typename,typename> class Container>
- inline bool token_is_then_assign(const token_t::token_type& ttype,
- Container<std::string,Allocator>& token_list,
- const bool advance_token = true)
- {
- if (current_token_.type != ttype)
- {
- return false;
- }
- token_list.push_back(current_token_.value);
- if (advance_token)
- {
- next_token();
- }
- return true;
- }
- inline bool peek_token_is(const token_t::token_type& ttype)
- {
- return (lexer_.peek_next_token().type == ttype);
- }
- inline bool peek_token_is(const std::string& s)
- {
- return (exprtk::details::imatch(lexer_.peek_next_token().value,s));
- }
- private:
- generator_t lexer_;
- token_t current_token_;
- token_t store_current_token_;
- };
- }
- template <typename T> class results_context;
- template <typename T>
- struct type_store
- {
- enum store_type
- {
- e_unknown,
- e_scalar,
- e_vector,
- e_string
- };
- type_store()
- : size(0),
- data(0),
- type(e_unknown)
- {}
- std::size_t size;
- void* data;
- store_type type;
- class parameter_list
- {
- public:
- parameter_list(std::vector<type_store>& pl)
- : parameter_list_(pl)
- {}
- inline bool empty() const
- {
- return parameter_list_.empty();
- }
- inline std::size_t size() const
- {
- return parameter_list_.size();
- }
- inline type_store& operator[](const std::size_t& index)
- {
- return parameter_list_[index];
- }
- inline const type_store& operator[](const std::size_t& index) const
- {
- return parameter_list_[index];
- }
- inline type_store& front()
- {
- return parameter_list_[0];
- }
- inline const type_store& front() const
- {
- return parameter_list_[0];
- }
- inline type_store& back()
- {
- return parameter_list_.back();
- }
- inline const type_store& back() const
- {
- return parameter_list_.back();
- }
- private:
- std::vector<type_store>& parameter_list_;
- friend class results_context<T>;
- };
- template <typename ViewType>
- struct type_view
- {
- typedef type_store<T> type_store_t;
- typedef ViewType value_t;
- type_view(type_store_t& ts)
- : ts_(ts),
- data_(reinterpret_cast<value_t*>(ts_.data))
- {}
- inline std::size_t size() const
- {
- return ts_.size;
- }
- inline value_t& operator[](const std::size_t& i)
- {
- return data_[i];
- }
- inline const value_t& operator[](const std::size_t& i) const
- {
- return data_[i];
- }
- inline const value_t* begin() const { return data_; }
- inline value_t* begin() { return data_; }
- inline const value_t* end() const
- {
- return static_cast<value_t*>(data_ + ts_.size);
- }
- inline value_t* end()
- {
- return static_cast<value_t*>(data_ + ts_.size);
- }
- type_store_t& ts_;
- value_t* data_;
- };
- typedef type_view<T> vector_view;
- typedef type_view<char> string_view;
- struct scalar_view
- {
- typedef type_store<T> type_store_t;
- typedef T value_t;
- scalar_view(type_store_t& ts)
- : v_(*reinterpret_cast<value_t*>(ts.data))
- {}
- scalar_view(const type_store_t& ts)
- : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
- {}
- value_t& operator()()
- {
- return v_;
- }
- const value_t& operator()() const
- {
- return v_;
- }
- T& v_;
- };
- };
- template <typename StringView>
- inline std::string to_str(const StringView& view)
- {
- return std::string(view.begin(),view.size());
- }
- namespace details
- {
- template <typename T> class return_node;
- template <typename T> class return_envelope_node;
- }
- template <typename T>
- class results_context
- {
- public:
- typedef type_store<T> type_store_t;
- results_context()
- : results_available_(false)
- {}
- inline std::size_t count() const
- {
- if (results_available_)
- return parameter_list_.size();
- else
- return 0;
- }
- inline type_store_t& operator[](const std::size_t& index)
- {
- return parameter_list_[index];
- }
- inline const type_store_t& operator[](const std::size_t& index) const
- {
- return parameter_list_[index];
- }
- private:
- inline void clear()
- {
- results_available_ = false;
- }
- typedef std::vector<type_store_t> ts_list_t;
- typedef typename type_store_t::parameter_list parameter_list_t;
- inline void assign(const parameter_list_t& pl)
- {
- parameter_list_ = pl.parameter_list_;
- results_available_ = true;
- }
- bool results_available_;
- ts_list_t parameter_list_;
- friend class details::return_node<T>;
- friend class details::return_envelope_node<T>;
- };
- namespace details
- {
- enum operator_type
- {
- e_default , e_null , e_add , e_sub ,
- e_mul , e_div , e_mod , e_pow ,
- e_atan2 , e_min , e_max , e_avg ,
- e_sum , e_prod , e_lt , e_lte ,
- e_eq , e_equal , e_ne , e_nequal ,
- e_gte , e_gt , e_and , e_nand ,
- e_or , e_nor , e_xor , e_xnor ,
- e_mand , e_mor , e_scand , e_scor ,
- e_shr , e_shl , e_abs , e_acos ,
- e_acosh , e_asin , e_asinh , e_atan ,
- e_atanh , e_ceil , e_cos , e_cosh ,
- e_exp , e_expm1 , e_floor , e_log ,
- e_log10 , e_log2 , e_log1p , e_logn ,
- e_neg , e_pos , e_round , e_roundn ,
- e_root , e_sqrt , e_sin , e_sinc ,
- e_sinh , e_sec , e_csc , e_tan ,
- e_tanh , e_cot , e_clamp , e_iclamp ,
- e_inrange , e_sgn , e_r2d , e_d2r ,
- e_d2g , e_g2d , e_hypot , e_notl ,
- e_erf , e_erfc , e_ncdf , e_frac ,
- e_trunc , e_assign , e_addass , e_subass ,
- e_mulass , e_divass , e_modass , e_in ,
- e_like , e_ilike , e_multi , e_swap ,
- // Do not add new functions/operators after this point.
- e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
- e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
- e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
- e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
- e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
- e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
- e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
- e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
- e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
- e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
- e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
- e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
- e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
- e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
- e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
- e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
- e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
- e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
- e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
- e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
- e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083,
- e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087,
- e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091,
- e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095,
- e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099,
- e_sffinal = 1100,
- e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003,
- e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007,
- e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011,
- e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015,
- e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019,
- e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023,
- e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027,
- e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031,
- e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035,
- e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
- e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043,
- e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
- e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
- e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
- e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059
- };
- struct base_operation_t
- {
- base_operation_t(const operator_type t, const unsigned int& np)
- : type(t),
- num_params(np)
- {}
- operator_type type;
- unsigned int num_params;
- };
- namespace numeric
- {
- namespace details
- {
- template <typename T>
- inline T process_impl(const operator_type operation, const T arg)
- {
- switch (operation)
- {
- case e_abs : return numeric::abs (arg);
- case e_acos : return numeric::acos (arg);
- case e_acosh : return numeric::acosh(arg);
- case e_asin : return numeric::asin (arg);
- case e_asinh : return numeric::asinh(arg);
- case e_atan : return numeric::atan (arg);
- case e_atanh : return numeric::atanh(arg);
- case e_ceil : return numeric::ceil (arg);
- case e_cos : return numeric::cos (arg);
- case e_cosh : return numeric::cosh (arg);
- case e_exp : return numeric::exp (arg);
- case e_expm1 : return numeric::expm1(arg);
- case e_floor : return numeric::floor(arg);
- case e_log : return numeric::log (arg);
- case e_log10 : return numeric::log10(arg);
- case e_log2 : return numeric::log2 (arg);
- case e_log1p : return numeric::log1p(arg);
- case e_neg : return numeric::neg (arg);
- case e_pos : return numeric::pos (arg);
- case e_round : return numeric::round(arg);
- case e_sin : return numeric::sin (arg);
- case e_sinc : return numeric::sinc (arg);
- case e_sinh : return numeric::sinh (arg);
- case e_sqrt : return numeric::sqrt (arg);
- case e_tan : return numeric::tan (arg);
- case e_tanh : return numeric::tanh (arg);
- case e_cot : return numeric::cot (arg);
- case e_sec : return numeric::sec (arg);
- case e_csc : return numeric::csc (arg);
- case e_r2d : return numeric::r2d (arg);
- case e_d2r : return numeric::d2r (arg);
- case e_d2g : return numeric::d2g (arg);
- case e_g2d : return numeric::g2d (arg);
- case e_notl : return numeric::notl (arg);
- case e_sgn : return numeric::sgn (arg);
- case e_erf : return numeric::erf (arg);
- case e_erfc : return numeric::erfc (arg);
- case e_ncdf : return numeric::ncdf (arg);
- case e_frac : return numeric::frac (arg);
- case e_trunc : return numeric::trunc(arg);
- default : return std::numeric_limits<T>::quiet_NaN();
- }
- }
- template <typename T>
- inline T process_impl(const operator_type operation, const T arg0, const T arg1)
- {
- switch (operation)
- {
- case e_add : return (arg0 + arg1);
- case e_sub : return (arg0 - arg1);
- case e_mul : return (arg0 * arg1);
- case e_div : return (arg0 / arg1);
- case e_mod : return modulus<T>(arg0,arg1);
- case e_pow : return pow<T>(arg0,arg1);
- case e_atan2 : return atan2<T>(arg0,arg1);
- case e_min : return std::min<T>(arg0,arg1);
- case e_max : return std::max<T>(arg0,arg1);
- case e_logn : return logn<T>(arg0,arg1);
- case e_lt : return (arg0 < arg1) ? T(1) : T(0);
- case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
- case e_eq : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0);
- case e_ne : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0);
- case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
- case e_gt : return (arg0 > arg1) ? T(1) : T(0);
- case e_and : return and_opr<T> (arg0,arg1);
- case e_nand : return nand_opr<T>(arg0,arg1);
- case e_or : return or_opr<T> (arg0,arg1);
- case e_nor : return nor_opr<T> (arg0,arg1);
- case e_xor : return xor_opr<T> (arg0,arg1);
- case e_xnor : return xnor_opr<T>(arg0,arg1);
- case e_root : return root<T> (arg0,arg1);
- case e_roundn : return roundn<T> (arg0,arg1);
- case e_equal : return equal<T> (arg0,arg1);
- case e_nequal : return nequal<T> (arg0,arg1);
- case e_hypot : return hypot<T> (arg0,arg1);
- case e_shr : return shr<T> (arg0,arg1);
- case e_shl : return shl<T> (arg0,arg1);
- default : return std::numeric_limits<T>::quiet_NaN();
- }
- }
- template <typename T>
- inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
- {
- switch (operation)
- {
- case e_add : return (arg0 + arg1);
- case e_sub : return (arg0 - arg1);
- case e_mul : return (arg0 * arg1);
- case e_div : return (arg0 / arg1);
- case e_mod : return arg0 % arg1;
- case e_pow : return pow<T>(arg0,arg1);
- case e_min : return std::min<T>(arg0,arg1);
- case e_max : return std::max<T>(arg0,arg1);
- case e_logn : return logn<T>(arg0,arg1);
- case e_lt : return (arg0 < arg1) ? T(1) : T(0);
- case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
- case e_eq : return (arg0 == arg1) ? T(1) : T(0);
- case e_ne : return (arg0 != arg1) ? T(1) : T(0);
- case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
- case e_gt : return (arg0 > arg1) ? T(1) : T(0);
- case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
- case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
- case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
- case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
- case e_xor : return arg0 ^ arg1;
- case e_xnor : return !(arg0 ^ arg1);
- case e_root : return root<T>(arg0,arg1);
- case e_equal : return arg0 == arg1;
- case e_nequal : return arg0 != arg1;
- case e_hypot : return hypot<T>(arg0,arg1);
- case e_shr : return arg0 >> arg1;
- case e_shl : return arg0 << arg1;
- default : return std::numeric_limits<T>::quiet_NaN();
- }
- }
- }
- template <typename T>
- inline T process(const operator_type operation, const T arg)
- {
- return exprtk::details::numeric::details::process_impl(operation,arg);
- }
- template <typename T>
- inline T process(const operator_type operation, const T arg0, const T arg1)
- {
- return exprtk::details::numeric::details::process_impl(operation,arg0,arg1);
- }
- }
- template <typename T>
- class expression_node
- {
- public:
- enum node_type
- {
- e_none , e_null , e_constant , e_unary ,
- e_binary , e_binary_ext , e_trinary , e_quaternary ,
- e_vararg , e_conditional , e_while , e_repeat ,
- e_for , e_switch , e_mswitch , e_return ,
- e_retenv , e_variable , e_stringvar , e_stringconst ,
- e_stringvarrng , e_cstringvarrng, e_strgenrange , e_strconcat ,
- e_stringvarsize, e_strswap , e_stringsize , e_function ,
- e_vafunction , e_genfunction , e_strfunction , e_strcondition ,
- e_strccondition, e_add , e_sub , e_mul ,
- e_div , e_mod , e_pow , e_lt ,
- e_lte , e_gt , e_gte , e_eq ,
- e_ne , e_and , e_nand , e_or ,
- e_nor , e_xor , e_xnor , e_in ,
- e_like , e_ilike , e_inranges , e_ipow ,
- e_ipowinv , e_abs , e_acos , e_acosh ,
- e_asin , e_asinh , e_atan , e_atanh ,
- e_ceil , e_cos , e_cosh , e_exp ,
- e_expm1 , e_floor , e_log , e_log10 ,
- e_log2 , e_log1p , e_neg , e_pos ,
- e_round , e_sin , e_sinc , e_sinh ,
- e_sqrt , e_tan , e_tanh , e_cot ,
- e_sec , e_csc , e_r2d , e_d2r ,
- e_d2g , e_g2d , e_notl , e_sgn ,
- e_erf , e_erfc , e_ncdf , e_frac ,
- e_trunc , e_uvouv , e_vov , e_cov ,
- e_voc , e_vob , e_bov , e_cob ,
- e_boc , e_vovov , e_vovoc , e_vocov ,
- e_covov , e_covoc , e_vovovov , e_vovovoc ,
- e_vovocov , e_vocovov , e_covovov , e_covocov ,
- e_vocovoc , e_covovoc , e_vococov , e_sf3ext ,
- e_sf4ext , e_nulleq , e_strass , e_vector ,
- e_vecelem , e_vecdefass , e_vecvalass , e_vecvecass ,
- e_vecopvalass , e_vecopvecass , e_vecfunc , e_vecvecswap ,
- e_vecvecineq , e_vecvalineq , e_valvecineq , e_vecvecarith ,
- e_vecvalarith , e_valvecarith , e_vecunaryop , e_break ,
- e_continue , e_swap
- };
- typedef T value_type;
- typedef expression_node<T>* expression_ptr;
- virtual ~expression_node()
- {}
- inline virtual T value() const
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
- {
- return reinterpret_cast<expression_ptr>(index * 0);
- }
- inline virtual node_type type() const
- {
- return e_none;
- }
- };
- template <typename T>
- inline bool is_generally_string_node(const expression_node<T>* node);
- inline bool is_true(const double v)
- {
- return std::not_equal_to<double>()(0.0,v);
- }
- inline bool is_true(const long double v)
- {
- return std::not_equal_to<long double>()(0.0L,v);
- }
- inline bool is_true(const float v)
- {
- return std::not_equal_to<float>()(0.0f,v);
- }
- template <typename T>
- inline bool is_true(const std::complex<T>& v)
- {
- return std::not_equal_to<std::complex<T> >()(std::complex<T>(0),v);
- }
- template <typename T>
- inline bool is_true(const expression_node<T>* node)
- {
- return std::not_equal_to<T>()(T(0),node->value());
- }
- template <typename T>
- inline bool is_false(const expression_node<T>* node)
- {
- return std::equal_to<T>()(T(0),node->value());
- }
- template <typename T>
- inline bool is_unary_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_unary == node->type());
- }
- template <typename T>
- inline bool is_neg_unary_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_neg == node->type());
- }
- template <typename T>
- inline bool is_binary_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_binary == node->type());
- }
- template <typename T>
- inline bool is_variable_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_variable == node->type());
- }
- template <typename T>
- inline bool is_ivariable_node(const expression_node<T>* node)
- {
- return node &&
- (
- details::expression_node<T>::e_variable == node->type() ||
- details::expression_node<T>::e_vecelem == node->type()
- );
- }
- template <typename T>
- inline bool is_vector_elem_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_vecelem == node->type());
- }
- template <typename T>
- inline bool is_vector_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_vector == node->type());
- }
- template <typename T>
- inline bool is_ivector_node(const expression_node<T>* node)
- {
- if (node)
- {
- switch (node->type())
- {
- case details::expression_node<T>::e_vector :
- case details::expression_node<T>::e_vecvalass :
- case details::expression_node<T>::e_vecvecass :
- case details::expression_node<T>::e_vecopvalass :
- case details::expression_node<T>::e_vecopvecass :
- case details::expression_node<T>::e_vecvecswap :
- case details::expression_node<T>::e_vecvecarith :
- case details::expression_node<T>::e_vecvalarith :
- case details::expression_node<T>::e_valvecarith :
- case details::expression_node<T>::e_vecunaryop : return true;
- default : return false;
- }
- }
- else
- return false;
- }
- template <typename T>
- inline bool is_constant_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_constant == node->type());
- }
- template <typename T>
- inline bool is_null_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_null == node->type());
- }
- template <typename T>
- inline bool is_break_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_break == node->type());
- }
- template <typename T>
- inline bool is_continue_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_continue == node->type());
- }
- template <typename T>
- inline bool is_swap_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_swap == node->type());
- }
- template <typename T>
- inline bool is_function(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_function == node->type());
- }
- template <typename T>
- inline bool is_return_node(const expression_node<T>* node)
- {
- return node && (details::expression_node<T>::e_return == node->type());
- }
- template <typename T> class unary_node;
- template <typename T>
- inline bool is_negate_node(const expression_node<T>* node)
- {
- if (node && is_unary_node(node))
- {
- return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
- }
- else
- return false;
- }
- template <typename T>
- inline bool branch_deletable(expression_node<T>* node)
- {
- return !is_variable_node(node) &&
- !is_string_node (node) ;
- }
- template <std::size_t N, typename T>
- inline bool all_nodes_valid(expression_node<T>* (&b)[N])
- {
- for (std::size_t i = 0; i < N; ++i)
- {
- if (0 == b[i]) return false;
- }
- return true;
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b)
- {
- for (std::size_t i = 0; i < b.size(); ++i)
- {
- if (0 == b[i]) return false;
- }
- return true;
- }
- template <std::size_t N, typename T>
- inline bool all_nodes_variables(expression_node<T>* (&b)[N])
- {
- for (std::size_t i = 0; i < N; ++i)
- {
- if (0 == b[i])
- return false;
- else if (!is_variable_node(b[i]))
- return false;
- }
- return true;
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline bool all_nodes_variables(Sequence<expression_node<T>*,Allocator>& b)
- {
- for (std::size_t i = 0; i < b.size(); ++i)
- {
- if (0 == b[i])
- return false;
- else if (!is_variable_node(b[i]))
- return false;
- }
- return true;
- }
- template <typename NodeAllocator, typename T, std::size_t N>
- inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N])
- {
- for (std::size_t i = 0; i < N; ++i)
- {
- free_node(node_allocator,b[i]);
- }
- }
- template <typename NodeAllocator,
- typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b)
- {
- for (std::size_t i = 0; i < b.size(); ++i)
- {
- free_node(node_allocator,b[i]);
- }
- b.clear();
- }
- template <typename NodeAllocator, typename T>
- inline void free_node(NodeAllocator& node_allocator, expression_node<T>*& node, const bool force_delete = false)
- {
- if (0 != node)
- {
- if (
- (is_variable_node(node) || is_string_node(node)) ||
- force_delete
- )
- return;
- node_allocator.free(node);
- node = 0;
- }
- }
- template <typename Type>
- class vector_holder
- {
- private:
- typedef Type value_type;
- typedef value_type* value_ptr;
- typedef const value_ptr const_value_ptr;
- class vector_holder_base
- {
- public:
- virtual ~vector_holder_base(){}
- inline value_ptr operator[](const std::size_t& index) const
- {
- return value_at(index);
- }
- inline std::size_t size() const
- {
- return vector_size();
- }
- protected:
- virtual value_ptr value_at(const std::size_t&) const = 0;
- virtual std::size_t vector_size() const = 0;
- };
- class array_vector_impl : public vector_holder_base
- {
- public:
- array_vector_impl(const Type* vec, const std::size_t& vec_size)
- : vec_(vec),
- size_(vec_size)
- {}
- protected:
- value_ptr value_at(const std::size_t& index) const
- {
- if (index < size_)
- return const_cast<const_value_ptr>(vec_ + index);
- else
- return const_value_ptr(0);
- }
- std::size_t vector_size() const
- {
- return size_;
- }
- private:
- array_vector_impl operator=(const array_vector_impl&);
- const Type* vec_;
- const std::size_t size_;
- };
- template <typename Allocator,
- template <typename,typename> class Sequence>
- class sequence_vector_impl : public vector_holder_base
- {
- public:
- typedef Sequence<Type,Allocator> sequence_t;
- sequence_vector_impl(sequence_t& seq)
- : sequence_(seq)
- {}
- protected:
- value_ptr value_at(const std::size_t& index) const
- {
- return (index < sequence_.size()) ? (&sequence_[index]) : const_value_ptr(0);
- }
- std::size_t vector_size() const
- {
- return sequence_.size();
- }
- private:
- sequence_vector_impl operator=(const sequence_vector_impl&);
- sequence_t& sequence_;
- };
- public:
- vector_holder(Type* vec, const std::size_t& vec_size)
- : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
- {}
- template <typename Allocator>
- vector_holder(std::vector<Type,Allocator>& vec)
- : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
- {}
- template <typename Allocator>
- vector_holder(std::deque<Type,Allocator>& deq)
- : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::deque>(deq))
- {}
- inline value_ptr operator[](const std::size_t& index) const
- {
- return (*vector_holder_base_)[index];
- }
- inline std::size_t size() const
- {
- return vector_holder_base_->size();
- }
- private:
- mutable vector_holder_base* vector_holder_base_;
- unsigned char buffer[64];
- };
- template <typename T>
- class null_node : public expression_node<T>
- {
- public:
- inline T value() const
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_null;
- }
- };
- template <typename T>
- class null_eq_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- null_eq_node(expression_ptr brnch, const bool equality = true)
- : branch_(brnch),
- branch_deletable_(branch_deletable(branch_)),
- equality_(equality)
- {}
- ~null_eq_node()
- {
- if (branch_ && branch_deletable_)
- {
- delete branch_;
- branch_ = 0;
- }
- }
- inline T value() const
- {
- const T v = branch_->value();
- const bool result = details::numeric::is_nan(v);
- if (result)
- return (equality_) ? T(1) : T(0);
- else
- return (equality_) ? T(0) : T(1);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_nulleq;
- }
- inline operator_type operation() const
- {
- return details::e_eq;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_;
- }
- private:
- expression_ptr branch_;
- bool branch_deletable_;
- bool equality_;
- };
- template <typename T>
- class literal_node : public expression_node<T>
- {
- public:
- explicit literal_node(const T& v)
- : value_(v)
- {}
- inline T value() const
- {
- return value_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_constant;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return reinterpret_cast<expression_node<T>*>(0);
- }
- private:
- literal_node(literal_node<T>&) {}
- literal_node<T>& operator=(literal_node<T>&) { return *this; }
- const T value_;
- };
- template <typename T>
- struct range_pack;
- template <typename T>
- struct range_data_type;
- template <typename T>
- class range_interface
- {
- public:
- typedef range_pack<T> range_t;
- virtual range_t& range_ref() = 0;
- virtual const range_t& range_ref() const = 0;
- };
- template <typename T>
- class string_base_node
- {
- public:
- typedef range_data_type<T> range_data_type_t;
- virtual std::string str () const = 0;
- virtual const char* base() const = 0;
- virtual std::size_t size() const = 0;
- };
- template <typename T>
- class string_literal_node : public expression_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef range_pack<T> range_t;
- explicit string_literal_node(const std::string& v)
- : value_(v)
- {
- rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
- rp_.cache.first = rp_.n0_c.second;
- rp_.cache.second = rp_.n1_c.second;
- }
- inline T value() const
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_stringconst;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return reinterpret_cast<expression_node<T>*>(0);
- }
- std::string str() const
- {
- return value_;
- }
- const char* base() const
- {
- return value_.data();
- }
- std::size_t size() const
- {
- return value_.size();
- }
- range_t& range_ref()
- {
- return rp_;
- }
- const range_t& range_ref() const
- {
- return rp_;
- }
- private:
- string_literal_node(const string_literal_node<T>&);
- string_literal_node<T>& operator=(const string_literal_node<T>&);
- const std::string value_;
- range_t rp_;
- };
- template <typename T>
- class unary_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- unary_node(const operator_type& opr,
- expression_ptr brnch)
- : operation_(opr),
- branch_(brnch),
- branch_deletable_(branch_deletable(branch_))
- {}
- ~unary_node()
- {
- if (branch_ && branch_deletable_)
- {
- delete branch_;
- branch_ = 0;
- }
- }
- inline T value() const
- {
- const T arg = branch_->value();
- return numeric::process<T>(operation_,arg);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_unary;
- }
- inline operator_type operation() const
- {
- return operation_;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_;
- }
- inline void release()
- {
- branch_deletable_ = false;
- }
- protected:
- operator_type operation_;
- expression_ptr branch_;
- bool branch_deletable_;
- };
- template <typename T, std::size_t D, bool B>
- struct construct_branch_pair
- {
- template <std::size_t N>
- static inline void process(std::pair<expression_node<T>*,bool> (&)[N], expression_node<T>*)
- {}
- };
- template <typename T, std::size_t D>
- struct construct_branch_pair<T,D,true>
- {
- template <std::size_t N>
- static inline void process(std::pair<expression_node<T>*,bool> (&branch)[N], expression_node<T>* b)
- {
- if (b)
- {
- branch[D] = std::make_pair(b,branch_deletable(b));
- }
- }
- };
- template <std::size_t N, typename T>
- inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
- expression_node<T>* b0,
- expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
- expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
- {
- construct_branch_pair<T,0,(N > 0)>::process(branch,b0);
- construct_branch_pair<T,1,(N > 1)>::process(branch,b1);
- construct_branch_pair<T,2,(N > 2)>::process(branch,b2);
- construct_branch_pair<T,3,(N > 3)>::process(branch,b3);
- construct_branch_pair<T,4,(N > 4)>::process(branch,b4);
- construct_branch_pair<T,5,(N > 5)>::process(branch,b5);
- construct_branch_pair<T,6,(N > 6)>::process(branch,b6);
- construct_branch_pair<T,7,(N > 7)>::process(branch,b7);
- construct_branch_pair<T,8,(N > 8)>::process(branch,b8);
- construct_branch_pair<T,9,(N > 9)>::process(branch,b9);
- }
- struct cleanup_branches
- {
- template <typename T, std::size_t N>
- static inline void execute(std::pair<expression_node<T>*,bool> (&branch)[N])
- {
- for (std::size_t i = 0; i < N; ++i)
- {
- if (branch[i].first && branch[i].second)
- {
- delete branch[i].first;
- branch[i].first = 0;
- }
- }
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline void execute(Sequence<std::pair<expression_node<T>*,bool>,Allocator>& branch)
- {
- for (std::size_t i = 0; i < branch.size(); ++i)
- {
- if (branch[i].first && branch[i].second)
- {
- delete branch[i].first;
- branch[i].first = 0;
- }
- }
- }
- };
- template <typename T>
- class binary_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- binary_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : operation_(opr)
- {
- init_branches<2>(branch_,branch0,branch1);
- }
- ~binary_node()
- {
- cleanup_branches::execute<T,2>(branch_);
- }
- inline T value() const
- {
- const T arg0 = branch_[0].first->value();
- const T arg1 = branch_[1].first->value();
- return numeric::process<T>(operation_,arg0,arg1);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_binary;
- }
- inline operator_type operation()
- {
- return operation_;
- }
- inline expression_node<T>* branch(const std::size_t& index = 0) const
- {
- if (0 == index)
- return branch_[0].first;
- else if (1 == index)
- return branch_[1].first;
- else
- return reinterpret_cast<expression_ptr>(0);
- }
- protected:
- operator_type operation_;
- branch_t branch_[2];
- };
- template <typename T, typename Operation>
- class binary_ext_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- binary_ext_node(expression_ptr branch0, expression_ptr branch1)
- {
- init_branches<2>(branch_,branch0,branch1);
- }
- ~binary_ext_node()
- {
- cleanup_branches::execute<T,2>(branch_);
- }
- inline T value() const
- {
- const T arg0 = branch_[0].first->value();
- const T arg1 = branch_[1].first->value();
- return Operation::process(arg0,arg1);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_binary_ext;
- }
- inline operator_type operation()
- {
- return Operation::operation();
- }
- inline expression_node<T>* branch(const std::size_t& index = 0) const
- {
- if (0 == index)
- return branch_[0].first;
- else if (1 == index)
- return branch_[1].first;
- else
- return reinterpret_cast<expression_ptr>(0);
- }
- protected:
- branch_t branch_[2];
- };
- template <typename T>
- class trinary_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- trinary_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1,
- expression_ptr branch2)
- : operation_(opr)
- {
- init_branches<3>(branch_,branch0,branch1,branch2);
- }
- ~trinary_node()
- {
- cleanup_branches::execute<T,3>(branch_);
- }
- inline T value() const
- {
- const T arg0 = branch_[0].first->value();
- const T arg1 = branch_[1].first->value();
- const T arg2 = branch_[2].first->value();
- switch (operation_)
- {
- case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
- case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
- case e_iclamp : if ((arg1 <= arg0) || (arg1 >= arg2))
- return arg1;
- else
- return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2);
- default : return std::numeric_limits<T>::quiet_NaN();
- }
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_trinary;
- }
- protected:
- operator_type operation_;
- branch_t branch_[3];
- };
- template <typename T>
- class quaternary_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- quaternary_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1,
- expression_ptr branch2,
- expression_ptr branch3)
- : operation_(opr)
- {
- init_branches<4>(branch_,branch0,branch1,branch2,branch3);
- }
- ~quaternary_node()
- {
- cleanup_branches::execute<T,4>(branch_);
- }
- inline T value() const
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_quaternary;
- }
- protected:
- operator_type operation_;
- branch_t branch_[4];
- };
- template <typename T>
- class conditional_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- conditional_node(expression_ptr test,
- expression_ptr consequent,
- expression_ptr alternative)
- : test_(test),
- consequent_(consequent),
- alternative_(alternative),
- test_deletable_(branch_deletable(test_)),
- consequent_deletable_(branch_deletable(consequent_)),
- alternative_deletable_(branch_deletable(alternative_))
- {}
- ~conditional_node()
- {
- if (test_ && test_deletable_ ) delete test_;
- if (consequent_ && consequent_deletable_ ) delete consequent_;
- if (alternative_ && alternative_deletable_) delete alternative_;
- }
- inline T value() const
- {
- if (is_true(test_))
- return consequent_->value();
- else
- return alternative_->value();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_conditional;
- }
- private:
- expression_ptr test_;
- expression_ptr consequent_;
- expression_ptr alternative_;
- bool test_deletable_;
- bool consequent_deletable_;
- bool alternative_deletable_;
- };
- template <typename T>
- class cons_conditional_node : public expression_node<T>
- {
- public:
- // Consequent only conditional statement node
- typedef expression_node<T>* expression_ptr;
- cons_conditional_node(expression_ptr test,
- expression_ptr consequent)
- : test_(test),
- consequent_(consequent),
- test_deletable_(branch_deletable(test_)),
- consequent_deletable_(branch_deletable(consequent_))
- {}
- ~cons_conditional_node()
- {
- if (test_ && test_deletable_ ) delete test_;
- if (consequent_ && consequent_deletable_) delete consequent_;
- }
- inline T value() const
- {
- if (is_true(test_))
- return consequent_->value();
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_conditional;
- }
- private:
- expression_ptr test_;
- expression_ptr consequent_;
- bool test_deletable_;
- bool consequent_deletable_;
- };
- #ifndef exprtk_disable_break_continue
- template <typename T>
- class break_exception
- {
- public:
- break_exception(const T& v)
- : value(v)
- {}
- T value;
- };
- class continue_exception
- {};
- template <typename T>
- class break_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- break_node(expression_ptr ret = expression_ptr(0))
- : return_(ret),
- return_deletable_(branch_deletable(return_))
- {}
- ~break_node()
- {
- if (return_deletable_)
- {
- delete return_;
- }
- }
- inline T value() const
- {
- throw break_exception<T>(return_ ? return_->value() : std::numeric_limits<T>::quiet_NaN());
- #ifndef _MSC_VER
- return std::numeric_limits<T>::quiet_NaN();
- #endif
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_break;
- }
- private:
- expression_ptr return_;
- bool return_deletable_;
- };
- template <typename T>
- class continue_node : public expression_node<T>
- {
- public:
- inline T value() const
- {
- throw continue_exception();
- #ifndef _MSC_VER
- return std::numeric_limits<T>::quiet_NaN();
- #endif
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_break;
- }
- };
- #endif
- template <typename T>
- class while_loop_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- while_loop_node(expression_ptr condition, expression_ptr loop_body)
- : condition_(condition),
- loop_body_(loop_body),
- condition_deletable_(branch_deletable(condition_)),
- loop_body_deletable_(branch_deletable(loop_body_))
- {}
- ~while_loop_node()
- {
- if (condition_ && condition_deletable_)
- {
- delete condition_;
- }
- if (loop_body_ && loop_body_deletable_)
- {
- delete loop_body_;
- }
- }
- inline T value() const
- {
- T result = T(0);
- while (is_true(condition_))
- {
- result = loop_body_->value();
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_while;
- }
- private:
- expression_ptr condition_;
- expression_ptr loop_body_;
- bool condition_deletable_;
- bool loop_body_deletable_;
- };
- template <typename T>
- class repeat_until_loop_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- repeat_until_loop_node(expression_ptr condition, expression_ptr loop_body)
- : condition_(condition),
- loop_body_(loop_body),
- condition_deletable_(branch_deletable(condition_)),
- loop_body_deletable_(branch_deletable(loop_body_))
- {}
- ~repeat_until_loop_node()
- {
- if (condition_ && condition_deletable_)
- {
- delete condition_;
- }
- if (loop_body_ && loop_body_deletable_)
- {
- delete loop_body_;
- }
- }
- inline T value() const
- {
- T result = T(0);
- do
- {
- result = loop_body_->value();
- }
- while (is_false(condition_));
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_repeat;
- }
- private:
- expression_ptr condition_;
- expression_ptr loop_body_;
- bool condition_deletable_;
- bool loop_body_deletable_;
- };
- template <typename T>
- class for_loop_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- for_loop_node(expression_ptr initialiser,
- expression_ptr condition,
- expression_ptr incrementor,
- expression_ptr loop_body)
- : initialiser_(initialiser),
- condition_ (condition),
- incrementor_(incrementor),
- loop_body_ (loop_body),
- initialiser_deletable_(branch_deletable(initialiser_)),
- condition_deletable_ (branch_deletable(condition_ )),
- incrementor_deletable_(branch_deletable(incrementor_)),
- loop_body_deletable_ (branch_deletable(loop_body_ ))
- {}
- ~for_loop_node()
- {
- if (initialiser_ && initialiser_deletable_)
- {
- delete initialiser_;
- }
- if (condition_ && condition_deletable_)
- {
- delete condition_;
- }
- if (incrementor_ && incrementor_deletable_)
- {
- delete incrementor_;
- }
- if (loop_body_ && loop_body_deletable_)
- {
- delete loop_body_;
- }
- }
- inline T value() const
- {
- T result = T(0);
- if (initialiser_)
- initialiser_->value();
- if (incrementor_)
- {
- while (is_true(condition_))
- {
- result = loop_body_->value();
- incrementor_->value();
- }
- }
- else
- {
- while (is_true(condition_))
- {
- result = loop_body_->value();
- }
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_for;
- }
- private:
- expression_ptr initialiser_;
- expression_ptr condition_ ;
- expression_ptr incrementor_;
- expression_ptr loop_body_ ;
- bool initialiser_deletable_;
- bool condition_deletable_ ;
- bool incrementor_deletable_;
- bool loop_body_deletable_ ;
- };
- #ifndef exprtk_disable_break_continue
- template <typename T>
- class while_loop_bc_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- while_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
- : condition_(condition),
- loop_body_(loop_body),
- condition_deletable_(branch_deletable(condition_)),
- loop_body_deletable_(branch_deletable(loop_body_))
- {}
- ~while_loop_bc_node()
- {
- if (condition_ && condition_deletable_)
- {
- delete condition_;
- }
- if (loop_body_ && loop_body_deletable_)
- {
- delete loop_body_;
- }
- }
- inline T value() const
- {
- T result = T(0);
- while (is_true(condition_))
- {
- try
- {
- result = loop_body_->value();
- }
- catch(const break_exception<T>& e)
- {
- return e.value;
- }
- catch(const continue_exception&)
- {}
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_while;
- }
- private:
- expression_ptr condition_;
- expression_ptr loop_body_;
- bool condition_deletable_;
- bool loop_body_deletable_;
- };
- template <typename T>
- class repeat_until_loop_bc_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
- : condition_(condition),
- loop_body_(loop_body),
- condition_deletable_(branch_deletable(condition_)),
- loop_body_deletable_(branch_deletable(loop_body_))
- {}
- ~repeat_until_loop_bc_node()
- {
- if (condition_ && condition_deletable_)
- {
- delete condition_;
- }
- if (loop_body_ && loop_body_deletable_)
- {
- delete loop_body_;
- }
- }
- inline T value() const
- {
- T result = T(0);
- do
- {
- try
- {
- result = loop_body_->value();
- }
- catch(const break_exception<T>& e)
- {
- return e.value;
- }
- catch(const continue_exception&)
- {}
- }
- while (is_false(condition_));
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_repeat;
- }
- private:
- expression_ptr condition_;
- expression_ptr loop_body_;
- bool condition_deletable_;
- bool loop_body_deletable_;
- };
- template <typename T>
- class for_loop_bc_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- for_loop_bc_node(expression_ptr initialiser,
- expression_ptr condition,
- expression_ptr incrementor,
- expression_ptr loop_body)
- : initialiser_(initialiser),
- condition_ (condition ),
- incrementor_(incrementor),
- loop_body_ (loop_body ),
- initialiser_deletable_(branch_deletable(initialiser_)),
- condition_deletable_ (branch_deletable(condition_ )),
- incrementor_deletable_(branch_deletable(incrementor_)),
- loop_body_deletable_ (branch_deletable(loop_body_ ))
- {}
- ~for_loop_bc_node()
- {
- if (initialiser_ && initialiser_deletable_)
- {
- delete initialiser_;
- }
- if (condition_ && condition_deletable_)
- {
- delete condition_;
- }
- if (incrementor_ && incrementor_deletable_)
- {
- delete incrementor_;
- }
- if (loop_body_ && loop_body_deletable_)
- {
- delete loop_body_;
- }
- }
- inline T value() const
- {
- T result = T(0);
- if (initialiser_)
- initialiser_->value();
- if (incrementor_)
- {
- while (is_true(condition_))
- {
- try
- {
- result = loop_body_->value();
- }
- catch(const break_exception<T>& e)
- {
- return e.value;
- }
- catch(const continue_exception&)
- {}
- incrementor_->value();
- }
- }
- else
- {
- while (is_true(condition_))
- {
- try
- {
- result = loop_body_->value();
- }
- catch(const break_exception<T>& e)
- {
- return e.value;
- }
- catch(const continue_exception&)
- {}
- }
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_for;
- }
- private:
- expression_ptr initialiser_;
- expression_ptr condition_ ;
- expression_ptr incrementor_;
- expression_ptr loop_body_ ;
- bool initialiser_deletable_;
- bool condition_deletable_ ;
- bool incrementor_deletable_;
- bool loop_body_deletable_ ;
- };
- #endif
- template <typename T>
- class switch_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- template <typename Allocator,
- template <typename,typename> class Sequence>
- switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
- {
- if (1 != (arg_list.size() & 1))
- return;
- arg_list_.resize(arg_list.size());
- delete_branch_.resize(arg_list.size());
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- if (arg_list[i])
- {
- arg_list_[i] = arg_list[i];
- delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
- }
- else
- {
- arg_list_.clear();
- delete_branch_.clear();
- return;
- }
- }
- }
- ~switch_node()
- {
- for (std::size_t i = 0; i < arg_list_.size(); ++i)
- {
- if (arg_list_[i] && delete_branch_[i])
- {
- delete arg_list_[i];
- arg_list_[i] = 0;
- }
- }
- }
- inline T value() const
- {
- if (!arg_list_.empty())
- {
- const std::size_t upper_bound = (arg_list_.size() - 1);
- for (std::size_t i = 0; i < upper_bound; i += 2)
- {
- expression_ptr condition = arg_list_[i ];
- expression_ptr consequent = arg_list_[i + 1];
- if (is_true(condition))
- {
- return consequent->value();
- }
- }
- return arg_list_[upper_bound]->value();
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_switch;
- }
- protected:
- std::vector<expression_ptr> arg_list_;
- std::vector<unsigned char> delete_branch_;
- };
- template <typename T, typename Switch_N>
- class switch_n_node : public switch_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- template <typename Allocator,
- template <typename,typename> class Sequence>
- switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
- : switch_node<T>(arg_list)
- {}
- inline T value() const
- {
- return Switch_N::process(switch_node<T>::arg_list_);
- }
- };
- template <typename T>
- class multi_switch_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- template <typename Allocator,
- template <typename,typename> class Sequence>
- multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
- {
- if (0 != (arg_list.size() & 1))
- return;
- arg_list_.resize(arg_list.size());
- delete_branch_.resize(arg_list.size());
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- if (arg_list[i])
- {
- arg_list_[i] = arg_list[i];
- delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
- }
- else
- {
- arg_list_.clear();
- delete_branch_.clear();
- return;
- }
- }
- }
- ~multi_switch_node()
- {
- for (std::size_t i = 0; i < arg_list_.size(); ++i)
- {
- if (arg_list_[i] && delete_branch_[i])
- {
- delete arg_list_[i];
- arg_list_[i] = 0;
- }
- }
- }
- inline T value() const
- {
- T result = T(0);
- if (arg_list_.empty())
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- const std::size_t upper_bound = (arg_list_.size() - 1);
- for (std::size_t i = 0; i < upper_bound; i += 2)
- {
- expression_ptr condition = arg_list_[i ];
- expression_ptr consequent = arg_list_[i + 1];
- if (is_true(condition))
- {
- result = consequent->value();
- }
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_mswitch;
- }
- private:
- std::vector<expression_ptr> arg_list_;
- std::vector<unsigned char> delete_branch_;
- };
- template <typename T>
- class ivariable
- {
- public:
- virtual T& ref() = 0;
- virtual const T& ref() const = 0;
- };
- template <typename T>
- class variable_node : public expression_node<T>,
- public ivariable <T>
- {
- public:
- static T null_value;
- explicit variable_node()
- : value_(&null_value),
- delete_value_(false)
- {}
- variable_node(T& v)
- : value_(&v),
- delete_value_(false)
- {}
- ~variable_node()
- {
- if (delete_value_)
- {
- delete value_;
- }
- }
- inline bool operator <(const variable_node<T>& v) const
- {
- return this < (&v);
- }
- inline T value() const
- {
- return (*value_);
- }
- inline T& ref()
- {
- return (*value_);
- }
- inline const T& ref() const
- {
- return (*value_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_variable;
- }
- inline bool& delete_value()
- {
- return delete_value_;
- }
- private:
- T* value_;
- bool delete_value_;
- };
- template <typename T>
- T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
- template <typename T>
- struct range_pack
- {
- typedef expression_node<T>* expression_node_ptr;
- typedef std::pair<std::size_t,std::size_t> cached_range_t;
- range_pack()
- : n0_e (std::make_pair(false,expression_node_ptr(0))),
- n1_e (std::make_pair(false,expression_node_ptr(0))),
- n0_c (std::make_pair(false,0)),
- n1_c (std::make_pair(false,0)),
- cache(std::make_pair(0,0))
- {}
- void clear()
- {
- n0_e = std::make_pair(false,expression_node_ptr(0));
- n1_e = std::make_pair(false,expression_node_ptr(0));
- n0_c = std::make_pair(false,0);
- n1_c = std::make_pair(false,0);
- cache = std::make_pair(0,0);
- }
- void free()
- {
- if (n0_e.first && n0_e.second)
- {
- n0_e.first = false;
- if (
- !is_variable_node(n0_e.second) &&
- !is_string_node (n0_e.second)
- )
- {
- delete n0_e.second;
- n0_e.second = expression_node_ptr(0);
- }
- }
- if (n1_e.first && n1_e.second)
- {
- n1_e.first = false;
- if (
- !is_variable_node(n1_e.second) &&
- !is_string_node (n1_e.second)
- )
- {
- delete n1_e.second;
- n1_e.second = expression_node_ptr(0);
- }
- }
- }
- bool const_range()
- {
- return ( n0_c.first && n1_c.first) &&
- (!n0_e.first && !n1_e.first);
- }
- bool var_range()
- {
- return ( n0_e.first && n1_e.first) &&
- (!n0_c.first && !n1_c.first);
- }
- bool operator()(std::size_t& r0, std::size_t& r1, const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
- {
- if (n0_c.first)
- r0 = n0_c.second;
- else if (n0_e.first)
- {
- T r0_value = n0_e.second->value();
- if (r0_value < 0)
- return false;
- else
- r0 = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
- }
- else
- return false;
- if (n1_c.first)
- r1 = n1_c.second;
- else if (n1_e.first)
- {
- T r1_value = n1_e.second->value();
- if (r1_value < 0)
- return false;
- else
- r1 = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
- }
- else
- return false;
- if (
- (std::numeric_limits<std::size_t>::max() != size) &&
- (std::numeric_limits<std::size_t>::max() == r1 )
- )
- {
- r1 = size - 1;
- }
- cache.first = r0;
- cache.second = r1;
- return (r0 <= r1);
- }
- inline std::size_t const_size() const
- {
- return (n1_c.second - n0_c.second + 1);
- }
- inline std::size_t cache_size() const
- {
- return (cache.second - cache.first + 1);
- }
- std::pair<bool,expression_node_ptr> n0_e;
- std::pair<bool,expression_node_ptr> n1_e;
- std::pair<bool,std::size_t > n0_c;
- std::pair<bool,std::size_t > n1_c;
- mutable cached_range_t cache;
- };
- template <typename T>
- class string_base_node;
- template <typename T>
- struct range_data_type
- {
- typedef range_pack<T> range_t;
- typedef string_base_node<T>* strbase_ptr_t;
- range_data_type()
- : range(0),
- data (0),
- size (0),
- type_size(0),
- str_node (0)
- {}
- range_t* range;
- void* data;
- std::size_t size;
- std::size_t type_size;
- strbase_ptr_t str_node;
- };
- template <typename T> class vector_node;
- template <typename T>
- class vector_interface
- {
- public:
- typedef vector_node<T>* vector_node_ptr;
- virtual ~vector_interface()
- {}
- virtual vector_node_ptr vec() const = 0;
- virtual vector_node_ptr vec() = 0;
- virtual std::size_t size() const = 0;
- };
- template <typename T>
- class vector_node : public expression_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_holder<T> vector_holder_t;
- typedef vector_node<T>* vector_node_ptr;
- vector_node(vector_holder_t* vh)
- : vector_holder_(vh)
- {}
- inline T value() const
- {
- return *(ref()[0]);
- }
- inline const vector_holder_t& ref() const
- {
- return (*vector_holder_);
- }
- inline vector_holder_t& ref()
- {
- return (*vector_holder_);
- }
- vector_node_ptr vec() const
- {
- return const_cast<vector_node_ptr>(this);
- }
- vector_node_ptr vec()
- {
- return this;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vector;
- }
- std::size_t size() const
- {
- return ref().size();
- }
- private:
- vector_holder_t* vector_holder_;
- };
- template <typename T>
- class vector_elem_node : public expression_node<T>,
- public ivariable <T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- vector_elem_node(expression_ptr index, T* vector_base)
- : index_(index),
- vector_base_(vector_base),
- index_deletable_(branch_deletable(index_))
- {}
- ~vector_elem_node()
- {
- if (index_ && index_deletable_)
- {
- delete index_;
- }
- }
- inline T value() const
- {
- return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
- }
- inline T& ref()
- {
- return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
- }
- inline const T& ref() const
- {
- return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecelem;
- }
- private:
- expression_ptr index_;
- T* vector_base_;
- bool index_deletable_;
- };
- template <typename T>
- class vector_assignment_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- vector_assignment_node(T* vector_base,
- const std::size_t& size,
- const std::vector<expression_ptr>& initialiser_list,
- const bool single_value_initialse)
- : vector_base_(vector_base),
- initialiser_list_(initialiser_list),
- size_(size),
- single_value_initialse_(single_value_initialse)
- {}
- ~vector_assignment_node()
- {
- for (std::size_t i = 0; i < initialiser_list_.size(); ++i)
- {
- if (branch_deletable(initialiser_list_[i]))
- {
- delete initialiser_list_[i];
- }
- }
- }
- inline T value() const
- {
- if (single_value_initialse_)
- {
- for (std::size_t i = 0; i < size_; ++i)
- {
- *(vector_base_ + i) = initialiser_list_[0]->value();
- }
- }
- else
- {
- std::size_t il_size = initialiser_list_.size();
- for (std::size_t i = 0; i < il_size; ++i)
- {
- *(vector_base_ + i) = initialiser_list_[i]->value();
- }
- if (il_size < size_)
- {
- for (std::size_t i = il_size; i < size_; ++i)
- {
- *(vector_base_ + i) = T(0);
- }
- }
- }
- return *(vector_base_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecdefass;
- }
- private:
- vector_assignment_node<T>& operator=(const vector_assignment_node<T>&);
- mutable T* vector_base_;
- std::vector<expression_ptr> initialiser_list_;
- const std::size_t size_;
- const bool single_value_initialse_;
- };
- template <typename T>
- class swap_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef variable_node<T>* variable_node_ptr;
- swap_node(variable_node_ptr var0, variable_node_ptr var1)
- : var0_(var0),
- var1_(var1)
- {}
- inline T value() const
- {
- std::swap(var0_->ref(),var1_->ref());
- return var1_->ref();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_swap;
- }
- private:
- variable_node_ptr var0_;
- variable_node_ptr var1_;
- };
- template <typename T>
- class swap_generic_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef ivariable<T>* ivariable_ptr;
- swap_generic_node(expression_ptr var0, expression_ptr var1)
- : binary_node<T>(details::e_swap,var0,var1),
- var0_(dynamic_cast<ivariable_ptr>(var0)),
- var1_(dynamic_cast<ivariable_ptr>(var1))
- {}
- inline T value() const
- {
- std::swap(var0_->ref(),var1_->ref());
- return var1_->ref();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_swap;
- }
- private:
- ivariable_ptr var0_;
- ivariable_ptr var1_;
- };
- template <typename T>
- class swap_vecvec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- swap_vecvec_node(expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(details::e_swap,branch0,branch1),
- vec0_node_ptr_(0),
- vec1_node_ptr_(0),
- vec_size_ (0),
- initialised_(false)
- {
- if (is_ivector_node(binary_node<T>::branch_[0].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
- {
- vec0_node_ptr_ = vi->vec();
- }
- }
- if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec1_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- vec_size_ = std::min(vec0_node_ptr_->ref().size(),
- vec1_node_ptr_->ref().size());
- initialised_ = true;
- }
- }
- inline T value() const
- {
- if (initialised_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- std::swap((*vec0[i]),(*vec1[i]));
- }
- return vec1_node_ptr_->value();
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec0_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec0_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvecswap;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec0_node_ptr_;
- vector_node<T>* vec1_node_ptr_;
- std::size_t vec_size_;
- bool initialised_;
- };
- #ifndef exprtk_disable_string_capabilities
- template <typename T>
- class stringvar_node : public expression_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef range_pack<T> range_t;
- static std::string null_value;
- explicit stringvar_node()
- : value_(&null_value)
- {}
- explicit stringvar_node(std::string& v)
- : value_(&v)
- {
- rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
- rp_.cache.first = rp_.n0_c.second;
- rp_.cache.second = rp_.n1_c.second;
- }
- inline bool operator <(const stringvar_node<T>& v) const
- {
- return this < (&v);
- }
- inline T value() const
- {
- rp_.n1_c.second = (*value_).size() - 1;
- rp_.cache.second = rp_.n1_c.second;
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return ref();
- }
- const char* base() const
- {
- return (*value_).data();
- }
- std::size_t size() const
- {
- return ref().size();
- }
- std::string& ref()
- {
- return (*value_);
- }
- const std::string& ref() const
- {
- return (*value_);
- }
- range_t& range_ref()
- {
- return rp_;
- }
- const range_t& range_ref() const
- {
- return rp_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_stringvar;
- }
- private:
- std::string* value_;
- mutable range_t rp_;
- };
- template <typename T>
- std::string stringvar_node<T>::null_value = std::string("");
- template <typename T>
- class string_range_node : public expression_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef range_pack<T> range_t;
- static std::string null_value;
- explicit string_range_node(std::string& v, range_t rp)
- : value_(&v),
- rp_(rp)
- {}
- ~string_range_node()
- {
- rp_.free();
- }
- inline bool operator <(const string_range_node<T>& v) const
- {
- return this < (&v);
- }
- inline T value() const
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline std::string str() const
- {
- return (*value_);
- }
- const char* base() const
- {
- return (*value_).data();
- }
- std::size_t size() const
- {
- return ref().size();
- }
- inline range_t range() const
- {
- return rp_;
- }
- inline virtual std::string& ref()
- {
- return (*value_);
- }
- inline virtual const std::string& ref() const
- {
- return (*value_);
- }
- inline range_t& range_ref()
- {
- return rp_;
- }
- inline const range_t& range_ref() const
- {
- return rp_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_stringvarrng;
- }
- private:
- std::string* value_;
- range_t rp_;
- };
- template <typename T>
- std::string string_range_node<T>::null_value = std::string("");
- template <typename T>
- class const_string_range_node : public expression_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef range_pack<T> range_t;
- explicit const_string_range_node(const std::string& v, range_t rp)
- : value_(v),
- rp_(rp)
- {}
- ~const_string_range_node()
- {
- rp_.free();
- }
- inline T value() const
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return value_;
- }
- const char* base() const
- {
- return value_.data();
- }
- std::size_t size() const
- {
- return value_.size();
- }
- range_t range() const
- {
- return rp_;
- }
- range_t& range_ref()
- {
- return rp_;
- }
- const range_t& range_ref() const
- {
- return rp_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_cstringvarrng;
- }
- private:
- const_string_range_node<T>& operator=(const const_string_range_node<T>&);
- const std::string value_;
- range_t rp_;
- };
- template <typename T>
- class generic_string_range_node : public expression_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef stringvar_node <T>* strvar_node_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- generic_string_range_node(expression_ptr str_branch, range_t brange)
- : initialised_(false),
- branch_(str_branch),
- branch_deletable_(branch_deletable(branch_)),
- str_base_ptr_ (0),
- str_range_ptr_(0),
- base_range_(brange)
- {
- range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
- range_.cache.first = range_.n0_c.second;
- range_.cache.second = range_.n1_c.second;
- if (is_generally_string_node(branch_))
- {
- str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
- if (0 == str_base_ptr_)
- return;
- str_range_ptr_ = dynamic_cast<irange_ptr>(branch_);
- if (0 == str_range_ptr_)
- return;
- }
- initialised_ = (str_base_ptr_ && str_range_ptr_);
- }
- ~generic_string_range_node()
- {
- base_range_.free();
- if (branch_ && branch_deletable_)
- {
- delete branch_;
- branch_ = 0;
- }
- }
- inline T value() const
- {
- if (initialised_)
- {
- branch_->value();
- std::size_t str_r0 = 0;
- std::size_t str_r1 = 0;
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- range_t& range = str_range_ptr_->range_ref();
- const std::size_t base_str_size = str_base_ptr_->size();
- if (
- range (str_r0,str_r1,base_str_size) &&
- base_range_( r0, r1,base_str_size)
- )
- {
- const std::size_t size = (r1 - r0) + 1;
- range_.n1_c.second = size - 1;
- range_.cache.second = range_.n1_c.second;
- value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return value_;
- }
- const char* base() const
- {
- return value_.data();
- }
- std::size_t size() const
- {
- return value_.size();
- }
- range_t& range_ref()
- {
- return range_;
- }
- const range_t& range_ref() const
- {
- return range_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strgenrange;
- }
- private:
- bool initialised_;
- expression_ptr branch_;
- bool branch_deletable_;
- str_base_ptr str_base_ptr_;
- irange_ptr str_range_ptr_;
- mutable range_t base_range_;
- mutable range_t range_;
- mutable std::string value_;
- };
- template <typename T>
- class string_concat_node : public binary_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- string_concat_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- initialised_(false),
- str0_base_ptr_ (0),
- str1_base_ptr_ (0),
- str0_range_ptr_(0),
- str1_range_ptr_(0)
- {
- range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
- range_.cache.first = range_.n0_c.second;
- range_.cache.second = range_.n1_c.second;
- if (is_generally_string_node(binary_node<T>::branch_[0].first))
- {
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
- if (0 == str0_base_ptr_)
- return;
- str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
- if (0 == str0_range_ptr_)
- return;
- }
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
- {
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
- if (0 == str1_base_ptr_)
- return;
- str1_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
- if (0 == str1_range_ptr_)
- return;
- }
- initialised_ = str0_base_ptr_ &&
- str1_base_ptr_ &&
- str0_range_ptr_ &&
- str1_range_ptr_ ;
- }
- inline T value() const
- {
- if (initialised_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- std::size_t str0_r0 = 0;
- std::size_t str0_r1 = 0;
- std::size_t str1_r0 = 0;
- std::size_t str1_r1 = 0;
- range_t& range0 = str0_range_ptr_->range_ref();
- range_t& range1 = str1_range_ptr_->range_ref();
- if (
- range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
- range1(str1_r0,str1_r1,str1_base_ptr_->size())
- )
- {
- const std::size_t size0 = (str0_r1 - str0_r0) + 1;
- const std::size_t size1 = (str1_r1 - str1_r0) + 1;
- value_.assign(str0_base_ptr_->base() + str0_r0, size0);
- value_.append(str1_base_ptr_->base() + str1_r0, size1);
- range_.n1_c.second = value_.size() - 1;
- range_.cache.second = range_.n1_c.second;
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return value_;
- }
- const char* base() const
- {
- return value_.data();
- }
- std::size_t size() const
- {
- return value_.size();
- }
- range_t& range_ref()
- {
- return range_;
- }
- const range_t& range_ref() const
- {
- return range_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strconcat;
- }
- private:
- bool initialised_;
- str_base_ptr str0_base_ptr_;
- str_base_ptr str1_base_ptr_;
- irange_ptr str0_range_ptr_;
- irange_ptr str1_range_ptr_;
- mutable range_t range_;
- mutable std::string value_;
- };
- template <typename T>
- class swap_string_node : public binary_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef stringvar_node <T>* strvar_node_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- swap_string_node(expression_ptr branch0, expression_ptr branch1)
- : binary_node<T>(details::e_swap,branch0,branch1),
- initialised_(false),
- str0_node_ptr_(0),
- str1_node_ptr_(0)
- {
- if (is_string_node(binary_node<T>::branch_[0].first))
- {
- str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
- }
- if (is_string_node(binary_node<T>::branch_[1].first))
- {
- str1_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[1].first);
- }
- initialised_ = (str0_node_ptr_ && str1_node_ptr_);
- }
- inline T value() const
- {
- if (initialised_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- std::swap(str0_node_ptr_->ref(),str1_node_ptr_->ref());
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return str0_node_ptr_->str();
- }
- const char* base() const
- {
- return str0_node_ptr_->base();
- }
- std::size_t size() const
- {
- return str0_node_ptr_->size();
- }
- range_t& range_ref()
- {
- return str0_node_ptr_->range_ref();
- }
- const range_t& range_ref() const
- {
- return str0_node_ptr_->range_ref();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strswap;
- }
- private:
- bool initialised_;
- strvar_node_ptr str0_node_ptr_;
- strvar_node_ptr str1_node_ptr_;
- };
- template <typename T>
- class stringvar_size_node : public expression_node<T>
- {
- public:
- static std::string null_value;
- explicit stringvar_size_node()
- : value_(&null_value)
- {}
- explicit stringvar_size_node(std::string& v)
- : value_(&v)
- {}
- inline T value() const
- {
- return T((*value_).size());
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_stringvarsize;
- }
- private:
- std::string* value_;
- };
- template <typename T>
- std::string stringvar_size_node<T>::null_value = std::string("");
- template <typename T>
- class string_size_node : public expression_node<T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef string_base_node<T>* str_base_ptr;
- string_size_node(expression_ptr brnch)
- : branch_(brnch),
- branch_deletable_(branch_deletable(branch_)),
- str_base_ptr_(0)
- {
- if (is_generally_string_node(branch_))
- {
- str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
- if (0 == str_base_ptr_)
- return;
- }
- }
- ~string_size_node()
- {
- if (branch_ && branch_deletable_)
- {
- delete branch_;
- branch_ = 0;
- }
- }
- inline T value() const
- {
- T result = std::numeric_limits<T>::quiet_NaN();
- if (str_base_ptr_)
- {
- branch_->value();
- result = T(str_base_ptr_->size());
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_stringsize;
- }
- private:
- expression_ptr branch_;
- bool branch_deletable_;
- str_base_ptr str_base_ptr_;
- };
- struct asn_assignment
- {
- static inline void execute(std::string& s, const char* data, const std::size_t size)
- { s.assign(data,size); }
- };
- struct asn_addassignment
- {
- static inline void execute(std::string& s, const char* data, const std::size_t size)
- { s.append(data,size); }
- };
- template <typename T, typename AssignmentProcess = asn_assignment>
- class assignment_string_node : public binary_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef stringvar_node <T>* strvar_node_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- assignment_string_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- initialised_(false),
- str0_base_ptr_ (0),
- str1_base_ptr_ (0),
- str0_node_ptr_ (0),
- str1_range_ptr_(0)
- {
- if (is_string_node(binary_node<T>::branch_[0].first))
- {
- str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
- }
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
- {
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
- if (0 == str1_base_ptr_)
- return;
- irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
- if (0 == range_ptr)
- return;
- str1_range_ptr_ = &(range_ptr->range_ref());
- }
- initialised_ = str0_base_ptr_ &&
- str1_base_ptr_ &&
- str0_node_ptr_ &&
- str1_range_ptr_ ;
- }
- inline T value() const
- {
- if (initialised_)
- {
- binary_node<T>::branch_[1].first->value();
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- range_t& range = (*str1_range_ptr_);
- if (range(r0,r1,str1_base_ptr_->size()))
- {
- AssignmentProcess::execute(str0_node_ptr_->ref(),
- str1_base_ptr_->base() + r0,
- (r1 - r0) + 1);
- binary_node<T>::branch_[0].first->value();
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return str0_node_ptr_->str();
- }
- const char* base() const
- {
- return str0_node_ptr_->base();
- }
- std::size_t size() const
- {
- return str0_node_ptr_->size();
- }
- range_t& range_ref()
- {
- return str0_node_ptr_->range_ref();
- }
- const range_t& range_ref() const
- {
- return str0_node_ptr_->range_ref();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strass;
- }
- private:
- bool initialised_;
- str_base_ptr str0_base_ptr_;
- str_base_ptr str1_base_ptr_;
- strvar_node_ptr str0_node_ptr_;
- range_ptr str1_range_ptr_;
- };
- template <typename T, typename AssignmentProcess = asn_assignment>
- class assignment_string_range_node : public binary_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef stringvar_node <T>* strvar_node_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- assignment_string_range_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- initialised_(false),
- str0_base_ptr_ (0),
- str1_base_ptr_ (0),
- str0_node_ptr_ (0),
- str0_range_ptr_(0),
- str1_range_ptr_(0)
- {
- if (is_string_range_node(binary_node<T>::branch_[0].first))
- {
- str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
- irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
- if (0 == range_ptr)
- return;
- str0_range_ptr_ = &(range_ptr->range_ref());
- }
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
- {
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
- if (0 == str1_base_ptr_)
- return;
- irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
- if (0 == range_ptr)
- return;
- str1_range_ptr_ = &(range_ptr->range_ref());
- }
- initialised_ = str0_base_ptr_ &&
- str1_base_ptr_ &&
- str0_node_ptr_ &&
- str0_range_ptr_ &&
- str1_range_ptr_ ;
- }
- inline T value() const
- {
- if (initialised_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- std::size_t s0_r0 = 0;
- std::size_t s0_r1 = 0;
- std::size_t s1_r0 = 0;
- std::size_t s1_r1 = 0;
- range_t& range0 = (*str0_range_ptr_);
- range_t& range1 = (*str1_range_ptr_);
- if (
- range0(s0_r0,s0_r1,str0_base_ptr_->size()) &&
- range1(s1_r0,s1_r1,str1_base_ptr_->size())
- )
- {
- std::size_t size = std::min((s0_r1 - s0_r0),(s1_r1 - s1_r0)) + 1;
- std::copy(str1_base_ptr_->base() + s1_r0,
- str1_base_ptr_->base() + s1_r0 + size,
- const_cast<char*>(base() + s0_r0));
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return str0_node_ptr_->str();
- }
- const char* base() const
- {
- return str0_node_ptr_->base();
- }
- std::size_t size() const
- {
- return str0_node_ptr_->size();
- }
- range_t& range_ref()
- {
- return str0_node_ptr_->range_ref();
- }
- const range_t& range_ref() const
- {
- return str0_node_ptr_->range_ref();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strass;
- }
- private:
- bool initialised_;
- str_base_ptr str0_base_ptr_;
- str_base_ptr str1_base_ptr_;
- strvar_node_ptr str0_node_ptr_;
- range_ptr str0_range_ptr_;
- range_ptr str1_range_ptr_;
- };
- template <typename T>
- class conditional_string_node : public trinary_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- conditional_string_node(expression_ptr test,
- expression_ptr consequent,
- expression_ptr alternative)
- : trinary_node<T>(details::e_default,consequent,alternative,test),
- initialised_(false),
- str0_base_ptr_ (0),
- str1_base_ptr_ (0),
- str0_range_ptr_(0),
- str1_range_ptr_(0),
- test_ (test),
- consequent_ (consequent),
- alternative_(alternative)
- {
- range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
- range_.cache.first = range_.n0_c.second;
- range_.cache.second = range_.n1_c.second;
- if (is_generally_string_node(trinary_node<T>::branch_[0].first))
- {
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first);
- if (0 == str0_base_ptr_)
- return;
- str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first);
- if (0 == str0_range_ptr_)
- return;
- }
- if (is_generally_string_node(trinary_node<T>::branch_[1].first))
- {
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first);
- if (0 == str1_base_ptr_)
- return;
- str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first);
- if (0 == str1_range_ptr_)
- return;
- }
- initialised_ = str0_base_ptr_ &&
- str1_base_ptr_ &&
- str0_range_ptr_ &&
- str1_range_ptr_ ;
- }
- inline T value() const
- {
- if (initialised_)
- {
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- if (is_true(test_))
- {
- consequent_->value();
- range_t& range = str0_range_ptr_->range_ref();
- if (range(r0,r1,str0_base_ptr_->size()))
- {
- const std::size_t size = (r1 - r0) + 1;
- value_.assign(str0_base_ptr_->base() + r0, size);
- range_.n1_c.second = value_.size() - 1;
- range_.cache.second = range_.n1_c.second;
- return T(1);
- }
- }
- else
- {
- alternative_->value();
- range_t& range = str1_range_ptr_->range_ref();
- if (range(r0,r1,str1_base_ptr_->size()))
- {
- const std::size_t size = (r1 - r0) + 1;
- value_.assign(str1_base_ptr_->base() + r0, size);
- range_.n1_c.second = value_.size() - 1;
- range_.cache.second = range_.n1_c.second;
- return T(0);
- }
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return value_;
- }
- const char* base() const
- {
- return value_.data();
- }
- std::size_t size() const
- {
- return value_.size();
- }
- range_t& range_ref()
- {
- return range_;
- }
- const range_t& range_ref() const
- {
- return range_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strcondition;
- }
- private:
- bool initialised_;
- str_base_ptr str0_base_ptr_;
- str_base_ptr str1_base_ptr_;
- irange_ptr str0_range_ptr_;
- irange_ptr str1_range_ptr_;
- mutable range_t range_;
- mutable std::string value_;
- expression_ptr test_;
- expression_ptr consequent_;
- expression_ptr alternative_;
- };
- template <typename T>
- class cons_conditional_str_node : public binary_node <T>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- cons_conditional_str_node(expression_ptr test,
- expression_ptr consequent)
- : binary_node<T>(details::e_default,consequent,test),
- initialised_(false),
- str0_base_ptr_ (0),
- str0_range_ptr_(0),
- test_ (test),
- consequent_(consequent)
- {
- range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
- range_.cache.first = range_.n0_c.second;
- range_.cache.second = range_.n1_c.second;
- if (is_generally_string_node(binary_node<T>::branch_[0].first))
- {
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
- if (0 == str0_base_ptr_)
- return;
- str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
- if (0 == str0_range_ptr_)
- return;
- }
- initialised_ = str0_base_ptr_ && str0_range_ptr_ ;
- }
- inline T value() const
- {
- if (initialised_)
- {
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- if (is_true(test_))
- {
- consequent_->value();
- range_t& range = str0_range_ptr_->range_ref();
- if (range(r0,r1,str0_base_ptr_->size()))
- {
- const std::size_t size = (r1 - r0) + 1;
- value_.assign(str0_base_ptr_->base() + r0, size);
- range_.n1_c.second = value_.size() - 1;
- range_.cache.second = range_.n1_c.second;
- return T(1);
- }
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string str() const
- {
- return value_;
- }
- const char* base() const
- {
- return value_.data();
- }
- std::size_t size() const
- {
- return value_.size();
- }
- range_t& range_ref()
- {
- return range_;
- }
- const range_t& range_ref() const
- {
- return range_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strccondition;
- }
- private:
- bool initialised_;
- str_base_ptr str0_base_ptr_;
- irange_ptr str0_range_ptr_;
- mutable range_t range_;
- mutable std::string value_;
- expression_ptr test_;
- expression_ptr consequent_;
- };
- #endif
- template <typename T, std::size_t N>
- inline T axn(T a, T x)
- {
- // a*x^n
- return a * exprtk::details::numeric::fast_exp<T,N>::result(x);
- }
- template <typename T, std::size_t N>
- inline T axnb(T a, T x, T b)
- {
- // a*x^n+b
- return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b;
- }
- template <typename T>
- struct sf_base
- {
- typedef typename details::functor_t<T>::Type Type;
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::qfunc_t quaternary_functor_t;
- typedef typename functor_t::tfunc_t trinary_functor_t;
- typedef typename functor_t::bfunc_t binary_functor_t;
- typedef typename functor_t::ufunc_t unary_functor_t;
- };
- #define define_sfop3(NN,OP0,OP1) \
- template <typename T> \
- struct sf##NN##_op : public sf_base<T> \
- { \
- typedef typename sf_base<T>::Type Type; \
- static inline T process(Type x, Type y, Type z) \
- { \
- return (OP0); \
- } \
- static inline std::string id() \
- { \
- return OP1; \
- } \
- }; \
- define_sfop3(00,(x + y) / z ,"(t+t)/t")
- define_sfop3(01,(x + y) * z ,"(t+t)*t")
- define_sfop3(02,(x + y) - z ,"(t+t)-t")
- define_sfop3(03,(x + y) + z ,"(t+t)+t")
- define_sfop3(04,(x - y) + z ,"(t-t)+t")
- define_sfop3(05,(x - y) / z ,"(t-t)/t")
- define_sfop3(06,(x - y) * z ,"(t-t)*t")
- define_sfop3(07,(x * y) + z ,"(t*t)+t")
- define_sfop3(08,(x * y) - z ,"(t*t)-t")
- define_sfop3(09,(x * y) / z ,"(t*t)/t")
- define_sfop3(10,(x * y) * z ,"(t*t)*t")
- define_sfop3(11,(x / y) + z ,"(t/t)+t")
- define_sfop3(12,(x / y) - z ,"(t/t)-t")
- define_sfop3(13,(x / y) / z ,"(t/t)/t")
- define_sfop3(14,(x / y) * z ,"(t/t)*t")
- define_sfop3(15,x / (y + z) ,"t/(t+t)")
- define_sfop3(16,x / (y - z) ,"t/(t-t)")
- define_sfop3(17,x / (y * z) ,"t/(t*t)")
- define_sfop3(18,x / (y / z) ,"t/(t/t)")
- define_sfop3(19,x * (y + z) ,"t*(t+t)")
- define_sfop3(20,x * (y - z) ,"t*(t-t)")
- define_sfop3(21,x * (y * z) ,"t*(t*t)")
- define_sfop3(22,x * (y / z) ,"t*(t/t)")
- define_sfop3(23,x - (y + z) ,"t-(t+t)")
- define_sfop3(24,x - (y - z) ,"t-(t-t)")
- define_sfop3(25,x - (y / z) ,"t-(t/t)")
- define_sfop3(26,x - (y * z) ,"t-(t*t)")
- define_sfop3(27,x + (y * z) ,"t+(t*t)")
- define_sfop3(28,x + (y / z) ,"t+(t/t)")
- define_sfop3(29,x + (y + z) ,"t+(t+t)")
- define_sfop3(30,x + (y - z) ,"t+(t-t)")
- define_sfop3(31,(axnb<T,2>(x,y,z))," ")
- define_sfop3(32,(axnb<T,3>(x,y,z))," ")
- define_sfop3(33,(axnb<T,4>(x,y,z))," ")
- define_sfop3(34,(axnb<T,5>(x,y,z))," ")
- define_sfop3(35,(axnb<T,6>(x,y,z))," ")
- define_sfop3(36,(axnb<T,7>(x,y,z))," ")
- define_sfop3(37,(axnb<T,8>(x,y,z))," ")
- define_sfop3(38,(axnb<T,9>(x,y,z))," ")
- define_sfop3(39,x * numeric::log(y) + z,"")
- define_sfop3(40,x * numeric::log(y) - z,"")
- define_sfop3(41,x * numeric::log10(y) + z,"")
- define_sfop3(42,x * numeric::log10(y) - z,"")
- define_sfop3(43,x * numeric::sin(y) + z ,"")
- define_sfop3(44,x * numeric::sin(y) - z ,"")
- define_sfop3(45,x * numeric::cos(y) + z ,"")
- define_sfop3(46,x * numeric::cos(y) - z ,"")
- define_sfop3(47,details::is_true(x) ? y : z,"")
- #define define_sfop4(NN,OP0,OP1) \
- template <typename T> \
- struct sf##NN##_op : public sf_base<T> \
- { \
- typedef typename sf_base<T>::Type Type; \
- static inline T process(Type x, Type y, Type z, Type w) \
- { \
- return (OP0); \
- } \
- static inline std::string id() { return OP1; } \
- }; \
- define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
- define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)")
- define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)")
- define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)")
- define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)")
- define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)")
- define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)")
- define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)")
- define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)")
- define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)")
- define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)")
- define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)")
- define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)")
- define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)")
- define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)")
- define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)")
- define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)")
- define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t")
- define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t")
- define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t")
- define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t")
- define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t")
- define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t")
- define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t")
- define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t")
- define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)")
- define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)")
- define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)")
- define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)")
- define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)")
- define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)")
- define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)")
- define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))")
- define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))")
- define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))")
- define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))")
- define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"")
- define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"")
- define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"")
- define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"")
- define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"")
- define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"")
- define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"")
- define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"")
- define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"")
- define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"")
- define_sfop4(94,((x < y) ? z : w),"")
- define_sfop4(95,((x <= y) ? z : w),"")
- define_sfop4(96,((x > y) ? z : w),"")
- define_sfop4(97,((x >= y) ? z : w),"")
- define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"")
- define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"")
- define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)")
- define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)")
- define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)")
- define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)")
- define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)")
- define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)")
- define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)")
- define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)")
- define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)")
- define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)")
- define_sfop4(ext10,((x + y) * (z - w)),"(t+t)*(t-t)")
- define_sfop4(ext11,((x + y) / (z - w)),"(t+t)/(t-t)")
- define_sfop4(ext12,((x - y) - (z + w)),"(t-t)-(t+t)")
- define_sfop4(ext13,((x - y) + (z + w)),"(t-t)+(t+t)")
- define_sfop4(ext14,((x - y) * (z + w)),"(t-t)*(t+t)")
- define_sfop4(ext15,((x - y) / (z + w)),"(t-t)/(t+t)")
- define_sfop4(ext16,((x * y) - (z + w)),"(t*t)-(t+t)")
- define_sfop4(ext17,((x / y) - (z + w)),"(t/t)-(t+t)")
- define_sfop4(ext18,((x * y) + (z + w)),"(t*t)+(t+t)")
- define_sfop4(ext19,((x / y) + (z + w)),"(t/t)+(t+t)")
- define_sfop4(ext20,((x * y) + (z - w)),"(t*t)+(t-t)")
- define_sfop4(ext21,((x / y) + (z - w)),"(t/t)+(t-t)")
- define_sfop4(ext22,((x * y) - (z - w)),"(t*t)-(t-t)")
- define_sfop4(ext23,((x / y) - (z - w)),"(t/t)-(t-t)")
- define_sfop4(ext24,((x + y) * (z * w)),"(t+t)*(t*t)")
- define_sfop4(ext25,((x + y) * (z / w)),"(t+t)*(t/t)")
- define_sfop4(ext26,((x + y) / (z * w)),"(t+t)/(t*t)")
- define_sfop4(ext27,((x + y) / (z / w)),"(t+t)/(t/t)")
- define_sfop4(ext28,((x - y) / (z * w)),"(t-t)/(t*t)")
- define_sfop4(ext29,((x - y) / (z / w)),"(t-t)/(t/t)")
- define_sfop4(ext30,((x - y) * (z * w)),"(t-t)*(t*t)")
- define_sfop4(ext31,((x - y) * (z / w)),"(t-t)*(t/t)")
- define_sfop4(ext32,((x * y) * (z + w)),"(t*t)*(t+t)")
- define_sfop4(ext33,((x / y) * (z + w)),"(t/t)*(t+t)")
- define_sfop4(ext34,((x * y) / (z + w)),"(t*t)/(t+t)")
- define_sfop4(ext35,((x / y) / (z + w)),"(t/t)/(t+t)")
- define_sfop4(ext36,((x * y) / (z - w)),"(t*t)/(t-t)")
- define_sfop4(ext37,((x / y) / (z - w)),"(t/t)/(t-t)")
- define_sfop4(ext38,((x * y) * (z - w)),"(t*t)*(t-t)")
- define_sfop4(ext39,((x * y) / (z * w)),"(t*t)/(t*t)")
- define_sfop4(ext40,((x / y) * (z / w)),"(t/t)*(t/t)")
- define_sfop4(ext41,((x / y) * (z - w)),"(t/t)*(t-t)")
- define_sfop4(ext42,((x * y) * (z * w)),"(t*t)*(t*t)")
- define_sfop4(ext43,(x + (y * (z / w))),"t+(t*(t/t))")
- define_sfop4(ext44,(x - (y * (z / w))),"t-(t*(t/t))")
- define_sfop4(ext45,(x + (y / (z * w))),"t+(t/(t*t))")
- define_sfop4(ext46,(x - (y / (z * w))),"t-(t/(t*t))")
- define_sfop4(ext47,(((x - y) - z) * w),"((t-t)-t)*t")
- define_sfop4(ext48,(((x - y) - z) / w),"((t-t)-t)/t")
- define_sfop4(ext49,(((x - y) + z) * w),"((t-t)+t)*t")
- define_sfop4(ext50,(((x - y) + z) / w),"((t-t)+t)/t")
- define_sfop4(ext51,((x + (y - z)) * w),"(t+(t-t))*t")
- define_sfop4(ext52,((x + (y - z)) / w),"(t+(t-t))/t")
- define_sfop4(ext53,((x + y) / (z + w)),"(t+t)/(t+t)")
- define_sfop4(ext54,((x - y) / (z - w)),"(t-t)/(t-t)")
- define_sfop4(ext55,((x + y) * (z + w)),"(t+t)*(t+t)")
- define_sfop4(ext56,((x - y) * (z - w)),"(t-t)*(t-t)")
- define_sfop4(ext57,((x - y) + (z - w)),"(t-t)+(t-t)")
- define_sfop4(ext58,((x - y) - (z - w)),"(t-t)-(t-t)")
- define_sfop4(ext59,((x / y) + (z * w)),"(t/t)+(t*t)")
- #undef define_sfop3
- #undef define_sfop4
- template <typename T, typename SpecialFunction>
- class sf3_node : public trinary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- sf3_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1,
- expression_ptr branch2)
- : trinary_node<T>(opr,branch0,branch1,branch2)
- {}
- inline T value() const
- {
- const T x = trinary_node<T>::branch_[0].first->value();
- const T y = trinary_node<T>::branch_[1].first->value();
- const T z = trinary_node<T>::branch_[2].first->value();
- return SpecialFunction::process(x,y,z);
- }
- };
- template <typename T, typename SpecialFunction>
- class sf4_node : public quaternary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- sf4_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1,
- expression_ptr branch2,
- expression_ptr branch3)
- : quaternary_node<T>(opr,branch0,branch1,branch2,branch3)
- {}
- inline T value() const
- {
- const T x = quaternary_node<T>::branch_[0].first->value();
- const T y = quaternary_node<T>::branch_[1].first->value();
- const T z = quaternary_node<T>::branch_[2].first->value();
- const T w = quaternary_node<T>::branch_[3].first->value();
- return SpecialFunction::process(x,y,z,w);
- }
- };
- template <typename T, typename SpecialFunction>
- class sf3_var_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- sf3_var_node(const T& v0, const T& v1, const T& v2)
- : v0_(v0),
- v1_(v1),
- v2_(v2)
- {}
- inline T value() const
- {
- return SpecialFunction::process(v0_,v1_,v2_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_trinary;
- }
- private:
- sf3_var_node(sf3_var_node<T,SpecialFunction>&);
- sf3_var_node<T,SpecialFunction>& operator=(sf3_var_node<T,SpecialFunction>&);
- const T& v0_;
- const T& v1_;
- const T& v2_;
- };
- template <typename T, typename SpecialFunction>
- class sf4_var_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
- : v0_(v0),
- v1_(v1),
- v2_(v2),
- v3_(v3)
- {}
- inline T value() const
- {
- return SpecialFunction::process(v0_,v1_,v2_,v3_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_trinary;
- }
- private:
- sf4_var_node(sf4_var_node<T,SpecialFunction>&);
- sf4_var_node<T,SpecialFunction>& operator=(sf4_var_node<T,SpecialFunction>&);
- const T& v0_;
- const T& v1_;
- const T& v2_;
- const T& v3_;
- };
- template <typename T, typename VarArgFunction>
- class vararg_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- template <typename Allocator,
- template <typename,typename> class Sequence>
- vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
- {
- arg_list_.resize(arg_list.size());
- delete_branch_.resize(arg_list.size());
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- if (arg_list[i])
- {
- arg_list_[i] = arg_list[i];
- delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
- }
- else
- {
- arg_list_.clear();
- delete_branch_.clear();
- return;
- }
- }
- }
- ~vararg_node()
- {
- for (std::size_t i = 0; i < arg_list_.size(); ++i)
- {
- if (arg_list_[i] && delete_branch_[i])
- {
- delete arg_list_[i];
- arg_list_[i] = 0;
- }
- }
- }
- inline T value() const
- {
- if (!arg_list_.empty())
- return VarArgFunction::process(arg_list_);
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vararg;
- }
- private:
- std::vector<expression_ptr> arg_list_;
- std::vector<unsigned char> delete_branch_;
- };
- template <typename T, typename VarArgFunction>
- class vararg_varnode : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- template <typename Allocator,
- template <typename,typename> class Sequence>
- vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
- {
- arg_list_.resize(arg_list.size());
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- if (arg_list[i] && is_variable_node(arg_list[i]))
- {
- variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]);
- arg_list_[i] = (&var_node_ptr->ref());
- }
- else
- {
- arg_list_.clear();
- return;
- }
- }
- }
- inline T value() const
- {
- if (!arg_list_.empty())
- return VarArgFunction::process(arg_list_);
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vararg;
- }
- private:
- std::vector<const T*> arg_list_;
- };
- template <typename T, typename VecFunction>
- class vectorize_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- vectorize_node(const expression_ptr v)
- : ivec_ptr_(0),
- v_(v),
- v_deletable_(branch_deletable(v_))
- {
- if (is_ivector_node(v))
- {
- ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v);
- }
- else
- ivec_ptr_ = 0;
- }
- ~vectorize_node()
- {
- if (v_ && v_deletable_)
- {
- delete v_;
- }
- }
- inline T value() const
- {
- if (ivec_ptr_)
- {
- v_->value();
- return VecFunction::process(ivec_ptr_);
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecfunc;
- }
- private:
- vector_interface<T>* ivec_ptr_;
- expression_ptr v_;
- bool v_deletable_;
- };
- template <typename T>
- class assignment_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- assignment_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- var_node_ptr_(0)
- {
- if (is_variable_node(binary_node<T>::branch_[0].first))
- {
- var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
- }
- }
- inline T value() const
- {
- if (var_node_ptr_)
- {
- T& result = var_node_ptr_->ref();
- result = binary_node<T>::branch_[1].first->value();
- return result;
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- private:
- variable_node<T>* var_node_ptr_;
- };
- template <typename T>
- class assignment_vec_elem_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- assignment_vec_elem_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec_node_ptr_(0)
- {
- if (is_vector_elem_node(binary_node<T>::branch_[0].first))
- {
- vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
- }
- }
- inline T value() const
- {
- if (vec_node_ptr_)
- {
- T& result = vec_node_ptr_->ref();
- result = binary_node<T>::branch_[1].first->value();
- return result;
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- private:
- vector_elem_node<T>* vec_node_ptr_;
- };
- template <typename T>
- class assignment_vec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- assignment_vec_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
- vec_size_ = vec_node_ptr_->ref().size();
- }
- }
- inline T value() const
- {
- if (vec_node_ptr_)
- {
- vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
- const T v = binary_node<T>::branch_[1].first->value();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- (*vec_hldr[i]) = v;
- }
- return vec_node_ptr_->value();
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvalass;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T>
- class assignment_vecvec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- assignment_vecvec_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec0_node_ptr_(0),
- vec1_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
- }
- if (is_vector_node(binary_node<T>::branch_[1].first))
- {
- vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec1_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- vec_size_ = std::min(vec0_node_ptr_->ref().size(),
- vec1_node_ptr_->ref().size());
- }
- }
- inline T value() const
- {
- binary_node<T>::branch_[1].first->value();
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- (*vec0[i]) = (*vec1[i]);
- }
- return vec0_node_ptr_->value();
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec0_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec0_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvecass;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec0_node_ptr_;
- vector_node<T>* vec1_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T, typename Operation>
- class assignment_op_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- assignment_op_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- var_node_ptr_(0)
- {
- if (is_variable_node(binary_node<T>::branch_[0].first))
- {
- var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
- }
- }
- inline T value() const
- {
- if (var_node_ptr_)
- {
- T& v = var_node_ptr_->ref();
- v = Operation::process(v,binary_node<T>::branch_[1].first->value());
- return v;
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- private:
- variable_node<T>* var_node_ptr_;
- };
- template <typename T, typename Operation>
- class assignment_vec_elem_op_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- assignment_vec_elem_op_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec_node_ptr_(0)
- {
- if (is_vector_elem_node(binary_node<T>::branch_[0].first))
- {
- vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
- }
- }
- inline T value() const
- {
- if (vec_node_ptr_)
- {
- T& v = vec_node_ptr_->ref();
- v = Operation::process(v,binary_node<T>::branch_[1].first->value());
- return v;
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- private:
- vector_elem_node<T>* vec_node_ptr_;
- };
- template <typename T, typename Operation>
- class assignment_vec_op_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- assignment_vec_op_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
- vec_size_ = vec_node_ptr_->ref().size();
- }
- }
- inline T value() const
- {
- if (vec_node_ptr_)
- {
- vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
- const T v = binary_node<T>::branch_[1].first->value();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- T& vec_i = *vec_hldr[i];
- vec_i = Operation::process(vec_i,v);
- }
- return vec_node_ptr_->value();
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecopvalass;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T, typename Operation>
- class assignment_vecvec_op_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- assignment_vecvec_op_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec0_node_ptr_(0),
- vec1_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
- }
- if (is_vector_node(binary_node<T>::branch_[1].first))
- {
- vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec1_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- vec_size_ = std::min(vec0_node_ptr_->ref().size(),
- vec1_node_ptr_->ref().size());
- }
- }
- inline T value() const
- {
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- T& vec0_i = *vec0[i];
- T& vec1_i = *vec1[i];
- vec0_i = Operation::process(vec0_i,vec1_i);
- }
- return vec0_node_ptr_->value();
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec0_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec0_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecopvecass;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec0_node_ptr_;
- vector_node<T>* vec1_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T, typename Operation>
- class eqineq_vecvec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- eqineq_vecvec_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec0_node_ptr_(0),
- vec1_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[0].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
- {
- vec0_node_ptr_ = vi->vec();
- }
- }
- if (is_vector_node(binary_node<T>::branch_[1].first))
- {
- vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec1_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- vec_size_ = std::min(vec0_node_ptr_->ref().size(),
- vec1_node_ptr_->ref().size());
- }
- }
- inline T value() const
- {
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- if (std::equal_to<T>()(T(0),Operation::process(*vec0[i],*vec1[i])))
- {
- return T(0);
- }
- }
- return T(1);
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec0_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec0_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvecineq;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec0_node_ptr_;
- vector_node<T>* vec1_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T, typename Operation>
- class eqineq_vecval_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- eqineq_vecval_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[0].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
- {
- vec_node_ptr_ = vi->vec();
- }
- }
- if (vec_node_ptr_)
- {
- vec_size_ = vec_node_ptr_->ref().size();
- }
- }
- inline T value() const
- {
- if (vec_node_ptr_)
- {
- binary_node<T>::branch_[0].first->value();
- T v = binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- if (std::equal_to<T>()(T(0),Operation::process(*vec_hldr[i],v)))
- {
- return T(0);
- }
- }
- return T(1);
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvalineq;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T, typename Operation>
- class eqineq_valvec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- eqineq_valvec_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec_node_ptr_(0),
- vec_size_ (0)
- {
- if (is_vector_node(binary_node<T>::branch_[1].first))
- {
- vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec_node_ptr_ = vi->vec();
- }
- }
- if (vec_node_ptr_)
- {
- vec_size_ = vec_node_ptr_->ref().size();
- }
- }
- inline T value() const
- {
- if (vec_node_ptr_)
- {
- T v = binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec_hldr = vec_node_ptr_->ref();
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- if (std::equal_to<T>()(T(0),Operation::process(v,*vec_hldr[i])))
- {
- return T(0);
- }
- }
- return T(1);
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return vec_node_ptr_;
- }
- vector_node_ptr vec()
- {
- return vec_node_ptr_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_valvecineq;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node<T>* vec_node_ptr_;
- std::size_t vec_size_;
- };
- template <typename T, typename Operation>
- class vecarith_vecvec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- typedef vector_holder<T>* vector_holder_ptr;
- vecarith_vecvec_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec0_node_ptr_(0),
- vec1_node_ptr_(0),
- vec_size_ (0),
- data_ (0),
- temp_ (0),
- temp_vec_node_(0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[0].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
- {
- vec0_node_ptr_ = vi->vec();
- }
- }
- if (is_vector_node(binary_node<T>::branch_[1].first))
- {
- vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec1_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- vec_size_ = std::min(vec0.size(),vec1.size());
- data_ = new T[vec_size_];
- temp_ = new vector_holder<T>(data_,vec_size_);
- temp_vec_node_ = new vector_node<T> (temp_);
- }
- }
- ~vecarith_vecvec_node()
- {
- delete[] data_;
- delete temp_;
- delete temp_vec_node_;
- }
- inline T value() const
- {
- if (vec0_node_ptr_ && vec1_node_ptr_)
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- vector_holder<T>& vec2 = *temp_;
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- T& vec0_i = *vec0[i];
- T& vec1_i = *vec1[i];
- T& vec2_i = *vec2[i];
- vec2_i = Operation::process(vec0_i,vec1_i);
- }
- return *vec2[0];
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return temp_vec_node_;
- }
- vector_node_ptr vec()
- {
- return temp_vec_node_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvecarith;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node_ptr vec0_node_ptr_;
- vector_node_ptr vec1_node_ptr_;
- std::size_t vec_size_;
- T* data_;
- vector_holder_ptr temp_;
- vector_node_ptr temp_vec_node_;
- };
- template <typename T, typename Operation>
- class vecarith_vecval_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- typedef vector_holder<T>* vector_holder_ptr;
- vecarith_vecval_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec0_node_ptr_(0),
- vec_size_ (0),
- data_ (0),
- temp_ (0),
- temp_vec_node_(0)
- {
- if (is_vector_node(binary_node<T>::branch_[0].first))
- {
- vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[0].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
- {
- vec0_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_)
- {
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vec_size_ = vec0.size();
- data_ = new T[vec_size_];
- temp_ = new vector_holder<T>(data_,vec_size_);
- temp_vec_node_ = new vector_node<T> (temp_);
- }
- }
- ~vecarith_vecval_node()
- {
- delete[] data_;
- delete temp_;
- delete temp_vec_node_;
- }
- inline T value() const
- {
- if (vec0_node_ptr_)
- {
- binary_node<T>::branch_[0].first->value();
- const T v = binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = *temp_;
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- T& vec0_i = *vec0[i];
- T& vec1_i = *vec1[i];
- vec1_i = Operation::process(vec0_i,v);
- }
- return *vec1[0];
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return temp_vec_node_;
- }
- vector_node_ptr vec()
- {
- return temp_vec_node_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvalarith;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node_ptr vec0_node_ptr_;
- std::size_t vec_size_;
- T* data_;
- vector_holder_ptr temp_;
- vector_node_ptr temp_vec_node_;
- };
- template <typename T, typename Operation>
- class vecarith_valvec_node : public binary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- typedef vector_holder<T>* vector_holder_ptr;
- vecarith_valvec_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- vec1_node_ptr_(0),
- vec_size_ (0),
- data_ (0),
- temp_ (0),
- temp_vec_node_(0)
- {
- if (is_vector_node(binary_node<T>::branch_[1].first))
- {
- vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
- }
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
- {
- vec1_node_ptr_ = vi->vec();
- }
- }
- if (vec1_node_ptr_)
- {
- vector_holder<T>& vec0 = vec1_node_ptr_->ref();
- vec_size_ = vec0.size();
- data_ = new T[vec_size_];
- temp_ = new vector_holder<T>(data_,vec_size_);
- temp_vec_node_ = new vector_node<T> (temp_);
- }
- }
- ~vecarith_valvec_node()
- {
- delete[] data_;
- delete temp_;
- delete temp_vec_node_;
- }
- inline T value() const
- {
- if (vec1_node_ptr_)
- {
- const T v = binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- vector_holder<T>& vec1 = vec1_node_ptr_->ref();
- vector_holder<T>& vec2 = *temp_;
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- T& vec1_i = *vec1[i];
- T& vec2_i = *vec2[i];
- vec2_i = Operation::process(v,vec1_i);
- }
- return *vec2[0];
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return temp_vec_node_;
- }
- vector_node_ptr vec()
- {
- return temp_vec_node_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecvalarith;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node_ptr vec1_node_ptr_;
- std::size_t vec_size_;
- T* data_;
- vector_holder_ptr temp_;
- vector_node_ptr temp_vec_node_;
- };
- template <typename T, typename Operation>
- class unary_vector_node : public unary_node <T>,
- public vector_interface<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef vector_node<T>* vector_node_ptr;
- typedef vector_holder<T>* vector_holder_ptr;
- unary_vector_node(const operator_type& opr, expression_ptr branch0)
- : unary_node<T>(opr,branch0),
- vec0_node_ptr_(0),
- vec_size_ (0),
- data_ (0),
- temp_ (0),
- temp_vec_node_(0)
- {
- if (is_vector_node(unary_node<T>::branch_))
- {
- vec0_node_ptr_ = static_cast<vector_node_ptr>(unary_node<T>::branch_);
- }
- else if (is_ivector_node(unary_node<T>::branch_))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if ((vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_)))
- {
- vec0_node_ptr_ = vi->vec();
- }
- }
- if (vec0_node_ptr_)
- {
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vec_size_ = vec0.size();
- data_ = new T[vec_size_];
- temp_ = new vector_holder<T>(data_,vec_size_);
- temp_vec_node_ = new vector_node<T> (temp_);
- }
- }
- ~unary_vector_node()
- {
- delete[] data_;
- delete temp_;
- delete temp_vec_node_;
- }
- inline T value() const
- {
- unary_node<T>::branch_->value();
- if (vec0_node_ptr_)
- {
- vector_holder<T>& vec0 = vec0_node_ptr_->ref();
- vector_holder<T>& vec1 = *temp_;
- for (std::size_t i = 0; i < vec_size_; ++i)
- {
- T& vec0_i = *vec0[i];
- T& vec1_i = *vec1[i];
- vec1_i = Operation::process(vec0_i);
- }
- return *vec1[0];
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- vector_node_ptr vec() const
- {
- return temp_vec_node_;
- }
- vector_node_ptr vec()
- {
- return temp_vec_node_;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vecunaryop;
- }
- std::size_t size() const
- {
- return vec_size_;
- }
- private:
- vector_node_ptr vec0_node_ptr_;
- std::size_t vec_size_;
- T* data_;
- vector_holder_ptr temp_;
- vector_node_ptr temp_vec_node_;
- };
- template <typename T>
- class scand_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- scand_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1)
- {}
- inline T value() const
- {
- return (
- std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[0].first->value()) &&
- std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[1].first->value())
- ) ? T(1) : T(0);
- }
- };
- template <typename T>
- class scor_node : public binary_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- scor_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1)
- {}
- inline T value() const
- {
- return (
- std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[0].first->value()) ||
- std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[1].first->value())
- ) ? T(1) : T(0);
- }
- };
- template <typename T, typename IFunction, std::size_t N>
- class function_N_node : public expression_node<T>
- {
- public:
- // Function of N paramters.
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- typedef IFunction ifunction;
- function_N_node(ifunction* func)
- : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
- parameter_count_(func->param_count)
- {}
- ~function_N_node()
- {
- cleanup_branches::execute<T,N>(branch_);
- }
- template <std::size_t NumBranches>
- bool init_branches(expression_ptr (&b)[NumBranches])
- {
- // Needed for incompetent and broken msvc compiler versions
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if (N != NumBranches)
- return false;
- else
- {
- for (std::size_t i = 0; i < NumBranches; ++i)
- {
- if (b[i])
- branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
- else
- return false;
- }
- return true;
- }
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- }
- inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
- {
- return this < (&fn);
- }
- inline T value() const
- {
- // Needed for incompetent and broken msvc compiler versions
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable: 4127)
- #endif
- if ((0 == function_) || (0 == N))
- return std::numeric_limits<T>::quiet_NaN();
- else
- {
- T v[N];
- evaluate_branches<T,N>::execute(v,branch_);
- return invoke<T,N>::execute(*function_,v);
- }
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- }
- template <typename T_, std::size_t BranchCount>
- struct evaluate_branches
- {
- static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
- {
- for (std::size_t i = 0; i < BranchCount; ++i)
- {
- v[i] = b[i].first->value();
- }
- }
- };
- template <typename T_>
- struct evaluate_branches <T_,5>
- {
- static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
- {
- v[0] = b[0].first->value();
- v[1] = b[1].first->value();
- v[2] = b[2].first->value();
- v[3] = b[3].first->value();
- v[4] = b[4].first->value();
- }
- };
- template <typename T_>
- struct evaluate_branches <T_,4>
- {
- static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
- {
- v[0] = b[0].first->value();
- v[1] = b[1].first->value();
- v[2] = b[2].first->value();
- v[3] = b[3].first->value();
- }
- };
- template <typename T_>
- struct evaluate_branches <T_,3>
- {
- static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
- {
- v[0] = b[0].first->value();
- v[1] = b[1].first->value();
- v[2] = b[2].first->value();
- }
- };
- template <typename T_>
- struct evaluate_branches <T_,2>
- {
- static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
- {
- v[0] = b[0].first->value();
- v[1] = b[1].first->value();
- }
- };
- template <typename T_>
- struct evaluate_branches <T_,1>
- {
- static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
- {
- v[0] = b[0].first->value();
- }
- };
- template <typename T_, std::size_t ParamCount>
- struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
- template <typename T_>
- struct invoke<T_,20>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[20])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18],v[19]); }
- };
- template <typename T_>
- struct invoke<T_,19>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[19])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18]); }
- };
- template <typename T_>
- struct invoke<T_,18>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[18])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17]); }
- };
- template <typename T_>
- struct invoke<T_,17>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[17])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16]); }
- };
- template <typename T_>
- struct invoke<T_,16>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[16])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15]); }
- };
- template <typename T_>
- struct invoke<T_,15>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[15])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14]); }
- };
- template <typename T_>
- struct invoke<T_,14>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[14])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13]); }
- };
- template <typename T_>
- struct invoke<T_,13>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[13])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12]); }
- };
- template <typename T_>
- struct invoke<T_,12>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[12])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11]); }
- };
- template <typename T_>
- struct invoke<T_,11>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[11])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10]); }
- };
- template <typename T_>
- struct invoke<T_,10>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[10])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); }
- };
- template <typename T_>
- struct invoke<T_,9>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[9])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); }
- };
- template <typename T_>
- struct invoke<T_,8>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[8])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); }
- };
- template <typename T_>
- struct invoke<T_,7>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[7])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); }
- };
- template <typename T_>
- struct invoke<T_,6>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[6])
- { return f(v[0],v[1],v[2],v[3],v[4],v[5]); }
- };
- template <typename T_>
- struct invoke<T_,5>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[5])
- { return f(v[0],v[1],v[2],v[3],v[4]); }
- };
- template <typename T_>
- struct invoke<T_,4>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[4])
- { return f(v[0],v[1],v[2],v[3]); }
- };
- template <typename T_>
- struct invoke<T_,3>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[3])
- { return f(v[0],v[1],v[2]); }
- };
- template <typename T_>
- struct invoke<T_,2>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[2])
- { return f(v[0],v[1]); }
- };
- template <typename T_>
- struct invoke<T_,1>
- {
- static inline T_ execute(ifunction& f, T_ (&v)[1])
- { return f(v[0]); }
- };
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_function;
- }
- private:
- ifunction* function_;
- std::size_t parameter_count_;
- branch_t branch_[N];
- };
- template <typename T, typename IFunction>
- class function_N_node<T,IFunction,0> : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef IFunction ifunction;
- function_N_node(ifunction* func)
- : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
- {}
- inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
- {
- return this < (&fn);
- }
- inline T value() const
- {
- if (function_)
- return (*function_)();
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_function;
- }
- private:
- ifunction* function_;
- };
- template <typename T, typename VarArgFunction>
- class vararg_function_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- vararg_function_node(VarArgFunction* func,
- const std::vector<expression_ptr>& arg_list)
- : function_(func),
- arg_list_(arg_list)
- {
- value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
- }
- ~vararg_function_node()
- {
- for (std::size_t i = 0; i < arg_list_.size(); ++i)
- {
- if (arg_list_[i] && !details::is_variable_node(arg_list_[i]))
- {
- delete arg_list_[i];
- arg_list_[i] = 0;
- }
- }
- }
- inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
- {
- return this < (&fn);
- }
- inline T value() const
- {
- if (function_)
- {
- populate_value_list();
- return (*function_)(value_list_);
- }
- else
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_vafunction;
- }
- private:
- inline void populate_value_list() const
- {
- for (std::size_t i = 0; i < arg_list_.size(); ++i)
- {
- value_list_[i] = arg_list_[i]->value();
- }
- }
- VarArgFunction* function_;
- std::vector<expression_ptr> arg_list_;
- mutable std::vector<T> value_list_;
- };
- template <typename T, typename GenericFunction>
- class generic_function_node : public expression_node<T>
- {
- public:
- typedef type_store<T> type_store_t;
- typedef expression_node<T>* expression_ptr;
- typedef variable_node<T> variable_node_t;
- typedef vector_elem_node<T> vector_elem_node_t;
- typedef vector_node<T> vector_node_t;
- typedef variable_node_t* variable_node_ptr_t;
- typedef vector_elem_node_t* vector_elem_node_ptr_t;
- typedef vector_node_t* vector_node_ptr_t;
- typedef range_interface<T> range_interface_t;
- typedef range_data_type<T> range_data_type_t;
- typedef range_pack<T> range_t;
- typedef std::pair<expression_ptr,bool> branch_t;
- typedef std::pair<void*,std::size_t> void_t;
- typedef std::vector<T> tmp_vs_t;
- typedef std::vector<type_store_t> typestore_list_t;
- typedef std::vector<range_data_type_t> range_list_t;
- generic_function_node(const std::vector<expression_ptr>& arg_list,
- GenericFunction* func = (GenericFunction*)(0))
- : function_(func),
- arg_list_(arg_list)
- {}
- ~generic_function_node()
- {
- cleanup_branches::execute(branch_);
- }
- virtual bool init_branches()
- {
- expr_as_vec1_store_.resize(arg_list_.size(),T(0) );
- typestore_list_ .resize(arg_list_.size(),type_store_t() );
- range_list_ .resize(arg_list_.size(),range_data_type_t());
- branch_ .resize(arg_list_.size(),branch_t((expression_ptr)0,false));
- for (std::size_t i = 0; i < arg_list_.size(); ++i)
- {
- type_store_t& ts = typestore_list_[i];
- if (0 == arg_list_[i])
- return false;
- else if (is_ivector_node(arg_list_[i]))
- {
- vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i])))
- return false;
- ts.size = vi->size();
- ts.data = vi->vec()->ref()[0];
- ts.type = type_store_t::e_vector;
- }
- else if (is_generally_string_node(arg_list_[i]))
- {
- string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0);
- if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i])))
- return false;
- ts.size = sbn->size();
- ts.data = reinterpret_cast<void*>(const_cast<char*>(sbn->base()));
- ts.type = type_store_t::e_string;
- range_list_[i].data = ts.data;
- range_list_[i].size = ts.size;
- range_list_[i].type_size = sizeof(char);
- range_list_[i].str_node = sbn;
- range_interface_t* ri = reinterpret_cast<range_interface_t*>(0);
- if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i])))
- return false;
- range_t& rp = ri->range_ref();
- if (
- rp.const_range() &&
- is_const_string_range_node(arg_list_[i])
- )
- {
- ts.size = rp.const_size();
- ts.data = static_cast<char*>(ts.data) + rp.n0_c.second;
- range_list_[i].range = reinterpret_cast<range_t*>(0);
- }
- else
- range_list_[i].range = &(ri->range_ref());
- }
- else if (is_variable_node(arg_list_[i]))
- {
- variable_node_ptr_t var = variable_node_ptr_t(0);
- if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i])))
- return false;
- ts.size = 1;
- ts.data = &var->ref();
- ts.type = type_store_t::e_scalar;
- }
- else if (is_vector_elem_node(arg_list_[i]))
- {
- vector_elem_node_ptr_t var = vector_elem_node_ptr_t(0);
- if (0 == (var = dynamic_cast<vector_elem_node_ptr_t>(arg_list_[i])))
- return false;
- ts.size = 1;
- ts.data = reinterpret_cast<void*>(&var->ref());
- ts.type = type_store_t::e_scalar;
- }
- else
- {
- ts.size = 1;
- ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]);
- ts.type = type_store_t::e_scalar;
- }
- branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]));
- }
- return true;
- }
- inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const
- {
- return this < (&fn);
- }
- inline T value() const
- {
- if (function_)
- {
- if (populate_value_list())
- {
- typedef typename GenericFunction::parameter_list_t parameter_list_t;
- return (*function_)(parameter_list_t(typestore_list_));
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_genfunction;
- }
- protected:
- inline virtual bool populate_value_list() const
- {
- for (std::size_t i = 0; i < branch_.size(); ++i)
- {
- expr_as_vec1_store_[i] = branch_[i].first->value();
- }
- for (std::size_t i = 0; i < branch_.size(); ++i)
- {
- range_data_type_t& rdt = range_list_[i];
- if (rdt.range)
- {
- range_t& rp = (*rdt.range);
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- if (rp(r0,r1,rdt.size))
- {
- type_store_t& ts = typestore_list_[i];
- ts.size = rp.cache_size();
- if (ts.type == type_store_t::e_string)
- ts.data = const_cast<char*>(rdt.str_node->base()) + rp.cache.first;
- else
- ts.data = static_cast<char*>(rdt.data) + (rp.cache.first * rdt.type_size);
- }
- else
- return false;
- }
- }
- return true;
- }
- GenericFunction* function_;
- mutable typestore_list_t typestore_list_;
- private:
- std::vector<expression_ptr> arg_list_;
- std::vector<branch_t> branch_;
- mutable tmp_vs_t expr_as_vec1_store_;
- mutable range_list_t range_list_;
- };
- template <typename T, typename StringFunction>
- class string_function_node : public generic_function_node<T,StringFunction>,
- public string_base_node<T>,
- public range_interface <T>
- {
- public:
- typedef generic_function_node<T,StringFunction> gen_function_t;
- typedef range_pack<T> range_t;
- string_function_node(StringFunction* func,
- const std::vector<typename gen_function_t::expression_ptr>& arg_list)
- : gen_function_t(arg_list,func)
- {
- range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
- range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
- range_.cache.first = range_.n0_c.second;
- range_.cache.second = range_.n1_c.second;
- }
- inline bool operator <(const string_function_node<T,StringFunction>& fn) const
- {
- return this < (&fn);
- }
- inline T value() const
- {
- T result = std::numeric_limits<T>::quiet_NaN();
- if (gen_function_t::function_)
- {
- if (gen_function_t::populate_value_list())
- {
- typedef typename StringFunction::parameter_list_t parameter_list_t;
- result = (*gen_function_t::function_)(ret_string_,
- parameter_list_t(gen_function_t::typestore_list_));
- range_.n1_c.second = ret_string_.size() - 1;
- range_.cache.second = range_.n1_c.second;
- return result;
- }
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strfunction;
- }
- std::string str() const
- {
- return ret_string_;
- }
- const char* base() const
- {
- return ret_string_.data();
- }
- std::size_t size() const
- {
- return ret_string_.size();
- }
- range_t& range_ref()
- {
- return range_;
- }
- const range_t& range_ref() const
- {
- return range_;
- }
- protected:
- mutable range_t range_;
- mutable std::string ret_string_;
- };
- template <typename T, typename GenericFunction>
- class multimode_genfunction_node : public generic_function_node<T,GenericFunction>
- {
- public:
- typedef generic_function_node<T,GenericFunction> gen_function_t;
- typedef range_pack<T> range_t;
- multimode_genfunction_node(GenericFunction* func,
- const std::size_t& param_seq_index,
- const std::vector<typename gen_function_t::expression_ptr>& arg_list)
- : gen_function_t(arg_list,func),
- param_seq_index_(param_seq_index)
- {}
- inline T value() const
- {
- T result = std::numeric_limits<T>::quiet_NaN();
- if (gen_function_t::function_)
- {
- if (gen_function_t::populate_value_list())
- {
- typedef typename GenericFunction::parameter_list_t parameter_list_t;
- return (*gen_function_t::function_)(param_seq_index_,
- parameter_list_t(gen_function_t::typestore_list_));
- }
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_genfunction;
- }
- private:
- std::size_t param_seq_index_;
- };
- template <typename T, typename StringFunction>
- class multimode_strfunction_node : public string_function_node<T,StringFunction>
- {
- public:
- typedef string_function_node<T,StringFunction> str_function_t;
- typedef range_pack<T> range_t;
- multimode_strfunction_node(StringFunction* func,
- const std::size_t& param_seq_index,
- const std::vector<typename str_function_t::expression_ptr>& arg_list)
- : str_function_t(func,arg_list),
- param_seq_index_(param_seq_index)
- {}
- inline T value() const
- {
- T result = std::numeric_limits<T>::quiet_NaN();
- if (str_function_t::function_)
- {
- if (str_function_t::populate_value_list())
- {
- typedef typename StringFunction::parameter_list_t parameter_list_t;
- result = (*str_function_t::function_)(param_seq_index_,
- str_function_t::ret_string_,
- parameter_list_t(str_function_t::typestore_list_));
- str_function_t::range_.n1_c.second = str_function_t::ret_string_.size() - 1;
- str_function_t::range_.cache.second = str_function_t::range_.n1_c.second;
- return result;
- }
- }
- return result;
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_strfunction;
- }
- private:
- std::size_t param_seq_index_;
- };
- class return_exception
- {};
- template <typename T>
- class null_igenfunc
- {
- public:
- typedef type_store<T> generic_type;
- typedef typename generic_type::parameter_list parameter_list_t;
- inline virtual T operator()(parameter_list_t)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- };
- template <typename T>
- class return_node : public generic_function_node<T,null_igenfunc<T> >
- {
- public:
- typedef null_igenfunc<T> igeneric_function_t;
- typedef igeneric_function_t* igeneric_function_ptr;
- typedef generic_function_node<T,igeneric_function_t> gen_function_t;
- typedef results_context<T> results_context_t;
- return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list,
- results_context_t& rc)
- : gen_function_t (arg_list),
- results_context_(&rc)
- {}
- inline T value() const
- {
- if (
- (0 != results_context_) &&
- gen_function_t::populate_value_list()
- )
- {
- typedef typename type_store<T>::parameter_list parameter_list_t;
- results_context_->
- assign(parameter_list_t(gen_function_t::typestore_list_));
- throw return_exception();
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_return;
- }
- private:
- results_context_t* results_context_;
- };
- template <typename T>
- class return_envelope_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef results_context<T> results_context_t;
- return_envelope_node(expression_ptr body, results_context_t& rc)
- : results_context_(&rc),
- return_invoked_ (false),
- body_ (body),
- body_deletable_ (branch_deletable(body_))
- {}
- ~return_envelope_node()
- {
- if (body_ && body_deletable_)
- {
- delete body_;
- }
- }
- inline T value() const
- {
- try
- {
- return_invoked_ = false;
- results_context_->clear();
- return body_->value();
- }
- catch(const return_exception&)
- {
- return_invoked_ = true;
- return std::numeric_limits<T>::quiet_NaN();
- }
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_retenv;
- }
- inline bool* retinvk_ptr()
- {
- return &return_invoked_;
- }
- private:
- results_context_t* results_context_;
- mutable bool return_invoked_;
- expression_ptr body_;
- bool body_deletable_;
- };
- #define exprtk_define_unary_op(OpName) \
- template <typename T> \
- struct OpName##_op \
- { \
- typedef typename functor_t<T>::Type Type; \
- \
- static inline T process(Type v) \
- { \
- return numeric:: OpName (v); \
- } \
- \
- static inline typename expression_node<T>::node_type type() \
- { \
- return expression_node<T>::e_##OpName; \
- } \
- \
- static inline details::operator_type operation() \
- { \
- return details::e_##OpName; \
- } \
- }; \
- exprtk_define_unary_op(abs )
- exprtk_define_unary_op(acos )
- exprtk_define_unary_op(acosh)
- exprtk_define_unary_op(asin )
- exprtk_define_unary_op(asinh)
- exprtk_define_unary_op(atan )
- exprtk_define_unary_op(atanh)
- exprtk_define_unary_op(ceil )
- exprtk_define_unary_op(cos )
- exprtk_define_unary_op(cosh )
- exprtk_define_unary_op(cot )
- exprtk_define_unary_op(csc )
- exprtk_define_unary_op(d2g )
- exprtk_define_unary_op(d2r )
- exprtk_define_unary_op(erf )
- exprtk_define_unary_op(erfc )
- exprtk_define_unary_op(exp )
- exprtk_define_unary_op(expm1)
- exprtk_define_unary_op(floor)
- exprtk_define_unary_op(frac )
- exprtk_define_unary_op(g2d )
- exprtk_define_unary_op(log )
- exprtk_define_unary_op(log10)
- exprtk_define_unary_op(log2 )
- exprtk_define_unary_op(log1p)
- exprtk_define_unary_op(ncdf )
- exprtk_define_unary_op(neg )
- exprtk_define_unary_op(notl )
- exprtk_define_unary_op(pos )
- exprtk_define_unary_op(r2d )
- exprtk_define_unary_op(round)
- exprtk_define_unary_op(sec )
- exprtk_define_unary_op(sgn )
- exprtk_define_unary_op(sin )
- exprtk_define_unary_op(sinc )
- exprtk_define_unary_op(sinh )
- exprtk_define_unary_op(sqrt )
- exprtk_define_unary_op(tan )
- exprtk_define_unary_op(tanh )
- exprtk_define_unary_op(trunc)
- #undef exprtk_define_unary_op
- template <typename T>
- struct opr_base
- {
- typedef typename details::functor_t<T>::Type Type;
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::qfunc_t quaternary_functor_t;
- typedef typename functor_t::tfunc_t trinary_functor_t;
- typedef typename functor_t::bfunc_t binary_functor_t;
- typedef typename functor_t::ufunc_t unary_functor_t;
- };
- template <typename T>
- struct add_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return t1 + t2; }
- static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; }
- static inline details::operator_type operation() { return details::e_add; }
- };
- template <typename T>
- struct mul_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return t1 * t2; }
- static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; }
- static inline details::operator_type operation() { return details::e_mul; }
- };
- template <typename T>
- struct sub_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return t1 - t2; }
- static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; }
- static inline details::operator_type operation() { return details::e_sub; }
- };
- template <typename T>
- struct div_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return t1 / t2; }
- static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; }
- static inline details::operator_type operation() { return details::e_div; }
- };
- template <typename T>
- struct mod_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
- static inline details::operator_type operation() { return details::e_mod; }
- };
- template <typename T>
- struct pow_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
- static inline details::operator_type operation() { return details::e_pow; }
- };
- template <typename T>
- struct lt_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
- static inline details::operator_type operation() { return details::e_lt; }
- };
- template <typename T>
- struct lte_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
- static inline details::operator_type operation() { return details::e_lte; }
- };
- template <typename T>
- struct gt_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
- static inline details::operator_type operation() { return details::e_gt; }
- };
- template <typename T>
- struct gte_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
- static inline details::operator_type operation() { return details::e_gte; }
- };
- template <typename T>
- struct eq_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
- static inline details::operator_type operation() { return details::e_eq; }
- };
- template <typename T>
- struct ne_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
- static inline details::operator_type operation() { return details::e_ne; }
- };
- template <typename T>
- struct and_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
- static inline details::operator_type operation() { return details::e_and; }
- };
- template <typename T>
- struct nand_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; }
- static inline details::operator_type operation() { return details::e_nand; }
- };
- template <typename T>
- struct or_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
- static inline details::operator_type operation() { return details::e_or; }
- };
- template <typename T>
- struct nor_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
- static inline details::operator_type operation() { return details::e_nor; }
- };
- template <typename T>
- struct xor_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
- static inline details::operator_type operation() { return details::e_xor; }
- };
- template <typename T>
- struct xnor_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
- static inline details::operator_type operation() { return details::e_xnor; }
- };
- template <typename T>
- struct in_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
- static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
- static inline details::operator_type operation() { return details::e_in; }
- };
- template <typename T>
- struct like_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
- static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; }
- static inline details::operator_type operation() { return details::e_like; }
- };
- template <typename T>
- struct ilike_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
- static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; }
- static inline details::operator_type operation() { return details::e_ilike; }
- };
- template <typename T>
- struct inrange_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
- static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
- {
- return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
- }
- static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_inranges; }
- static inline details::operator_type operation() { return details::e_inrange; }
- };
- template <typename T>
- inline T value(details::expression_node<T>* n)
- {
- return n->value();
- }
- template <typename T>
- inline T value(T* t)
- {
- return (*t);
- }
- template <typename T>
- struct vararg_add_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 0 : return T(0);
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default :
- {
- T result = T(0);
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- result += value(arg_list[i]);
- }
- return result;
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return value(arg_list[0]);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return value(arg_list[0]) + value(arg_list[1]);
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return value(arg_list[0]) + value(arg_list[1]) +
- value(arg_list[2]);
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return value(arg_list[0]) + value(arg_list[1]) +
- value(arg_list[2]) + value(arg_list[3]);
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return value(arg_list[0]) + value(arg_list[1]) +
- value(arg_list[2]) + value(arg_list[3]) +
- value(arg_list[4]);
- }
- };
- template <typename T>
- struct vararg_mul_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 0 : return T(0);
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default :
- {
- T result = T(value(arg_list[0]));
- for (std::size_t i = 1; i < arg_list.size(); ++i)
- {
- result *= value(arg_list[i]);
- }
- return result;
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return value(arg_list[0]);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return value(arg_list[0]) * value(arg_list[1]);
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return value(arg_list[0]) * value(arg_list[1]) *
- value(arg_list[2]);
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return value(arg_list[0]) * value(arg_list[1]) *
- value(arg_list[2]) * value(arg_list[3]);
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return value(arg_list[0]) * value(arg_list[1]) *
- value(arg_list[2]) * value(arg_list[3]) *
- value(arg_list[4]);
- }
- };
- template <typename T>
- struct vararg_avg_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 0 : return T(0);
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default : return vararg_add_op<T>::process(arg_list) / arg_list.size();
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return value(arg_list[0]);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return (value(arg_list[0]) + value(arg_list[1])) / T(2);
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3);
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return (value(arg_list[0]) + value(arg_list[1]) +
- value(arg_list[2]) + value(arg_list[3])) / T(4);
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return (value(arg_list[0]) + value(arg_list[1]) +
- value(arg_list[2]) + value(arg_list[3]) +
- value(arg_list[4])) / T(5);
- }
- };
- template <typename T>
- struct vararg_min_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 0 : return T(0);
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default :
- {
- T result = T(value(arg_list[0]));
- for (std::size_t i = 1; i < arg_list.size(); ++i)
- {
- const T v = value(arg_list[i]);
- if (v < result)
- result = v;
- }
- return result;
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return value(arg_list[0]);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return std::min<T>(value(arg_list[0]),value(arg_list[1]));
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return std::min<T>(
- std::min<T>(value(arg_list[0]),value(arg_list[1])),
- std::min<T>(value(arg_list[2]),value(arg_list[3])));
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return std::min<T>(
- std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),
- std::min<T>(value(arg_list[2]),value(arg_list[3]))),
- value(arg_list[4]));
- }
- };
- template <typename T>
- struct vararg_max_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 0 : return T(0);
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default :
- {
- T result = T(value(arg_list[0]));
- for (std::size_t i = 1; i < arg_list.size(); ++i)
- {
- const T v = value(arg_list[i]);
- if (v > result)
- result = v;
- }
- return result;
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return value(arg_list[0]);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return std::max<T>(value(arg_list[0]),value(arg_list[1]));
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return std::max<T>(
- std::max<T>(value(arg_list[0]),value(arg_list[1])),
- std::max<T>(value(arg_list[2]),value(arg_list[3])));
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return std::max<T>(
- std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),
- std::max<T>(value(arg_list[2]),value(arg_list[3]))),
- value(arg_list[4]));
- }
- };
- template <typename T>
- struct vararg_mand_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default :
- {
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- if (std::equal_to<T>()(T(0),value(arg_list[i])))
- return T(0);
- }
- return T(1);
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return std::not_equal_to<T>()
- (T(0),value(arg_list[0])) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[1]))
- ) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[2]))
- ) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[3]))
- ) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[3])) &&
- std::not_equal_to<T>()(T(0),value(arg_list[4]))
- ) ? T(1) : T(0);
- }
- };
- template <typename T>
- struct vararg_mor_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- default :
- {
- for (std::size_t i = 0; i < arg_list.size(); ++i)
- {
- if (std::not_equal_to<T>()(T(0),value(arg_list[i])))
- return T(1);
- }
- return T(0);
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return std::not_equal_to<T>()
- (T(0),value(arg_list[0])) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[1]))
- ) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[2]))
- ) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[3]))
- ) ? T(1) : T(0);
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- return (
- std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[3])) ||
- std::not_equal_to<T>()(T(0),value(arg_list[4]))
- ) ? T(1) : T(0);
- }
- };
- template <typename T>
- struct vararg_multi_op : public opr_base<T>
- {
- typedef typename opr_base<T>::Type Type;
- template <typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- static inline T process(const Sequence<Type,Allocator>& arg_list)
- {
- switch (arg_list.size())
- {
- case 0 : return std::numeric_limits<T>::quiet_NaN();
- case 1 : return process_1(arg_list);
- case 2 : return process_2(arg_list);
- case 3 : return process_3(arg_list);
- case 4 : return process_4(arg_list);
- case 5 : return process_5(arg_list);
- case 6 : return process_6(arg_list);
- case 7 : return process_7(arg_list);
- case 8 : return process_8(arg_list);
- default :
- {
- for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
- {
- value(arg_list[i]);
- }
- return value(arg_list.back());
- }
- }
- }
- template <typename Sequence>
- static inline T process_1(const Sequence& arg_list)
- {
- return value(arg_list[0]);
- }
- template <typename Sequence>
- static inline T process_2(const Sequence& arg_list)
- {
- value(arg_list[0]);
- return value(arg_list[1]);
- }
- template <typename Sequence>
- static inline T process_3(const Sequence& arg_list)
- {
- value(arg_list[0]);
- value(arg_list[1]);
- return value(arg_list[2]);
- }
- template <typename Sequence>
- static inline T process_4(const Sequence& arg_list)
- {
- value(arg_list[0]);
- value(arg_list[1]);
- value(arg_list[2]);
- return value(arg_list[3]);
- }
- template <typename Sequence>
- static inline T process_5(const Sequence& arg_list)
- {
- value(arg_list[0]);
- value(arg_list[1]);
- value(arg_list[2]);
- value(arg_list[3]);
- return value(arg_list[4]);
- }
- template <typename Sequence>
- static inline T process_6(const Sequence& arg_list)
- {
- value(arg_list[0]);
- value(arg_list[1]);
- value(arg_list[2]);
- value(arg_list[3]);
- value(arg_list[4]);
- return value(arg_list[5]);
- }
- template <typename Sequence>
- static inline T process_7(const Sequence& arg_list)
- {
- value(arg_list[0]);
- value(arg_list[1]);
- value(arg_list[2]);
- value(arg_list[3]);
- value(arg_list[4]);
- value(arg_list[5]);
- return value(arg_list[6]);
- }
- template <typename Sequence>
- static inline T process_8(const Sequence& arg_list)
- {
- value(arg_list[0]);
- value(arg_list[1]);
- value(arg_list[2]);
- value(arg_list[3]);
- value(arg_list[4]);
- value(arg_list[5]);
- value(arg_list[6]);
- return value(arg_list[7]);
- }
- };
- template <typename T>
- struct vec_add_op
- {
- typedef vector_interface<T>* ivector_ptr;
- static inline T process(const ivector_ptr v)
- {
- vector_holder<T>& vec = v->vec()->ref();
- T result = T(0);
- for (std::size_t i = 0; i < vec.size(); ++i)
- {
- result += (*vec[i]);
- }
- return result;
- }
- };
- template <typename T>
- struct vec_mul_op
- {
- typedef vector_interface<T>* ivector_ptr;
- static inline T process(const ivector_ptr v)
- {
- vector_holder<T>& vec = v->vec()->ref();
- T result = (*vec[0]);
- for (std::size_t i = 1; i < vec.size(); ++i)
- {
- result *= (*vec[i]);
- }
- return result;
- }
- };
- template <typename T>
- struct vec_avg_op
- {
- typedef vector_interface<T>* ivector_ptr;
- static inline T process(const ivector_ptr v)
- {
- vector_holder<T>& vec = v->vec()->ref();
- T result = T(0);
- for (std::size_t i = 0; i < vec.size(); ++i)
- {
- result += (*vec[i]);
- }
- return result / vec.size();
- }
- };
- template <typename T>
- struct vec_min_op
- {
- typedef vector_interface<T>* ivector_ptr;
- static inline T process(const ivector_ptr v)
- {
- vector_holder<T>& vec = v->vec()->ref();
- T result = (*vec[0]);
- for (std::size_t i = 1; i < vec.size(); ++i)
- {
- T v_i = (*vec[i]);
- if (v_i < result)
- result = v_i;
- }
- return result;
- }
- };
- template <typename T>
- struct vec_max_op
- {
- typedef vector_interface<T>* ivector_ptr;
- static inline T process(const ivector_ptr v)
- {
- vector_holder<T>& vec = v->vec()->ref();
- T result = (*vec[0]);
- for (std::size_t i = 1; i < vec.size(); ++i)
- {
- T v_i = (*vec[i]);
- if (v_i > result)
- result = v_i;
- }
- return result;
- }
- };
- template <typename T>
- class vov_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- virtual const T& v0() const = 0;
- virtual const T& v1() const = 0;
- };
- template <typename T>
- class cov_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- virtual const T c() const = 0;
- virtual const T& v() const = 0;
- };
- template <typename T>
- class voc_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- virtual const T c() const = 0;
- virtual const T& v() const = 0;
- };
- template <typename T>
- class vob_base_node : public expression_node<T>
- {
- public:
- virtual const T& v() const = 0;
- };
- template <typename T>
- class bov_base_node : public expression_node<T>
- {
- public:
- virtual const T& v() const = 0;
- };
- template <typename T>
- class cob_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- virtual const T c() const = 0;
- virtual void set_c(const T) = 0;
- virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
- };
- template <typename T>
- class boc_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- virtual const T c() const = 0;
- virtual void set_c(const T) = 0;
- virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
- };
- template <typename T>
- class uv_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- virtual const T& v() const = 0;
- };
- template <typename T>
- class sos_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- };
- template <typename T>
- class sosos_base_node : public expression_node<T>
- {
- public:
- inline virtual operator_type operation() const
- {
- return details::e_default;
- }
- };
- template <typename T>
- class T0oT1oT2_base_node : public expression_node<T>
- {
- public:
- virtual std::string type_id() const = 0;
- };
- template <typename T>
- class T0oT1oT2oT3_base_node : public expression_node<T>
- {
- public:
- virtual std::string type_id() const = 0;
- };
- template <typename T, typename Operation>
- class unary_variable_node : public uv_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- explicit unary_variable_node(const T& var)
- : v_(var)
- {}
- inline T value() const
- {
- return Operation::process(v_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T& v() const
- {
- return v_;
- }
- private:
- unary_variable_node(unary_variable_node<T,Operation>&);
- unary_variable_node<T,Operation>& operator=(unary_variable_node<T,Operation>&);
- const T& v_;
- };
- template <typename T>
- class uvouv_node : public expression_node<T>
- {
- public:
- // UOpr1(v0) Op UOpr2(v1)
- typedef expression_node<T>* expression_ptr;
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::bfunc_t bfunc_t;
- typedef typename functor_t::ufunc_t ufunc_t;
- explicit uvouv_node(const T& var0,const T& var1,
- ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
- : v0_(var0),
- v1_(var1),
- u0_(uf0),
- u1_(uf1),
- f_ (bf)
- {}
- inline T value() const
- {
- return f_(u0_(v0_),u1_(v1_));
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_uvouv;
- }
- inline operator_type operation() const
- {
- return details::e_default;
- }
- inline const T& v0()
- {
- return v0_;
- }
- inline const T& v1()
- {
- return v1_;
- }
- inline ufunc_t u0()
- {
- return u0_;
- }
- inline ufunc_t u1()
- {
- return u1_;
- }
- inline ufunc_t f()
- {
- return f_;
- }
- private:
- uvouv_node(uvouv_node<T>&);
- uvouv_node<T>& operator=(uvouv_node<T>&);
- const T& v0_;
- const T& v1_;
- const ufunc_t u0_;
- const ufunc_t u1_;
- const bfunc_t f_;
- };
- template <typename T, typename Operation>
- class unary_branch_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- explicit unary_branch_node(expression_ptr brnch)
- : branch_(brnch),
- branch_deletable_(branch_deletable(branch_))
- {}
- ~unary_branch_node()
- {
- if (branch_ && branch_deletable_)
- {
- delete branch_;
- branch_ = 0;
- }
- }
- inline T value() const
- {
- return Operation::process(branch_->value());
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_;
- }
- inline void release()
- {
- branch_deletable_ = false;
- }
- private:
- unary_branch_node(unary_branch_node<T,Operation>&);
- unary_branch_node<T,Operation>& operator=(unary_branch_node<T,Operation>&);
- expression_ptr branch_;
- bool branch_deletable_;
- };
- template <typename T> struct is_const { enum {result = 0}; };
- template <typename T> struct is_const <const T> { enum {result = 1}; };
- template <typename T> struct is_const_ref { enum {result = 0}; };
- template <typename T> struct is_const_ref <const T&> { enum {result = 1}; };
- template <typename T> struct is_ref { enum {result = 0}; };
- template <typename T> struct is_ref<T&> { enum {result = 1}; };
- template <typename T> struct is_ref<const T&> { enum {result = 0}; };
- template <std::size_t State>
- struct param_to_str { static std::string result() { static const std::string r("v"); return r; } };
- template <>
- struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } };
- #define exprtk_crtype(Type) \
- param_to_str<is_const_ref< Type >::result>::result() \
- template <typename T>
- struct T0oT1oT2process
- {
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::bfunc_t bfunc_t;
- struct mode0
- {
- static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
- {
- // (T0 o0 T1) o1 T2
- return bf1(bf0(t0,t1),t2);
- }
- template <typename T0, typename T1, typename T2>
- static inline std::string id()
- {
- static const std::string result = "(" + exprtk_crtype(T0) + "o" +
- exprtk_crtype(T1) + ")o(" +
- exprtk_crtype(T2) + ")" ;
- return result;
- }
- };
- struct mode1
- {
- static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
- {
- // T0 o0 (T1 o1 T2)
- return bf0(t0,bf1(t1,t2));
- }
- template <typename T0, typename T1, typename T2>
- static inline std::string id()
- {
- static const std::string result = "(" + exprtk_crtype(T0) + ")o(" +
- exprtk_crtype(T1) + "o" +
- exprtk_crtype(T2) + ")" ;
- return result;
- }
- };
- };
- template <typename T>
- struct T0oT1oT20T3process
- {
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::bfunc_t bfunc_t;
- struct mode0
- {
- static inline T process(const T& t0, const T& t1,
- const T& t2, const T& t3,
- const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
- {
- // (T0 o0 T1) o1 (T2 o2 T3)
- return bf1(bf0(t0,t1),bf2(t2,t3));
- }
- template <typename T0, typename T1, typename T2, typename T3>
- static inline std::string id()
- {
- static const std::string result = "(" + exprtk_crtype(T0) + "o" +
- exprtk_crtype(T1) + ")o" +
- "(" + exprtk_crtype(T2) + "o" +
- exprtk_crtype(T3) + ")" ;
- return result;
- }
- };
- struct mode1
- {
- static inline T process(const T& t0, const T& t1,
- const T& t2, const T& t3,
- const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
- {
- // (T0 o0 (T1 o1 (T2 o2 T3))
- return bf0(t0,bf1(t1,bf2(t2,t3)));
- }
- template <typename T0, typename T1, typename T2, typename T3>
- static inline std::string id()
- {
- static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
- exprtk_crtype(T1) + ")o(" +
- exprtk_crtype(T2) + "o" +
- exprtk_crtype(T3) + "))" ;
- return result;
- }
- };
- struct mode2
- {
- static inline T process(const T& t0, const T& t1,
- const T& t2, const T& t3,
- const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
- {
- // (T0 o0 ((T1 o1 T2) o2 T3)
- return bf0(t0,bf2(bf1(t1,t2),t3));
- }
- template <typename T0, typename T1, typename T2, typename T3>
- static inline std::string id()
- {
- static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
- exprtk_crtype(T1) + "o" +
- exprtk_crtype(T2) + ")o(" +
- exprtk_crtype(T3) + "))" ;
- return result;
- }
- };
- struct mode3
- {
- static inline T process(const T& t0, const T& t1,
- const T& t2, const T& t3,
- const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
- {
- // (((T0 o0 T1) o1 T2) o2 T3)
- return bf2(bf1(bf0(t0,t1),t2),t3);
- }
- template <typename T0, typename T1, typename T2, typename T3>
- static inline std::string id()
- {
- static const std::string result = "((" + exprtk_crtype(T0) + "o" +
- exprtk_crtype(T1) + ")o(" +
- exprtk_crtype(T2) + "))o(" +
- exprtk_crtype(T3) + ")";
- return result;
- }
- };
- struct mode4
- {
- static inline T process(const T& t0, const T& t1,
- const T& t2, const T& t3,
- const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
- {
- // ((T0 o0 (T1 o1 T2)) o2 T3
- return bf2(bf0(t0,bf1(t1,t2)),t3);
- }
- template <typename T0, typename T1, typename T2, typename T3>
- static inline std::string id()
- {
- static const std::string result = "((" + exprtk_crtype(T0) + ")o(" +
- exprtk_crtype(T1) + "o" +
- exprtk_crtype(T2) + "))o(" +
- exprtk_crtype(T3) + ")" ;
- return result;
- }
- };
- };
- #undef exprtk_crtype
- template <typename T, typename T0, typename T1>
- struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; };
- template <typename T, typename T0, typename T1>
- const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none;
- #define synthesis_node_type_define(T0_,T1_,v_) \
- template <typename T, typename T0, typename T1> \
- struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
- template <typename T, typename T0, typename T1> \
- const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
- synthesis_node_type_define(const T0&,const T1&, e_vov)
- synthesis_node_type_define(const T0&,const T1 , e_voc)
- synthesis_node_type_define(const T0 ,const T1&, e_cov)
- synthesis_node_type_define( T0&, T1&,e_none)
- synthesis_node_type_define(const T0 ,const T1 ,e_none)
- synthesis_node_type_define( T0&,const T1 ,e_none)
- synthesis_node_type_define(const T0 , T1&,e_none)
- synthesis_node_type_define(const T0&, T1&,e_none)
- synthesis_node_type_define( T0&,const T1&,e_none)
- #undef synthesis_node_type_define
- template <typename T, typename T0, typename T1, typename T2>
- struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
- template <typename T, typename T0, typename T1, typename T2>
- const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none;
- #define synthesis_node_type_define(T0_,T1_,T2_,v_) \
- template <typename T, typename T0, typename T1, typename T2> \
- struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
- template <typename T, typename T0, typename T1, typename T2> \
- const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
- synthesis_node_type_define(const T0&,const T1&,const T2&, e_vovov)
- synthesis_node_type_define(const T0&,const T1&,const T2 , e_vovoc)
- synthesis_node_type_define(const T0&,const T1 ,const T2&, e_vocov)
- synthesis_node_type_define(const T0 ,const T1&,const T2&, e_covov)
- synthesis_node_type_define(const T0 ,const T1&,const T2 , e_covoc)
- synthesis_node_type_define(const T0 ,const T1 ,const T2 , e_none )
- synthesis_node_type_define(const T0 ,const T1 ,const T2&, e_none )
- synthesis_node_type_define(const T0&,const T1 ,const T2 , e_none )
- synthesis_node_type_define( T0&, T1&, T2&, e_none )
- #undef synthesis_node_type_define
- template <typename T, typename T0, typename T1, typename T2, typename T3>
- struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; };
- template <typename T, typename T0, typename T1, typename T2, typename T3>
- const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none;
- #define synthesis_node_type_define(T0_,T1_,T2_,T3_,v_) \
- template <typename T, typename T0, typename T1, typename T2, typename T3> \
- struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
- template <typename T, typename T0, typename T1, typename T2, typename T3> \
- const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
- synthesis_node_type_define(const T0&,const T1&,const T2&, const T3&,e_vovovov)
- synthesis_node_type_define(const T0&,const T1&,const T2&, const T3 ,e_vovovoc)
- synthesis_node_type_define(const T0&,const T1&,const T2 , const T3&,e_vovocov)
- synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3&,e_vocovov)
- synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3&,e_covovov)
- synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3&,e_covocov)
- synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc)
- synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3 ,e_covovoc)
- synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3&,e_vococov)
- synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3 ,e_none )
- synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3&,e_none )
- synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3 ,e_none )
- synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3 ,e_none )
- synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3 ,e_none )
- synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3&,e_none )
- synthesis_node_type_define(const T0&,const T1&,const T2 , const T3 ,e_none )
- #undef synthesis_node_type_define
- template <typename T, typename T0, typename T1>
- class T0oT1 : public expression_node<T>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::bfunc_t bfunc_t;
- typedef T value_type;
- typedef T0oT1<T,T0,T1> node_type;
- T0oT1(T0 p0, T1 p1, const bfunc_t p2)
- : t0_(p0),
- t1_(p1),
- f_ (p2)
- {}
- inline typename expression_node<T>::node_type type() const
- {
- static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result;
- return result;
- }
- inline operator_type operation() const
- {
- return e_default;
- }
- inline T value() const
- {
- return f_(t0_,t1_);
- }
- inline T0 t0() const
- {
- return t0_;
- }
- inline T1 t1() const
- {
- return t1_;
- }
- inline bfunc_t f() const
- {
- return f_;
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator,
- T0 p0, T1 p1,
- bfunc_t p2)
- {
- return allocator.template allocate_type<node_type,T0,T1,bfunc_t&>(p0,p1,p2);
- }
- private:
- T0oT1(T0oT1<T,T0,T1>&) {}
- T0oT1<T,T0,T1>& operator=(T0oT1<T,T0,T1>&) { return *this; }
- T0 t0_;
- T1 t1_;
- const bfunc_t f_;
- };
- template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
- class T0oT1oT2 : public T0oT1oT2_base_node<T>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::bfunc_t bfunc_t;
- typedef T value_type;
- typedef T0oT1oT2<T,T0,T1,T2,ProcessMode> node_type;
- typedef ProcessMode process_mode_t;
- T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
- : t0_(p0),
- t1_(p1),
- t2_(p2),
- f0_(p3),
- f1_(p4)
- {}
- inline typename expression_node<T>::node_type type() const
- {
- static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
- return result;
- }
- inline operator_type operation() const
- {
- return e_default;
- }
- inline T value() const
- {
- return ProcessMode::process(t0_,t1_,t2_,f0_,f1_);
- }
- inline T0 t0() const
- {
- return t0_;
- }
- inline T1 t1() const
- {
- return t1_;
- }
- inline T2 t2() const
- {
- return t2_;
- }
- bfunc_t f0() const
- {
- return f0_;
- }
- bfunc_t f1() const
- {
- return f1_;
- }
- std::string type_id() const
- {
- return id();
- }
- static inline std::string id()
- {
- return process_mode_t::template id<T0,T1,T2>();
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
- {
- return allocator.template allocate_type<node_type,T0,T1,T2,bfunc_t,bfunc_t>(p0,p1,p2,p3,p4);
- }
- private:
- T0oT1oT2(node_type&) {}
- node_type& operator=(node_type&) { return *this; }
- T0 t0_;
- T1 t1_;
- T2 t2_;
- const bfunc_t f0_;
- const bfunc_t f1_;
- };
- template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode>
- class T0oT1oT2oT3 : public T0oT1oT2oT3_base_node<T>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::bfunc_t bfunc_t;
- typedef T value_type;
- typedef T0_ T0;
- typedef T1_ T1;
- typedef T2_ T2;
- typedef T3_ T3;
- typedef T0oT1oT2oT3<T,T0,T1,T2,T3,ProcessMode> node_type;
- typedef ProcessMode process_mode_t;
- T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
- : t0_(p0),
- t1_(p1),
- t2_(p2),
- t3_(p3),
- f0_(p4),
- f1_(p5),
- f2_(p6)
- {}
- inline T value() const
- {
- return ProcessMode::process(t0_,t1_,t2_,t3_,f0_,f1_,f2_);
- }
- inline T0 t0() const
- {
- return t0_;
- }
- inline T1 t1() const
- {
- return t1_;
- }
- inline T2 t2() const
- {
- return t2_;
- }
- inline T3 t3() const
- {
- return t3_;
- }
- inline bfunc_t f0() const
- {
- return f0_;
- }
- inline bfunc_t f1() const
- {
- return f1_;
- }
- inline bfunc_t f2() const
- {
- return f2_;
- }
- inline std::string type_id() const
- {
- return id();
- }
- static inline std::string id()
- {
- return process_mode_t::template id<T0,T1,T2,T3>();
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator,
- T0 p0, T1 p1, T2 p2, T3 p3,
- bfunc_t p4, bfunc_t p5, bfunc_t p6)
- {
- return allocator.template allocate_type<node_type,T0,T1,T2,T3,bfunc_t,bfunc_t>(p0,p1,p2,p3,p4,p5,p6);
- }
- private:
- T0oT1oT2oT3(node_type&) {}
- node_type& operator=(node_type&) { return *this; }
- T0 t0_;
- T1 t1_;
- T2 t2_;
- T3 t3_;
- const bfunc_t f0_;
- const bfunc_t f1_;
- const bfunc_t f2_;
- };
- template <typename T, typename T0, typename T1, typename T2>
- class T0oT1oT2_sf3 : public T0oT1oT2_base_node<T>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::tfunc_t tfunc_t;
- typedef T value_type;
- typedef T0oT1oT2_sf3<T,T0,T1,T2> node_type;
- T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
- : t0_(p0),
- t1_(p1),
- t2_(p2),
- f_ (p3)
- {}
- inline typename expression_node<T>::node_type type() const
- {
- static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
- return result;
- }
- inline operator_type operation() const
- {
- return e_default;
- }
- inline T value() const
- {
- return f_(t0_,t1_,t2_);
- }
- inline T0 t0() const
- {
- return t0_;
- }
- inline T1 t1() const
- {
- return t1_;
- }
- inline T2 t2() const
- {
- return t2_;
- }
- tfunc_t f() const
- {
- return f_;
- }
- std::string type_id() const
- {
- return id();
- }
- static inline std::string id()
- {
- return "sf3";
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
- {
- return allocator.template allocate_type<node_type,T0,T1,T2,tfunc_t>(p0,p1,p2,p3);
- }
- private:
- T0oT1oT2_sf3(node_type&) {}
- node_type& operator=(node_type&) { return *this; }
- T0 t0_;
- T1 t1_;
- T2 t2_;
- const tfunc_t f_;
- };
- template <typename T, typename T0, typename T1, typename T2>
- class sf3ext_type_node : public T0oT1oT2_base_node<T>
- {
- public:
- virtual T0 t0() const = 0;
- virtual T1 t1() const = 0;
- virtual T2 t2() const = 0;
- };
- template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
- class T0oT1oT2_sf3ext : public sf3ext_type_node<T,T0,T1,T2>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::tfunc_t tfunc_t;
- typedef T value_type;
- typedef T0oT1oT2_sf3ext<T,T0,T1,T2,SF3Operation> node_type;
- T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
- : t0_(p0),
- t1_(p1),
- t2_(p2)
- {}
- inline typename expression_node<T>::node_type type() const
- {
- static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
- return result;
- }
- inline operator_type operation() const
- {
- return e_default;
- }
- inline T value() const
- {
- return SF3Operation::process(t0_,t1_,t2_);
- }
- T0 t0() const
- {
- return t0_;
- }
- T1 t1() const
- {
- return t1_;
- }
- T2 t2() const
- {
- return t2_;
- }
- std::string type_id() const
- {
- return id();
- }
- static inline std::string id()
- {
- return SF3Operation::id();
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2)
- {
- return allocator.template allocate_type<node_type,T0,T1,T2>(p0,p1,p2);
- }
- private:
- T0oT1oT2_sf3ext(node_type&) {}
- node_type& operator=(node_type&) { return *this; }
- T0 t0_;
- T1 t1_;
- T2 t2_;
- };
- template <typename T>
- inline bool is_sf3ext_node(const expression_node<T>* n)
- {
- switch (n->type())
- {
- case expression_node<T>::e_vovov : return true;
- case expression_node<T>::e_vovoc : return true;
- case expression_node<T>::e_vocov : return true;
- case expression_node<T>::e_covov : return true;
- case expression_node<T>::e_covoc : return true;
- default : return false;
- }
- }
- template <typename T, typename T0, typename T1, typename T2, typename T3>
- class T0oT1oT2oT3_sf4 : public T0oT1oT2_base_node<T>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::qfunc_t qfunc_t;
- typedef T value_type;
- typedef T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> node_type;
- T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
- : t0_(p0),
- t1_(p1),
- t2_(p2),
- t3_(p3),
- f_ (p4)
- {}
- inline typename expression_node<T>::node_type type() const
- {
- static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
- return result;
- }
- inline operator_type operation() const
- {
- return e_default;
- }
- inline T value() const
- {
- return f_(t0_,t1_,t2_,t3_);
- }
- inline T0 t0() const
- {
- return t0_;
- }
- inline T1 t1() const
- {
- return t1_;
- }
- inline T2 t2() const
- {
- return t2_;
- }
- inline T3 t3() const
- {
- return t3_;
- }
- qfunc_t f() const
- {
- return f_;
- }
- std::string type_id() const
- {
- return id();
- }
- static inline std::string id()
- {
- return "sf4";
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
- {
- return allocator.template allocate_type<node_type,T0,T1,T2,T3,qfunc_t>(p0,p1,p2,p3,p4);
- }
- private:
- T0oT1oT2oT3_sf4(node_type&) {}
- node_type& operator=(node_type&) { return *this; }
- T0 t0_;
- T1 t1_;
- T2 t2_;
- T3 t3_;
- const qfunc_t f_;
- };
- template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation>
- class T0oT1oT2oT3_sf4ext : public T0oT1oT2oT3_base_node<T>
- {
- public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::tfunc_t tfunc_t;
- typedef T value_type;
- typedef T0oT1oT2oT3_sf4ext<T,T0,T1,T2,T3,SF4Operation> node_type;
- T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
- : t0_(p0),
- t1_(p1),
- t2_(p2),
- t3_(p3)
- {}
- inline typename expression_node<T>::node_type type() const
- {
- static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
- return result;
- }
- inline operator_type operation() const
- {
- return e_default;
- }
- inline T value() const
- {
- return SF4Operation::process(t0_,t1_,t2_,t3_);
- }
- inline T0 t0() const
- {
- return t0_;
- }
- inline T1 t1() const
- {
- return t1_;
- }
- inline T2 t2() const
- {
- return t2_;
- }
- inline T3 t3() const
- {
- return t2_;
- }
- std::string type_id() const
- {
- return id();
- }
- static inline std::string id()
- {
- return SF4Operation::id();
- }
- template <typename Allocator>
- static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3)
- {
- return allocator.template allocate_type<node_type,T0,T1,T2,T3>(p0,p1,p2,p3);
- }
- private:
- T0oT1oT2oT3_sf4ext(node_type&) {}
- node_type& operator=(node_type&) { return *this; }
- T0 t0_;
- T1 t1_;
- T2 t2_;
- T3 t3_;
- };
- template <typename T>
- inline bool is_sf4ext_node(const expression_node<T>* n)
- {
- switch (n->type())
- {
- case expression_node<T>::e_vovovov : return true;
- case expression_node<T>::e_vovovoc : return true;
- case expression_node<T>::e_vovocov : return true;
- case expression_node<T>::e_vocovov : return true;
- case expression_node<T>::e_covovov : return true;
- case expression_node<T>::e_covocov : return true;
- case expression_node<T>::e_vocovoc : return true;
- case expression_node<T>::e_covovoc : return true;
- case expression_node<T>::e_vococov : return true;
- default : return false;
- }
- }
- template <typename T, typename T0, typename T1>
- struct T0oT1_define
- {
- typedef details::T0oT1<T,T0,T1> type0;
- };
- template <typename T, typename T0, typename T1, typename T2>
- struct T0oT1oT2_define
- {
- typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode0> type0;
- typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode1> type1;
- typedef details::T0oT1oT2_sf3<T,T0,T1,T2> sf3_type;
- typedef details::sf3ext_type_node<T,T0,T1,T2> sf3_type_node;
- };
- template <typename T, typename T0, typename T1, typename T2, typename T3>
- struct T0oT1oT2oT3_define
- {
- typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode0> type0;
- typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode1> type1;
- typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode2> type2;
- typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode3> type3;
- typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode4> type4;
- typedef details::T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> sf4_type;
- };
- template <typename T, typename Operation>
- class vov_node : public vov_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // variable op variable node
- explicit vov_node(const T& var0, const T& var1)
- : v0_(var0),
- v1_(var1)
- {}
- inline T value() const
- {
- return Operation::process(v0_,v1_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T& v0() const
- {
- return v0_;
- }
- inline const T& v1() const
- {
- return v1_;
- }
- protected:
- const T& v0_;
- const T& v1_;
- private:
- vov_node(vov_node<T,Operation>&);
- vov_node<T,Operation>& operator=(vov_node<T,Operation>&);
- };
- template <typename T, typename Operation>
- class cov_node : public cov_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // constant op variable node
- explicit cov_node(const T& const_var, const T& var)
- : c_(const_var),
- v_(var)
- {}
- inline T value() const
- {
- return Operation::process(c_,v_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T c() const
- {
- return c_;
- }
- inline const T& v() const
- {
- return v_;
- }
- protected:
- const T c_;
- const T& v_;
- private:
- cov_node(const cov_node<T,Operation>&);
- cov_node<T,Operation>& operator=(const cov_node<T,Operation>&);
- };
- template <typename T, typename Operation>
- class voc_node : public voc_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // variable op constant node
- explicit voc_node(const T& var, const T& const_var)
- : v_(var),
- c_(const_var)
- {}
- inline T value() const
- {
- return Operation::process(v_,c_);
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T c() const
- {
- return c_;
- }
- inline const T& v() const
- {
- return v_;
- }
- protected:
- const T& v_;
- const T c_;
- private:
- voc_node(const voc_node<T,Operation>&);
- voc_node<T,Operation>& operator=(const voc_node<T,Operation>&);
- };
- template <typename T, typename Operation>
- class vob_node : public vob_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- typedef Operation operation_t;
- // variable op constant node
- explicit vob_node(const T& var, const expression_ptr brnch)
- : v_(var)
- {
- init_branches<1>(branch_,brnch);
- }
- ~vob_node()
- {
- cleanup_branches::execute<T,1>(branch_);
- }
- inline T value() const
- {
- return Operation::process(v_,branch_[0].first->value());
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T& v() const
- {
- return v_;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_[0].first;
- }
- private:
- vob_node(const vob_node<T,Operation>&);
- vob_node<T,Operation>& operator=(const vob_node<T,Operation>&);
- const T& v_;
- branch_t branch_[1];
- };
- template <typename T, typename Operation>
- class bov_node : public bov_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- typedef Operation operation_t;
- // variable op constant node
- explicit bov_node(const expression_ptr brnch, const T& var)
- : v_(var)
- {
- init_branches<1>(branch_,brnch);
- }
- ~bov_node()
- {
- cleanup_branches::execute<T,1>(branch_);
- }
- inline T value() const
- {
- return Operation::process(branch_[0].first->value(),v_);
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T& v() const
- {
- return v_;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_[0].first;
- }
- private:
- bov_node(const bov_node<T,Operation>&);
- bov_node<T,Operation>& operator=(const bov_node<T,Operation>&);
- const T& v_;
- branch_t branch_[1];
- };
- template <typename T, typename Operation>
- class cob_node : public cob_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- typedef Operation operation_t;
- // variable op constant node
- explicit cob_node(const T const_var, const expression_ptr brnch)
- : c_(const_var)
- {
- init_branches<1>(branch_,brnch);
- }
- ~cob_node()
- {
- cleanup_branches::execute<T,1>(branch_);
- }
- inline T value() const
- {
- return Operation::process(c_,branch_[0].first->value());
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T c() const
- {
- return c_;
- }
- inline void set_c(const T new_c)
- {
- (*const_cast<T*>(&c_)) = new_c;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_[0].first;
- }
- inline expression_node<T>* move_branch(const std::size_t&)
- {
- branch_[0].second = false;
- return branch_[0].first;
- }
- private:
- cob_node(const cob_node<T,Operation>&);
- cob_node<T,Operation>& operator=(const cob_node<T,Operation>&);
- const T c_;
- branch_t branch_[1];
- };
- template <typename T, typename Operation>
- class boc_node : public boc_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef std::pair<expression_ptr,bool> branch_t;
- typedef Operation operation_t;
- // variable op constant node
- explicit boc_node(const expression_ptr brnch, const T const_var)
- : c_(const_var)
- {
- init_branches<1>(branch_,brnch);
- }
- ~boc_node()
- {
- cleanup_branches::execute<T,1>(branch_);
- }
- inline T value() const
- {
- return Operation::process(branch_[0].first->value(),c_);
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline const T c() const
- {
- return c_;
- }
- inline void set_c(const T new_c)
- {
- (*const_cast<T*>(&c_)) = new_c;
- }
- inline expression_node<T>* branch(const std::size_t&) const
- {
- return branch_[0].first;
- }
- inline expression_node<T>* move_branch(const std::size_t&)
- {
- branch_[0].second = false;
- return branch_[0].first;
- }
- private:
- boc_node(const boc_node<T,Operation>&);
- boc_node<T,Operation>& operator=(const boc_node<T,Operation>&);
- const T c_;
- branch_t branch_[1];
- };
- #ifndef exprtk_disable_string_capabilities
- template <typename T, typename SType0, typename SType1, typename Operation>
- class sos_node : public sos_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // string op string node
- explicit sos_node(SType0 p0, SType1 p1)
- : s0_(p0),
- s1_(p1)
- {}
- inline T value() const
- {
- return Operation::process(s0_,s1_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline std::string& s0()
- {
- return s0_;
- }
- inline std::string& s1()
- {
- return s1_;
- }
- protected:
- SType0 s0_;
- SType1 s1_;
- private:
- sos_node(sos_node<T,SType0,SType1,Operation>&);
- sos_node<T,SType0,SType1,Operation>& operator=(sos_node<T,SType0,SType1,Operation>&);
- };
- template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
- class str_xrox_node : public sos_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // string-range op string node
- explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
- : s0_(p0),
- s1_(p1),
- rp0_(rp0)
- {}
- ~str_xrox_node()
- {
- rp0_.free();
- }
- inline T value() const
- {
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- if (rp0_(r0,r1,s0_.size()))
- return Operation::process(s0_.substr(r0,(r1 - r0) + 1),s1_);
- else
- return T(0);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline std::string& s0()
- {
- return s0_;
- }
- inline std::string& s1()
- {
- return s1_;
- }
- protected:
- SType0 s0_;
- SType1 s1_;
- RangePack rp0_;
- private:
- str_xrox_node(str_xrox_node<T,SType0,SType1,RangePack,Operation>&);
- str_xrox_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xrox_node<T,SType0,SType1,RangePack,Operation>&);
- };
- template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
- class str_xoxr_node : public sos_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // string op string range node
- explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
- : s0_ (p0 ),
- s1_ (p1 ),
- rp1_(rp1)
- {}
- ~str_xoxr_node()
- {
- rp1_.free();
- }
- inline T value() const
- {
- std::size_t r0 = 0;
- std::size_t r1 = 0;
- if (rp1_(r0,r1,s1_.size()))
- return Operation::process(s0_,s1_.substr(r0,(r1 - r0) + 1));
- else
- return T(0);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline std::string& s0()
- {
- return s0_;
- }
- inline std::string& s1()
- {
- return s1_;
- }
- protected:
- SType0 s0_;
- SType1 s1_;
- RangePack rp1_;
- private:
- str_xoxr_node(str_xoxr_node<T,SType0,SType1,RangePack,Operation>&);
- str_xoxr_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xoxr_node<T,SType0,SType1,RangePack,Operation>&);
- };
- template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
- class str_xroxr_node : public sos_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // string-range op string-range node
- explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
- : s0_ (p0 ),
- s1_ (p1 ),
- rp0_(rp0),
- rp1_(rp1)
- {}
- ~str_xroxr_node()
- {
- rp0_.free();
- rp1_.free();
- }
- inline T value() const
- {
- std::size_t r0_0 = 0;
- std::size_t r0_1 = 0;
- std::size_t r1_0 = 0;
- std::size_t r1_1 = 0;
- if (
- rp0_(r0_0,r1_0,s0_.size()) &&
- rp1_(r0_1,r1_1,s1_.size())
- )
- {
- return Operation::process(
- s0_.substr(r0_0,(r1_0 - r0_0) + 1),
- s1_.substr(r0_1,(r1_1 - r0_1) + 1)
- );
- }
- else
- return T(0);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline std::string& s0()
- {
- return s0_;
- }
- inline std::string& s1()
- {
- return s1_;
- }
- protected:
- SType0 s0_;
- SType1 s1_;
- RangePack rp0_;
- RangePack rp1_;
- private:
- str_xroxr_node(str_xroxr_node<T,SType0,SType1,RangePack,Operation>&);
- str_xroxr_node<T,SType0,SType1,RangePack,Operation>& operator=(str_xroxr_node<T,SType0,SType1,RangePack,Operation>&);
- };
- template <typename T, typename Operation>
- class str_sogens_node : public binary_node<T>
- {
- public:
- typedef expression_node <T>* expression_ptr;
- typedef string_base_node<T>* str_base_ptr;
- typedef range_pack <T> range_t;
- typedef range_t* range_ptr;
- typedef range_interface<T> irange_t;
- typedef irange_t* irange_ptr;
- str_sogens_node(const operator_type& opr,
- expression_ptr branch0,
- expression_ptr branch1)
- : binary_node<T>(opr,branch0,branch1),
- str0_base_ptr_ (0),
- str1_base_ptr_ (0),
- str0_range_ptr_(0),
- str1_range_ptr_(0)
- {
- if (is_generally_string_node(binary_node<T>::branch_[0].first))
- {
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
- if (0 == str0_base_ptr_)
- return;
- irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
- if (0 == range_ptr)
- return;
- str0_range_ptr_ = &(range_ptr->range_ref());
- }
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
- {
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
- if (0 == str1_base_ptr_)
- return;
- irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
- if (0 == range_ptr)
- return;
- str1_range_ptr_ = &(range_ptr->range_ref());
- }
- }
- inline T value() const
- {
- if (
- str0_base_ptr_ &&
- str1_base_ptr_ &&
- str0_range_ptr_ &&
- str1_range_ptr_
- )
- {
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
- std::size_t str0_r0 = 0;
- std::size_t str0_r1 = 0;
- std::size_t str1_r0 = 0;
- std::size_t str1_r1 = 0;
- range_t& range0 = (*str0_range_ptr_);
- range_t& range1 = (*str1_range_ptr_);
- if (
- range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
- range1(str1_r0,str1_r1,str1_base_ptr_->size())
- )
- {
- return Operation::process(
- str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0) + 1),
- str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0) + 1)
- );
- }
- }
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- private:
- str_sogens_node(str_sogens_node<T,Operation>&);
- str_sogens_node<T,Operation>& operator=(str_sogens_node<T,Operation>&);
- str_base_ptr str0_base_ptr_;
- str_base_ptr str1_base_ptr_;
- range_ptr str0_range_ptr_;
- range_ptr str1_range_ptr_;
- };
- template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
- class sosos_node : public sosos_base_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef Operation operation_t;
- // variable op variable node
- explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
- : s0_(p0),
- s1_(p1),
- s2_(p2)
- {}
- inline T value() const
- {
- return Operation::process(s0_,s1_,s2_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return Operation::type();
- }
- inline operator_type operation() const
- {
- return Operation::operation();
- }
- inline std::string& s0()
- {
- return s0_;
- }
- inline std::string& s1()
- {
- return s1_;
- }
- inline std::string& s2()
- {
- return s2_;
- }
- protected:
- SType0 s0_;
- SType1 s1_;
- SType2 s2_;
- private:
- sosos_node(sosos_node<T,SType0,SType1,SType2,Operation>&);
- sosos_node<T,SType0,SType1,SType2,Operation>& operator=(sosos_node<T,SType0,SType1,SType2,Operation>&);
- };
- #endif
- template <typename T, typename PowOp>
- class ipow_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef PowOp operation_t;
- explicit ipow_node(const T& v)
- : v_(v)
- {}
- inline T value() const
- {
- return PowOp::result(v_);
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_ipow;
- }
- private:
- ipow_node(const ipow_node<T,PowOp>&);
- ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&);
- const T& v_;
- };
- template <typename T, typename PowOp>
- class ipowinv_node : public expression_node<T>
- {
- public:
- typedef expression_node<T>* expression_ptr;
- typedef PowOp operation_t;
- explicit ipowinv_node(const T& v)
- : v_(v)
- {}
- inline T value() const
- {
- return (T(1) / PowOp::result(v_));
- }
- inline typename expression_node<T>::node_type type() const
- {
- return expression_node<T>::e_ipowinv;
- }
- private:
- ipowinv_node(const ipowinv_node<T,PowOp>&);
- ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&);
- const T& v_;
- };
- template <typename T>
- inline bool is_vov_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const vov_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_cov_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const cov_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_voc_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const voc_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_cob_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const cob_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_boc_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const boc_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_t0ot1ot2_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_uv_node(const expression_node<T>* node)
- {
- return (0 != dynamic_cast<const uv_base_node<T>*>(node));
- }
- template <typename T>
- inline bool is_string_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_stringvar == node->type());
- }
- template <typename T>
- inline bool is_string_range_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_stringvarrng == node->type());
- }
- template <typename T>
- inline bool is_const_string_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_stringconst == node->type());
- }
- template <typename T>
- inline bool is_const_string_range_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_cstringvarrng == node->type());
- }
- template <typename T>
- inline bool is_string_assignment_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_strass == node->type());
- }
- template <typename T>
- inline bool is_string_concat_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_strconcat == node->type());
- }
- template <typename T>
- inline bool is_string_function_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_strfunction == node->type());
- }
- template <typename T>
- inline bool is_string_condition_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_strcondition == node->type());
- }
- template <typename T>
- inline bool is_string_ccondition_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_strccondition == node->type());
- }
- template <typename T>
- inline bool is_genricstring_range_node(const expression_node<T>* node)
- {
- return node && (expression_node<T>::e_strgenrange == node->type());
- }
- template <typename T>
- inline bool is_generally_string_node(const expression_node<T>* node)
- {
- if (node)
- {
- switch (node->type())
- {
- case expression_node<T>::e_stringvar :
- case expression_node<T>::e_stringconst :
- case expression_node<T>::e_stringvarrng :
- case expression_node<T>::e_cstringvarrng :
- case expression_node<T>::e_strgenrange :
- case expression_node<T>::e_strass :
- case expression_node<T>::e_strconcat :
- case expression_node<T>::e_strfunction :
- case expression_node<T>::e_strcondition :
- case expression_node<T>::e_strccondition : return true;
- default : return false;
- }
- }
- return false;
- }
- class node_allocator
- {
- public:
- template <typename ResultNode, typename OpType, typename ExprNode>
- inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1])
- {
- return allocate<ResultNode>(operation,branch[0]);
- }
- template <typename ResultNode, typename OpType, typename ExprNode>
- inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2])
- {
- return allocate<ResultNode>(operation,branch[0],branch[1]);
- }
- template <typename ResultNode, typename OpType, typename ExprNode>
- inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3])
- {
- return allocate<ResultNode>(operation,branch[0],branch[1],branch[2]);
- }
- template <typename ResultNode, typename OpType, typename ExprNode>
- inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4])
- {
- return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3]);
- }
- template <typename ResultNode, typename OpType, typename ExprNode>
- inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5])
- {
- return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4]);
- }
- template <typename ResultNode, typename OpType, typename ExprNode>
- inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6])
- {
- return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4],branch[5]);
- }
- template <typename node_type>
- inline expression_node<typename node_type::value_type>* allocate() const
- {
- return new node_type();
- }
- template <typename node_type,
- typename Type,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const
- {
- return new node_type(seq);
- }
- template <typename node_type, typename T1>
- inline expression_node<typename node_type::value_type>* allocate(T1& t1) const
- {
- return new node_type(t1);
- }
- template <typename node_type, typename T1>
- inline expression_node<typename node_type::value_type>* allocate_c(const T1& t1) const
- {
- return new node_type(t1);
- }
- template <typename node_type,
- typename T1, typename T2>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
- {
- return new node_type(t1,t2);
- }
- template <typename node_type,
- typename T1, typename T2>
- inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const
- {
- return new node_type(t1,t2);
- }
- template <typename node_type,
- typename T1, typename T2>
- inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
- {
- return new node_type(t1,t2);
- }
- template <typename node_type,
- typename T1, typename T2>
- inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const
- {
- return new node_type(t1,t2);
- }
- template <typename node_type,
- typename T1, typename T2>
- inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const
- {
- return new node_type(t1,t2);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3>
- inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const
- {
- return new node_type(t1,t2,t3);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3, typename T4>
- inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
- {
- return new node_type(t1,t2,t3,t4);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3>
- inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const
- {
- return new node_type(t1,t2,t3);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3, typename T4>
- inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const
- {
- return new node_type(t1,t2,t3,t4);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3, typename T4, typename T5>
- inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
- {
- return new node_type(t1,t2,t3,t4,t5);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3) const
- {
- return new node_type(t1,t2,t3);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4) const
- {
- return new node_type(t1,t2,t3,t4);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4, typename T5>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4,
- const T5& t5) const
- {
- return new node_type(t1,t2,t3,t4,t5);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4, typename T5, typename T6>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4,
- const T5& t5, const T6& t6) const
- {
- return new node_type(t1,t2,t3,t4,t5,t6);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4,
- typename T5, typename T6, typename T7>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4,
- const T5& t5, const T6& t6,
- const T7& t7) const
- {
- return new node_type(t1,t2,t3,t4,t5,t6,t7);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4,
- typename T5, typename T6,
- typename T7, typename T8>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4,
- const T5& t5, const T6& t6,
- const T7& t7, const T8& t8) const
- {
- return new node_type(t1,t2,t3,t4,t5,t6,t7,t8);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4,
- typename T5, typename T6,
- typename T7, typename T8, typename T9>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4,
- const T5& t5, const T6& t6,
- const T7& t7, const T8& t8,
- const T9& t9) const
- {
- return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4,
- typename T5, typename T6,
- typename T7, typename T8,
- typename T9, typename T10>
- inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
- const T3& t3, const T4& t4,
- const T5& t5, const T6& t6,
- const T7& t7, const T8& t8,
- const T9& t9, const T10& t10) const
- {
- return new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
- }
- template <typename node_type,
- typename T1, typename T2, typename T3>
- inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const
- {
- return new node_type(t1,t2,t3);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4>
- inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
- T3 t3, T4 t4) const
- {
- return new node_type(t1,t2,t3,t4);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4,
- typename T5>
- inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
- T3 t3, T4 t4,
- T5 t5) const
- {
- return new node_type(t1,t2,t3,t4,t5);
- }
- template <typename node_type,
- typename T1, typename T2,
- typename T3, typename T4,
- typename T5, typename T6, typename T7>
- inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
- T3 t3, T4 t4,
- T5 t5, T6 t6,
- T7 t7) const
- {
- return new node_type(t1,t2,t3,t4,t5,t6,t7);
- }
- template <typename T>
- void inline free(expression_node<T>*& e) const
- {
- delete e;
- e = 0;
- }
- };
- inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
- {
- #define register_op(Symbol,Type,Args) \
- m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
- register_op( "abs",e_abs , 1)
- register_op( "acos",e_acos , 1)
- register_op( "acosh",e_acosh , 1)
- register_op( "asin",e_asin , 1)
- register_op( "asinh",e_asinh , 1)
- register_op( "atan",e_atan , 1)
- register_op( "atanh",e_atanh , 1)
- register_op( "ceil",e_ceil , 1)
- register_op( "cos",e_cos , 1)
- register_op( "cosh",e_cosh , 1)
- register_op( "exp",e_exp , 1)
- register_op( "expm1",e_expm1 , 1)
- register_op( "floor",e_floor , 1)
- register_op( "log",e_log , 1)
- register_op( "log10",e_log10 , 1)
- register_op( "log2",e_log2 , 1)
- register_op( "log1p",e_log1p , 1)
- register_op( "round",e_round , 1)
- register_op( "sin",e_sin , 1)
- register_op( "sinc",e_sinc , 1)
- register_op( "sinh",e_sinh , 1)
- register_op( "sec",e_sec , 1)
- register_op( "csc",e_csc , 1)
- register_op( "sqrt",e_sqrt , 1)
- register_op( "tan",e_tan , 1)
- register_op( "tanh",e_tanh , 1)
- register_op( "cot",e_cot , 1)
- register_op( "rad2deg",e_r2d , 1)
- register_op( "deg2rad",e_d2r , 1)
- register_op( "deg2grad",e_d2g , 1)
- register_op( "grad2deg",e_g2d , 1)
- register_op( "sgn",e_sgn , 1)
- register_op( "not",e_notl , 1)
- register_op( "erf",e_erf , 1)
- register_op( "erfc",e_erfc , 1)
- register_op( "ncdf",e_ncdf , 1)
- register_op( "frac",e_frac , 1)
- register_op( "trunc",e_trunc , 1)
- register_op( "atan2",e_atan2 , 2)
- register_op( "mod",e_mod , 2)
- register_op( "logn",e_logn , 2)
- register_op( "pow",e_pow , 2)
- register_op( "root",e_root , 2)
- register_op( "roundn",e_roundn , 2)
- register_op( "equal",e_equal , 2)
- register_op("not_equal",e_nequal , 2)
- register_op( "hypot",e_hypot , 2)
- register_op( "shr",e_shr , 2)
- register_op( "shl",e_shl , 2)
- register_op( "clamp",e_clamp , 3)
- register_op( "iclamp",e_iclamp , 3)
- register_op( "inrange",e_inrange , 3)
- #undef register_op
- }
- } // namespace details
- class function_traits
- {
- public:
- function_traits()
- : allow_zero_parameters_(false),
- has_side_effects_(true)
- {}
- inline bool& allow_zero_parameters()
- {
- return allow_zero_parameters_;
- }
- inline bool& has_side_effects()
- {
- return has_side_effects_;
- }
- private:
- bool allow_zero_parameters_;
- bool has_side_effects_;
- };
- template <typename FunctionType>
- void enable_zero_parameters(FunctionType& func)
- {
- func.allow_zero_parameters() = true;
- }
- template <typename FunctionType>
- void disable_zero_parameters(FunctionType& func)
- {
- func.allow_zero_parameters() = false;
- }
- template <typename FunctionType>
- void enable_has_side_effects(FunctionType& func)
- {
- func.has_side_effects() = true;
- }
- template <typename FunctionType>
- void disable_has_side_effects(FunctionType& func)
- {
- func.has_side_effects() = false;
- }
- template <typename T>
- class ifunction : public function_traits
- {
- public:
- explicit ifunction(const std::size_t& pc)
- : param_count(pc)
- {}
- virtual ~ifunction()
- {}
- inline virtual T operator()()
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&,const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
- const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
- {
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::size_t param_count;
- };
- template <typename T>
- class ivararg_function : public function_traits
- {
- public:
- virtual ~ivararg_function()
- {}
- inline virtual T operator()(const std::vector<T>&)
- {
- exprtk_debug(("ivararg_function::operator() - Operator has not been overridden.\n"));
- return std::numeric_limits<T>::quiet_NaN();
- }
- };
- template <typename T>
- class igeneric_function : public function_traits
- {
- public:
- typedef T type;
- typedef type_store<T> generic_type;
- typedef typename generic_type::parameter_list parameter_list_t;
- igeneric_function(const std::string& param_seq = "")
- : parameter_sequence(param_seq)
- {}
- virtual ~igeneric_function()
- {}
- // f(i_0,i_1,....,i_N) --> Number
- inline virtual T operator()(parameter_list_t)
- {
- exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [1]\n"));
- return std::numeric_limits<T>::quiet_NaN();
- }
- // f(i_0,i_1,....,i_N) --> String
- inline virtual T operator()(std::string&, parameter_list_t)
- {
- exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [2]\n"));
- return std::numeric_limits<T>::quiet_NaN();
- }
- // f(psi,i_0,i_1,....,i_N) --> Number
- inline virtual T operator()(const std::size_t&, parameter_list_t)
- {
- exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [3]\n"));
- return std::numeric_limits<T>::quiet_NaN();
- }
- // f(psi,i_0,i_1,....,i_N) --> String
- inline virtual T operator()(const std::size_t&, std::string&, parameter_list_t)
- {
- exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [4]\n"));
- return std::numeric_limits<T>::quiet_NaN();
- }
- std::string parameter_sequence;
- };
- template <typename T> class parser;
- template <typename T> class expression_helper;
- template <typename T>
- class symbol_table
- {
- protected:
- template <typename Type, typename RawType>
- struct type_store
- {
- typedef details::expression_node<T>* expression_ptr;
- typedef typename details::variable_node<T> variable_node_t;
- typedef ifunction<T> ifunction_t;
- typedef ivararg_function<T> ivararg_function_t;
- typedef igeneric_function<T> igeneric_function_t;
- typedef details::vector_holder<T> vector_t;
- #ifndef exprtk_disable_string_capabilities
- typedef typename details::stringvar_node<T> stringvar_node_t;
- #endif
- typedef Type type_t;
- typedef type_t* type_ptr;
- typedef std::pair<bool,type_ptr> type_pair_t;
- typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
- typedef typename type_map_t::iterator tm_itr_t;
- typedef typename type_map_t::const_iterator tm_const_itr_t;
- enum { lut_size = 256 };
- type_map_t map;
- std::size_t size;
- type_store()
- : size(0)
- {}
- inline bool symbol_exists(const std::string& symbol_name) const
- {
- if (symbol_name.empty())
- return false;
- else if (map.end() != map.find(symbol_name))
- return true;
- else
- return false;
- }
- template <typename PtrType>
- inline std::string entity_name(const PtrType& ptr) const
- {
- if (map.empty())
- return std::string();
- tm_const_itr_t itr = map.begin();
- while (map.end() != itr)
- {
- if (itr->second.second == ptr)
- {
- return itr->first;
- }
- else
- ++itr;
- }
- return std::string();
- }
- inline bool is_constant(const std::string& symbol_name) const
- {
- if (symbol_name.empty())
- return false;
- else
- {
- tm_const_itr_t itr = map.find(symbol_name);
- if (map.end() == itr)
- return false;
- else
- return (*itr).second.first;
- }
- }
- template <typename Tie, typename RType>
- inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const)
- {
- if (symbol_name.size() > 1)
- {
- for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
- {
- if (details::imatch(symbol_name,details::reserved_symbols[i]))
- {
- return false;
- }
- }
- }
- tm_itr_t itr = map.find(symbol_name);
- if (map.end() == itr)
- {
- map[symbol_name] = Tie::make(t,is_const);
- ++size;
- }
- return true;
- }
- struct tie_array
- {
- static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false)
- {
- return std::make_pair(is_const,new vector_t(v.first,v.second));
- }
- };
- struct tie_stdvec
- {
- template <typename Allocator>
- static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false)
- {
- return std::make_pair(is_const,new vector_t(v));
- }
- };
- struct tie_stddeq
- {
- template <typename Allocator>
- static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false)
- {
- return std::make_pair(is_const,new vector_t(v));
- }
- };
- template <std::size_t v_size>
- inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false)
- {
- return add_impl<tie_array,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_const);
- }
- inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false)
- {
- return add_impl<tie_array,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_const);
- }
- template <typename Allocator>
- inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false)
- {
- return add_impl<tie_stdvec,std::vector<T,Allocator>&>(symbol_name,v,is_const);
- }
- template <typename Allocator>
- inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
- {
- return add_impl<tie_stddeq,std::deque<T,Allocator>&>(symbol_name,v,is_const);
- }
- inline bool add(const std::string& symbol_name, RawType& t, const bool is_const = false)
- {
- struct tie
- {
- static inline std::pair<bool,variable_node_t*> make(T& t,const bool is_const = false)
- {
- return std::make_pair(is_const,new variable_node_t(t));
- }
- #ifndef exprtk_disable_string_capabilities
- static inline std::pair<bool,stringvar_node_t*> make(std::string& t,const bool is_const = false)
- {
- return std::make_pair(is_const,new stringvar_node_t(t));
- }
- #endif
- static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
- {
- return std::make_pair(is_constant,&t);
- }
- static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_const = false)
- {
- return std::make_pair(is_const,&t);
- }
- static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false)
- {
- return std::make_pair(is_constant,&t);
- }
- };
- tm_itr_t itr = map.find(symbol_name);
- if (map.end() == itr)
- {
- map[symbol_name] = tie::make(t,is_const);
- ++size;
- }
- return true;
- }
- inline type_ptr get(const std::string& symbol_name) const
- {
- tm_const_itr_t itr = map.find(symbol_name);
- if (map.end() == itr)
- return reinterpret_cast<type_ptr>(0);
- else
- return itr->second.second;
- }
- template <typename TType, typename TRawType, typename PtrType>
- struct ptr_match
- {
- static inline bool test(const PtrType, const void*)
- {
- return false;
- }
- };
- template <typename TType, typename TRawType>
- struct ptr_match<TType,TRawType,variable_node_t*>
- {
- static inline bool test(const variable_node_t* p, const void* ptr)
- {
- exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p->ref())),ptr));
- return (&(p->ref()) == ptr);
- }
- };
- inline type_ptr get_from_varptr(const void* ptr) const
- {
- tm_const_itr_t itr = map.begin();
- while (map.end() != itr)
- {
- type_ptr ret_ptr = itr->second.second;
- if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr))
- {
- return ret_ptr;
- }
- ++itr;
- }
- return type_ptr(0);
- }
- inline bool remove(const std::string& symbol_name, const bool delete_node = true)
- {
- tm_itr_t itr = map.find(symbol_name);
- if (map.end() != itr)
- {
- struct deleter
- {
- static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
- static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
- #ifndef exprtk_disable_string_capabilities
- static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
- #endif
- static inline void process(std::pair<bool,function_t*>&) { }
- };
- if (delete_node)
- {
- deleter::process((*itr).second);
- }
- map.erase(itr);
- --size;
- return true;
- }
- else
- return false;
- }
- inline RawType& type_ref(const std::string& symbol_name)
- {
- struct init_type
- {
- static inline double set(double) { return (0.0); }
- static inline double set(long double) { return (0.0); }
- static inline float set(float) { return (0.0f); }
- static inline std::string set(std::string) { return std::string(""); }
- };
- static RawType null_type = init_type::set(RawType());
- tm_const_itr_t itr = map.find(symbol_name);
- if (map.end() == itr)
- return null_type;
- else
- return itr->second.second->ref();
- }
- inline void clear(const bool delete_node = true)
- {
- struct deleter
- {
- static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
- static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
- static inline void process(std::pair<bool,function_t*>&) { }
- #ifndef exprtk_disable_string_capabilities
- static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
- #endif
- };
- if (!map.empty())
- {
- if (delete_node)
- {
- tm_itr_t itr = map.begin();
- tm_itr_t end = map.end();
- while (end != itr)
- {
- deleter::process((*itr).second);
- ++itr;
- }
- }
- map.clear();
- }
- size = 0;
- }
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
- {
- std::size_t count = 0;
- if (!map.empty())
- {
- tm_const_itr_t itr = map.begin();
- tm_const_itr_t end = map.end();
- while (end != itr)
- {
- list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
- ++itr;
- ++count;
- }
- }
- return count;
- }
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
- {
- std::size_t count = 0;
- if (!map.empty())
- {
- tm_const_itr_t itr = map.begin();
- tm_const_itr_t end = map.end();
- while (end != itr)
- {
- vlist.push_back((*itr).first);
- ++itr;
- ++count;
- }
- }
- return count;
- }
- };
- typedef details::expression_node<T>* expression_ptr;
- typedef typename details::variable_node<T> variable_t;
- typedef typename details::vector_holder<T> vector_holder_t;
- typedef variable_t* variable_ptr;
- #ifndef exprtk_disable_string_capabilities
- typedef typename details::stringvar_node<T> stringvar_t;
- typedef stringvar_t* stringvar_ptr;
- #endif
- typedef ifunction <T> function_t;
- typedef ivararg_function <T> vararg_function_t;
- typedef igeneric_function<T> generic_function_t;
- typedef function_t* function_ptr;
- typedef vararg_function_t* vararg_function_ptr;
- typedef generic_function_t* generic_function_ptr;
- static const std::size_t lut_size = 256;
- // Symbol Table Holder
- struct st_holder
- {
- struct st_data
- {
- type_store<typename details::variable_node<T>,T> variable_store;
- #ifndef exprtk_disable_string_capabilities
- type_store<typename details::stringvar_node<T>,std::string> stringvar_store;
- #endif
- type_store<ifunction<T>,ifunction<T> > function_store;
- type_store<ivararg_function <T>,ivararg_function <T> > vararg_function_store;
- type_store<igeneric_function<T>,igeneric_function<T> > generic_function_store;
- type_store<igeneric_function<T>,igeneric_function<T> > string_function_store;
- type_store<vector_holder_t,vector_holder_t> vector_store;
- st_data()
- {
- for (std::size_t i = 0; i < details::reserved_words_size; ++i)
- {
- reserved_symbol_table_.insert(details::reserved_words[i]);
- }
- for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
- {
- reserved_symbol_table_.insert(details::reserved_symbols[i]);
- }
- }
- inline bool is_reserved_symbol(const std::string& symbol) const
- {
- return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
- }
- std::list<T> local_symbol_list_;
- std::list<std::string> local_stringvar_list_;
- std::set<std::string> reserved_symbol_table_;
- };
- st_holder()
- : ref_count(1),
- data_(new st_data)
- {}
- st_holder(st_data* data)
- : ref_count(1),
- data_(data)
- {}
- ~st_holder()
- {
- if (data_ && (0 == ref_count))
- {
- delete data_;
- data_ = 0;
- }
- }
- std::size_t ref_count;
- st_data* data_;
- };
- public:
- symbol_table()
- : holder_(new st_holder)
- {
- clear();
- }
- ~symbol_table()
- {
- if (holder_)
- {
- if (0 == --holder_->ref_count)
- {
- clear();
- delete holder_;
- }
- }
- }
- symbol_table(const symbol_table<T>& st)
- {
- holder_ = st.holder_;
- holder_->ref_count++;
- }
- inline symbol_table<T>& operator=(const symbol_table<T>& st)
- {
- if (holder_)
- {
- if (0 == --holder_->ref_count)
- {
- delete holder_;
- }
- holder_ = 0;
- }
- holder_ = st.holder_;
- holder_->ref_count++;
- return *this;
- }
- inline bool operator==(const symbol_table<T>& st)
- {
- return (this == &st) || (holder_ == st.holder_);
- }
- inline void clear_variables(const bool delete_node = true)
- {
- local_data().variable_store.clear(delete_node);
- }
- inline void clear_functions()
- {
- local_data().function_store.clear();
- }
- inline void clear_strings()
- {
- #ifndef exprtk_disable_string_capabilities
- local_data().stringvar_store.clear();
- #endif
- }
- inline void clear_vectors()
- {
- local_data().vector_store.clear();
- }
- inline void clear()
- {
- if (!valid()) return;
- clear_variables();
- clear_functions();
- clear_strings ();
- clear_vectors ();
- }
- inline std::size_t variable_count() const
- {
- if (valid())
- return local_data().variable_store.size;
- else
- return 0;
- }
- #ifndef exprtk_disable_string_capabilities
- inline std::size_t stringvar_count() const
- {
- if (valid())
- return local_data().stringvar_store.size;
- else
- return 0;
- }
- #endif
- inline std::size_t function_count() const
- {
- if (valid())
- return local_data().function_store.size;
- else
- return 0;
- }
- inline std::size_t vector_count() const
- {
- if (valid())
- return local_data().vector_store.size;
- else
- return 0;
- }
- inline variable_ptr get_variable(const std::string& variable_name) const
- {
- if (!valid())
- return reinterpret_cast<variable_ptr>(0);
- else if (!valid_symbol(variable_name))
- return reinterpret_cast<variable_ptr>(0);
- else
- return local_data().variable_store.get(variable_name);
- }
- inline variable_ptr get_variable(const T& var_ref) const
- {
- if (!valid())
- return reinterpret_cast<variable_ptr>(0);
- else
- return local_data().variable_store.get_from_varptr(
- reinterpret_cast<const void*>(&var_ref));
- }
- #ifndef exprtk_disable_string_capabilities
- inline stringvar_ptr get_stringvar(const std::string& string_name) const
- {
- if (!valid())
- return reinterpret_cast<stringvar_ptr>(0);
- else if (!valid_symbol(string_name))
- return reinterpret_cast<stringvar_ptr>(0);
- else
- return local_data().stringvar_store.get(string_name);
- }
- #endif
- inline function_ptr get_function(const std::string& function_name) const
- {
- if (!valid())
- return reinterpret_cast<function_ptr>(0);
- else if (!valid_symbol(function_name))
- return reinterpret_cast<function_ptr>(0);
- else
- return local_data().function_store.get(function_name);
- }
- inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
- {
- if (!valid())
- return reinterpret_cast<vararg_function_ptr>(0);
- else if (!valid_symbol(vararg_function_name))
- return reinterpret_cast<vararg_function_ptr>(0);
- else
- return local_data().vararg_function_store.get(vararg_function_name);
- }
- inline generic_function_ptr get_generic_function(const std::string& function_name) const
- {
- if (!valid())
- return reinterpret_cast<generic_function_ptr>(0);
- else if (!valid_symbol(function_name))
- return reinterpret_cast<generic_function_ptr>(0);
- else
- return local_data().generic_function_store.get(function_name);
- }
- inline generic_function_ptr get_string_function(const std::string& function_name) const
- {
- if (!valid())
- return reinterpret_cast<generic_function_ptr>(0);
- else if (!valid_symbol(function_name))
- return reinterpret_cast<generic_function_ptr>(0);
- else
- return local_data().string_function_store.get(function_name);
- }
- typedef vector_holder_t* vector_holder_ptr;
- inline vector_holder_ptr get_vector(const std::string& vector_name) const
- {
- if (!valid())
- return reinterpret_cast<vector_holder_ptr>(0);
- else if (!valid_symbol(vector_name))
- return reinterpret_cast<vector_holder_ptr>(0);
- else
- return local_data().vector_store.get(vector_name);
- }
- inline T& variable_ref(const std::string& symbol_name)
- {
- static T null_var = T(0);
- if (!valid())
- return null_var;
- else if (!valid_symbol(symbol_name))
- return null_var;
- else
- return local_data().variable_store.type_ref(symbol_name);
- }
- #ifndef exprtk_disable_string_capabilities
- inline std::string& stringvar_ref(const std::string& symbol_name)
- {
- static std::string null_stringvar;
- if (!valid())
- return null_stringvar;
- else if (!valid_symbol(symbol_name))
- return null_stringvar;
- else
- return local_data().stringvar_store.type_ref(symbol_name);
- }
- #endif
- inline bool is_constant_node(const std::string& symbol_name) const
- {
- if (!valid())
- return false;
- else if (!valid_symbol(symbol_name))
- return false;
- else
- return local_data().variable_store.is_constant(symbol_name);
- }
- #ifndef exprtk_disable_string_capabilities
- inline bool is_constant_string(const std::string& symbol_name) const
- {
- if (!valid())
- return false;
- else if (!valid_symbol(symbol_name))
- return false;
- else if (!local_data().stringvar_store.symbol_exists(symbol_name))
- return false;
- else
- return local_data().stringvar_store.is_constant(symbol_name);
- }
- #endif
- inline bool create_variable(const std::string& variable_name, const T& value = T(0))
- {
- if (!valid())
- return false;
- else if (!valid_symbol(variable_name))
- return false;
- else if (symbol_exists(variable_name))
- return false;
- local_data().local_symbol_list_.push_back(value);
- T& t = local_data().local_symbol_list_.back();
- return add_variable(variable_name,t);
- }
- #ifndef exprtk_disable_string_capabilities
- inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
- {
- if (!valid())
- return false;
- else if (!valid_symbol(stringvar_name))
- return false;
- else if (symbol_exists(stringvar_name))
- return false;
- local_data().local_stringvar_list_.push_back(value);
- std::string& s = local_data().local_stringvar_list_.back();
- return add_stringvar(stringvar_name,s);
- }
- #endif
- inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(variable_name))
- return false;
- else if (symbol_exists(variable_name))
- return false;
- else
- return local_data().variable_store.add(variable_name,t,is_constant);
- }
- inline bool add_constant(const std::string& constant_name, const T& value)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(constant_name))
- return false;
- else if (symbol_exists(constant_name))
- return false;
- local_data().local_symbol_list_.push_back(value);
- T& t = local_data().local_symbol_list_.back();
- return add_variable(constant_name,t,true);
- }
- #ifndef exprtk_disable_string_capabilities
- inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(stringvar_name))
- return false;
- else if (symbol_exists(stringvar_name))
- return false;
- else
- return local_data().stringvar_store.add(stringvar_name,s,is_constant);
- }
- #endif
- inline bool add_function(const std::string& function_name, function_t& function)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(function_name))
- return false;
- else if (symbol_exists(function_name))
- return false;
- else
- return local_data().function_store.add(function_name,function);
- }
- inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(vararg_function_name))
- return false;
- else if (symbol_exists(vararg_function_name))
- return false;
- else
- return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
- }
- enum func_type
- {
- e_ft_unknown = 0,
- e_ft_basicfunc = 1,
- e_ft_strfunc = 2
- };
- inline bool add_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(function_name))
- return false;
- else if (symbol_exists(function_name))
- return false;
- else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
- return false;
- else if (e_ft_basicfunc == ft)
- return local_data().generic_function_store.add(function_name,function);
- else if (e_ft_strfunc == ft)
- return local_data().string_function_store.add(function_name, function);
- else
- return false;
- }
- inline bool add_reserved_function(const std::string& function_name, function_t& function)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(function_name,false))
- return false;
- else if (symbol_exists(function_name,false))
- return false;
- else
- return local_data().function_store.add(function_name,function);
- }
- inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(vararg_function_name,false))
- return false;
- else if (symbol_exists(vararg_function_name,false))
- return false;
- else
- return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
- }
- inline bool add_reserved_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(function_name,false))
- return false;
- else if (symbol_exists(function_name,false))
- return false;
- else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
- return false;
- else if (e_ft_basicfunc == ft)
- return local_data().generic_function_store.add(function_name,function);
- else if (e_ft_strfunc == ft)
- return local_data().string_function_store.add(function_name, function);
- else
- return false;
- }
- template <std::size_t N>
- inline bool add_vector(const std::string& vector_name, T (&v)[N])
- {
- if (!valid())
- return false;
- else if (!valid_symbol(vector_name))
- return false;
- else if (symbol_exists(vector_name))
- return false;
- else
- return local_data().vector_store.add(vector_name,v);
- }
- inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(vector_name))
- return false;
- else if (symbol_exists(vector_name))
- return false;
- else
- return local_data().vector_store.add(vector_name,v,v_size);
- }
- template <typename Allocator>
- inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(vector_name))
- return false;
- else if (symbol_exists(vector_name))
- return false;
- else
- return local_data().vector_store.add(vector_name,v);
- }
- template <typename Allocator>
- inline bool add_vector(const std::string& vector_name, std::deque<T,Allocator>& v)
- {
- if (!valid())
- return false;
- else if (!valid_symbol(vector_name))
- return false;
- else if (symbol_exists(vector_name))
- return false;
- else
- return local_data().vector_store.add(vector_name,v);
- }
- inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
- {
- if (!valid())
- return false;
- else
- return local_data().variable_store.remove(variable_name, delete_node);
- }
- #ifndef exprtk_disable_string_capabilities
- inline bool remove_stringvar(const std::string& string_name)
- {
- if (!valid())
- return false;
- else
- return local_data().stringvar_store.remove(string_name);
- }
- #endif
- inline bool remove_function(const std::string& function_name)
- {
- if (!valid())
- return false;
- else
- return local_data().function_store.remove(function_name);
- }
- inline bool remove_vararg_function(const std::string& vararg_function_name)
- {
- if (!valid())
- return false;
- else
- return local_data().vararg_function_store.remove(vararg_function_name);
- }
- inline bool remove_vector(const std::string& vector_name)
- {
- if (!valid())
- return false;
- else
- return local_data().vector_store.remove(vector_name);
- }
- inline bool add_constants()
- {
- return add_pi () &&
- add_epsilon () &&
- add_infinity();
- }
- inline bool add_pi()
- {
- static const T local_pi = T(details::numeric::constant::pi);
- return add_constant("pi",local_pi);
- }
- inline bool add_epsilon()
- {
- static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
- return add_constant("epsilon",local_epsilon);
- }
- inline bool add_infinity()
- {
- static const T local_infinity = std::numeric_limits<T>::infinity();
- return add_constant("inf",local_infinity);
- }
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
- {
- if (!valid())
- return 0;
- else
- return local_data().variable_store.get_list(vlist);
- }
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
- {
- if (!valid())
- return 0;
- else
- return local_data().variable_store.get_list(vlist);
- }
- #ifndef exprtk_disable_string_capabilities
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
- {
- if (!valid())
- return 0;
- else
- return local_data().stringvar_store.get_list(svlist);
- }
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
- {
- if (!valid())
- return 0;
- else
- return local_data().stringvar_store.get_list(svlist);
- }
- #endif
- template <typename Allocator,
- template <typename, typename> class Sequence>
- inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vlist) const
- {
- if (!valid())
- return 0;
- else
- return local_data().vector_store.get_list(vlist);
- }
- inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const
- {
- /*
- Will return true if symbol_name exists as either a reserved symbol,
- variable, stringvar or function name in any of the type stores.
- */
- if (!valid())
- return false;
- else if (local_data().variable_store.symbol_exists(symbol_name))
- return true;
- #ifndef exprtk_disable_string_capabilities
- else if (local_data().stringvar_store.symbol_exists(symbol_name))
- return true;
- #endif
- else if (local_data().function_store.symbol_exists(symbol_name))
- return true;
- else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name))
- return true;
- else
- return false;
- }
- inline bool is_variable(const std::string& variable_name) const
- {
- if (!valid())
- return false;
- else
- return local_data().variable_store.symbol_exists(variable_name);
- }
- #ifndef exprtk_disable_string_capabilities
- inline bool is_stringvar(const std::string& stringvar_name) const
- {
- if (!valid())
- return false;
- else
- return local_data().stringvar_store.symbol_exists(stringvar_name);
- }
- inline bool is_conststr_stringvar(const std::string& symbol_name) const
- {
- if (!valid())
- return false;
- else if (!valid_symbol(symbol_name))
- return false;
- else if (!local_data().stringvar_store.symbol_exists(symbol_name))
- return false;
- return (
- local_data().stringvar_store.symbol_exists(symbol_name) ||
- local_data().stringvar_store.is_constant (symbol_name)
- );
- }
- #endif
- inline bool is_function(const std::string& function_name) const
- {
- if (!valid())
- return false;
- else
- return local_data().function_store.symbol_exists(function_name);
- }
- inline bool is_vararg_function(const std::string& vararg_function_name) const
- {
- if (!valid())
- return false;
- else
- return local_data().vararg_function_store.symbol_exists(vararg_function_name);
- }
- inline bool is_vector(const std::string& vector_name) const
- {
- if (!valid())
- return false;
- else
- return local_data().vector_store.symbol_exists(vector_name);
- }
- inline std::string get_variable_name(const expression_ptr& ptr) const
- {
- return local_data().variable_store.entity_name(ptr);
- }
- inline std::string get_vector_name(const vector_holder_ptr& ptr) const
- {
- return local_data().vector_store.entity_name(ptr);
- }
- #ifndef exprtk_disable_string_capabilities
- inline std::string get_stringvar_name(const expression_ptr& ptr) const
- {
- return local_data().stringvar_store.entity_name(ptr);
- }
- inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const
- {
- return local_data().stringvar_store.entity_name(ptr);
- }
- #endif
- inline bool valid() const
- {
- // Symbol table sanity check.
- return holder_ && holder_->data_;
- }
- inline void load_from(const symbol_table<T>& st)
- {
- {
- std::vector<std::string> name_list;
- st.local_data().function_store.get_list(name_list);
- if (!name_list.empty())
- {
- for (std::size_t i = 0; i < name_list.size(); ++i)
- {
- exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]);
- add_function(name_list[i],ifunc);
- }
- }
- }
- {
- std::vector<std::string> name_list;
- st.local_data().vararg_function_store.get_list(name_list);
- if (!name_list.empty())
- {
- for (std::size_t i = 0; i < name_list.size(); ++i)
- {
- exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]);
- add_function(name_list[i],ivafunc);
- }
- }
- }
- {
- std::vector<std::string> name_list;
- st.local_data().generic_function_store.get_list(name_list);
- if (!name_list.empty())
- {
- for (std::size_t i = 0; i < name_list.size(); ++i)
- {
- exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]);
- add_function(name_list[i],ifunc);
- }
- }
- }
- {
- std::vector<std::string> name_list;
- st.local_data().string_function_store.get_list(name_list);
- if (!name_list.empty())
- {
- for (std::size_t i = 0; i < name_list.size(); ++i)
- {
- exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
- add_function(name_list[i],ifunc,e_ft_strfunc);
- }
- }
- }
- }
- private:
- inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const
- {
- if (symbol.empty())
- return false;
- if (!details::is_letter(symbol[0]))
- return false;
- else if (symbol.size() > 1)
- {
- for (std::size_t i = 1; i < symbol.size(); ++i)
- {
- if (
- (!details::is_letter(symbol[i])) &&
- (!details:: is_digit(symbol[i])) &&
- ('_' != symbol[i])
- )
- {
- return false;
- }
- }
- }
- return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true;
- }
- inline bool valid_function(const std::string& symbol) const
- {
- if (symbol.empty())
- return false;
- if (!details::is_letter(symbol[0]))
- return false;
- else if (symbol.size() > 1)
- {
- for (std::size_t i = 1; i < symbol.size(); ++i)
- {
- if (
- (!details::is_letter(symbol[i])) &&
- (!details:: is_digit(symbol[i])) &&
- ('_' != symbol[i])
- )
- {
- return false;
- }
- }
- }
- return true;
- }
- typedef typename st_holder::st_data local_data_t;
- inline local_data_t& local_data()
- {
- return *(holder_->data_);
- }
- inline const local_data_t& local_data() const
- {
- return *(holder_->data_);
- }
- st_holder* holder_;
- friend class parser<T>;
- };
- template <typename T>
- class function_compositor;
- template <typename T>
- class expression
- {
- private:
- typedef details::expression_node<T>* expression_ptr;
- typedef details::vector_holder<T>* vector_holder_ptr;
- typedef std::vector<symbol_table<T> > symtab_list_t;
- struct expression_holder
- {
- enum data_type
- {
- e_unknown ,
- e_expr ,
- e_vecholder,
- e_data ,
- e_vecdata ,
- e_string
- };
- struct data_pack
- {
- data_pack()
- : pointer(0),
- type(e_unknown),
- size(0)
- {}
- data_pack(void* ptr, data_type dt, std::size_t sz = 0)
- : pointer(ptr),
- type(dt),
- size(sz)
- {}
- void* pointer;
- data_type type;
- std::size_t size;
- };
- typedef std::vector<data_pack> local_data_list_t;
- typedef results_context<T> results_context_t;
- expression_holder()
- : ref_count(0),
- expr (0),
- results (0),
- retinv_null(false),
- return_invoked(&retinv_null)
- {}
- expression_holder(expression_ptr e)
- : ref_count(1),
- expr (e),
- results (0),
- retinv_null(false),
- return_invoked(&retinv_null)
- {}
- ~expression_holder()
- {
- if (expr && details::branch_deletable(expr))
- {
- delete expr;
- }
- if (!local_data_list.empty())
- {
- for (std::size_t i = 0; i < local_data_list.size(); ++i)
- {
- switch (local_data_list[i].type)
- {
- case e_expr : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer);
- break;
- case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer);
- break;
- case e_data : delete (T*)(local_data_list[i].pointer);
- break;
- case e_vecdata : delete [] (T*)(local_data_list[i].pointer);
- break;
- case e_string : delete (std::string*)(local_data_list[i].pointer);
- break;
- default : break;
- }
- }
- }
- if (results)
- {
- delete results;
- }
- }
- std::size_t ref_count;
- expression_ptr expr;
- local_data_list_t local_data_list;
- results_context_t* results;
- bool retinv_null;
- bool* return_invoked;
- friend class function_compositor<T>;
- };
- public:
- expression()
- : expression_holder_(0)
- {
- set_expression(new details::null_node<T>());
- }
- expression(const expression<T>& e)
- : expression_holder_(e.expression_holder_),
- symbol_table_list_(e.symbol_table_list_)
- {
- expression_holder_->ref_count++;
- }
- inline expression<T>& operator=(const expression<T>& e)
- {
- if (this != &e)
- {
- if (expression_holder_)
- {
- if (0 == --expression_holder_->ref_count)
- {
- delete expression_holder_;
- }
- expression_holder_ = 0;
- }
- expression_holder_ = e.expression_holder_;
- expression_holder_->ref_count++;
- symbol_table_list_ = e.symbol_table_list_;
- }
- return *this;
- }
- inline bool operator==(const expression<T>& e)
- {
- return (this == &e);
- }
- inline bool operator!() const
- {
- return (
- (0 == expression_holder_ ) ||
- (0 == expression_holder_->expr)
- );
- }
- inline expression<T>& release()
- {
- if (expression_holder_)
- {
- if (0 == --expression_holder_->ref_count)
- {
- delete expression_holder_;
- }
- expression_holder_ = 0;
- }
- return *this;
- }
- ~expression()
- {
- if (expression_holder_)
- {
- if (0 == --expression_holder_->ref_count)
- {
- delete expression_holder_;
- }
- }
- }
- inline T value() const
- {
- return expression_holder_->expr->value();
- }
- inline T operator()() const
- {
- return value();
- }
- inline operator T() const
- {
- return value();
- }
- inline operator bool() const
- {
- return details::is_true(value());
- }
- inline void register_symbol_table(symbol_table<T>& st)
- {
- symbol_table_list_.push_back(st);
- }
- inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const
- {
- return symbol_table_list_[index];
- }
- inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0)
- {
- return symbol_table_list_[index];
- }
- typedef results_context<T> results_context_t;
- inline const results_context_t& results() const
- {
- if (expression_holder_->results)
- return (*expression_holder_->results);
- else
- {
- static const results_context_t null_results;
- return null_results;
- }
- }
- inline bool return_invoked() const
- {
- return (*expression_holder_->return_invoked);
- }
- private:
- inline symtab_list_t get_symbol_table_list() const
- {
- return symbol_table_list_;
- }
- inline void set_expression(const expression_ptr expr)
- {
- if (expr)
- {
- if (expression_holder_)
- {
- if (0 == --expression_holder_->ref_count)
- {
- delete expression_holder_;
- }
- }
- expression_holder_ = new expression_holder(expr);
- }
- }
- inline void register_local_var(expression_ptr expr)
- {
- if (expr)
- {
- if (expression_holder_)
- {
- expression_holder_->
- local_data_list.push_back(
- typename expression<T>::expression_holder::
- data_pack(reinterpret_cast<void*>(expr),
- expression_holder::e_expr));
- }
- }
- }
- inline void register_local_var(vector_holder_ptr vec_holder)
- {
- if (vec_holder)
- {
- if (expression_holder_)
- {
- expression_holder_->
- local_data_list.push_back(
- typename expression<T>::expression_holder::
- data_pack(reinterpret_cast<void*>(vec_holder),
- expression_holder::e_vecholder));
- }
- }
- }
- inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0)
- {
- if (data)
- {
- if (expression_holder_)
- {
- typename expression_holder::data_type dt = expression_holder::e_data;
- switch(data_mode)
- {
- case 0 : dt = expression_holder::e_data; break;
- case 1 : d