4068375e |
/*
******************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
|
a65c8e8b |
* Author: Arash Partow (1999-2022) *
* URL: https://www.partow.net/programming/exprtk/index.html *
|
4068375e |
* *
* 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 MIT License. *
|
a65c8e8b |
* https://www.opensource.org/licenses/MIT *
|
4068375e |
* *
* 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>
|
a65c8e8b |
#include <cassert>
|
4068375e |
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#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
{
#ifdef exprtk_enable_debugging
#define exprtk_debug(params) printf params
#else
#define exprtk_debug(params) (void)0
#endif
#define exprtk_error_location \
"exprtk.hpp:" + details::to_str(__LINE__) \
#if defined(__GNUC__) && (__GNUC__ >= 7)
#define exprtk_disable_fallthrough_begin \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
#define exprtk_disable_fallthrough_end \
_Pragma ("GCC diagnostic pop") \
#else
#define exprtk_disable_fallthrough_begin (void)0;
#define exprtk_disable_fallthrough_end (void)0;
#endif
|
a65c8e8b |
#if __cplusplus >= 201103L
#define exprtk_override override
#define exprtk_final final
#define exprtk_delete = delete
#else
#define exprtk_override
#define exprtk_final
#define exprtk_delete
#endif
|
4068375e |
namespace details
{
|
a65c8e8b |
typedef char char_t;
typedef char_t* char_ptr;
|
4068375e |
typedef char_t const* char_cptr;
|
a65c8e8b |
typedef unsigned char uchar_t;
typedef uchar_t* uchar_ptr;
typedef uchar_t const* uchar_cptr;
|
4068375e |
typedef unsigned long long int _uint64_t;
|
a65c8e8b |
typedef long long int _int64_t;
|
4068375e |
inline bool is_whitespace(const char_t c)
{
return (' ' == c) || ('\n' == c) ||
('\r' == c) || ('\t' == c) ||
('\b' == c) || ('\v' == c) ||
('\f' == c) ;
}
inline bool is_operator_char(const char_t 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_t c)
{
return (('a' <= c) && (c <= 'z')) ||
(('A' <= c) && (c <= 'Z')) ;
}
inline bool is_digit(const char_t c)
{
return ('0' <= c) && (c <= '9');
}
inline bool is_letter_or_digit(const char_t c)
{
return is_letter(c) || is_digit(c);
}
inline bool is_left_bracket(const char_t c)
{
return ('(' == c) || ('[' == c) || ('{' == c);
}
inline bool is_right_bracket(const char_t c)
{
return (')' == c) || (']' == c) || ('}' == c);
}
inline bool is_bracket(const char_t c)
{
return is_left_bracket(c) || is_right_bracket(c);
}
inline bool is_sign(const char_t c)
{
return ('+' == c) || ('-' == c);
}
inline bool is_invalid(const char_t c)
{
return !is_whitespace (c) &&
!is_operator_char(c) &&
!is_letter (c) &&
!is_digit (c) &&
('.' != c) &&
('_' != c) &&
('$' != c) &&
('~' != c) &&
('\'' != c);
}
inline bool is_valid_string_char(const char_t c)
{
|
a65c8e8b |
return std::isprint(static_cast<uchar_t>(c)) ||
|
4068375e |
is_whitespace(c);
}
#ifndef exprtk_disable_caseinsensitivity
inline void case_normalise(std::string& s)
{
for (std::size_t i = 0; i < s.size(); ++i)
{
s[i] = static_cast<std::string::value_type>(std::tolower(s[i]));
}
}
inline bool imatch(const char_t c1, const char_t 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;
}
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)
{
|
a65c8e8b |
const char_t c1 = static_cast<char_t>(std::tolower(s1[i]));
const char_t c2 = static_cast<char_t>(std::tolower(s2[i]));
|
4068375e |
if (c1 > c2)
return false;
else if (c1 < c2)
return true;
}
return s1.size() < s2.size();
}
};
#else
inline void case_normalise(std::string&)
{}
inline bool imatch(const char_t c1, const char_t c2)
{
return c1 == c2;
}
inline bool imatch(const std::string& s1, const std::string& s2)
{
return s1 == s2;
}
struct ilesscompare
{
inline bool operator() (const std::string& s1, const std::string& s2) const
{
return s1 < s2;
}
};
#endif
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_t& front(const std::string& s)
{
return s[0];
}
inline const char_t& 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;
|
a65c8e8b |
const int sign = (i < 0) ? -1 : 1;
|
4068375e |
|
a65c8e8b |
for ( ; i; i /= 10)
{
result += '0' + static_cast<char_t>(sign * (i % 10));
|
4068375e |
}
|
a65c8e8b |
if (sign < 0)
|
4068375e |
{
|
a65c8e8b |
result += '-';
|
4068375e |
}
std::reverse(result.begin(), result.end());
|
a65c8e8b |
|
4068375e |
return result;
}
inline std::string to_str(std::size_t i)
{
return to_str(static_cast<int>(i));
}
|
a65c8e8b |
inline bool is_hex_digit(const uchar_t digit)
|
4068375e |
{
return (('0' <= digit) && (digit <= '9')) ||
(('A' <= digit) && (digit <= 'F')) ||
(('a' <= digit) && (digit <= 'f')) ;
}
inline uchar_t hex_to_bin(uchar_t h)
{
if (('0' <= h) && (h <= '9'))
return (h - '0');
else
|
a65c8e8b |
return static_cast<uchar_t>(std::toupper(h) - 'A');
|
4068375e |
}
template <typename Iterator>
inline bool parse_hex(Iterator& itr, Iterator end,
|
a65c8e8b |
char_t& result)
|
4068375e |
{
if (
(end == (itr )) ||
(end == (itr + 1)) ||
(end == (itr + 2)) ||
(end == (itr + 3)) ||
('0' != *(itr )) ||
('X' != std::toupper(*(itr + 1))) ||
(!is_hex_digit(*(itr + 2))) ||
(!is_hex_digit(*(itr + 3)))
)
{
return false;
}
result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 |
hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ;
return true;
}
inline bool 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))
{
if (end == ++itr1)
{
return false;
}
else if (parse_hex(itr1, end, *itr2))
{
itr1+= 4;
itr2+= 1;
removal_count +=4;
}
else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; }
else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; }
else if ('f' == (*itr1)) { (*itr2++) = '\f'; ++itr1; ++removal_count; }
else if ('n' == (*itr1)) { (*itr2++) = '\n'; ++itr1; ++removal_count; }
else if ('r' == (*itr1)) { (*itr2++) = '\r'; ++itr1; ++removal_count; }
else if ('t' == (*itr1)) { (*itr2++) = '\t'; ++itr1; ++removal_count; }
else if ('v' == (*itr1)) { (*itr2++) = '\v'; ++itr1; ++removal_count; }
else if ('0' == (*itr1)) { (*itr2++) = '\0'; ++itr1; ++removal_count; }
else
{
(*itr2++) = (*itr1++);
++removal_count;
}
continue;
}
else
(*itr2++) = (*itr1++);
}
if ((removal_count > s.size()) || (0 == removal_count))
return false;
s.resize(s.size() - removal_count);
return true;
}
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 << (char_cptr 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_;
};
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[] =
{
"if", "switch", "for", "while", "repeat", "return"
};
static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
static const std::string arithmetic_ops_list[] =
{
"+", "-", "*", "/", "%", "^"
};
static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
static const std::string assignment_ops_list[] =
{
":=", "+=", "-=",
"*=", "/=", "%="
};
static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
static const std::string inequality_ops_list[] =
{
"<", "<=", "==",
"=", "!=", "<>",
">=", ">"
};
static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_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 < logic_ops_list_size; ++i)
{
if (imatch(lgc_opr, logic_ops_list[i]))
{
return true;
}
}
return false;
}
struct cs_match
{
static inline bool cmp(const char_t c0, const char_t c1)
{
return (c0 == c1);
}
};
struct cis_match
{
static inline bool cmp(const char_t c0, const char_t 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,
|
a65c8e8b |
const typename std::iterator_traits<Iterator>::value_type& exactly_one )
|
4068375e |
{
const Iterator null_itr(0);
|
a65c8e8b |
Iterator p_itr = pattern_begin;
Iterator d_itr = data_begin;
Iterator np_itr = null_itr;
Iterator nd_itr = null_itr;
|
4068375e |
|
a65c8e8b |
for ( ; ; )
|
4068375e |
{
|
a65c8e8b |
const bool pvalid = p_itr != pattern_end;
const bool dvalid = d_itr != data_end;
|
4068375e |
|
a65c8e8b |
if (!pvalid && !dvalid)
break;
|
4068375e |
|
a65c8e8b |
if (pvalid)
{
|
4068375e |
const typename std::iterator_traits<Iterator>::value_type c = *(p_itr);
|
a65c8e8b |
if (zero_or_more == c)
{
np_itr = p_itr;
nd_itr = d_itr + 1;
++p_itr;
continue;
}
else if (dvalid && ((exactly_one == c) || Compare::cmp(c,*(d_itr))))
|
4068375e |
{
|
a65c8e8b |
++p_itr;
|
4068375e |
++d_itr;
|
a65c8e8b |
continue;
|
4068375e |
}
}
|
a65c8e8b |
if ((null_itr != nd_itr) && (nd_itr <= data_end))
{
p_itr = np_itr;
d_itr = nd_itr;
|
4068375e |
continue;
}
|
a65c8e8b |
return false;
|
4068375e |
}
|
a65c8e8b |
return true;
|
4068375e |
}
inline bool wc_match(const std::string& wild_card,
const std::string& str)
{
|
a65c8e8b |
return match_impl<char_cptr,cs_match>(
wild_card.data(),
wild_card.data() + wild_card.size(),
str.data(),
str.data() + str.size(),
'*', '?');
|
4068375e |
}
inline bool wc_imatch(const std::string& wild_card,
const std::string& str)
{
|
a65c8e8b |
return match_impl<char_cptr,cis_match>(
wild_card.data(),
wild_card.data() + wild_card.size(),
str.data(),
str.data() + str.size(),
'*', '?');
|
4068375e |
}
inline bool sequence_match(const std::string& pattern,
const std::string& str,
std::size_t& diff_index,
char_t& diff_value)
{
if (str.empty())
{
return ("Z" == pattern);
}
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();
|
a65c8e8b |
const itr_t p_end = pattern.end();
const itr_t s_end = str .end();
|
4068375e |
while ((s_end != s_itr) && (p_end != p_itr))
{
if ('*' == (*p_itr))
{
|
a65c8e8b |
const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1)));
|
4068375e |
if ('*' == target)
{
diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
|
a65c8e8b |
diff_value = static_cast<char_t>(std::toupper(*p_itr));
|
4068375e |
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 = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
|
a65c8e8b |
diff_value = static_cast<char_t>(std::toupper(*p_itr));
|
4068375e |
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.71828182845904523536028747135266249775724709369996;
static const double pi = 3.14159265358979323846264338327950288419716939937510;
static const double pi_2 = 1.57079632679489661923132169163975144209858469968755;
static const double pi_4 = 0.78539816339744830961566084581987572104929234984378;
static const double pi_180 = 0.01745329251994329576923690768488612713442871888542;
static const double _1_pi = 0.31830988618379067153776752674502872406891929148091;
static const double _2_pi = 0.63661977236758134307553505349005744813783858296183;
static const double _180_pi = 57.29577951308232087679815481410517033240547246656443;
static const double log2 = 0.69314718055994530941723212145817656807550013436026;
static const double sqrt2 = 1.41421356237309504880168872420969807856967187537695;
}
namespace details
{
struct unknown_type_tag { unknown_type_tag() {} };
struct real_type_tag { real_type_tag () {} };
struct complex_type_tag { complex_type_tag() {} };
struct int_type_tag { int_type_tag () {} };
template <typename T>
struct number_type
{
typedef unknown_type_tag type;
number_type() {}
};
#define exprtk_register_real_type_tag(T) \
|
a65c8e8b |
template <> struct number_type<T> \
|
4068375e |
{ typedef real_type_tag type; number_type() {} }; \
#define exprtk_register_complex_type_tag(T) \
|
a65c8e8b |
template <> struct number_type<std::complex<T> > \
|
4068375e |
{ typedef complex_type_tag type; number_type() {} }; \
#define exprtk_register_int_type_tag(T) \
|
a65c8e8b |
template <> struct number_type<T> \
|
4068375e |
{ typedef int_type_tag type; number_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(_int64_t )
exprtk_register_int_type_tag(unsigned short)
exprtk_register_int_type_tag(unsigned int )
exprtk_register_int_type_tag(_uint64_t )
#undef exprtk_register_real_type_tag
#undef exprtk_register_int_type_tag
template <typename T>
|
a65c8e8b |
struct epsilon_type {};
|
4068375e |
|
a65c8e8b |
#define exprtk_define_epsilon_type(Type, Epsilon) \
template <> struct epsilon_type<Type> \
{ \
static inline Type value() \
{ \
const Type epsilon = static_cast<Type>(Epsilon); \
return epsilon; \
} \
}; \
|
4068375e |
|
a65c8e8b |
exprtk_define_epsilon_type(float , 0.00000100000f)
exprtk_define_epsilon_type(double , 0.000000000100)
exprtk_define_epsilon_type(long double, 0.000000000001)
#undef exprtk_define_epsilon_type
|
4068375e |
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 _int64_t to_int64_impl(const T v, real_type_tag)
{
return static_cast<_int64_t>(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)
{
if (v1 < T(0))
return std::numeric_limits<T>::quiet_NaN();
const std::size_t n = static_cast<std::size_t>(v1);
if ((v0 < T(0)) && (0 == (n % 2)))
return std::numeric_limits<T>::quiet_NaN();
return std::pow(v0, T(1) / n);
}
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)
{
|
a65c8e8b |
const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1))));
|
4068375e |
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)
{
|
a65c8e8b |
if (v > T(0)) return T(+1);
|
4068375e |
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)
{
|
a65c8e8b |
if (v > T(0)) return T(+1);
|
4068375e |
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);
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
|
a65c8e8b |
#define exprtk_define_erf(TT, impl) \
inline TT erf_impl(const TT v) { return impl(v); } \
|
4068375e |
exprtk_define_erf( float,::erff)
exprtk_define_erf( double,::erf )
exprtk_define_erf(long double,::erfl)
#undef exprtk_define_erf
#endif
template <typename T>
|
a65c8e8b |
inline T erf_impl(const T v, real_type_tag)
|
4068375e |
{
#if defined(_MSC_VER) && (_MSC_VER < 1900)
// Credits: Abramowitz & Stegun Equations 7.1.25-28
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)
};
const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
|
a65c8e8b |
const 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]))))))))));
|
4068375e |
return (v >= T(0)) ? result : -result;
#else
return erf_impl(v);
#endif
}
template <typename T>
|
a65c8e8b |
inline T erf_impl(const T v, int_type_tag)
|
4068375e |
{
return erf_impl(static_cast<double>(v),real_type_tag());
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
|
a65c8e8b |
#define exprtk_define_erfc(TT, impl) \
inline TT erfc_impl(const TT v) { return impl(v); } \
|
4068375e |
|
a65c8e8b |
exprtk_define_erfc(float ,::erfcf)
exprtk_define_erfc(double ,::erfc )
|
4068375e |
exprtk_define_erfc(long double,::erfcl)
#undef exprtk_define_erfc
#endif
template <typename T>
|
a65c8e8b |
inline T erfc_impl(const T v, real_type_tag)
|
4068375e |
{
#if defined(_MSC_VER) && (_MSC_VER < 1900)
return T(1) - erf_impl(v,real_type_tag());
#else
return erfc_impl(v);
#endif
}
template <typename T>
|
a65c8e8b |
inline T erfc_impl(const T v, int_type_tag)
|
4068375e |
{
return erfc_impl(static_cast<double>(v),real_type_tag());
}
template <typename T>
|
a65c8e8b |
inline T ncdf_impl(const T v, real_type_tag)
|
4068375e |
{
|
a65c8e8b |
const T cnd = T(0.5) * (T(1) +
erf_impl(abs_impl(v,real_type_tag()) /
T(numeric::constant::sqrt2),real_type_tag()));
|
4068375e |
return (v < T(0)) ? (T(1) - cnd) : cnd;
}
template <typename T>
|
a65c8e8b |
inline T ncdf_impl(const T v, int_type_tag)
|
4068375e |
{
return ncdf_impl(static_cast<double>(v),real_type_tag());
}
template <typename T>
|
a65c8e8b |
inline T sinc_impl(const T v, real_type_tag)
|
4068375e |
{
if (std::abs(v) >= std::numeric_limits<T>::epsilon())
return(std::sin(v) / v);
else
return T(1);
}
template <typename T>
|
a65c8e8b |
inline T sinc_impl(const T v, int_type_tag)
|
4068375e |
{
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) - std::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)); }
|
a65c8e8b |
template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(10.0/9.0)); }
template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/10.0)); }
|
4068375e |
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)); }
|
a65c8e8b |
template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); }
template <typename T> inline T const_e_impl(real_type_tag) { return T(numeric::constant::e); }
template <typename T> inline T const_qnan_impl(real_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
|
4068375e |
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 }; };
|
a65c8e8b |
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 }; };
|
4068375e |
template <typename T>
inline int to_int32(const T v)
{
const typename details::number_type<T>::type num_type;
return to_int32_impl(v, num_type);
}
template <typename T>
inline _int64_t to_int64(const T v)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
const 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)
{
|
a65c8e8b |
if (1 == (k % 2))
|
4068375e |
{
l *= v;
--k;
}
v *= v;
|
a65c8e8b |
k /= 2;
|
4068375e |
}
return l;
}
};
|
a65c8e8b |
template <typename T> struct fast_exp<T,10> { static inline T result(const 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(const T v) { return fast_exp<T,8>::result(v) * v; } };
template <typename T> struct fast_exp<T, 8> { static inline T result(const 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(const T v) { return fast_exp<T,6>::result(v) * v; } };
template <typename T> struct fast_exp<T, 6> { static inline T result(const 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(const T v) { return fast_exp<T,4>::result(v) * v; } };
template <typename T> struct fast_exp<T, 4> { static inline T result(const T v) { T v_2 = v * v; return v_2 * v_2; } };
template <typename T> struct fast_exp<T, 3> { static inline T result(const T v) { return v * v * v; } };
template <typename T> struct fast_exp<T, 2> { static inline T result(const T v) { return v * v; } };
template <typename T> struct fast_exp<T, 1> { static inline T result(const T v) { return v; } };
template <typename T> struct fast_exp<T, 0> { static inline T result(const T ) { return T(1); } };
|
4068375e |
#define exprtk_define_unary_function(FunctionName) \
template <typename T> \
inline T FunctionName (const T v) \
{ \
const 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;
const bool negative = ('-' == (*itr));
if (negative || ('+' == (*itr)))
{
if (end == ++itr)
return false;
}
static const uchar_t zero = static_cast<uchar_t>('0');
while ((end != itr) && (zero == (*itr))) ++itr;
bool return_result = true;
unsigned int digit = 0;
|
a65c8e8b |
const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
|
4068375e |
if (length <= 4)
{
exprtk_disable_fallthrough_begin
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++ - zero)) < 10) \
result = result * T(10) + digit; \
else \
{ \
return_result = false; \
break; \
} \
#endif
|
a65c8e8b |
case 4 : exprtk_process_digit
case 3 : exprtk_process_digit
case 2 : exprtk_process_digit
case 1 : if ((digit = (*itr - zero))>= 10)
{
digit = 0;
return_result = false;
}
|
4068375e |
#undef exprtk_process_digit
}
exprtk_disable_fallthrough_end
}
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>
|
a65c8e8b |
static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, const bool negative)
|
4068375e |
{
static const char_t inf_uc[] = "INFINITY";
static const char_t inf_lc[] = "infinity";
static const std::size_t inf_length = 8;
const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
if ((3 != length) && (inf_length != length))
return false;
char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
while (end != itr)
{
|
a65c8e8b |
if (*inf_itr == static_cast<char_t>(*itr))
|
4068375e |
{
++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 T>
inline bool valid_exponent(const int exponent, numeric::details::real_type_tag)
{
|
a65c8e8b |
using namespace details::numeric;
return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp);
|
4068375e |
}
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);
const bool negative = ('-' == (*itr));
if (negative || '+' == (*itr))
{
if (end == ++itr)
return false;
}
bool instate = false;
static const char_t zero = static_cast<uchar_t>('0');
#define parse_digit_1(d) \
if ((digit = (*itr - zero)) < 10) \
{ d = d * T(10) + digit; } \
else \
{ break; } \
if (end == ++itr) break; \
#define parse_digit_2(d) \
if ((digit = (*itr - zero)) < 10) \
{ d = d * T(10) + digit; } \
|
a65c8e8b |
else \
{ break; } \
|
4068375e |
++itr; \
if ('.' != (*itr))
{
const Iterator curr = itr;
while ((end != itr) && (zero == (*itr))) ++itr;
while (end != itr)
{
unsigned int digit;
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;
T tmp_d = T(0);
while (end != itr)
{
unsigned int digit;
parse_digit_1(tmp_d)
parse_digit_1(tmp_d)
parse_digit_2(tmp_d)
}
if (curr != itr)
{
instate = true;
|
a65c8e8b |
const int frac_exponent = static_cast<int>(-std::distance(curr, itr));
|
4068375e |
|
a65c8e8b |
if (!valid_exponent<T>(frac_exponent, numeric::details::real_type_tag()))
|
4068375e |
return false;
|
a65c8e8b |
d += compute_pow10(tmp_d, frac_exponent);
|
4068375e |
}
#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 (!valid_exponent<T>(exponent, numeric::details::real_type_tag()))
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 typename numeric::details::number_type<T>::type num_type;
char_cptr begin = s.data();
char_cptr end = s.data() + s.size();
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& RefType;
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
struct loop_runtime_check
{
enum loop_types
{
e_invalid = 0,
e_for_loop = 1,
e_while_loop = 2,
e_repeat_until_loop = 4,
e_all_loops = 7
};
enum violation_type
{
e_unknown = 0,
e_iteration_count = 1,
e_timeout = 2
};
loop_types loop_set;
loop_runtime_check()
|
a65c8e8b |
: loop_set(e_invalid)
, max_loop_iterations(0)
|
4068375e |
{}
details::_uint64_t max_loop_iterations;
struct violation_context
{
loop_types loop;
violation_type violation;
details::_uint64_t iteration_count;
};
virtual void handle_runtime_violation(const violation_context&)
{
throw std::runtime_error("ExprTk Loop run-time violation.");
}
virtual ~loop_runtime_check() {}
};
typedef loop_runtime_check* loop_runtime_check_ptr;
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()
|
a65c8e8b |
: type(e_none)
, value("")
, position(std::numeric_limits<std::size_t>::max())
|
4068375e |
{}
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 = static_cast<std::size_t>(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 = static_cast<std::size_t>(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 = static_cast<std::size_t>(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 = static_cast<std::size_t>(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 = static_cast<std::size_t>(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 token_list_t::iterator token_list_itr_t;
typedef details::char_t char_t;
generator()
|
a65c8e8b |
: base_itr_(0)
, s_itr_ (0)
, s_end_ (0)
|
4068375e |
{
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() && 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);
}
}
|
a65c8e8b |
inline std::string substr(const std::size_t& begin, const std::size_t& end) const
|
4068375e |
{
const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
|
a65c8e8b |
const details::char_cptr end_itr = ((base_itr_ + end ) < s_end_) ? (base_itr_ + end ) : s_end_;
|
4068375e |
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:
|
a65c8e8b |
inline bool is_end(details::char_cptr itr) const
|
4068375e |
{
return (s_end_ == itr);
}
|
a65c8e8b |
#ifndef exprtk_disable_comments
inline bool is_comment_start(details::char_cptr itr) const
|
4068375e |
{
const char_t c0 = *(itr + 0);
const char_t c1 = *(itr + 1);
if ('#' == c0)
return true;
else if (!is_end(itr + 1))
{
if (('/' == c0) && ('/' == c1)) return true;
if (('/' == c0) && ('*' == c1)) return true;
}
return false;
}
|
a65c8e8b |
#else
inline bool is_comment_start(details::char_cptr) const
{
return false;
}
#endif
|
4068375e |
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_t c0, const char_t c1, int& mode, int& incr)
{
mode = 0;
|
a65c8e8b |
if ('#' == c0) { mode = 1; incr = 1; }
|
4068375e |
else if ('/' == c0)
{
|
a65c8e8b |
if ('/' == c1) { mode = 1; incr = 2; }
|
4068375e |
else if ('*' == c1) { mode = 2; incr = 2; }
}
return (0 != mode);
}
static inline bool comment_end(const char_t c0, const char_t c1, int& mode)
{
if (
((1 == mode) && ('\n' == c0)) ||
((2 == mode) && ( '*' == c0) && ('/' == c1))
)
{
mode = 0;
return true;
}
else
return false;
}
};
int mode = 0;
int increment = 0;
if (is_end(s_itr_))
return;
else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment))
return;
details::char_cptr cmt_start = s_itr_;
s_itr_ += increment;
while (!is_end(s_itr_))
{
if ((1 == mode) && test::comment_end(*s_itr_, 0, mode))
{
++s_itr_;
return;
}
if ((2 == mode))
{
if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode))
{
s_itr_ += 2;
return;
}
}
++s_itr_;
}
if (2 == mode)
{
token_t t;
t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_);
token_list_.push_back(t);
}
#endif
}
inline void scan_token()
{
if (details::is_whitespace(*s_itr_))
{
skip_whitespace();
return;
}
else if (is_comment_start(s_itr_))
{
skip_comments();
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_t c0 = s_itr_[0];
if (!is_end(s_itr_ + 1))
{
const char_t c1 = s_itr_[1];
if (!is_end(s_itr_ + 2))
{
const char_t 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;
|
a65c8e8b |
if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
|
4068375e |
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()
{
details::char_cptr initial_itr = s_itr_;
while (!is_end(s_itr_))
{
if (!details::is_letter_or_digit(*s_itr_) && ('_' != (*s_itr_)))
{
if ('.' != (*s_itr_))
break;
/*
Permit symbols that contain a 'dot'
Allowed : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123
Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...>
*/
if (
(s_itr_ != initial_itr) &&
!is_end(s_itr_ + 1) &&
!details::is_letter_or_digit(*(s_itr_ + 1)) &&
('_' != (*(s_itr_ + 1)))
)
break;
}
++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:
(01) 123456
(02) 123456.
(03) 123.456
(04) 123.456e3
(05) 123.456E3
(06) 123.456e+3
(07) 123.456E+3
(08) 123.456e-3
(09) 123.456E-3
(00) .1234
(11) .1234e3
(12) .1234E+3
(13) .1234e+3
(14) .1234E-3
(15) .1234e-3
*/
details::char_cptr initial_itr = s_itr_;
bool dot_found = false;
bool e_found = false;
bool post_e_sign_found = false;
bool post_e_digit_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 ('e' == std::tolower(*s_itr_))
{
const char_t& 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_) && !post_e_digit_found)
{
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 (e_found && details::is_digit(*s_itr_))
{
post_e_digit_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()
{
details::char_cptr initial_itr = s_itr_;
token_t t;
// $fdd(x,x,x) = at least 11 chars
if (std::distance(s_itr_,s_end_) < 11)
{
|
a65c8e8b |
t.set_error(
token::e_err_sfunc,
initial_itr, std::min(initial_itr + 11, s_end_),
base_itr_);
|
4068375e |
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))))
)
{
|
a65c8e8b |
t.set_error(
token::e_err_sfunc,
initial_itr, std::min(initial_itr + 4, s_end_),
base_itr_);
|
4068375e |
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()
{
details::char_cptr 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 (!details::is_valid_string_char(*s_itr_))
{
t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
token_list_.push_back(t);
return;
}
else 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_)) &&
((s_itr_ + 4) <= s_end_)
)
{
const bool x_seperator = ('X' == std::toupper(*(s_itr_ + 1)));
const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
details::is_hex_digit(*(s_itr_ + 3)) ;
if (!(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_);
if (!details::cleanup_escapes(parsed_string))
{
t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
token_list_.push_back(t);
return;
}
t.set_string(
parsed_string,
static_cast<std::size_t>(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_;
details::char_cptr base_itr_;
details::char_cptr s_itr_;
details::char_cptr s_end_;
friend class token_scanner;
friend class token_modifier;
friend class token_inserter;
friend class token_joiner;
|
a65c8e8b |
}; // class generator
|
4068375e |
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:
|
a65c8e8b |
virtual ~token_scanner() {}
|
4068375e |
explicit token_scanner(const std::size_t& stride)
: stride_(stride)
{
if (stride > 4)
{
throw std::invalid_argument("token_scanner() - Invalid stride value");
}
}
|
a65c8e8b |
inline std::size_t process(generator& g) exprtk_override
|
4068375e |
{
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:
const std::size_t stride_;
|
a65c8e8b |
}; // class token_scanner
|
4068375e |
class token_modifier : public helper_interface
{
public:
|
a65c8e8b |
inline std::size_t process(generator& g) exprtk_override
|
4068375e |
{
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");
}
}
|
a65c8e8b |
inline std::size_t process(generator& g) exprtk_override
|
4068375e |
{
if (g.token_list_.empty())
return 0;
else if (g.token_list_.size() < stride_)
return 0;
std::size_t changes = 0;
typedef std::pair<std::size_t, token> insert_t;
std::vector<insert_t> insert_list;
insert_list.reserve(10000);
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)))
{
insert_list.push_back(insert_t(i, t));
changes++;
}
}
if (!insert_list.empty())
{
generator::token_list_t token_list;
std::size_t insert_index = 0;
for (std::size_t i = 0; i < g.token_list_.size(); ++i)
{
token_list.push_back(g.token_list_[i]);
if (
(insert_index < insert_list.size()) &&
(insert_list[insert_index].first == i)
)
{
token_list.push_back(insert_list[insert_index].second);
insert_index++;
}
}
std::swap(g.token_list_,token_list);
}
return changes;
}
#define token_inserter_empty_body \
{ \
return -1; \
} \
inline virtual int insert(const token&, token&)
token_inserter_empty_body
inline virtual int insert(const token&, const token&, token&)
token_inserter_empty_body
inline virtual int insert(const token&, const token&, const token&, token&)
token_inserter_empty_body
inline virtual int insert(const token&, const token&, const token&, const token&, token&)
token_inserter_empty_body
inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
token_inserter_empty_body
#undef token_inserter_empty_body
private:
const std::size_t stride_;
};
class token_joiner : public helper_interface
{
public:
explicit token_joiner(const std::size_t& stride)
: stride_(stride)
{}
|
a65c8e8b |
inline std::size_t process(generator& g) exprtk_override
|
4068375e |
{
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;
generator::token_list_t token_list;
token_list.reserve(10000);
for (int i = 0; i < static_cast<int>(g.token_list_.size() - 1); ++i)
{
token t;
for ( ; ; )
{
if (!join(g[i], g[i + 1], t))
{
token_list.push_back(g[i]);
break;
}
token_list.push_back(t);
++changes;
i+=2;
|
a65c8e8b |
if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1))
|
4068375e |
break;
}
}
token_list.push_back(g.token_list_.back());
|
a65c8e8b |
assert(token_list.size() <= g.token_list_.size());
|
4068375e |
std::swap(token_list, g.token_list_);
return changes;
}
inline std::size_t process_stride_3(generator& g)
{
if (g.token_list_.size() < 3)
return 0;
std::size_t changes = 0;
generator::token_list_t token_list;
token_list.reserve(10000);
for (int i = 0; i < static_cast<int>(g.token_list_.size() - 2); ++i)
{
token t;
for ( ; ; )
{
if (!join(g[i], g[i + 1], g[i + 2], t))
{
token_list.push_back(g[i]);
break;
}
token_list.push_back(t);
++changes;
i+=3;
|
a65c8e8b |
if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2))
|
4068375e |
break;
}
}
token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 2));
token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 1));
|
a65c8e8b |
assert(token_list.size() <= g.token_list_.size());
|
4068375e |
std::swap(token_list, g.token_list_);
return changes;
}
const std::size_t stride_;
};
namespace helper
{
inline void dump(const lexer::generator& generator)
{
for (std::size_t i = 0; i < generator.size(); ++i)
{
const 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:
using lexer::token_inserter::insert;
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;
}
}
|
a65c8e8b |
if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
|
4068375e |
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;
else if ((t0.type == lexer::token::e_symbol ) && (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:
explicit 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;
}
// '! =' --> '!='
|
a65c8e8b |
else if ((static_cast<details::char_t>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
|
4068375e |
{
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 if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub))
{
t.type = lexer::token::e_sub;
t.value = "-";
t.position = t0.position;
return true;
}
// '- +' --> '-'
else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add))
{
t.type = lexer::token::e_sub;
t.value = "-";
t.position = t0.position;
return true;
}
// '- -' --> '+'
else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub))
{
/*
Note: May need to reconsider this when wanting to implement
pre/postfix decrement operator
*/
t.type = lexer::token::e_add;
t.value = "+";
t.position = t0.position;
return true;
}
else
return false;
}
|
a65c8e8b |
inline bool join(const lexer::token& t0,
const lexer::token& t1,
const lexer::token& t2,
lexer::token& t)
|
4068375e |
{
// '[ * ]' --> '[*]'
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:
using lexer::token_scanner::operator();
bracket_checker()
|
a65c8e8b |
: token_scanner(1)
, state_(true)
|
4068375e |
{}
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])
)
{
details::char_t c = t.value[0];
|
a65c8e8b |
if (t.type == lexer::token::e_lbracket ) stack_.push(std::make_pair(')',t.position));
|
4068375e |
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:
using lexer::token_scanner::operator();
numeric_checker()
|
a65c8e8b |
: token_scanner (1)
, current_index_(0)
|
4068375e |
{}
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)
{
const 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)
{
const 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;
const 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:
using lexer::token_scanner::operator();
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_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)
{
const 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() const
{
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:
|
a65c8e8b |
void add_invalid(const lexer::token::token_type base, const lexer::token::token_type t)
|
4068375e |
{
invalid_comb_.insert(std::make_pair(base,t));
}
|
a65c8e8b |
void add_invalid_set1(const lexer::token::token_type t)
|
4068375e |
{
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 );
}
|
a65c8e8b |
bool invalid_bracket_check(const lexer::token::token_type base, const lexer::token::token_type t)
|
4068375e |
{
|
a65c8e8b |
if (details::is_right_bracket(static_cast<details::char_t>(base)))
|
4068375e |
{
switch (t)
{
case lexer::token::e_assign : return (']' != base);
case lexer::token::e_string : return (')' != base);
default : return false;
}
}
|
a65c8e8b |
else if (details::is_left_bracket(static_cast<details::char_t>(base)))
|
4068375e |
{
|
a65c8e8b |
if (details::is_right_bracket(static_cast<details::char_t>(t)))
|
4068375e |
return false;
|
a65c8e8b |
else if (details::is_left_bracket(static_cast<details::char_t>(t)))
|
4068375e |
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 ;
}
}
}
|
a65c8e8b |
else if (details::is_right_bracket(static_cast<details::char_t>(t)))
|
4068375e |
{
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 ;
}
}
|
a65c8e8b |
else if (details::is_left_bracket(static_cast<details::char_t>(t)))
|
4068375e |
{
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_;
};
class sequence_validator_3tokens : public lexer::token_scanner
{
private:
typedef lexer::token::token_type token_t;
typedef std::pair<token_t,std::pair<token_t,token_t> > token_triplet_t;
typedef std::set<token_triplet_t> set_t;
public:
using lexer::token_scanner::operator();
sequence_validator_3tokens()
: lexer::token_scanner(3)
{
|
a65c8e8b |
add_invalid(lexer::token::e_number , lexer::token::e_number , lexer::token::e_number);
add_invalid(lexer::token::e_string , lexer::token::e_string , lexer::token::e_string);
add_invalid(lexer::token::e_comma , lexer::token::e_comma , lexer::token::e_comma );
|
4068375e |
|
a65c8e8b |
add_invalid(lexer::token::e_add , lexer::token::e_add , lexer::token::e_add );
add_invalid(lexer::token::e_sub , lexer::token::e_sub , lexer::token::e_sub );
add_invalid(lexer::token::e_div , lexer::token::e_div , lexer::token::e_div );
add_invalid(lexer::token::e_mul , lexer::token::e_mul , lexer::token::e_mul );
add_invalid(lexer::token::e_mod , lexer::token::e_mod , lexer::token::e_mod );
add_invalid(lexer::token::e_pow , lexer::token::e_pow , lexer::token::e_pow );
|
4068375e |
|
a65c8e8b |
add_invalid(lexer::token::e_add , lexer::token::e_sub , lexer::token::e_add );
add_invalid(lexer::token::e_sub , lexer::token::e_add , lexer::token::e_sub );
add_invalid(lexer::token::e_div , lexer::token::e_mul , lexer::token::e_div );
add_invalid(lexer::token::e_mul , lexer::token::e_div , lexer::token::e_mul );
add_invalid(lexer::token::e_mod , lexer::token::e_pow , lexer::token::e_mod );
add_invalid(lexer::token::e_pow , lexer::token::e_mod , lexer::token::e_pow );
|
4068375e |
}
bool result()
{
return error_list_.empty();
}
bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2)
{
const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type));
if (invalid_comb_.find(p) != invalid_comb_.end())
{
error_list_.push_back(std::make_pair(t0,t1));
}
return true;
}
std::size_t error_count() const
{
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:
|
a65c8e8b |
void add_invalid(const token_t t0, const token_t t1, const token_t t2)
|
4068375e |
{
invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2)));
}
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);
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 true;
}
inline bool run_joiners(lexer::generator& g)
{
error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
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 true;
}
inline bool run_inserters(lexer::generator& g)
{
error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
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 true;
}
inline bool run_scanners(lexer::generator& g)
{
error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
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 true;
}
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:
|
a65c8e8b |
typedef token token_t;
|
4068375e |
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_;
}
enum token_advance_mode
{
e_hold = 0,
e_advance = 1
};
inline void advance_token(const token_advance_mode mode)
{
if (e_advance == mode)
{
next_token();
}
}
inline bool token_is(const token_t::token_type& ttype, const token_advance_mode mode = e_advance)
{
if (current_token().type != ttype)
{
return false;
}
advance_token(mode);
return true;
}
inline bool token_is(const token_t::token_type& ttype,
const std::string& value,
const token_advance_mode mode = e_advance)
{
if (
(current_token().type != ttype) ||
!exprtk::details::imatch(value,current_token().value)
)
{
return false;
}
advance_token(mode);
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 vector_view
{
public:
typedef T* data_ptr_t;
vector_view(data_ptr_t data, const std::size_t& size)
|
a65c8e8b |
: size_(size)
, data_(data)
, data_ref_(0)
|
4068375e |
{}
vector_view(const vector_view<T>& vv)
|
a65c8e8b |
: size_(vv.size_)
, data_(vv.data_)
, data_ref_(0)
|
4068375e |
{}
inline void rebase(data_ptr_t data)
{
data_ = data;
if (!data_ref_.empty())
{
for (std::size_t i = 0; i < data_ref_.size(); ++i)
{
(*data_ref_[i]) = data;
}
}
}
inline data_ptr_t data() const
{
return data_;
}
inline std::size_t size() const
{
return size_;
}
inline const T& operator[](const std::size_t index) const
{
return data_[index];
}
inline T& operator[](const std::size_t index)
{
return data_[index];
}
void set_ref(data_ptr_t* data_ref)
{
data_ref_.push_back(data_ref);
}
private:
const std::size_t size_;
data_ptr_t data_;
std::vector<data_ptr_t*> data_ref_;
};
template <typename T>
inline vector_view<T> make_vector_view(T* data,
const std::size_t size, const std::size_t offset = 0)
{
return vector_view<T>(data + offset, size);
}
template <typename T>
inline vector_view<T> make_vector_view(std::vector<T>& v,
const std::size_t size, const std::size_t offset = 0)
{
return vector_view<T>(v.data() + offset, size);
}
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()
|
a65c8e8b |
: data(0)
, size(0)
, type(e_unknown)
|
4068375e |
{}
union
{
|
a65c8e8b |
void* data;
T* vec_data;
|
4068375e |
};
std::size_t size;
store_type type;
class parameter_list
{
public:
|
a65c8e8b |
explicit parameter_list(std::vector<type_store>& pl)
|
4068375e |
: 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;
|
a65c8e8b |
explicit type_view(type_store_t& ts)
: ts_(ts)
, data_(reinterpret_cast<value_t*>(ts_.data))
|
4068375e |
{}
|
a65c8e8b |
explicit type_view(const type_store_t& ts)
: ts_(const_cast<type_store_t&>(ts))
, data_(reinterpret_cast<value_t*>(ts_.data))
|
4068375e |
{}
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;
|
a65c8e8b |
explicit scalar_view(type_store_t& ts)
|
4068375e |
: v_(*reinterpret_cast<value_t*>(ts.data))
{}
|
a65c8e8b |
explicit scalar_view(const type_store_t& ts)
|
4068375e |
: v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
{}
inline value_t& operator() ()
{
return v_;
}
inline const value_t& operator() () const
{
return v_;
}
template <typename IntType>
inline bool to_int(IntType& i) const
{
if (!exprtk::details::numeric::is_integer(v_))
return false;
i = static_cast<IntType>(v_);
return true;
}
template <typename UIntType>
inline bool to_uint(UIntType& u) const
{
if (v_ < T(0))
return false;
else if (!exprtk::details::numeric::is_integer(v_))
return false;
u = static_cast<UIntType>(v_);
return true;
}
T& v_;
};
};
template <typename StringView>
inline std::string to_str(const StringView& view)
{
return std::string(view.begin(),view.size());
}
#ifndef exprtk_disable_return_statement
namespace details
{
template <typename T> class return_node;
template <typename T> class return_envelope_node;
}
#endif
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_;
#ifndef exprtk_disable_return_statement
friend class details::return_node<T>;
friend class details::return_envelope_node<T>;
#endif
};
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_smulti ,
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,
e_sf4ext60 = 2060, e_sf4ext61 = 2061
};
inline std::string to_str(const operator_type opr)
{
switch (opr)
{
case e_add : return "+" ;
case e_sub : return "-" ;
case e_mul : return "*" ;
case e_div : return "/" ;
case e_mod : return "%" ;
case e_pow : return "^" ;
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_lt : return "<" ;
case e_lte : return "<=" ;
case e_eq : return "==" ;
case e_equal : return "=" ;
case e_ne : return "!=" ;
case e_nequal : return "<>" ;
case e_gte : return ">=" ;
case e_gt : return ">" ;
case e_and : return "and" ;
case e_or : return "or" ;
case e_xor : return "xor" ;
case e_nand : return "nand";
case e_nor : return "nor" ;
case e_xnor : return "xnor";
default : return "N/A" ;
}
}
struct base_operation_t
{
base_operation_t(const operator_type t, const unsigned int& np)
|
a65c8e8b |
: type(t)
, num_params(np)
|
4068375e |
{}
operator_type type;
unsigned int num_params;
};
namespace loop_unroll
{
#ifndef exprtk_disable_superscalar_unroll
const unsigned int global_loop_batch_size = 16;
#else
const unsigned int global_loop_batch_size = 4;
#endif
struct details
{
explicit details(const std::size_t& vsize,
const unsigned int loop_batch_size = global_loop_batch_size)
|
a65c8e8b |
: batch_size(loop_batch_size )
, remainder (vsize % batch_size)
, upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
|
4068375e |
{}
unsigned int batch_size;
|
a65c8e8b |
int remainder;
|
4068375e |
int upper_bound;
};
}
#ifdef exprtk_enable_debugging
inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0)
{
if (size)
exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr));
else
exprtk_debug(("%s - addr: %p size: %d\n",
s.c_str(),
ptr,
static_cast<unsigned int>(size)));
}
#else
inline void dump_ptr(const std::string&, const void*) {}
inline void dump_ptr(const std::string&, const void*, const std::size_t) {}
#endif
template <typename T>
class vec_data_store
{
public:
typedef vec_data_store<T> type;
typedef T* data_t;
private:
struct control_block
{
control_block()
|
a65c8e8b |
: ref_count(1)
, size (0)
, data (0)
, destruct (true)
|
4068375e |
{}
|
a65c8e8b |
explicit control_block(const std::size_t& dsize)
: ref_count(1 )
, size (dsize)
, data (0 )
, destruct (true )
|
4068375e |
{ create_data(); }
control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false)
|
a65c8e8b |
: ref_count(1 )
, size (dsize )
, data (dptr )
, destruct (dstrct)
|
4068375e |
{}
~control_block()
{
if (data && destruct && (0 == ref_count))
{
dump_ptr("~control_block() data",data);
delete[] data;
data = reinterpret_cast<data_t>(0);
}
}
static inline control_block* create(const std::size_t& dsize, data_t data_ptr = data_t(0), bool dstrct = false)
{
if (dsize)
{
if (0 == data_ptr)
return (new control_block(dsize));
else
return (new control_block(dsize, data_ptr, dstrct));
}
else
return (new control_block);
}
static inline void destroy(control_block*& cntrl_blck)
{
if (cntrl_blck)
{
if (
(0 != cntrl_blck->ref_count) &&
(0 == --cntrl_blck->ref_count)
)
{
delete cntrl_blck;
}
cntrl_blck = 0;
}
}
std::size_t ref_count;
std::size_t size;
data_t data;
bool destruct;
private:
|
a65c8e8b |
control_block(const control_block&) exprtk_delete;
control_block& operator=(const control_block&) exprtk_delete;
|
4068375e |
inline void create_data()
{
destruct = true;
data = new T[size];
|
a65c8e8b |
std::fill_n(data, size, T(0));
dump_ptr("control_block::create_data() - data", data, size);
|
4068375e |
}
};
public:
vec_data_store()
: control_block_(control_block::create(0))
{}
|
a65c8e8b |
explicit vec_data_store(const std::size_t& size)
: control_block_(control_block::create(size,reinterpret_cast<data_t>(0),true))
|
4068375e |
{}
vec_data_store(const std::size_t& size, data_t data, bool dstrct = false)
: control_block_(control_block::create(size, data, dstrct))
{}
vec_data_store(const type& vds)
{
control_block_ = vds.control_block_;
control_block_->ref_count++;
}
~vec_data_store()
{
control_block::destroy(control_block_);
}
type& operator=(const type& vds)
{
if (this != &vds)
{
std::size_t final_size = min_size(control_block_, vds.control_block_);
vds.control_block_->size = final_size;
control_block_->size = final_size;
if (control_block_->destruct || (0 == control_block_->data))
{
control_block::destroy(control_block_);
control_block_ = vds.control_block_;
control_block_->ref_count++;
}
}
return (*this);
}
inline data_t data()
{
return control_block_->data;
}
inline data_t data() const
{
return control_block_->data;
}
inline std::size_t size() const
{
return control_block_->size;
}
inline data_t& ref()
{
return control_block_->data;
}
inline void dump() const
{
#ifdef exprtk_enable_debugging
exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n",
size(),
data(),
(control_block_->destruct ? 'T' : 'F')));
for (std::size_t i = 0; i < size(); ++i)
{
if (5 == i)
exprtk_debug(("\n"));
exprtk_debug(("%15.10f ",data()[i]));
}
exprtk_debug(("\n"));
#endif
}
static inline void match_sizes(type& vds0, type& vds1)
{
const std::size_t size = min_size(vds0.control_block_,vds1.control_block_);
vds0.control_block_->size = size;
vds1.control_block_->size = size;
}
private:
|
a65c8e8b |
static inline std::size_t min_size(const control_block* cb0, const control_block* cb1)
|
4068375e |
{
const std::size_t size0 = cb0->size;
const std::size_t size1 = cb1->size;
if (size0 && size1)
return std::min(size0,size1);
else
return (size0) ? size0 : size1;
}
control_block* control_block_;
};
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 : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n"));
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 (arg0,arg1);
case e_nequal : return nequal (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 : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n"));
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 : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n"));
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 Node>
struct node_collector_interface
{
typedef Node* node_ptr_t;
typedef Node** node_pp_t;
typedef std::vector<node_pp_t> noderef_list_t;
virtual ~node_collector_interface() {}
virtual void collect_nodes(noderef_list_t&) {}
};
template <typename Node>
struct node_depth_base;
template <typename T>
class expression_node : public node_collector_interface<expression_node<T> >,
public node_depth_base<expression_node<T> >
{
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_stringvararg ,
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_rbvecelem , e_rbveccelem ,
e_vecdefass , e_vecvalass , e_vecvecass , e_vecopvalass ,
e_vecopvecass , e_vecfunc , e_vecvecswap , e_vecvecineq ,
e_vecvalineq , e_valvecineq , e_vecvecarith , e_vecvalarith ,
|
a65c8e8b |
e_valvecarith , e_vecunaryop , e_vecondition , e_break ,
e_continue , e_swap
|
4068375e |
};
typedef T value_type;
typedef expression_node<T>* expression_ptr;
typedef node_collector_interface<expression_node<T> > nci_t;
typedef typename nci_t::noderef_list_t noderef_list_t;
typedef node_depth_base<expression_node<T> > ndb_t;
|
a65c8e8b |
virtual ~expression_node() {}
|
4068375e |
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;
}
|
a65c8e8b |
}; // class expression_node
|
4068375e |
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());
}
|
a65c8e8b |
template <typename T>
inline bool is_true(const std::pair<expression_node<T>*,bool>& node)
{
return std::not_equal_to<T>()(T(0),node.first->value());
}
|
4068375e |
template <typename T>
inline bool is_false(const expression_node<T>* node)
{
return std::equal_to<T>()(T(0),node->value());
}
|
a65c8e8b |
template <typename T>
inline bool is_false(const std::pair<expression_node<T>*,bool>& node)
{
return std::equal_to<T>()(T(0),node.first->value());
}
|
4068375e |
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() ||
details::expression_node<T>::e_rbvecelem == node->type() ||
details::expression_node<T>::e_rbveccelem == 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_rebasevector_elem_node(const expression_node<T>* node)
{
return node && (details::expression_node<T>::e_rbvecelem == node->type());
}
template <typename T>
inline bool is_rebasevector_celem_node(const expression_node<T>* node)
{
return node && (details::expression_node<T>::e_rbveccelem == 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 :
|
a65c8e8b |
case details::expression_node<T>::e_vecunaryop :
case details::expression_node<T>::e_vecondition : return true;
|
4068375e |
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 (0 != node) &&
!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 Node>
class node_collection_destructor
{
public:
typedef node_collector_interface<Node> nci_t;
typedef typename nci_t::node_ptr_t node_ptr_t;
typedef typename nci_t::node_pp_t node_pp_t;
typedef typename nci_t::noderef_list_t noderef_list_t;
static void delete_nodes(node_ptr_t& root)
{
std::vector<node_pp_t> node_delete_list;
node_delete_list.reserve(1000);
collect_nodes(root, node_delete_list);
for (std::size_t i = 0; i < node_delete_list.size(); ++i)
{
node_ptr_t& node = *node_delete_list[i];
exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", static_cast<void*>(node)));
delete node;
node = reinterpret_cast<node_ptr_t>(0);
}
}
private:
static void collect_nodes(node_ptr_t& root, noderef_list_t& node_delete_list)
{
std::deque<node_ptr_t> node_list;
node_list.push_back(root);
node_delete_list.push_back(&root);
noderef_list_t child_node_delete_list;
child_node_delete_list.reserve(1000);
while (!node_list.empty())
{
node_list.front()->collect_nodes(child_node_delete_list);
if (!child_node_delete_list.empty())
{
for (std::size_t i = 0; i < child_node_delete_list.size(); ++i)
{
node_pp_t& node = child_node_delete_list[i];
if (0 == (*node))
{
exprtk_debug(("ncd::collect_nodes() - null node encountered.\n"));
}
node_list.push_back(*node);
}
node_delete_list.insert(
node_delete_list.end(),
child_node_delete_list.begin(), child_node_delete_list.end());
child_node_delete_list.clear();
}
node_list.pop_front();
}
std::reverse(node_delete_list.begin(), node_delete_list.end());
}
};
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&, expression_node<T>*& node)
{
if ((0 == node) || is_variable_node(node) || is_string_node(node))
{
return;
}
node_collection_destructor<expression_node<T> >
::delete_nodes(node);
}
template <typename T>
inline void destroy_node(expression_node<T>*& node)
{
if (0 != node)
{
node_collection_destructor<expression_node<T> >
::delete_nodes(node);
}
}
template <typename Node>
struct node_depth_base
{
|
a65c8e8b |
typedef Node* node_ptr_t;
typedef std::pair<node_ptr_t,bool> nb_pair_t;
|
4068375e |
node_depth_base()
|
a65c8e8b |
: depth_set(false)
, depth(0)
|
4068375e |
{}
virtual ~node_depth_base() {}
virtual std::size_t node_depth() const { return 1; }
std::size_t compute_node_depth(const Node* const& node) const
{
if (!depth_set)
{
depth = 1 + (node ? node->node_depth() : 0);
depth_set = true;
}
return depth;
}
|
a65c8e8b |
std::size_t compute_node_depth(const nb_pair_t& branch) const
|
4068375e |
{
if (!depth_set)
{
depth = 1 + (branch.first ? branch.first->node_depth() : 0);
depth_set = true;
}
return depth;
}
template <std::size_t N>
|
a65c8e8b |
std::size_t compute_node_depth(const nb_pair_t (&branch)[N]) const
|
4068375e |
{
if (!depth_set)
{
depth = 0;
for (std::size_t i = 0; i < N; ++i)
{
if (branch[i].first)
{
depth = std::max(depth,branch[i].first->node_depth());
}
}
depth += 1;
depth_set = true;
}
return depth;
}
template <typename BranchType>
std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const
{
if (!depth_set)
{
depth = 1 + std::max(compute_node_depth(n0), compute_node_depth(n1));
depth_set = true;
}
return depth;
}
template <typename BranchType>
std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1,
const BranchType& n2) const
{
if (!depth_set)
{
depth = 1 + std::max(
std::max(compute_node_depth(n0), compute_node_depth(n1)),
compute_node_depth(n2));
depth_set = true;
}
return depth;
}
template <typename BranchType>
std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1,
const BranchType& n2, const BranchType& n3) const
{
if (!depth_set)
{
depth = 1 + std::max(
std::max(compute_node_depth(n0), compute_node_depth(n1)),
std::max(compute_node_depth(n2), compute_node_depth(n3)));
depth_set = true;
}
return depth;
}
template <typename Allocator,
template <typename, typename> class Sequence>
|
a65c8e8b |
std::size_t compute_node_depth(const Sequence<node_ptr_t, Allocator>& branch_list) const
|
4068375e |
{
if (!depth_set)
{
for (std::size_t i = 0; i < branch_list.size(); ++i)
{
if (branch_list[i])
{
depth = std::max(depth, compute_node_depth(branch_list[i]));
}
}
depth_set = true;
}
return depth;
}
template <typename Allocator,
template <typename, typename> class Sequence>
|
a65c8e8b |
std::size_t compute_node_depth(const Sequence<nb_pair_t,Allocator>& branch_list) const
|
4068375e |
{
if (!depth_set)
{
for (std::size_t i = 0; i < branch_list.size(); ++i)
{
if (branch_list[i].first)
{
depth = std::max(depth, compute_node_depth(branch_list[i].first));
}
}
depth_set = true;
}
return depth;
}
mutable bool depth_set;
mutable std::size_t depth;
template <typename NodeSequence>
|
a65c8e8b |
void collect(node_ptr_t const& node,
|
4068375e |
const bool deletable,
NodeSequence& delete_node_list) const
{
if ((0 != node) && deletable)
{
|
a65c8e8b |
delete_node_list.push_back(const_cast<node_ptr_t*>(&node));
|
4068375e |
}
}
template <typename NodeSequence>
|
a65c8e8b |
void collect(const nb_pair_t& branch,
|
4068375e |
NodeSequence& delete_node_list) const
{
collect(branch.first, branch.second, delete_node_list);
}
template <typename NodeSequence>
void collect(Node*& node,
NodeSequence& delete_node_list) const
{
collect(node, branch_deletable(node), delete_node_list);
}
template <std::size_t N, typename NodeSequence>
|
a65c8e8b |
void collect(const nb_pair_t(&branch)[N],
|
4068375e |
NodeSequence& delete_node_list) const
{
for (std::size_t i = 0; i < N; ++i)
{
collect(branch[i].first, branch[i].second, delete_node_list);
}
}
template <typename Allocator,
template <typename, typename> class Sequence,
typename NodeSequence>
|
a65c8e8b |
void collect(const Sequence<nb_pair_t, Allocator>& branch,
|
4068375e |
NodeSequence& delete_node_list) const
{
for (std::size_t i = 0; i < branch.size(); ++i)
{
collect(branch[i].first, branch[i].second, delete_node_list);
}
}
template <typename Allocator,
template <typename, typename> class Sequence,
typename NodeSequence>
|
a65c8e8b |
void collect(const Sequence<node_ptr_t, Allocator>& branch_list,
|
4068375e |
NodeSequence& delete_node_list) const
{
for (std::size_t i = 0; i < branch_list.size(); ++i)
{
collect(branch_list[i], branch_deletable(branch_list[i]), delete_node_list);
}
}
template <typename Boolean,
typename AllocatorT,
typename AllocatorB,
template <typename, typename> class Sequence,
typename NodeSequence>
|
a65c8e8b |
void collect(const Sequence<node_ptr_t, AllocatorT>& branch_list,
|
4068375e |
const Sequence<Boolean, AllocatorB>& branch_deletable_list,
NodeSequence& delete_node_list) const
{
for (std::size_t i = 0; i < branch_list.size(); ++i)
{
collect(branch_list[i], branch_deletable_list[i], delete_node_list);
}
}
};
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();
}
inline value_ptr data() const
{
return value_at(0);
}
virtual inline bool rebaseable() const
{
return false;
}
virtual void set_ref(value_ptr*) {}
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)
|
a65c8e8b |
: vec_(vec)
, size_(vec_size)
|
4068375e |
{}
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:
|
a65c8e8b |
array_vector_impl(const array_vector_impl&) exprtk_delete;
array_vector_impl& operator=(const array_vector_impl&) exprtk_delete;
|
4068375e |
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:
|
a65c8e8b |
sequence_vector_impl(const sequence_vector_impl&) exprtk_delete;
sequence_vector_impl& operator=(const sequence_vector_impl&) exprtk_delete;
|
4068375e |
sequence_t& sequence_;
};
class vector_view_impl : public vector_holder_base
{
public:
typedef exprtk::vector_view<Type> vector_view_t;
vector_view_impl(vector_view_t& vec_view)
: vec_view_(vec_view)
{}
void set_ref(value_ptr* ref)
{
vec_view_.set_ref(ref);
}
virtual inline bool rebaseable() const
{
return true;
}
protected:
value_ptr value_at(const std::size_t& index) const
{
return (index < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0);
}
std::size_t vector_size() const
{
return vec_view_.size();
}
private:
|
a65c8e8b |
vector_view_impl(const vector_view_impl&) exprtk_delete;
vector_view_impl& operator=(const vector_view_impl&) exprtk_delete;
|
4068375e |
vector_view_t& vec_view_;
};
public:
typedef typename details::vec_data_store<Type> vds_t;
vector_holder(Type* vec, const std::size_t& vec_size)
: vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
{}
vector_holder(const vds_t& vds)
: vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size()))
{}
template <typename Allocator>
vector_holder(std::vector<Type,Allocator>& vec)
: vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
{}
vector_holder(exprtk::vector_view<Type>& vec)
: vector_holder_base_(new(buffer)vector_view_impl(vec))
{}
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();
}
inline value_ptr data() const
{
return vector_holder_base_->data();
}
void set_ref(value_ptr* ref)
{
vector_holder_base_->set_ref(ref);
}
bool rebaseable() const
{
return vector_holder_base_->rebaseable();
}
private:
mutable vector_holder_base* vector_holder_base_;
uchar_t buffer[64];
};
template <typename T>
|
a65c8e8b |
class null_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_null;
}
};
template <typename T, std::size_t N>
inline void construct_branch_pair(std::pair<expression_node<T>*,bool> (&branch)[N],
expression_node<T>* b,
const std::size_t& index)
{
if (b && (index < N))
{
branch[index] = std::make_pair(b,branch_deletable(b));
}
}
template <typename T>
inline void construct_branch_pair(std::pair<expression_node<T>*,bool>& branch, expression_node<T>* b)
{
if (b)
{
branch = 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(branch, b0, 0);
construct_branch_pair(branch, b1, 1);
construct_branch_pair(branch, b2, 2);
construct_branch_pair(branch, b3, 3);
construct_branch_pair(branch, b4, 4);
construct_branch_pair(branch, b5, 5);
construct_branch_pair(branch, b6, 6);
construct_branch_pair(branch, b7, 7);
construct_branch_pair(branch, b8, 8);
construct_branch_pair(branch, b9, 9);
}
template <typename T>
|
a65c8e8b |
class null_eq_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
|
a65c8e8b |
explicit null_eq_node(expression_ptr branch, const bool equality = true)
|
4068375e |
: equality_(equality)
{
|
a65c8e8b |
construct_branch_pair(branch_, branch);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
const T v = branch_.first->value();
const bool result = details::numeric::is_nan(v);
if (result)
return (equality_) ? T(1) : T(0);
else
return (equality_) ? T(0) : T(1);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_nulleq;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
bool equality_;
branch_t branch_;
};
template <typename T>
|
a65c8e8b |
class literal_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
explicit literal_node(const T& v)
: value_(v)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return value_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_constant;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return reinterpret_cast<expression_node<T>*>(0);
}
private:
|
a65c8e8b |
literal_node(const literal_node<T>&) exprtk_delete;
literal_node<T>& operator=(const literal_node<T>&) exprtk_delete;
|
4068375e |
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;
|
a65c8e8b |
virtual ~range_interface() {}
|
4068375e |
virtual range_t& range_ref() = 0;
virtual const range_t& range_ref() const = 0;
};
#ifndef exprtk_disable_string_capabilities
template <typename T>
class string_base_node
{
public:
typedef range_data_type<T> range_data_type_t;
|
a65c8e8b |
virtual ~string_base_node() {}
|
4068375e |
virtual std::string str () const = 0;
virtual char_cptr base() const = 0;
virtual std::size_t size() const = 0;
};
template <typename T>
|
a65c8e8b |
class string_literal_node exprtk_final
: public expression_node <T>,
|
4068375e |
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;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_stringconst;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return reinterpret_cast<expression_node<T>*>(0);
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return value_;
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return value_.data();
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return value_.size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return rp_;
}
private:
|
a65c8e8b |
string_literal_node(const string_literal_node<T>&) exprtk_delete;
string_literal_node<T>& operator=(const string_literal_node<T>&) exprtk_delete;
|
4068375e |
const std::string value_;
range_t rp_;
};
#endif
template <typename T>
class unary_node : public expression_node<T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
|
a65c8e8b |
unary_node(const operator_type& opr, expression_ptr branch)
|
4068375e |
: operation_(opr)
{
|
a65c8e8b |
construct_branch_pair(branch_,branch);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
const T arg = branch_.first->value();
return numeric::process<T>(operation_,arg);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_unary;
}
|
a65c8e8b |
inline operator_type operation()
|
4068375e |
{
return operation_;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
inline void release()
{
branch_.second = false;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
protected:
operator_type operation_;
branch_t branch_;
};
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_[0].first);
assert(branch_[1].first);
|
4068375e |
const T arg0 = branch_[0].first->value();
const T arg1 = branch_[1].first->value();
return numeric::process<T>(operation_,arg0,arg1);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_binary;
}
inline operator_type operation()
{
return operation_;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
|
4068375e |
{
if (0 == index)
return branch_[0].first;
else if (1 == index)
return branch_[1].first;
else
return reinterpret_cast<expression_ptr>(0);
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
}
protected:
operator_type operation_;
branch_t branch_[2];
};
template <typename T, typename Operation>
|
a65c8e8b |
class binary_ext_node exprtk_final : public expression_node<T>
|
4068375e |
{
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_[0].first);
assert(branch_[1].first);
|
4068375e |
const T arg0 = branch_[0].first->value();
const T arg1 = branch_[1].first->value();
return Operation::process(arg0,arg1);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_binary_ext;
}
inline operator_type operation()
{
return Operation::operation();
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
|
4068375e |
{
if (0 == index)
return branch_[0].first;
else if (1 == index)
return branch_[1].first;
else
return reinterpret_cast<expression_ptr>(0);
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
}
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_[0].first);
assert(branch_[1].first);
assert(branch_[2].first);
|
4068375e |
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 : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
return std::numeric_limits<T>::quiet_NaN();
}
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_trinary;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::template compute_node_depth<3>(branch_);
}
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_quaternary;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::template compute_node_depth<4>(branch_);
}
protected:
operator_type operation_;
branch_t branch_[4];
};
template <typename T>
|
a65c8e8b |
class conditional_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
|
a65c8e8b |
conditional_node(expression_ptr condition,
|
4068375e |
expression_ptr consequent,
expression_ptr alternative)
{
|
a65c8e8b |
construct_branch_pair(condition_ , condition );
|
4068375e |
construct_branch_pair(consequent_ , consequent );
construct_branch_pair(alternative_, alternative);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(condition_ .first);
assert(consequent_ .first);
assert(alternative_.first);
if (is_true(condition_))
|
4068375e |
return consequent_.first->value();
else
return alternative_.first->value();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_conditional;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
expression_node<T>::ndb_t::collect(consequent_ , node_delete_list);
expression_node<T>::ndb_t::collect(alternative_ , node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
return expression_node<T>::ndb_t::compute_node_depth
(condition_, consequent_, alternative_);
|
4068375e |
}
private:
|
a65c8e8b |
branch_t condition_;
|
4068375e |
branch_t consequent_;
branch_t alternative_;
};
template <typename T>
|
a65c8e8b |
class cons_conditional_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
// Consequent only conditional statement node
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
|
a65c8e8b |
cons_conditional_node(expression_ptr condition,
|
4068375e |
expression_ptr consequent)
{
|
a65c8e8b |
construct_branch_pair(condition_ , condition );
|
4068375e |
construct_branch_pair(consequent_, consequent);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(condition_ .first);
assert(consequent_.first);
if (is_true(condition_))
|
4068375e |
return consequent_.first->value();
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_conditional;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
expression_node<T>::ndb_t::collect(consequent_ , node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
return expression_node<T>::ndb_t::
compute_node_depth(condition_, consequent_);
|
4068375e |
}
private:
|
a65c8e8b |
branch_t condition_;
|
4068375e |
branch_t consequent_;
};
#ifndef exprtk_disable_break_continue
template <typename T>
class break_exception
{
public:
|
a65c8e8b |
explicit break_exception(const T& v)
|
4068375e |
: value(v)
{}
T value;
};
|
a65c8e8b |
class continue_exception {};
|
4068375e |
template <typename T>
|
a65c8e8b |
class break_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
break_node(expression_ptr ret = expression_ptr(0))
{
construct_branch_pair(return_, ret);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
const T result = return_.first ?
return_.first->value() :
std::numeric_limits<T>::quiet_NaN();
throw break_exception<T>(result);
|
4068375e |
#ifndef _MSC_VER
return std::numeric_limits<T>::quiet_NaN();
#endif
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_break;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(return_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(return_);
}
private:
branch_t return_;
};
template <typename T>
|
a65c8e8b |
class continue_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
throw continue_exception();
#ifndef _MSC_VER
return std::numeric_limits<T>::quiet_NaN();
#endif
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_break;
}
};
#endif
struct loop_runtime_checker
{
|
a65c8e8b |
loop_runtime_checker(loop_runtime_check_ptr loop_runtime_check,
|
4068375e |
loop_runtime_check::loop_types lp_typ = loop_runtime_check::e_invalid)
|
a65c8e8b |
: iteration_count_(0)
, loop_runtime_check_(loop_runtime_check)
, max_loop_iterations_(loop_runtime_check_->max_loop_iterations)
, loop_type_(lp_typ)
{
assert(loop_runtime_check_);
}
|
4068375e |
inline void reset(const _uint64_t initial_value = 0) const
{
iteration_count_ = initial_value;
}
inline bool check() const
{
if (
(0 == loop_runtime_check_) ||
|
a65c8e8b |
(++iteration_count_ <= max_loop_iterations_)
|
4068375e |
)
{
return true;
}
loop_runtime_check::violation_context ctxt;
|
a65c8e8b |
ctxt.loop = loop_type_;
|
4068375e |
ctxt.violation = loop_runtime_check::e_iteration_count;
loop_runtime_check_->handle_runtime_violation(ctxt);
return false;
}
mutable _uint64_t iteration_count_;
mutable loop_runtime_check_ptr loop_runtime_check_;
|
a65c8e8b |
const details::_uint64_t& max_loop_iterations_;
loop_runtime_check::loop_types loop_type_;
|
4068375e |
};
template <typename T>
|
a65c8e8b |
class while_loop_node : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
while_loop_node(expression_ptr condition,
|
a65c8e8b |
expression_ptr loop_body)
|
4068375e |
{
construct_branch_pair(condition_, condition);
construct_branch_pair(loop_body_, loop_body);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(condition_.first);
assert(loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
|
a65c8e8b |
while (is_true(condition_))
|
4068375e |
{
result = loop_body_.first->value();
}
return result;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_while;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_);
}
|
a65c8e8b |
protected:
|
4068375e |
branch_t condition_;
branch_t loop_body_;
};
template <typename T>
|
a65c8e8b |
class while_loop_rtc_node exprtk_final
: public while_loop_node<T>
, public loop_runtime_checker
{
public:
typedef while_loop_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
while_loop_rtc_node(expression_ptr condition,
expression_ptr loop_body,
loop_runtime_check_ptr loop_rt_chk)
: parent_t(condition, loop_body)
, loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop)
{}
inline T value() const exprtk_override
{
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
T result = T(0);
loop_runtime_checker::reset();
while (is_true(parent_t::condition_) && loop_runtime_checker::check())
{
result = parent_t::loop_body_.first->value();
}
return result;
}
};
template <typename T>
class repeat_until_loop_node : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
repeat_until_loop_node(expression_ptr condition,
|
a65c8e8b |
expression_ptr loop_body)
|
4068375e |
{
construct_branch_pair(condition_, condition);
construct_branch_pair(loop_body_, loop_body);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(condition_.first);
assert(loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
do
{
result = loop_body_.first->value();
}
|
a65c8e8b |
while (is_false(condition_.first));
|
4068375e |
return result;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_repeat;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_);
}
|
a65c8e8b |
protected:
|
4068375e |
branch_t condition_;
branch_t loop_body_;
};
template <typename T>
|
a65c8e8b |
class repeat_until_loop_rtc_node exprtk_final
: public repeat_until_loop_node<T>
, public loop_runtime_checker
{
public:
typedef repeat_until_loop_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
repeat_until_loop_rtc_node(expression_ptr condition,
expression_ptr loop_body,
loop_runtime_check_ptr loop_rt_chk)
: parent_t(condition, loop_body)
, loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop)
{}
inline T value() const exprtk_override
{
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
T result = T(0);
loop_runtime_checker::reset(1);
do
{
result = parent_t::loop_body_.first->value();
}
while (is_false(parent_t::condition_.first) && loop_runtime_checker::check());
return result;
}
};
template <typename T>
class for_loop_node : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
for_loop_node(expression_ptr initialiser,
expression_ptr condition,
expression_ptr incrementor,
|
a65c8e8b |
expression_ptr loop_body)
|
4068375e |
{
construct_branch_pair(initialiser_, initialiser);
construct_branch_pair(condition_ , condition );
construct_branch_pair(incrementor_, incrementor);
construct_branch_pair(loop_body_ , loop_body );
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(condition_.first);
assert(loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
if (initialiser_.first)
initialiser_.first->value();
if (incrementor_.first)
{
|
a65c8e8b |
while (is_true(condition_))
|
4068375e |
{
result = loop_body_.first->value();
incrementor_.first->value();
}
}
else
{
|
a65c8e8b |
while (is_true(condition_))
|
4068375e |
{
result = loop_body_.first->value();
}
}
return result;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_for;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(initialiser_ , node_delete_list);
expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
expression_node<T>::ndb_t::collect(incrementor_ , node_delete_list);
expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth
(initialiser_, condition_, incrementor_, loop_body_);
}
|
a65c8e8b |
protected:
|
4068375e |
branch_t initialiser_;
branch_t condition_ ;
branch_t incrementor_;
branch_t loop_body_ ;
};
template <typename T>
|
a65c8e8b |
class for_loop_rtc_node exprtk_final
: public for_loop_node<T>
, public loop_runtime_checker
|
4068375e |
{
public:
|
a65c8e8b |
typedef for_loop_node<T> parent_t;
|
4068375e |
typedef expression_node<T>* expression_ptr;
|
a65c8e8b |
for_loop_rtc_node(expression_ptr initialiser,
expression_ptr condition,
expression_ptr incrementor,
expression_ptr loop_body,
loop_runtime_check_ptr loop_rt_chk)
: parent_t(initialiser, condition, incrementor, loop_body)
, loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop)
{}
|
4068375e |
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
|
4068375e |
T result = T(0);
loop_runtime_checker::reset();
|
a65c8e8b |
if (parent_t::initialiser_.first)
parent_t::initialiser_.first->value();
if (parent_t::incrementor_.first)
{
while (is_true(parent_t::condition_) && loop_runtime_checker::check())
{
result = parent_t::loop_body_.first->value();
parent_t::incrementor_.first->value();
}
}
else
{
while (is_true(parent_t::condition_) && loop_runtime_checker::check())
{
result = parent_t::loop_body_.first->value();
}
}
return result;
}
};
#ifndef exprtk_disable_break_continue
template <typename T>
class while_loop_bc_node : public while_loop_node<T>
{
public:
typedef while_loop_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
while_loop_bc_node(expression_ptr condition,
expression_ptr loop_body)
: parent_t(condition, loop_body)
{}
inline T value() const exprtk_override
{
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
T result = T(0);
while (is_true(parent_t::condition_))
|
4068375e |
{
try
{
|
a65c8e8b |
result = parent_t::loop_body_.first->value();
|
4068375e |
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
}
return result;
}
|
a65c8e8b |
};
|
4068375e |
|
a65c8e8b |
template <typename T>
class while_loop_bc_rtc_node exprtk_final
: public while_loop_bc_node<T>
, public loop_runtime_checker
{
public:
|
4068375e |
|
a65c8e8b |
typedef while_loop_bc_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
|
4068375e |
|
a65c8e8b |
while_loop_bc_rtc_node(expression_ptr condition,
expression_ptr loop_body,
loop_runtime_check_ptr loop_rt_chk)
: parent_t(condition, loop_body)
, loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop)
{}
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
|
a65c8e8b |
loop_runtime_checker::reset();
while (is_true(parent_t::condition_) && loop_runtime_checker::check())
{
try
{
result = parent_t::loop_body_.first->value();
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
}
return result;
}
|
4068375e |
};
template <typename T>
|
a65c8e8b |
class repeat_until_loop_bc_node : public repeat_until_loop_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef repeat_until_loop_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
|
4068375e |
repeat_until_loop_bc_node(expression_ptr condition,
|
a65c8e8b |
expression_ptr loop_body)
: parent_t(condition, loop_body)
{}
|
4068375e |
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
do
{
try
{
|
a65c8e8b |
result = parent_t::loop_body_.first->value();
|
4068375e |
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
}
|
a65c8e8b |
while (is_false(parent_t::condition_.first));
|
4068375e |
return result;
}
|
a65c8e8b |
};
|
4068375e |
|
a65c8e8b |
template <typename T>
class repeat_until_loop_bc_rtc_node exprtk_final
: public repeat_until_loop_bc_node<T>,
public loop_runtime_checker
{
public:
|
4068375e |
|
a65c8e8b |
typedef repeat_until_loop_bc_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
|
4068375e |
|
a65c8e8b |
repeat_until_loop_bc_rtc_node(expression_ptr condition,
expression_ptr loop_body,
loop_runtime_check_ptr loop_rt_chk)
: parent_t(condition, loop_body)
, loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop)
{}
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
|
a65c8e8b |
loop_runtime_checker::reset();
do
{
try
{
result = parent_t::loop_body_.first->value();
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
}
while (is_false(parent_t::condition_.first) && loop_runtime_checker::check());
return result;
}
|
4068375e |
};
template <typename T>
|
a65c8e8b |
class for_loop_bc_node : public for_loop_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef for_loop_node<T> parent_t;
|
4068375e |
typedef expression_node<T>* expression_ptr;
for_loop_bc_node(expression_ptr initialiser,
expression_ptr condition,
expression_ptr incrementor,
|
a65c8e8b |
expression_ptr loop_body)
: parent_t(initialiser, condition, incrementor, loop_body)
{}
|
4068375e |
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
|
4068375e |
T result = T(0);
|
a65c8e8b |
if (parent_t::initialiser_.first)
parent_t::initialiser_.first->value();
|
4068375e |
|
a65c8e8b |
if (parent_t::incrementor_.first)
|
4068375e |
{
|
a65c8e8b |
while (is_true(parent_t::condition_))
|
4068375e |
{
try
{
|
a65c8e8b |
result = parent_t::loop_body_.first->value();
|
4068375e |
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
|
a65c8e8b |
parent_t::incrementor_.first->value();
|
4068375e |
}
}
else
{
|
a65c8e8b |
while (is_true(parent_t::condition_))
|
4068375e |
{
try
{
|
a65c8e8b |
result = parent_t::loop_body_.first->value();
|
4068375e |
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
}
}
return result;
}
|
a65c8e8b |
};
|
4068375e |
|
a65c8e8b |
template <typename T>
class for_loop_bc_rtc_node exprtk_final
: public for_loop_bc_node<T>
, public loop_runtime_checker
{
public:
|
4068375e |
|
a65c8e8b |
typedef for_loop_bc_node<T> parent_t;
typedef expression_node<T>* expression_ptr;
for_loop_bc_rtc_node(expression_ptr initialiser,
expression_ptr condition,
expression_ptr incrementor,
expression_ptr loop_body,
loop_runtime_check_ptr loop_rt_chk)
: parent_t(initialiser, condition, incrementor, loop_body)
, loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop)
{}
|
4068375e |
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(parent_t::condition_.first);
assert(parent_t::loop_body_.first);
|
4068375e |
|
a65c8e8b |
T result = T(0);
|
4068375e |
|
a65c8e8b |
loop_runtime_checker::reset();
if (parent_t::initialiser_.first)
parent_t::initialiser_.first->value();
if (parent_t::incrementor_.first)
{
while (is_true(parent_t::condition_) && loop_runtime_checker::check())
{
try
{
result = parent_t::loop_body_.first->value();
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
parent_t::incrementor_.first->value();
}
}
else
{
while (is_true(parent_t::condition_) && loop_runtime_checker::check())
{
try
{
result = parent_t::loop_body_.first->value();
}
catch(const break_exception<T>& e)
{
return e.value;
}
catch(const continue_exception&)
{}
}
}
return result;
}
|
4068375e |
};
#endif
template <typename T>
class switch_node : public expression_node<T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
template <typename Allocator,
template <typename, typename> class Sequence>
explicit switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
{
if (1 != (arg_list.size() & 1))
return;
arg_list_.resize(arg_list.size());
for (std::size_t i = 0; i < arg_list.size(); ++i)
{
if (arg_list[i])
{
construct_branch_pair(arg_list_[i], arg_list[i]);
}
else
{
arg_list_.clear();
return;
}
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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 ].first;
expression_ptr consequent = arg_list_[i + 1].first;
if (is_true(condition))
{
return consequent->value();
}
}
return arg_list_[upper_bound].first->value();
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::e_switch;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(arg_list_);
}
protected:
std::vector<branch_t> arg_list_;
};
template <typename T, typename Switch_N>
|
a65c8e8b |
class switch_n_node exprtk_final : public switch_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
template <typename Allocator,
template <typename, typename> class Sequence>
explicit switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
: switch_node<T>(arg_list)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Switch_N::process(switch_node<T>::arg_list_);
}
};
template <typename T>
|
a65c8e8b |
class multi_switch_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
template <typename Allocator,
template <typename, typename> class Sequence>
explicit multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
{
if (0 != (arg_list.size() & 1))
return;
arg_list_.resize(arg_list.size());
for (std::size_t i = 0; i < arg_list.size(); ++i)
{
if (arg_list[i])
{
construct_branch_pair(arg_list_[i], arg_list[i]);
}
else
{
arg_list_.clear();
return;
}
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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 ].first;
expression_ptr consequent = arg_list_[i + 1].first;
if (is_true(condition))
{
result = consequent->value();
}
}
return result;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_mswitch;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(arg_list_);
}
private:
std::vector<branch_t> arg_list_;
};
template <typename T>
class ivariable
{
public:
|
a65c8e8b |
virtual ~ivariable() {}
|
4068375e |
virtual T& ref() = 0;
virtual const T& ref() const = 0;
};
template <typename T>
|
a65c8e8b |
class variable_node exprtk_final
: public expression_node<T>,
|
4068375e |
public ivariable <T>
{
public:
static T null_value;
explicit variable_node()
: value_(&null_value)
{}
explicit variable_node(T& v)
: value_(&v)
{}
inline bool operator <(const variable_node<T>& v) const
{
return this < (&v);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return (*value_);
}
|
a65c8e8b |
inline T& ref() exprtk_override
|
4068375e |
{
return (*value_);
}
|
a65c8e8b |
inline const T& ref() const exprtk_override
|
4068375e |
{
return (*value_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_variable;
}
private:
T* 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()
|
a65c8e8b |
: 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))
|
4068375e |
{}
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)
)
{
destroy_node(n0_e.second);
}
}
if (n1_e.first && n1_e.second)
{
n1_e.first = false;
if (
!is_variable_node(n1_e.second) &&
!is_string_node (n1_e.second)
)
{
destroy_node(n1_e.second);
}
}
}
|
a65c8e8b |
bool const_range() const
|
4068375e |
{
return ( n0_c.first && n1_c.first) &&
(!n0_e.first && !n1_e.first);
}
|
a65c8e8b |
bool var_range() const
|
4068375e |
{
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)
{
|
a65c8e8b |
r0 = static_cast<std::size_t>(details::numeric::to_int64(n0_e.second->value()));
|
4068375e |
}
else
return false;
if (n1_c.first)
r1 = n1_c.second;
else if (n1_e.first)
{
|
a65c8e8b |
r1 = static_cast<std::size_t>(details::numeric::to_int64(n1_e.second->value()));
|
4068375e |
}
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;
|
a65c8e8b |
#ifndef exprtk_enable_range_runtime_checks
|
4068375e |
return (r0 <= r1);
|
a65c8e8b |
#else
return range_runtime_check(r0, r1, size);
#endif
|
4068375e |
}
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;
|
a65c8e8b |
#ifdef exprtk_enable_range_runtime_checks
bool range_runtime_check(const std::size_t r0,
const std::size_t r1,
const std::size_t size) const
{
if (r0 >= size)
{
throw std::runtime_error("range error: (r0 < 0) || (r0 >= size)");
return false;
}
if (r1 >= size)
{
throw std::runtime_error("range error: (r1 < 0) || (r1 >= size)");
return false;
}
return (r0 <= r1);
}
#endif
|
4068375e |
};
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()
|
a65c8e8b |
: range(0)
, data (0)
, size (0)
, type_size(0)
, str_node (0)
|
4068375e |
{}
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;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
|
a65c8e8b |
virtual ~vector_interface() {}
|
4068375e |
virtual std::size_t size () const = 0;
virtual vector_node_ptr vec() const = 0;
virtual vector_node_ptr vec() = 0;
virtual vds_t& vds () = 0;
virtual const vds_t& vds () const = 0;
virtual bool side_effect () const { return false; }
};
template <typename T>
|
a65c8e8b |
class vector_node exprtk_final
: public expression_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
|
4068375e |
typedef vector_holder<T> vector_holder_t;
typedef vector_node<T>* vector_node_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
explicit vector_node(vector_holder_t* vh)
|
a65c8e8b |
: vector_holder_(vh)
, vds_((*vector_holder_).size(),(*vector_holder_)[0])
|
4068375e |
{
vector_holder_->set_ref(&vds_.ref());
}
vector_node(const vds_t& vds, vector_holder_t* vh)
|
a65c8e8b |
: vector_holder_(vh)
, vds_(vds)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return vds().data()[0];
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return const_cast<vector_node_ptr>(this);
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return this;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vector;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
inline vector_holder_t& vec_holder()
{
return (*vector_holder_);
}
private:
vector_holder_t* vector_holder_;
vds_t vds_;
};
template <typename T>
|
a65c8e8b |
class vector_elem_node exprtk_final
: public expression_node<T>,
|
4068375e |
public ivariable <T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef vector_holder<T> vector_holder_t;
typedef vector_holder_t* vector_holder_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
vector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
|
a65c8e8b |
: vec_holder_(vec_holder)
, vector_base_((*vec_holder)[0])
|
4068375e |
{
construct_branch_pair(index_, index);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
}
|
a65c8e8b |
inline T& ref() exprtk_override
|
4068375e |
{
return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
}
|
a65c8e8b |
inline const T& ref() const exprtk_override
|
4068375e |
{
return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecelem;
}
inline vector_holder_t& vec_holder()
{
return (*vec_holder_);
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(index_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(index_);
}
private:
vector_holder_ptr vec_holder_;
T* vector_base_;
branch_t index_;
};
template <typename T>
|
a65c8e8b |
class rebasevector_elem_node exprtk_final
: public expression_node<T>,
|
4068375e |
public ivariable <T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef vector_holder<T> vector_holder_t;
typedef vector_holder_t* vector_holder_ptr;
typedef vec_data_store<T> vds_t;
typedef std::pair<expression_ptr,bool> branch_t;
rebasevector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
|
a65c8e8b |
: vector_holder_(vec_holder)
, vds_((*vector_holder_).size(),(*vector_holder_)[0])
|
4068375e |
{
vector_holder_->set_ref(&vds_.ref());
construct_branch_pair(index_, index);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
}
|
a65c8e8b |
inline T& ref() exprtk_override
|
4068375e |
{
return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
}
|
a65c8e8b |
inline const T& ref() const exprtk_override
|
4068375e |
{
return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_rbvecelem;
}
inline vector_holder_t& vec_holder()
{
return (*vector_holder_);
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(index_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(index_);
}
private:
vector_holder_ptr vector_holder_;
vds_t vds_;
branch_t index_;
};
template <typename T>
|
a65c8e8b |
class rebasevector_celem_node exprtk_final
: public expression_node<T>,
|
4068375e |
public ivariable <T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef vector_holder<T> vector_holder_t;
typedef vector_holder_t* vector_holder_ptr;
typedef vec_data_store<T> vds_t;
rebasevector_celem_node(const std::size_t index, vector_holder_ptr vec_holder)
|
a65c8e8b |
: index_(index)
, vector_holder_(vec_holder)
, vds_((*vector_holder_).size(),(*vector_holder_)[0])
|
4068375e |
{
vector_holder_->set_ref(&vds_.ref());
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return *(vds_.data() + index_);
}
|
a65c8e8b |
inline T& ref() exprtk_override
|
4068375e |
{
return *(vds_.data() + index_);
}
|
a65c8e8b |
inline const T& ref() const exprtk_override
|
4068375e |
{
return *(vds_.data() + index_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_rbveccelem;
}
inline vector_holder_t& vec_holder()
{
return (*vector_holder_);
}
private:
const std::size_t index_;
vector_holder_ptr vector_holder_;
vds_t vds_;
};
template <typename T>
|
a65c8e8b |
class vector_assignment_node exprtk_final : public expression_node<T>
|
4068375e |
{
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)
|
a65c8e8b |
: vector_base_(vector_base)
, initialiser_list_(initialiser_list)
, size_(size)
, single_value_initialse_(single_value_initialse)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (single_value_initialse_)
{
for (std::size_t i = 0; i < size_; ++i)
{
*(vector_base_ + i) = initialiser_list_[0]->value();
}
}
else
{
|
a65c8e8b |
const std::size_t initialiser_list_size = initialiser_list_.size();
|
4068375e |
|
a65c8e8b |
for (std::size_t i = 0; i < initialiser_list_size; ++i)
|
4068375e |
{
*(vector_base_ + i) = initialiser_list_[i]->value();
}
|
a65c8e8b |
if (initialiser_list_size < size_)
|
4068375e |
{
|
a65c8e8b |
for (std::size_t i = initialiser_list_size; i < size_; ++i)
|
4068375e |
{
*(vector_base_ + i) = T(0);
}
}
}
return *(vector_base_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecdefass;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
}
private:
|
a65c8e8b |
vector_assignment_node(const vector_assignment_node<T>&) exprtk_delete;
vector_assignment_node<T>& operator=(const vector_assignment_node<T>&) exprtk_delete;
|
4068375e |
mutable T* vector_base_;
std::vector<expression_ptr> initialiser_list_;
const std::size_t size_;
const bool single_value_initialse_;
};
template <typename T>
|
a65c8e8b |
class swap_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef variable_node<T>* variable_node_ptr;
swap_node(variable_node_ptr var0, variable_node_ptr var1)
|
a65c8e8b |
: var0_(var0)
, var1_(var1)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
std::swap(var0_->ref(),var1_->ref());
return var1_->ref();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_swap;
}
private:
variable_node_ptr var0_;
variable_node_ptr var1_;
};
template <typename T>
|
a65c8e8b |
class swap_generic_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
|
a65c8e8b |
typedef ivariable<T>* ivariable_ptr;
|
4068375e |
swap_generic_node(expression_ptr var0, expression_ptr var1)
|
a65c8e8b |
: binary_node<T>(details::e_swap, var0, var1)
, var0_(dynamic_cast<ivariable_ptr>(var0))
, var1_(dynamic_cast<ivariable_ptr>(var1))
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
std::swap(var0_->ref(),var1_->ref());
return var1_->ref();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_swap;
}
private:
ivariable_ptr var0_;
ivariable_ptr var1_;
};
template <typename T>
|
a65c8e8b |
class swap_vecvec_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
typedef vector_node <T>* vector_node_ptr;
typedef vec_data_store <T> vds_t;
|
4068375e |
swap_vecvec_node(expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(details::e_swap, branch0, branch1)
, vec0_node_ptr_(0)
, vec1_node_ptr_(0)
, vec_size_ (0)
, initialised_ (false)
|
4068375e |
{
if (is_ivector_node(binary_node<T>::branch_[0].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
{
vec0_node_ptr_ = vi->vec();
vds() = vi->vds();
}
}
if (is_ivector_node(binary_node<T>::branch_[1].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (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_->vds().size(),
vec1_node_ptr_->vds().size());
initialised_ = true;
}
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
binary_node<T>::branch_[0].first->value();
binary_node<T>::branch_[1].first->value();
T* vec0 = vec0_node_ptr_->vds().data();
T* vec1 = vec1_node_ptr_->vds().data();
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();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return vec0_node_ptr_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return vec0_node_ptr_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecvecswap;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vec_size_;
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node<T>* vec0_node_ptr_;
vector_node<T>* vec1_node_ptr_;
std::size_t vec_size_;
bool initialised_;
vds_t vds_;
};
#ifndef exprtk_disable_string_capabilities
template <typename T>
|
a65c8e8b |
class stringvar_node exprtk_final
: public expression_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
|
4068375e |
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
rp_.n1_c.second = (*value_).size() - 1;
rp_.cache.second = rp_.n1_c.second;
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return ref();
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return &(*value_)[0];
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return ref().size();
}
std::string& ref()
{
return (*value_);
}
const std::string& ref() const
{
return (*value_);
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_stringvar;
}
|
a65c8e8b |
void rebase(std::string& s)
{
value_ = &s;
rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
rp_.n1_c = std::make_pair<bool,std::size_t>(true,value_->size() - 1);
rp_.cache.first = rp_.n0_c.second;
rp_.cache.second = rp_.n1_c.second;
}
|
4068375e |
private:
std::string* value_;
mutable range_t rp_;
};
template <typename T>
std::string stringvar_node<T>::null_value = std::string("");
template <typename T>
|
a65c8e8b |
class string_range_node exprtk_final
: public expression_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
|
4068375e |
static std::string null_value;
explicit string_range_node(std::string& v, const range_t& rp)
|
a65c8e8b |
: value_(&v)
, rp_(rp)
|
4068375e |
{}
virtual ~string_range_node()
{
rp_.free();
}
inline bool operator <(const string_range_node<T>& v) const
{
return this < (&v);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline std::string str() const exprtk_override
|
4068375e |
{
return (*value_);
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return &(*value_)[0];
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
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_);
}
|
a65c8e8b |
inline range_t& range_ref() exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
inline const range_t& range_ref() const exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
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>
|
a65c8e8b |
class const_string_range_node exprtk_final
: public expression_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
|
4068375e |
explicit const_string_range_node(const std::string& v, const range_t& rp)
|
a65c8e8b |
: value_(v)
, rp_(rp)
|
4068375e |
{}
~const_string_range_node()
{
rp_.free();
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return value_;
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return value_.data();
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return value_.size();
}
range_t range() const
{
return rp_;
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return rp_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_cstringvarrng;
}
private:
|
a65c8e8b |
const_string_range_node(const const_string_range_node<T>&) exprtk_delete;
const_string_range_node<T>& operator=(const const_string_range_node<T>&) exprtk_delete;
|
4068375e |
const std::string value_;
range_t rp_;
};
template <typename T>
|
a65c8e8b |
class generic_string_range_node exprtk_final
: public expression_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef expression_node <T>* expression_ptr;
typedef stringvar_node <T>* strvar_node_ptr;
typedef string_base_node<T>* str_base_ptr;
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface<T> irange_t;
typedef irange_t* irange_ptr;
|
4068375e |
typedef std::pair<expression_ptr,bool> branch_t;
generic_string_range_node(expression_ptr str_branch, const range_t& brange)
|
a65c8e8b |
: initialised_(false)
, str_base_ptr_ (0)
, str_range_ptr_(0)
, base_range_(brange)
|
4068375e |
{
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;
construct_branch_pair(branch_, str_branch);
if (is_generally_string_node(branch_.first))
{
str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
if (0 == str_base_ptr_)
return;
str_range_ptr_ = dynamic_cast<irange_ptr>(branch_.first);
if (0 == str_range_ptr_)
return;
}
initialised_ = (str_base_ptr_ && str_range_ptr_);
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
~generic_string_range_node()
{
base_range_.free();
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
branch_.first->value();
std::size_t str_r0 = 0;
std::size_t str_r1 = 0;
std::size_t r0 = 0;
std::size_t r1 = 0;
|
a65c8e8b |
const range_t& range = str_range_ptr_->range_ref();
|
4068375e |
const std::size_t base_str_size = str_base_ptr_->size();
if (
range (str_r0, str_r1, base_str_size) &&
|
a65c8e8b |
base_range_( r0, r1, base_str_size - str_r0)
|
4068375e |
)
{
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();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return value_;
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return &value_[0];
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return value_.size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strgenrange;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
bool initialised_;
|
a65c8e8b |
branch_t branch_;
str_base_ptr str_base_ptr_;
irange_ptr str_range_ptr_;
mutable range_t base_range_;
mutable range_t range_;
mutable std::string value_;
|
4068375e |
};
template <typename T>
|
a65c8e8b |
class string_concat_node exprtk_final
: public binary_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_interface<T> irange_t;
typedef irange_t* irange_ptr;
typedef range_t* range_ptr;
typedef expression_node <T>* expression_ptr;
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
string_concat_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, initialised_(false)
, str0_base_ptr_ (0)
, str1_base_ptr_ (0)
, str0_range_ptr_(0)
, str1_range_ptr_(0)
|
4068375e |
{
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_ ;
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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;
|
a65c8e8b |
const range_t& range0 = str0_range_ptr_->range_ref();
const range_t& range1 = str1_range_ptr_->range_ref();
|
4068375e |
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();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return value_;
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return &value_[0];
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return value_.size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strconcat;
}
private:
|
a65c8e8b |
bool initialised_;
str_base_ptr str0_base_ptr_;
str_base_ptr str1_base_ptr_;
irange_ptr str0_range_ptr_;
irange_ptr str1_range_ptr_;
|
4068375e |
mutable range_t range_;
mutable std::string value_;
};
template <typename T>
|
a65c8e8b |
class swap_string_node exprtk_final
: public binary_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface<T> irange_t;
typedef irange_t* irange_ptr;
typedef expression_node <T>* expression_ptr;
|
4068375e |
typedef stringvar_node <T>* strvar_node_ptr;
|
a65c8e8b |
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
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_);
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->str();
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->base();
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return str0_node_ptr_->range_ref();
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->range_ref();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strswap;
}
private:
bool initialised_;
strvar_node_ptr str0_node_ptr_;
strvar_node_ptr str1_node_ptr_;
};
template <typename T>
|
a65c8e8b |
class swap_genstrings_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface<T> irange_t;
typedef irange_t* irange_ptr;
|
4068375e |
typedef expression_node <T>* expression_ptr;
|
a65c8e8b |
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
swap_genstrings_node(expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(details::e_default, branch0, branch1)
, str0_base_ptr_ (0)
, str1_base_ptr_ (0)
, str0_range_ptr_(0)
, str1_range_ptr_(0)
, initialised_(false)
|
4068375e |
{
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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
if (0 == range)
return;
str0_range_ptr_ = &(range->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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
if (0 == range)
return;
str1_range_ptr_ = &(range->range_ref());
}
initialised_ = str0_base_ptr_ &&
str1_base_ptr_ &&
str0_range_ptr_ &&
str1_range_ptr_ ;
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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;
|
a65c8e8b |
const range_t& range0 = (*str0_range_ptr_);
const range_t& range1 = (*str1_range_ptr_);
|
4068375e |
if (
range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
range1(str1_r0, str1_r1, str1_base_ptr_->size())
)
{
const std::size_t size0 = range0.cache_size();
const std::size_t size1 = range1.cache_size();
const std::size_t max_size = std::min(size0,size1);
char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
loop_unroll::details lud(max_size);
char_cptr upper_bound = s0 + lud.upper_bound;
while (s0 < upper_bound)
{
#define exprtk_loop(N) \
std::swap(s0[N], s1[N]); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
s0 += lud.batch_size;
s1 += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : { std::swap(s0[i], s1[i]); ++i; } \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
}
}
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strswap;
}
private:
|
a65c8e8b |
swap_genstrings_node(const swap_genstrings_node<T>&) exprtk_delete;
swap_genstrings_node<T>& operator=(const swap_genstrings_node<T>&) exprtk_delete;
|
4068375e |
str_base_ptr str0_base_ptr_;
str_base_ptr str1_base_ptr_;
range_ptr str0_range_ptr_;
range_ptr str1_range_ptr_;
bool initialised_;
};
template <typename T>
|
a65c8e8b |
class stringvar_size_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
static std::string null_value;
explicit stringvar_size_node()
: value_(&null_value)
{}
explicit stringvar_size_node(std::string& v)
: value_(&v)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return T((*value_).size());
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
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>
|
a65c8e8b |
class string_size_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node <T>* expression_ptr;
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
typedef std::pair<expression_ptr,bool> branch_t;
explicit string_size_node(expression_ptr branch)
: str_base_ptr_(0)
{
construct_branch_pair(branch_, branch);
if (is_generally_string_node(branch_.first))
{
str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
if (0 == str_base_ptr_)
return;
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
T result = std::numeric_limits<T>::quiet_NaN();
if (str_base_ptr_)
{
branch_.first->value();
result = T(str_base_ptr_->size());
}
return result;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_stringsize;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
branch_t branch_;
str_base_ptr str_base_ptr_;
};
struct asn_assignment
{
static inline void execute(std::string& s, char_cptr data, const std::size_t size)
{ s.assign(data,size); }
};
struct asn_addassignment
{
static inline void execute(std::string& s, char_cptr data, const std::size_t size)
{ s.append(data,size); }
};
template <typename T, typename AssignmentProcess = asn_assignment>
|
a65c8e8b |
class assignment_string_node exprtk_final
: public binary_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface <T> irange_t;
typedef irange_t* irange_ptr;
typedef expression_node <T>* expression_ptr;
|
4068375e |
typedef stringvar_node <T>* strvar_node_ptr;
|
a65c8e8b |
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
assignment_string_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, initialised_(false)
, str0_base_ptr_ (0)
, str1_base_ptr_ (0)
, str0_node_ptr_ (0)
, str1_range_ptr_(0)
|
4068375e |
{
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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
if (0 == range)
return;
str1_range_ptr_ = &(range->range_ref());
}
initialised_ = str0_base_ptr_ &&
str1_base_ptr_ &&
str0_node_ptr_ &&
str1_range_ptr_ ;
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
binary_node<T>::branch_[1].first->value();
std::size_t r0 = 0;
std::size_t r1 = 0;
|
a65c8e8b |
const range_t& range = (*str1_range_ptr_);
|
4068375e |
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();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->str();
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->base();
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return str0_node_ptr_->range_ref();
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return str0_node_ptr_->range_ref();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
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>
|
a65c8e8b |
class assignment_string_range_node exprtk_final
: public binary_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface <T> irange_t;
typedef irange_t* irange_ptr;
typedef expression_node <T>* expression_ptr;
typedef stringvar_node <T>* strvar_node_ptr;
|
4068375e |
typedef string_range_node<T>* str_rng_node_ptr;
|
a65c8e8b |
typedef string_base_node <T>* str_base_ptr;
|
4068375e |
assignment_string_range_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, initialised_(false)
, str0_base_ptr_ (0)
, str1_base_ptr_ (0)
, str0_rng_node_ptr_(0)
, str0_range_ptr_ (0)
, str1_range_ptr_ (0)
|
4068375e |
{
if (is_string_range_node(binary_node<T>::branch_[0].first))
{
str0_rng_node_ptr_ = static_cast<str_rng_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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
if (0 == range)
return;
str0_range_ptr_ = &(range->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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
if (0 == range)
return;
str1_range_ptr_ = &(range->range_ref());
}
initialised_ = str0_base_ptr_ &&
str1_base_ptr_ &&
str0_rng_node_ptr_ &&
str0_range_ptr_ &&
str1_range_ptr_ ;
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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;
|
a65c8e8b |
const range_t& range0 = (*str0_range_ptr_);
const range_t& range1 = (*str1_range_ptr_);
|
4068375e |
if (
range0(s0_r0, s0_r1, str0_base_ptr_->size()) &&
range1(s1_r0, s1_r1, str1_base_ptr_->size())
)
{
const 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_ptr>(base() + s0_r0));
}
}
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return str0_base_ptr_->str();
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return str0_base_ptr_->base();
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return str0_base_ptr_->size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return str0_rng_node_ptr_->range_ref();
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return str0_rng_node_ptr_->range_ref();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strass;
}
private:
bool initialised_;
str_base_ptr str0_base_ptr_;
str_base_ptr str1_base_ptr_;
str_rng_node_ptr str0_rng_node_ptr_;
range_ptr str0_range_ptr_;
range_ptr str1_range_ptr_;
};
template <typename T>
|
a65c8e8b |
class conditional_string_node exprtk_final
: public trinary_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface <T> irange_t;
typedef irange_t* irange_ptr;
|
4068375e |
typedef expression_node <T>* expression_ptr;
|
a65c8e8b |
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
|
a65c8e8b |
conditional_string_node(expression_ptr condition,
|
4068375e |
expression_ptr consequent,
expression_ptr alternative)
|
a65c8e8b |
: trinary_node<T>(details::e_default, consequent, alternative, condition)
, initialised_(false)
, str0_base_ptr_ (0)
, str1_base_ptr_ (0)
, str0_range_ptr_(0)
, str1_range_ptr_(0)
, condition_ (condition )
, consequent_ (consequent )
, alternative_(alternative)
|
4068375e |
{
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_ ;
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(condition_ );
assert(consequent_ );
assert(alternative_);
|
4068375e |
std::size_t r0 = 0;
std::size_t r1 = 0;
|
a65c8e8b |
if (is_true(condition_))
|
4068375e |
{
consequent_->value();
|
a65c8e8b |
const range_t& range = str0_range_ptr_->range_ref();
|
4068375e |
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();
|
a65c8e8b |
const range_t& range = str1_range_ptr_->range_ref();
|
4068375e |
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();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return value_;
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return &value_[0];
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return value_.size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
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_;
|
a65c8e8b |
expression_ptr condition_;
|
4068375e |
expression_ptr consequent_;
expression_ptr alternative_;
};
template <typename T>
|
a65c8e8b |
class cons_conditional_str_node exprtk_final
: public binary_node <T>,
|
4068375e |
public string_base_node<T>,
public range_interface <T>
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface <T> irange_t;
typedef irange_t* irange_ptr;
|
4068375e |
typedef expression_node <T>* expression_ptr;
|
a65c8e8b |
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
|
a65c8e8b |
cons_conditional_str_node(expression_ptr condition,
|
4068375e |
expression_ptr consequent)
|
a65c8e8b |
: binary_node<T>(details::e_default, consequent, condition)
, initialised_(false)
, str0_base_ptr_ (0)
, str0_range_ptr_(0)
, condition_ (condition )
, consequent_(consequent)
|
4068375e |
{
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_ ;
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(condition_ );
assert(consequent_);
if (is_true(condition_))
|
4068375e |
{
consequent_->value();
|
a65c8e8b |
const range_t& range = str0_range_ptr_->range_ref();
|
4068375e |
std::size_t r0 = 0;
std::size_t r1 = 0;
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_;
}
char_cptr base() const
{
return &value_[0];
}
std::size_t size() const
{
return value_.size();
}
range_t& range_ref()
{
return range_;
}
const range_t& range_ref() const
{
return range_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
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_;
|
a65c8e8b |
expression_ptr condition_;
|
4068375e |
expression_ptr consequent_;
};
template <typename T, typename VarArgFunction>
|
a65c8e8b |
class str_vararg_node exprtk_final
: public expression_node <T>,
public string_base_node<T>,
public range_interface <T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
typedef range_t* range_ptr;
typedef range_interface <T> irange_t;
typedef irange_t* irange_ptr;
typedef expression_node <T>* expression_ptr;
typedef string_base_node<T>* str_base_ptr;
|
4068375e |
typedef std::pair<expression_ptr,bool> branch_t;
template <typename Allocator,
template <typename, typename> class Sequence>
explicit str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
|
a65c8e8b |
: initialised_(false)
, str_base_ptr_ (0)
, str_range_ptr_(0)
|
4068375e |
{
construct_branch_pair(final_node_, const_cast<expression_ptr>(arg_list.back()));
if (0 == final_node_.first)
return;
else if (!is_generally_string_node(final_node_.first))
return;
str_base_ptr_ = dynamic_cast<str_base_ptr>(final_node_.first);
if (0 == str_base_ptr_)
return;
str_range_ptr_ = dynamic_cast<irange_ptr>(final_node_.first);
if (0 == str_range_ptr_)
return;
initialised_ = str_base_ptr_ && str_range_ptr_;
if (arg_list.size() > 1)
{
const std::size_t arg_list_size = arg_list.size() - 1;
arg_list_.resize(arg_list_size);
for (std::size_t i = 0; i < arg_list_size; ++i)
{
if (arg_list[i])
{
construct_branch_pair(arg_list_[i], arg_list[i]);
}
else
{
arg_list_.clear();
return;
}
}
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (!arg_list_.empty())
{
VarArgFunction::process(arg_list_);
}
final_node_.first->value();
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return str_base_ptr_->str();
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return str_base_ptr_->base();
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return str_base_ptr_->size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return str_range_ptr_->range_ref();
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return str_range_ptr_->range_ref();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_stringvararg;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
|
a65c8e8b |
expression_node<T>::ndb_t::collect(final_node_ , node_delete_list);
expression_node<T>::ndb_t::collect(arg_list_ , node_delete_list);
|
4068375e |
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return std::max(
expression_node<T>::ndb_t::compute_node_depth(final_node_),
expression_node<T>::ndb_t::compute_node_depth(arg_list_ ));
}
private:
bool initialised_;
branch_t final_node_;
str_base_ptr str_base_ptr_;
irange_ptr str_range_ptr_;
std::vector<branch_t> arg_list_;
};
#endif
template <typename T, std::size_t N>
|
a65c8e8b |
inline T axn(const T a, const T x)
|
4068375e |
{
// a*x^n
return a * exprtk::details::numeric::fast_exp<T,N>::result(x);
}
template <typename T, std::size_t N>
|
a65c8e8b |
inline T axnb(const T a, const T x, const T b)
|
4068375e |
{
// 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;
|
a65c8e8b |
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;
|
4068375e |
};
|
a65c8e8b |
#define define_sfop3(NN, OP0, OP1) \
|
4068375e |
template <typename T> \
struct sf##NN##_op : public sf_base<T> \
{ \
typedef typename sf_base<T>::Type const 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,"")
|
a65c8e8b |
#define define_sfop4(NN, OP0, OP1) \
|
4068375e |
template <typename T> \
struct sf##NN##_op : public sf_base<T> \
{ \
typedef typename sf_base<T>::Type const 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)")
define_sfop4(ext60,((x / y) + (z * w)),"(t/t)+(t*t)")
define_sfop4(ext61,(((x * y) * z) / w),"((t*t)*t)/t")
#undef define_sfop3
#undef define_sfop4
template <typename T, typename SpecialFunction>
|
a65c8e8b |
class sf3_node exprtk_final : public trinary_node<T>
|
4068375e |
{
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)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(trinary_node<T>::branch_[0].first);
assert(trinary_node<T>::branch_[1].first);
assert(trinary_node<T>::branch_[2].first);
|
4068375e |
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>
|
a65c8e8b |
class sf4_node exprtk_final : public quaternary_node<T>
|
4068375e |
{
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)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(quaternary_node<T>::branch_[0].first);
assert(quaternary_node<T>::branch_[1].first);
assert(quaternary_node<T>::branch_[2].first);
assert(quaternary_node<T>::branch_[3].first);
|
4068375e |
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>
|
a65c8e8b |
class sf3_var_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
sf3_var_node(const T& v0, const T& v1, const T& v2)
|
a65c8e8b |
: v0_(v0)
, v1_(v1)
, v2_(v2)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return SpecialFunction::process(v0_, v1_, v2_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_trinary;
}
private:
|
a65c8e8b |
sf3_var_node(const sf3_var_node<T,SpecialFunction>&) exprtk_delete;
sf3_var_node<T,SpecialFunction>& operator=(const sf3_var_node<T,SpecialFunction>&) exprtk_delete;
|
4068375e |
const T& v0_;
const T& v1_;
const T& v2_;
};
template <typename T, typename SpecialFunction>
|
a65c8e8b |
class sf4_var_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
|
a65c8e8b |
: v0_(v0)
, v1_(v1)
, v2_(v2)
, v3_(v3)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return SpecialFunction::process(v0_, v1_, v2_, v3_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_trinary;
}
private:
|
a65c8e8b |
sf4_var_node(const sf4_var_node<T,SpecialFunction>&) exprtk_delete;
sf4_var_node<T,SpecialFunction>& operator=(const sf4_var_node<T,SpecialFunction>&) exprtk_delete;
|
4068375e |
const T& v0_;
const T& v1_;
const T& v2_;
const T& v3_;
};
template <typename T, typename VarArgFunction>
|
a65c8e8b |
class vararg_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
template <typename Allocator,
template <typename, typename> class Sequence>
explicit vararg_node(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])
{
construct_branch_pair(arg_list_[i],arg_list[i]);
}
else
{
arg_list_.clear();
return;
}
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return VarArgFunction::process(arg_list_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vararg;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(arg_list_);
}
private:
std::vector<branch_t> arg_list_;
};
template <typename T, typename VarArgFunction>
|
a65c8e8b |
class vararg_varnode exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
template <typename Allocator,
template <typename, typename> class Sequence>
explicit 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;
}
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (!arg_list_.empty())
return VarArgFunction::process(arg_list_);
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vararg;
}
private:
std::vector<const T*> arg_list_;
};
template <typename T, typename VecFunction>
|
a65c8e8b |
class vectorize_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
explicit vectorize_node(const expression_ptr v)
: ivec_ptr_(0)
{
construct_branch_pair(v_, v);
if (is_ivector_node(v_.first))
{
ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v_.first);
}
else
ivec_ptr_ = 0;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (ivec_ptr_)
{
|
a65c8e8b |
assert(v_.first);
|
4068375e |
v_.first->value();
|
a65c8e8b |
|
4068375e |
return VecFunction::process(ivec_ptr_);
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecfunc;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(v_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(v_);
}
private:
vector_interface<T>* ivec_ptr_;
branch_t v_;
};
template <typename T>
|
a65c8e8b |
class assignment_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, var_node_ptr_(0)
|
4068375e |
{
if (is_variable_node(binary_node<T>::branch_[0].first))
{
var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (var_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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>
|
a65c8e8b |
class assignment_vec_elem_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_vec_elem_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
|
4068375e |
{
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);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (vec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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>
|
a65c8e8b |
class assignment_rebasevec_elem_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_rebasevec_elem_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
|
4068375e |
{
if (is_rebasevector_elem_node(binary_node<T>::branch_[0].first))
{
rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(binary_node<T>::branch_[0].first);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (rbvec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
T& result = rbvec_node_ptr_->ref();
result = binary_node<T>::branch_[1].first->value();
return result;
}
else
return std::numeric_limits<T>::quiet_NaN();
}
private:
rebasevector_elem_node<T>* rbvec_node_ptr_;
};
template <typename T>
|
a65c8e8b |
class assignment_rebasevec_celem_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_rebasevec_celem_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
|
4068375e |
{
if (is_rebasevector_celem_node(binary_node<T>::branch_[0].first))
{
rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(binary_node<T>::branch_[0].first);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (rbvec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
T& result = rbvec_node_ptr_->ref();
result = binary_node<T>::branch_[1].first->value();
return result;
}
else
return std::numeric_limits<T>::quiet_NaN();
}
private:
rebasevector_celem_node<T>* rbvec_node_ptr_;
};
template <typename T>
|
a65c8e8b |
class assignment_vec_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
|
a65c8e8b |
typedef vector_node<T>* vector_node_ptr;
typedef vec_data_store<T> vds_t;
|
4068375e |
assignment_vec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
|
4068375e |
{
if (is_vector_node(binary_node<T>::branch_[0].first))
{
vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
vds() = vec_node_ptr_->vds();
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (vec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
const T v = binary_node<T>::branch_[1].first->value();
T* vec = vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec + lud.upper_bound;
while (vec < upper_bound)
{
#define exprtk_loop(N) \
vec[N] = v; \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec += lud.batch_size;
}
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : *vec++ = v; \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return vec_node_ptr_->value();
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return vec_node_ptr_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return vec_node_ptr_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecvalass;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node<T>* vec_node_ptr_;
vds_t vds_;
};
template <typename T>
|
a65c8e8b |
class assignment_vecvec_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
|
4068375e |
typedef vector_node<T>* vector_node_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
assignment_vecvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec0_node_ptr_(0)
, vec1_node_ptr_(0)
, initialised_(false)
, src_is_ivec_(false)
|
4068375e |
{
if (is_vector_node(binary_node<T>::branch_[0].first))
{
vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
vds() = vec0_node_ptr_->vds();
}
if (is_vector_node(binary_node<T>::branch_[1].first))
{
vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
vds_t::match_sizes(vds(),vec1_node_ptr_->vds());
}
else if (is_ivector_node(binary_node<T>::branch_[1].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
{
vec1_node_ptr_ = vi->vec();
if (!vi->side_effect())
{
vi->vds() = vds();
src_is_ivec_ = true;
}
else
vds_t::match_sizes(vds(),vi->vds());
}
}
initialised_ = (vec0_node_ptr_ && vec1_node_ptr_);
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
binary_node<T>::branch_[1].first->value();
if (src_is_ivec_)
return vec0_node_ptr_->value();
T* vec0 = vec0_node_ptr_->vds().data();
T* vec1 = vec1_node_ptr_->vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec0 + lud.upper_bound;
while (vec0 < upper_bound)
{
#define exprtk_loop(N) \
vec0[N] = vec1[N]; \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec0 += lud.batch_size;
vec1 += lud.batch_size;
}
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : *vec0++ = *vec1++; \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return vec0_node_ptr_->value();
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return vec0_node_ptr_;
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return vec0_node_ptr_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecvecass;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node<T>* vec0_node_ptr_;
vector_node<T>* vec1_node_ptr_;
bool initialised_;
bool src_is_ivec_;
vds_t vds_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class assignment_op_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, var_node_ptr_(0)
|
4068375e |
{
if (is_variable_node(binary_node<T>::branch_[0].first))
{
var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (var_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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>
|
a65c8e8b |
class assignment_vec_elem_op_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_vec_elem_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
|
4068375e |
{
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);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (vec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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>
|
a65c8e8b |
class assignment_rebasevec_elem_op_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_rebasevec_elem_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
|
4068375e |
{
if (is_rebasevector_elem_node(binary_node<T>::branch_[0].first))
{
rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(binary_node<T>::branch_[0].first);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (rbvec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
T& v = rbvec_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:
rebasevector_elem_node<T>* rbvec_node_ptr_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class assignment_rebasevec_celem_op_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
assignment_rebasevec_celem_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
|
4068375e |
{
if (is_rebasevector_celem_node(binary_node<T>::branch_[0].first))
{
rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(binary_node<T>::branch_[0].first);
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (rbvec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
T& v = rbvec_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:
rebasevector_celem_node<T>* rbvec_node_ptr_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class assignment_vec_op_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
|
4068375e |
typedef vector_node<T>* vector_node_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
assignment_vec_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
|
4068375e |
{
if (is_vector_node(binary_node<T>::branch_[0].first))
{
vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
vds() = vec_node_ptr_->vds();
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (vec_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[1].first);
|
4068375e |
const T v = binary_node<T>::branch_[1].first->value();
T* vec = vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec + lud.upper_bound;
while (vec < upper_bound)
{
#define exprtk_loop(N) \
Operation::assign(vec[N],v); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec += lud.batch_size;
}
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : Operation::assign(*vec++,v); \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return vec_node_ptr_->value();
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return vec_node_ptr_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return vec_node_ptr_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecopvalass;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
bool side_effect() const exprtk_override
|
4068375e |
{
return true;
}
private:
vector_node<T>* vec_node_ptr_;
vds_t vds_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class assignment_vecvec_op_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
|
4068375e |
typedef vector_node<T>* vector_node_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
assignment_vecvec_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec0_node_ptr_(0)
, vec1_node_ptr_(0)
, initialised_(false)
|
4068375e |
{
if (is_vector_node(binary_node<T>::branch_[0].first))
{
vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
vds() = vec0_node_ptr_->vds();
}
if (is_vector_node(binary_node<T>::branch_[1].first))
{
vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
vec1_node_ptr_->vds() = vds();
}
else if (is_ivector_node(binary_node<T>::branch_[1].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
{
vec1_node_ptr_ = vi->vec();
vec1_node_ptr_->vds() = vds();
}
else
vds_t::match_sizes(vds(),vec1_node_ptr_->vds());
}
initialised_ = (vec0_node_ptr_ && vec1_node_ptr_);
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
binary_node<T>::branch_[0].first->value();
binary_node<T>::branch_[1].first->value();
T* vec0 = vec0_node_ptr_->vds().data();
const T* vec1 = vec1_node_ptr_->vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec0 + lud.upper_bound;
while (vec0 < upper_bound)
{
#define exprtk_loop(N) \
vec0[N] = Operation::process(vec0[N], vec1[N]); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec0 += lud.batch_size;
vec1 += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return vec0_node_ptr_->value();
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return vec0_node_ptr_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return vec0_node_ptr_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecopvecass;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
bool side_effect() const exprtk_override
|
4068375e |
{
return true;
}
private:
vector_node<T>* vec0_node_ptr_;
vector_node<T>* vec1_node_ptr_;
bool initialised_;
vds_t vds_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class vec_binop_vecvec_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
|
4068375e |
typedef vector_holder<T>* vector_holder_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
vec_binop_vecvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec0_node_ptr_(0)
, vec1_node_ptr_(0)
, temp_ (0)
, temp_vec_node_(0)
, initialised_(false)
|
4068375e |
{
bool v0_is_ivec = false;
bool v1_is_ivec = false;
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 (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
{
vec0_node_ptr_ = vi->vec();
v0_is_ivec = true;
}
}
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 (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
{
vec1_node_ptr_ = vi->vec();
v1_is_ivec = true;
}
}
if (vec0_node_ptr_ && vec1_node_ptr_)
{
vector_holder<T>& vec0 = vec0_node_ptr_->vec_holder();
vector_holder<T>& vec1 = vec1_node_ptr_->vec_holder();
if (v0_is_ivec && (vec0.size() <= vec1.size()))
vds_ = vds_t(vec0_node_ptr_->vds());
else if (v1_is_ivec && (vec1.size() <= vec0.size()))
vds_ = vds_t(vec1_node_ptr_->vds());
else
vds_ = vds_t(std::min(vec0.size(),vec1.size()));
temp_ = new vector_holder<T>(vds().data(),vds().size());
|
a65c8e8b |
temp_vec_node_ = new vector_node <T>(vds(),temp_);
|
4068375e |
initialised_ = true;
}
|
a65c8e8b |
assert(initialised_);
|
4068375e |
}
~vec_binop_vecvec_node()
{
delete temp_;
delete temp_vec_node_;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (initialised_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
binary_node<T>::branch_[0].first->value();
binary_node<T>::branch_[1].first->value();
const T* vec0 = vec0_node_ptr_->vds().data();
const T* vec1 = vec1_node_ptr_->vds().data();
T* vec2 = vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec2 + lud.upper_bound;
while (vec2 < upper_bound)
{
#define exprtk_loop(N) \
vec2[N] = Operation::process(vec0[N], vec1[N]); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec0 += lud.batch_size;
vec1 += lud.batch_size;
vec2 += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return (vds().data())[0];
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecvecarith;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds_.size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node_ptr vec0_node_ptr_;
vector_node_ptr vec1_node_ptr_;
vector_holder_ptr temp_;
vector_node_ptr temp_vec_node_;
bool initialised_;
vds_t vds_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class vec_binop_vecval_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
|
4068375e |
typedef vector_holder<T>* vector_holder_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
vec_binop_vecval_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec0_node_ptr_(0)
, temp_ (0)
, temp_vec_node_(0)
|
4068375e |
{
bool v0_is_ivec = false;
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 (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
{
vec0_node_ptr_ = vi->vec();
v0_is_ivec = true;
}
}
if (vec0_node_ptr_)
{
if (v0_is_ivec)
vds() = vec0_node_ptr_->vds();
else
vds() = vds_t(vec0_node_ptr_->size());
temp_ = new vector_holder<T>(vds());
|
a65c8e8b |
temp_vec_node_ = new vector_node <T>(vds(),temp_);
|
4068375e |
}
}
~vec_binop_vecval_node()
{
delete temp_;
delete temp_vec_node_;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (vec0_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
binary_node<T>::branch_[0].first->value();
const T v = binary_node<T>::branch_[1].first->value();
const T* vec0 = vec0_node_ptr_->vds().data();
T* vec1 = vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec0 + lud.upper_bound;
while (vec0 < upper_bound)
{
#define exprtk_loop(N) \
vec1[N] = Operation::process(vec0[N], v); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec0 += lud.batch_size;
vec1 += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return (vds().data())[0];
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecvalarith;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node_ptr vec0_node_ptr_;
vector_holder_ptr temp_;
vector_node_ptr temp_vec_node_;
vds_t vds_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class vec_binop_valvec_node exprtk_final
: public binary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
|
4068375e |
typedef vector_holder<T>* vector_holder_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
vec_binop_valvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, vec1_node_ptr_(0)
, temp_ (0)
, temp_vec_node_(0)
|
4068375e |
{
bool v1_is_ivec = false;
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 (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
{
vec1_node_ptr_ = vi->vec();
v1_is_ivec = true;
}
}
if (vec1_node_ptr_)
{
if (v1_is_ivec)
vds() = vec1_node_ptr_->vds();
else
vds() = vds_t(vec1_node_ptr_->size());
temp_ = new vector_holder<T>(vds());
|
a65c8e8b |
temp_vec_node_ = new vector_node <T>(vds(),temp_);
|
4068375e |
}
}
~vec_binop_valvec_node()
{
delete temp_;
delete temp_vec_node_;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (vec1_node_ptr_)
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
const T v = binary_node<T>::branch_[0].first->value();
binary_node<T>::branch_[1].first->value();
T* vec0 = vds().data();
const T* vec1 = vec1_node_ptr_->vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec0 + lud.upper_bound;
while (vec0 < upper_bound)
{
#define exprtk_loop(N) \
vec0[N] = Operation::process(v, vec1[N]); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec0 += lud.batch_size;
vec1 += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return (vds().data())[0];
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecvalarith;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node_ptr vec1_node_ptr_;
vector_holder_ptr temp_;
vector_node_ptr temp_vec_node_;
vds_t vds_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class unary_vector_node exprtk_final
: public unary_node <T>
, public vector_interface<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
|
4068375e |
typedef vector_holder<T>* vector_holder_ptr;
|
a65c8e8b |
typedef vec_data_store<T> vds_t;
|
4068375e |
unary_vector_node(const operator_type& opr, expression_ptr branch0)
|
a65c8e8b |
: unary_node<T>(opr, branch0)
, vec0_node_ptr_(0)
, temp_ (0)
, temp_vec_node_(0)
|
4068375e |
{
bool vec0_is_ivec = false;
if (is_vector_node(unary_node<T>::branch_.first))
{
vec0_node_ptr_ = static_cast<vector_node_ptr>(unary_node<T>::branch_.first);
}
else if (is_ivector_node(unary_node<T>::branch_.first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_.first)))
{
vec0_node_ptr_ = vi->vec();
vec0_is_ivec = true;
}
}
if (vec0_node_ptr_)
{
if (vec0_is_ivec)
vds_ = vec0_node_ptr_->vds();
else
vds_ = vds_t(vec0_node_ptr_->size());
temp_ = new vector_holder<T>(vds());
|
a65c8e8b |
temp_vec_node_ = new vector_node <T>(vds(),temp_);
|
4068375e |
}
}
~unary_vector_node()
{
delete temp_;
delete temp_vec_node_;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(unary_node<T>::branch_.first);
|
4068375e |
unary_node<T>::branch_.first->value();
if (vec0_node_ptr_)
{
const T* vec0 = vec0_node_ptr_->vds().data();
T* vec1 = vds().data();
loop_unroll::details lud(size());
const T* upper_bound = vec0 + lud.upper_bound;
while (vec0 < upper_bound)
{
#define exprtk_loop(N) \
vec1[N] = Operation::process(vec0[N]); \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec0 += lud.batch_size;
vec1 += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return (vds().data())[0];
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
vector_node_ptr vec() const exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
vector_node_ptr vec() exprtk_override
|
4068375e |
{
return temp_vec_node_;
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vecunaryop;
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return vds().size();
}
|
a65c8e8b |
vds_t& vds() exprtk_override
|
4068375e |
{
return vds_;
}
|
a65c8e8b |
const vds_t& vds() const exprtk_override
|
4068375e |
{
return vds_;
}
private:
vector_node_ptr vec0_node_ptr_;
vector_holder_ptr temp_;
vector_node_ptr temp_vec_node_;
vds_t vds_;
};
template <typename T>
|
a65c8e8b |
class conditional_vector_node exprtk_final
: public expression_node <T>
, public vector_interface<T>
{
public:
typedef expression_node <T>* expression_ptr;
typedef vector_interface<T>* vec_interface_ptr;
typedef vector_node <T>* vector_node_ptr;
typedef vector_holder <T>* vector_holder_ptr;
typedef vec_data_store <T> vds_t;
typedef std::pair<expression_ptr,bool> branch_t;
conditional_vector_node(expression_ptr condition,
expression_ptr consequent,
expression_ptr alternative)
: consequent_node_ptr_ (0)
, alternative_node_ptr_(0)
, temp_vec_node_ (0)
, temp_ (0)
, vec_size_ (0)
, initialised_ (false)
{
construct_branch_pair(condition_ , condition );
construct_branch_pair(consequent_ , consequent );
construct_branch_pair(alternative_, alternative);
if (details::is_ivector_node(consequent_.first))
{
vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(consequent_.first);
if (0 != ivec_ptr)
{
consequent_node_ptr_ = ivec_ptr->vec();
}
}
if (details::is_ivector_node(alternative_.first))
{
vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(alternative_.first);
if (0 != ivec_ptr)
{
alternative_node_ptr_ = ivec_ptr->vec();
}
}
if (consequent_node_ptr_ && alternative_node_ptr_)
{
vec_size_ = std::min(consequent_node_ptr_ ->vds().size(),
alternative_node_ptr_->vds().size());
vds_ = vds_t(vec_size_);
temp_ = new vector_holder<T>(vds_);
temp_vec_node_ = new vector_node <T>(vds(),temp_);
initialised_ = true;
}
assert(initialised_ && (vec_size_ > 0));
}
~conditional_vector_node()
{
delete temp_;
delete temp_vec_node_;
}
inline T value() const exprtk_override
{
if (initialised_)
{
assert(condition_ .first);
assert(consequent_ .first);
assert(alternative_.first);
T result = T(0);
T* source_vector = 0;
T* result_vector = vds().data();
if (is_true(condition_))
{
result = consequent_.first->value();
source_vector = consequent_node_ptr_->vds().data();
}
else
{
result = alternative_.first->value();
source_vector = alternative_node_ptr_->vds().data();
}
for (std::size_t i = 0; i < vec_size_; ++i)
{
result_vector[i] = source_vector[i];
}
return result;
}
return std::numeric_limits<T>::quiet_NaN();
}
vector_node_ptr vec() const exprtk_override
{
return temp_vec_node_;
}
vector_node_ptr vec() exprtk_override
{
return temp_vec_node_;
}
inline typename expression_node<T>::node_type type() const exprtk_override
{
return expression_node<T>::e_vecondition;
}
std::size_t size() const exprtk_override
{
return vec_size_;
}
vds_t& vds() exprtk_override
{
return vds_;
}
const vds_t& vds() const exprtk_override
{
return vds_;
}
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
{
expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
expression_node<T>::ndb_t::collect(consequent_ , node_delete_list);
expression_node<T>::ndb_t::collect(alternative_ , node_delete_list);
}
std::size_t node_depth() const exprtk_override
{
return expression_node<T>::ndb_t::compute_node_depth
(condition_, consequent_, alternative_);
}
private:
branch_t condition_;
branch_t consequent_;
branch_t alternative_;
vector_node_ptr consequent_node_ptr_;
vector_node_ptr alternative_node_ptr_;
vector_node_ptr temp_vec_node_;
vector_holder_ptr temp_;
vds_t vds_;
std::size_t vec_size_;
bool initialised_;
};
template <typename T>
class scand_node exprtk_final : public binary_node<T>
|
4068375e |
{
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)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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>
|
a65c8e8b |
class scor_node exprtk_final : public binary_node<T>
|
4068375e |
{
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)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(binary_node<T>::branch_[0].first);
assert(binary_node<T>::branch_[1].first);
|
4068375e |
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>
|
a65c8e8b |
class function_N_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
// Function of N paramters.
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr,bool> branch_t;
typedef IFunction ifunction;
explicit function_N_node(ifunction* func)
|
a65c8e8b |
: function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
, parameter_count_(func->param_count)
|
4068375e |
{}
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
// 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
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
{
return expression_node<T>::e_function;
}
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
std::size_t node_depth() const exprtk_override
{
return expression_node<T>::ndb_t::template compute_node_depth<N>(branch_);
}
|
4068375e |
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])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,17>
{
static inline T_ execute(ifunction& f, T_ (&v)[17])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,16>
{
static inline T_ execute(ifunction& f, T_ (&v)[16])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,15>
{
static inline T_ execute(ifunction& f, T_ (&v)[15])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,14>
{
static inline T_ execute(ifunction& f, T_ (&v)[14])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,13>
{
static inline T_ execute(ifunction& f, T_ (&v)[13])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,12>
{
static inline T_ execute(ifunction& f, T_ (&v)[12])
|
a65c8e8b |
{ 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]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,11>
{
static inline T_ execute(ifunction& f, T_ (&v)[11])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,10>
{
static inline T_ execute(ifunction& f, T_ (&v)[10])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,9>
{
static inline T_ execute(ifunction& f, T_ (&v)[9])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,8>
{
static inline T_ execute(ifunction& f, T_ (&v)[8])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,7>
{
static inline T_ execute(ifunction& f, T_ (&v)[7])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,6>
{
static inline T_ execute(ifunction& f, T_ (&v)[6])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4], v[5]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,5>
{
static inline T_ execute(ifunction& f, T_ (&v)[5])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3], v[4]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,4>
{
static inline T_ execute(ifunction& f, T_ (&v)[4])
|
a65c8e8b |
{ return f(v[0], v[1], v[2], v[3]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,3>
{
static inline T_ execute(ifunction& f, T_ (&v)[3])
|
a65c8e8b |
{ return f(v[0], v[1], v[2]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,2>
{
static inline T_ execute(ifunction& f, T_ (&v)[2])
|
a65c8e8b |
{ return f(v[0], v[1]); }
|
4068375e |
};
template <typename T_>
struct invoke<T_,1>
{
static inline T_ execute(ifunction& f, T_ (&v)[1])
{ return f(v[0]); }
};
private:
ifunction* function_;
std::size_t parameter_count_;
branch_t branch_[N];
};
template <typename T, typename IFunction>
|
a65c8e8b |
class function_N_node<T,IFunction,0> exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef IFunction ifunction;
explicit 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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (function_)
return (*function_)();
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_function;
}
private:
ifunction* function_;
};
template <typename T, typename VarArgFunction>
|
a65c8e8b |
class vararg_function_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
vararg_function_node(VarArgFunction* func,
const std::vector<expression_ptr>& arg_list)
|
a65c8e8b |
: function_(func)
, arg_list_(arg_list)
|
4068375e |
{
value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
}
inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
{
return this < (&fn);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (function_)
{
populate_value_list();
return (*function_)(value_list_);
}
else
return std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_vafunction;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
for (std::size_t i = 0; i < arg_list_.size(); ++i)
{
if (arg_list_[i] && !details::is_variable_node(arg_list_[i]))
{
node_delete_list.push_back(&arg_list_[i]);
}
}
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(arg_list_);
}
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:
|
a65c8e8b |
typedef type_store<T> type_store_t;
typedef expression_node<T>* expression_ptr;
typedef variable_node<T> variable_node_t;
typedef vector_node<T> vector_node_t;
typedef variable_node_t* variable_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 typename range_interface<T>::range_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;
|
4068375e |
explicit generic_function_node(const std::vector<expression_ptr>& arg_list,
|
a65c8e8b |
GenericFunction* func = reinterpret_cast<GenericFunction*>(0))
: function_(func)
, arg_list_(arg_list)
|
4068375e |
{}
|
a65c8e8b |
virtual ~generic_function_node() {}
|
4068375e |
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(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());
|
a65c8e8b |
branch_ .resize(arg_list_.size(),branch_t(reinterpret_cast<expression_ptr>(0),false));
|
4068375e |
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->vds().data();
ts.type = type_store_t::e_vector;
vi->vec()->vec_holder().set_ref(&ts.vec_data);
}
#ifndef exprtk_disable_string_capabilities
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_ptr>(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;
|
a65c8e8b |
const range_t& rp = ri->range_ref();
|
4068375e |
if (
rp.const_range() &&
is_const_string_range_node(arg_list_[i])
)
{
ts.size = rp.const_size();
ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second;
range_list_[i].range = reinterpret_cast<range_t*>(0);
}
else
range_list_[i].range = &(ri->range_ref());
}
#endif
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
{
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
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)
{
|
a65c8e8b |
const range_t& rp = (*rdt.range);
std::size_t r0 = 0;
std::size_t r1 = 0;
|
4068375e |
|
a65c8e8b |
if (rp(r0, r1, rdt.size))
|
4068375e |
{
type_store_t& ts = typestore_list_[i];
ts.size = rp.cache_size();
#ifndef exprtk_disable_string_capabilities
if (ts.type == type_store_t::e_string)
ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
else
#endif
ts.data = static_cast<char_ptr>(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_;
};
#ifndef exprtk_disable_string_capabilities
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;
|
a65c8e8b |
typedef typename range_interface<T>::range_t range_t;
|
4068375e |
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);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (gen_function_t::function_)
{
if (gen_function_t::populate_value_list())
{
typedef typename StringFunction::parameter_list_t parameter_list_t;
const 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 std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strfunction;
}
|
a65c8e8b |
std::string str() const exprtk_override
|
4068375e |
{
return ret_string_;
}
|
a65c8e8b |
char_cptr base() const exprtk_override
|
4068375e |
{
return &ret_string_[0];
}
|
a65c8e8b |
std::size_t size() const exprtk_override
|
4068375e |
{
return ret_string_.size();
}
|
a65c8e8b |
range_t& range_ref() exprtk_override
|
4068375e |
{
return range_;
}
|
a65c8e8b |
const range_t& range_ref() const exprtk_override
|
4068375e |
{
return range_;
}
protected:
mutable range_t range_;
mutable std::string ret_string_;
};
#endif
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;
|
a65c8e8b |
typedef typename gen_function_t::range_t range_t;
|
4068375e |
multimode_genfunction_node(GenericFunction* func,
const std::size_t& param_seq_index,
const std::vector<typename gen_function_t::expression_ptr>& arg_list)
|
a65c8e8b |
: gen_function_t(arg_list,func)
, param_seq_index_(param_seq_index)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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 std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final
|
4068375e |
{
return expression_node<T>::e_genfunction;
}
private:
std::size_t param_seq_index_;
};
#ifndef exprtk_disable_string_capabilities
template <typename T, typename StringFunction>
|
a65c8e8b |
class multimode_strfunction_node exprtk_final : public string_function_node<T,StringFunction>
|
4068375e |
{
public:
typedef string_function_node<T,StringFunction> str_function_t;
|
a65c8e8b |
typedef typename str_function_t::range_t range_t;
|
4068375e |
multimode_strfunction_node(StringFunction* func,
const std::size_t& param_seq_index,
const std::vector<typename str_function_t::expression_ptr>& arg_list)
|
a65c8e8b |
: str_function_t(func,arg_list)
, param_seq_index_(param_seq_index)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
if (str_function_t::function_)
{
if (str_function_t::populate_value_list())
{
typedef typename StringFunction::parameter_list_t parameter_list_t;
const 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 std::numeric_limits<T>::quiet_NaN();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_strfunction;
}
private:
const std::size_t param_seq_index_;
};
#endif
class return_exception
{};
template <typename T>
class null_igenfunc
{
public:
|
a65c8e8b |
virtual ~null_igenfunc() {}
|
4068375e |
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();
}
};
#ifndef exprtk_disable_return_statement
template <typename T>
|
a65c8e8b |
class return_node exprtk_final : public generic_function_node<T,null_igenfunc<T> >
|
4068375e |
{
public:
|
a65c8e8b |
typedef results_context<T> results_context_t;
typedef null_igenfunc<T> igeneric_function_t;
|
4068375e |
typedef igeneric_function_t* igeneric_function_ptr;
typedef generic_function_node<T,igeneric_function_t> gen_function_t;
return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list,
results_context_t& rc)
|
a65c8e8b |
: gen_function_t (arg_list)
, results_context_(&rc)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_return;
}
private:
results_context_t* results_context_;
};
template <typename T>
|
a65c8e8b |
class return_envelope_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef results_context<T> results_context_t;
typedef std::pair<expression_ptr,bool> branch_t;
return_envelope_node(expression_ptr body, results_context_t& rc)
|
a65c8e8b |
: results_context_(&rc )
, return_invoked_ (false)
|
4068375e |
{
construct_branch_pair(body_, body);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(body_.first);
|
4068375e |
try
{
return_invoked_ = false;
results_context_->clear();
return body_.first->value();
}
catch(const return_exception&)
{
return_invoked_ = true;
return std::numeric_limits<T>::quiet_NaN();
}
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_retenv;
}
inline bool* retinvk_ptr()
{
return &return_invoked_;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(body_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(body_);
}
private:
results_context_t* results_context_;
mutable bool return_invoked_;
branch_t body_;
};
#endif
#define exprtk_define_unary_op(OpName) \
template <typename T> \
struct OpName##_op \
{ \
typedef typename functor_t<T>::Type Type; \
typedef typename expression_node<T>::node_type node_t; \
\
static inline T process(Type v) \
{ \
return numeric:: OpName (v); \
} \
\
static inline node_t 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>::RefType RefType;
|
a65c8e8b |
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;
|
4068375e |
};
template <typename T>
struct add_op : public opr_base<T>
{
typedef typename opr_base<T>::Type Type;
typedef typename opr_base<T>::RefType RefType;
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 void assign(RefType t1, Type t2) { t1 += t2; }
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;
typedef typename opr_base<T>::RefType RefType;
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 void assign(RefType t1, Type t2) { t1 *= t2; }
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;
typedef typename opr_base<T>::RefType RefType;
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 void assign(RefType t1, Type t2) { t1 -= t2; }
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;
typedef typename opr_base<T>::RefType RefType;
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 void assign(RefType t1, Type t2) { t1 /= t2; }
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;
typedef typename opr_base<T>::RefType RefType;
static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
static inline void assign(RefType t1, Type t2) { t1 = 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;
typedef typename opr_base<T>::RefType RefType;
static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
static inline void assign(RefType t1, Type t2) { t1 = 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 equal_op : public opr_base<T>
{
typedef typename opr_base<T>::Type Type;
static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); }
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_equal; }
};
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(std::pair<details::expression_node<T>*,bool> n)
{
return n.first->value();
}
template <typename T>
inline T value(const T* t)
{
return (*t);
}
template <typename T>
inline T value(const 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)
{
const T* vec = v->vec()->vds().data();
const std::size_t vec_size = v->vec()->vds().size();
loop_unroll::details lud(vec_size);
if (vec_size <= static_cast<std::size_t>(lud.batch_size))
{
T result = T(0);
int i = 0;
exprtk_disable_fallthrough_begin
switch (vec_size)
{
#define case_stmt(N) \
case N : result += vec[i++]; \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(16) case_stmt(15)
case_stmt(14) case_stmt(13)
case_stmt(12) case_stmt(11)
case_stmt(10) case_stmt( 9)
case_stmt( 8) case_stmt( 7)
case_stmt( 6) case_stmt( 5)
#endif
case_stmt( 4) case_stmt( 3)
case_stmt( 2) case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef case_stmt
return result;
}
T r[] = {
T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0),
T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0)
};
const T* upper_bound = vec + lud.upper_bound;
while (vec < upper_bound)
{
#define exprtk_loop(N) \
r[N] += vec[N]; \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : r[0] += vec[i++]; \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return (r[ 0] + r[ 1] + r[ 2] + r[ 3])
#ifndef exprtk_disable_superscalar_unroll
+ (r[ 4] + r[ 5] + r[ 6] + r[ 7])
+ (r[ 8] + r[ 9] + r[10] + r[11])
+ (r[12] + r[13] + r[14] + r[15])
#endif
;
}
};
template <typename T>
struct vec_mul_op
{
typedef vector_interface<T>* ivector_ptr;
static inline T process(const ivector_ptr v)
{
const T* vec = v->vec()->vds().data();
const std::size_t vec_size = v->vec()->vds().size();
loop_unroll::details lud(vec_size);
if (vec_size <= static_cast<std::size_t>(lud.batch_size))
{
T result = T(1);
int i = 0;
exprtk_disable_fallthrough_begin
switch (vec_size)
{
#define case_stmt(N) \
case N : result *= vec[i++]; \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(16) case_stmt(15)
case_stmt(14) case_stmt(13)
case_stmt(12) case_stmt(11)
case_stmt(10) case_stmt( 9)
case_stmt( 8) case_stmt( 7)
case_stmt( 6) case_stmt( 5)
#endif
case_stmt( 4) case_stmt( 3)
case_stmt( 2) case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef case_stmt
return result;
}
T r[] = {
T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1),
T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1)
};
const T* upper_bound = vec + lud.upper_bound;
while (vec < upper_bound)
{
#define exprtk_loop(N) \
r[N] *= vec[N]; \
exprtk_loop( 0) exprtk_loop( 1)
exprtk_loop( 2) exprtk_loop( 3)
#ifndef exprtk_disable_superscalar_unroll
exprtk_loop( 4) exprtk_loop( 5)
exprtk_loop( 6) exprtk_loop( 7)
exprtk_loop( 8) exprtk_loop( 9)
exprtk_loop(10) exprtk_loop(11)
exprtk_loop(12) exprtk_loop(13)
exprtk_loop(14) exprtk_loop(15)
#endif
vec += lud.batch_size;
}
int i = 0;
exprtk_disable_fallthrough_begin
switch (lud.remainder)
{
#define case_stmt(N) \
case N : r[0] *= vec[i++]; \
#ifndef exprtk_disable_superscalar_unroll
case_stmt(15) case_stmt(14)
case_stmt(13) case_stmt(12)
case_stmt(11) case_stmt(10)
case_stmt( 9) case_stmt( 8)
case_stmt( 7) case_stmt( 6)
case_stmt( 5) case_stmt( 4)
#endif
case_stmt( 3) case_stmt( 2)
case_stmt( 1)
}
exprtk_disable_fallthrough_end
#undef exprtk_loop
#undef case_stmt
return (r[ 0] * r[ 1] * r[ 2] * r[ 3])
#ifndef exprtk_disable_superscalar_unroll
+ (r[ 4] * r[ 5] * r[ 6] * r[ 7])
+ (r[ 8] * r[ 9] * r[10] * r[11])
+ (r[12] * r[13] * r[14] * r[15])
#endif
;
}
};
template <typename T>
struct vec_avg_op
{
typedef vector_interface<T>* ivector_ptr;
static inline T process(const ivector_ptr v)
{
const std::size_t vec_size = v->vec()->vds().size();
return vec_add_op<T>::process(v) / vec_size;
}
};
template <typename T>
struct vec_min_op
{
typedef vector_interface<T>* ivector_ptr;
static inline T process(const ivector_ptr v)
{
const T* vec = v->vec()->vds().data();
const std::size_t vec_size = v->vec()->vds().size();
T result = vec[0];
for (std::size_t i = 1; i < vec_size; ++i)
{
const 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)
{
const T* vec = v->vec()->vds().data();
const std::size_t vec_size = v->vec()->vds().size();
T result = vec[0];
for (std::size_t i = 1; i < vec_size; ++i)
{
const 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:
|
a65c8e8b |
virtual ~vov_base_node() {}
|
4068375e |
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:
|
a65c8e8b |
virtual ~cov_base_node() {}
|
4068375e |
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:
|
a65c8e8b |
virtual ~voc_base_node() {}
|
4068375e |
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:
|
a65c8e8b |
virtual ~vob_base_node() {}
|
4068375e |
virtual const T& v() const = 0;
};
template <typename T>
class bov_base_node : public expression_node<T>
{
public:
|
a65c8e8b |
virtual ~bov_base_node() {}
|
4068375e |
virtual const T& v() const = 0;
};
template <typename T>
class cob_base_node : public expression_node<T>
{
public:
|
a65c8e8b |
virtual ~cob_base_node() {}
|
4068375e |
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:
|
a65c8e8b |
virtual ~boc_base_node() {}
|
4068375e |
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:
|
a65c8e8b |
virtual ~uv_base_node() {}
|
4068375e |
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:
|
a65c8e8b |
virtual ~sos_base_node() {}
|
4068375e |
inline virtual operator_type operation() const
{
return details::e_default;
}
};
template <typename T>
class sosos_base_node : public expression_node<T>
{
public:
|
a65c8e8b |
virtual ~sosos_base_node() {}
|
4068375e |
inline virtual operator_type operation() const
{
return details::e_default;
}
};
template <typename T>
class T0oT1oT2_base_node : public expression_node<T>
{
public:
|
a65c8e8b |
virtual ~T0oT1oT2_base_node() {}
|
4068375e |
virtual std::string type_id() const = 0;
};
template <typename T>
class T0oT1oT2oT3_base_node : public expression_node<T>
{
public:
|
a65c8e8b |
virtual ~T0oT1oT2oT3_base_node() {}
|
4068375e |
virtual std::string type_id() const = 0;
};
template <typename T, typename Operation>
|
a65c8e8b |
class unary_variable_node exprtk_final : public uv_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
explicit unary_variable_node(const T& var)
: v_(var)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Operation::process(v_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline const T& v() const exprtk_override
|
4068375e |
{
return v_;
}
private:
|
a65c8e8b |
unary_variable_node(const unary_variable_node<T,Operation>&) exprtk_delete;
unary_variable_node<T,Operation>& operator=(const unary_variable_node<T,Operation>&) exprtk_delete;
|
4068375e |
const T& v_;
};
template <typename T>
|
a65c8e8b |
class uvouv_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
// UOpr1(v0) Op UOpr2(v1)
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::bfunc_t bfunc_t;
typedef typename functor_t::ufunc_t ufunc_t;
typedef expression_node<T>* expression_ptr;
|
4068375e |
explicit uvouv_node(const T& var0,const T& var1,
ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
|
a65c8e8b |
: v0_(var0)
, v1_(var1)
, u0_(uf0 )
, u1_(uf1 )
, f_ (bf )
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return f_(u0_(v0_),u1_(v1_));
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_uvouv;
}
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:
|
a65c8e8b |
uvouv_node(const uvouv_node<T>&) exprtk_delete;
uvouv_node<T>& operator=(const uvouv_node<T>&) exprtk_delete;
|
4068375e |
const T& v0_;
const T& v1_;
const ufunc_t u0_;
const ufunc_t u1_;
const bfunc_t f_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class unary_branch_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
|
a65c8e8b |
typedef Operation operation_t;
typedef expression_node<T>* expression_ptr;
|
4068375e |
typedef std::pair<expression_ptr,bool> branch_t;
explicit unary_branch_node(expression_ptr branch)
{
construct_branch_pair(branch_, branch);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Operation::process(branch_.first->value());
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation()
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
inline void release()
{
branch_.second = false;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
|
a65c8e8b |
unary_branch_node(const unary_branch_node<T,Operation>&) exprtk_delete;
unary_branch_node<T,Operation>& operator=(const unary_branch_node<T,Operation>&) exprtk_delete;
|
4068375e |
branch_t branch_;
};
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;
|
a65c8e8b |
typedef typename functor_t::bfunc_t bfunc_t;
|
4068375e |
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;
|
a65c8e8b |
typedef typename functor_t::bfunc_t bfunc_t;
|
4068375e |
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;
|
a65c8e8b |
#define synthesis_node_type_define(T0_, T1_, v_) \
|
4068375e |
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;
|
a65c8e8b |
#define synthesis_node_type_define(T0_, T1_, T2_, v_) \
|
4068375e |
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;
|
a65c8e8b |
#define synthesis_node_type_define(T0_, T1_, T2_, T3_, v_) \
|
4068375e |
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>
|
a65c8e8b |
class T0oT1 exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::bfunc_t bfunc_t;
|
4068375e |
typedef T value_type;
typedef T0oT1<T,T0,T1> node_type;
T0oT1(T0 p0, T1 p1, const bfunc_t p2)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, f_ (p2)
|
4068375e |
{}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result;
return result;
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return e_default;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1(const T0oT1<T,T0,T1>&) exprtk_delete;
T0oT1<T,T0,T1>& operator=(const T0oT1<T,T0,T1>&) { return (*this); }
|
4068375e |
T0 t0_;
T1 t1_;
const bfunc_t f_;
};
template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
|
a65c8e8b |
class T0oT1oT2 exprtk_final : public T0oT1oT2_base_node<T>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::bfunc_t bfunc_t;
|
4068375e |
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)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, t2_(p2)
, f0_(p3)
, f1_(p4)
|
4068375e |
{}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
return result;
}
|
a65c8e8b |
inline operator_type operation()
|
4068375e |
{
return e_default;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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_;
}
|
a65c8e8b |
std::string type_id() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1oT2(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) { return (*this); }
|
4068375e |
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>
|
a65c8e8b |
class T0oT1oT2oT3 exprtk_final : public T0oT1oT2oT3_base_node<T>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::bfunc_t bfunc_t;
|
4068375e |
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)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, t2_(p2)
, t3_(p3)
, f0_(p4)
, f1_(p5)
, f2_(p6)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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_;
}
|
a65c8e8b |
inline std::string type_id() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1oT2oT3(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) { return (*this); }
|
4068375e |
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>
|
a65c8e8b |
class T0oT1oT2_sf3 exprtk_final : public T0oT1oT2_base_node<T>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::tfunc_t tfunc_t;
|
4068375e |
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)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, t2_(p2)
, f_ (p3)
|
4068375e |
{}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
return result;
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return e_default;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1oT2_sf3(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) { return (*this); }
|
4068375e |
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:
|
a65c8e8b |
virtual ~sf3ext_type_node() {}
|
4068375e |
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>
|
a65c8e8b |
class T0oT1oT2_sf3ext exprtk_final : public sf3ext_type_node<T,T0,T1,T2>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::tfunc_t tfunc_t;
|
4068375e |
typedef T value_type;
|
a65c8e8b |
typedef T0oT1oT2_sf3ext<T, T0, T1, T2, SF3Operation> node_type;
|
4068375e |
T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, t2_(p2)
|
4068375e |
{}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result;
return result;
}
|
a65c8e8b |
inline operator_type operation()
|
4068375e |
{
return e_default;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return SF3Operation::process(t0_, t1_, t2_);
}
|
a65c8e8b |
T0 t0() const exprtk_override
|
4068375e |
{
return t0_;
}
|
a65c8e8b |
T1 t1() const exprtk_override
|
4068375e |
{
return t1_;
}
|
a65c8e8b |
T2 t2() const exprtk_override
|
4068375e |
{
return t2_;
}
|
a65c8e8b |
std::string type_id() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1oT2_sf3ext(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) { return (*this); }
|
4068375e |
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>
|
a65c8e8b |
class T0oT1oT2oT3_sf4 exprtk_final : public T0oT1oT2_base_node<T>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::qfunc_t qfunc_t;
|
4068375e |
typedef T value_type;
|
a65c8e8b |
typedef T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> node_type;
|
4068375e |
T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, t2_(p2)
, t3_(p3)
, f_ (p4)
|
4068375e |
{}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
return result;
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return e_default;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1oT2oT3_sf4(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) { return (*this); }
|
4068375e |
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>
|
a65c8e8b |
class T0oT1oT2oT3_sf4ext exprtk_final : public T0oT1oT2oT3_base_node<T>
|
4068375e |
{
public:
typedef typename details::functor_t<T> functor_t;
|
a65c8e8b |
typedef typename functor_t::tfunc_t tfunc_t;
|
4068375e |
typedef T value_type;
|
a65c8e8b |
typedef T0oT1oT2oT3_sf4ext<T, T0, T1, T2, T3, SF4Operation> node_type;
|
4068375e |
T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
|
a65c8e8b |
: t0_(p0)
, t1_(p1)
, t2_(p2)
, t3_(p3)
|
4068375e |
{}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result;
return result;
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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 t3_;
}
|
a65c8e8b |
std::string type_id() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
T0oT1oT2oT3_sf4ext(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) { return (*this); }
|
4068375e |
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>
|
a65c8e8b |
class vov_node exprtk_final : public vov_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
// variable op variable node
explicit vov_node(const T& var0, const T& var1)
|
a65c8e8b |
: v0_(var0)
, v1_(var1)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Operation::process(v0_,v1_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline const T& v0() const exprtk_override
|
4068375e |
{
return v0_;
}
|
a65c8e8b |
inline const T& v1() const exprtk_override
|
4068375e |
{
return v1_;
}
protected:
const T& v0_;
const T& v1_;
private:
|
a65c8e8b |
vov_node(const vov_node<T,Operation>&) exprtk_delete;
vov_node<T,Operation>& operator=(const vov_node<T,Operation>&) exprtk_delete;
|
4068375e |
};
template <typename T, typename Operation>
|
a65c8e8b |
class cov_node exprtk_final : public cov_base_node<T>
|
4068375e |
{
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)
|
a65c8e8b |
: c_(const_var)
, v_(var)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Operation::process(c_,v_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline const T c() const exprtk_override
|
4068375e |
{
return c_;
}
|
a65c8e8b |
inline const T& v() const exprtk_override
|
4068375e |
{
return v_;
}
protected:
const T c_;
const T& v_;
private:
|
a65c8e8b |
cov_node(const cov_node<T,Operation>&) exprtk_delete;
cov_node<T,Operation>& operator=(const cov_node<T,Operation>&) exprtk_delete;
|
4068375e |
};
template <typename T, typename Operation>
|
a65c8e8b |
class voc_node exprtk_final : public voc_base_node<T>
|
4068375e |
{
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)
|
a65c8e8b |
: v_(var)
, c_(const_var)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Operation::process(v_,c_);
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline const T c() const exprtk_override
|
4068375e |
{
return c_;
}
|
a65c8e8b |
inline const T& v() const exprtk_override
|
4068375e |
{
return v_;
}
protected:
const T& v_;
const T c_;
private:
|
a65c8e8b |
voc_node(const voc_node<T,Operation>&) exprtk_delete;
voc_node<T,Operation>& operator=(const voc_node<T,Operation>&) exprtk_delete;
|
4068375e |
};
template <typename T, typename Operation>
|
a65c8e8b |
class vob_node exprtk_final : public vob_base_node<T>
|
4068375e |
{
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 branch)
: v_(var)
{
construct_branch_pair(branch_, branch);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
return Operation::process(v_,branch_.first->value());
}
|
a65c8e8b |
inline const T& v() const exprtk_override
|
4068375e |
{
return v_;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
|
a65c8e8b |
vob_node(const vob_node<T,Operation>&) exprtk_delete;
vob_node<T,Operation>& operator=(const vob_node<T,Operation>&) exprtk_delete;
|
4068375e |
const T& v_;
branch_t branch_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class bov_node exprtk_final : public bov_base_node<T>
|
4068375e |
{
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 branch, const T& var)
: v_(var)
{
construct_branch_pair(branch_, branch);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
return Operation::process(branch_.first->value(),v_);
}
|
a65c8e8b |
inline const T& v() const exprtk_override
|
4068375e |
{
return v_;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
|
a65c8e8b |
bov_node(const bov_node<T,Operation>&) exprtk_delete;
bov_node<T,Operation>& operator=(const bov_node<T,Operation>&) exprtk_delete;
|
4068375e |
const T& v_;
branch_t branch_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class cob_node exprtk_final : public cob_base_node<T>
|
4068375e |
{
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 branch)
: c_(const_var)
{
construct_branch_pair(branch_, branch);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
return Operation::process(c_,branch_.first->value());
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline const T c() const exprtk_override
|
4068375e |
{
return c_;
}
|
a65c8e8b |
inline void set_c(const T new_c) exprtk_override
|
4068375e |
{
(*const_cast<T*>(&c_)) = new_c;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
|
a65c8e8b |
inline expression_node<T>* move_branch(const std::size_t&) exprtk_override
|
4068375e |
{
branch_.second = false;
return branch_.first;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
|
a65c8e8b |
cob_node(const cob_node<T,Operation>&) exprtk_delete;
cob_node<T,Operation>& operator=(const cob_node<T,Operation>&) exprtk_delete;
|
4068375e |
const T c_;
branch_t branch_;
};
template <typename T, typename Operation>
|
a65c8e8b |
class boc_node exprtk_final : public boc_base_node<T>
|
4068375e |
{
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 branch, const T const_var)
: c_(const_var)
{
construct_branch_pair(branch_, branch);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
return Operation::process(branch_.first->value(),c_);
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
|
a65c8e8b |
inline const T c() const exprtk_override
|
4068375e |
{
return c_;
}
|
a65c8e8b |
inline void set_c(const T new_c) exprtk_override
|
4068375e |
{
(*const_cast<T*>(&c_)) = new_c;
}
|
a65c8e8b |
inline expression_node<T>* branch(const std::size_t&) const exprtk_override
|
4068375e |
{
return branch_.first;
}
|
a65c8e8b |
inline expression_node<T>* move_branch(const std::size_t&) exprtk_override
|
4068375e |
{
branch_.second = false;
return branch_.first;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
|
a65c8e8b |
boc_node(const boc_node<T,Operation>&) exprtk_delete;
boc_node<T,Operation>& operator=(const boc_node<T,Operation>&) exprtk_delete;
|
4068375e |
const T c_;
branch_t branch_;
};
#ifndef exprtk_disable_string_capabilities
template <typename T, typename SType0, typename SType1, typename Operation>
|
a65c8e8b |
class sos_node exprtk_final : public sos_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
// string op string node
explicit sos_node(SType0 p0, SType1 p1)
|
a65c8e8b |
: s0_(p0)
, s1_(p1)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return Operation::process(s0_,s1_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
inline std::string& s0()
{
return s0_;
}
inline std::string& s1()
{
return s1_;
}
protected:
SType0 s0_;
SType1 s1_;
private:
|
a65c8e8b |
sos_node(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete;
sos_node<T,SType0,SType1,Operation>& operator=(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete;
|
4068375e |
};
template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
|
a65c8e8b |
class str_xrox_node exprtk_final : public sos_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
|
a65c8e8b |
typedef str_xrox_node<T,SType0,SType1,RangePack,Operation> node_type;
|
4068375e |
// string-range op string node
explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
|
a65c8e8b |
: s0_ (p0 )
, s1_ (p1 )
, rp0_(rp0)
|
4068375e |
{}
~str_xrox_node()
{
rp0_.free();
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
inline std::string& s0()
{
return s0_;
}
inline std::string& s1()
{
return s1_;
}
protected:
SType0 s0_;
SType1 s1_;
RangePack rp0_;
private:
|
a65c8e8b |
str_xrox_node(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) exprtk_delete;
|
4068375e |
};
template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
|
a65c8e8b |
class str_xoxr_node exprtk_final : public sos_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
|
a65c8e8b |
typedef str_xoxr_node<T,SType0,SType1,RangePack,Operation> node_type;
|
4068375e |
// string op string range node
explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
|
a65c8e8b |
: s0_ (p0 )
, s1_ (p1 )
, rp1_(rp1)
|
4068375e |
{}
~str_xoxr_node()
{
rp1_.free();
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
return Operation::operation();
}
inline std::string& s0()
{
return s0_;
}
inline std::string& s1()
{
return s1_;
}
protected:
SType0 s0_;
SType1 s1_;
RangePack rp1_;
private:
|
a65c8e8b |
str_xoxr_node(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) exprtk_delete;
|
4068375e |
};
template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
|
a65c8e8b |
class str_xroxr_node exprtk_final : public sos_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
|
a65c8e8b |
typedef str_xroxr_node<T,SType0,SType1,RangePack,Operation> node_type;
|
4068375e |
// string-range op string-range node
explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
|
a65c8e8b |
: s0_ (p0 )
, s1_ (p1 )
, rp0_(rp0)
, rp1_(rp1)
|
4068375e |
{}
~str_xroxr_node()
{
rp0_.free();
rp1_.free();
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
str_xroxr_node(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) exprtk_delete;
|
4068375e |
};
template <typename T, typename Operation>
|
a65c8e8b |
class str_sogens_node exprtk_final : public binary_node<T>
|
4068375e |
{
public:
typedef expression_node <T>* expression_ptr;
|
a65c8e8b |
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;
|
4068375e |
str_sogens_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
|
a65c8e8b |
: binary_node<T>(opr, branch0, branch1)
, str0_base_ptr_ (0)
, str1_base_ptr_ (0)
, str0_range_ptr_(0)
, str1_range_ptr_(0)
|
4068375e |
{
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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
if (0 == range)
return;
str0_range_ptr_ = &(range->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 = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
if (0 == range)
return;
str1_range_ptr_ = &(range->range_ref());
}
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
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;
|
a65c8e8b |
const range_t& range0 = (*str0_range_ptr_);
const range_t& range1 = (*str1_range_ptr_);
|
4068375e |
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();
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
private:
|
a65c8e8b |
str_sogens_node(const str_sogens_node<T,Operation>&) exprtk_delete;
str_sogens_node<T,Operation>& operator=(const str_sogens_node<T,Operation>&) exprtk_delete;
|
4068375e |
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>
|
a65c8e8b |
class sosos_node exprtk_final : public sosos_base_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef Operation operation_t;
|
a65c8e8b |
typedef sosos_node<T, SType0, SType1, SType2, Operation> node_type;
|
4068375e |
// variable op variable node
explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
|
a65c8e8b |
: s0_(p0)
, s1_(p1)
, s2_(p2)
|
4068375e |
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
return Operation::process(s0_, s1_, s2_);
|
4068375e |
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return Operation::type();
}
|
a65c8e8b |
inline operator_type operation() const exprtk_override
|
4068375e |
{
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:
|
a65c8e8b |
sosos_node(const node_type&) exprtk_delete;
node_type& operator=(const node_type&) exprtk_delete;
|
4068375e |
};
#endif
template <typename T, typename PowOp>
|
a65c8e8b |
class ipow_node exprtk_final: public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef PowOp operation_t;
explicit ipow_node(const T& v)
: v_(v)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return PowOp::result(v_);
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_ipow;
}
private:
|
a65c8e8b |
ipow_node(const ipow_node<T,PowOp>&) exprtk_delete;
ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&) exprtk_delete;
|
4068375e |
const T& v_;
};
template <typename T, typename PowOp>
|
a65c8e8b |
class bipow_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr, bool> branch_t;
typedef PowOp operation_t;
explicit bipow_node(expression_ptr branch)
{
construct_branch_pair(branch_, branch);
}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
|
a65c8e8b |
assert(branch_.first);
|
4068375e |
return PowOp::result(branch_.first->value());
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_ipow;
}
|
a65c8e8b |
void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
|
4068375e |
{
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
|
a65c8e8b |
std::size_t node_depth() const exprtk_override
|
4068375e |
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
private:
|
a65c8e8b |
bipow_node(const bipow_node<T,PowOp>&) exprtk_delete;
bipow_node<T,PowOp>& operator=(const bipow_node<T,PowOp>&) exprtk_delete;
|
4068375e |
branch_t branch_;
};
template <typename T, typename PowOp>
|
a65c8e8b |
class ipowinv_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef PowOp operation_t;
explicit ipowinv_node(const T& v)
: v_(v)
{}
|
a65c8e8b |
inline T value() const exprtk_override
|
4068375e |
{
return (T(1) / PowOp::result(v_));
}
|
a65c8e8b |
inline typename expression_node<T>::node_type type() const exprtk_override
|
4068375e |
{
return expression_node<T>::e_ipowinv;
}
private:
|
a65c8e8b |
ipowinv_node(const ipowinv_node<T,PowOp>&) exprtk_delete;
ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&) exprtk_delete;
|
4068375e |
const T& v_;
};
template <typename T, typename PowOp>
|
a65c8e8b |
class bipowninv_node exprtk_final : public expression_node<T>
|
4068375e |
{
public:
typedef expression_node<T>* expression_ptr;
typedef std::pair<expression_ptr, bool> branch_t;
typedef PowOp operation_t;
explicit bipowninv_node(expression_ptr branch)
{
construct_branch_pair(branch_, branch);
}
|