C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
7ead3055af
commit
656b858d59
632
exprtk.hpp
632
exprtk.hpp
|
@ -46,6 +46,7 @@
|
|||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace exprtk
|
||||
|
@ -224,7 +225,7 @@ namespace exprtk
|
|||
static const std::string reserved_words[] =
|
||||
{
|
||||
"and", "false", "for", "if", "ilike", "in", "like", "nand", "nor", "not",
|
||||
"null", "or", "shl", "shr", "true", "while", "xor"
|
||||
"null", "or", "shl", "shr", "true", "while", "xnor", "xor"
|
||||
};
|
||||
|
||||
static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
|
||||
|
@ -237,7 +238,7 @@ namespace exprtk
|
|||
"in", "inrange", "like", "log", "log10", "logn", "log1p", "max", "min", "mod",
|
||||
"mul", "nand", "nor", "not", "not_equal", "null", "or", "pow", "rad2deg",
|
||||
"root", "round", "roundn", "sec", "sgn", "shl", "shr", "sin", "sinh", "sqrt",
|
||||
"sum", "tan", "tanh", "true", "trunc", "while", "xor"
|
||||
"sum", "tan", "tanh", "true", "trunc", "while", "xnor", "xor"
|
||||
};
|
||||
|
||||
static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
|
||||
|
@ -403,6 +404,18 @@ namespace exprtk
|
|||
#undef exprtk_register_real_type_tag
|
||||
#undef exprtk_register_int_type_tag
|
||||
|
||||
template <typename T>
|
||||
inline bool is_true_impl(const T v)
|
||||
{
|
||||
return (v != T(0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool is_false_impl(const T v)
|
||||
{
|
||||
return (v == T(0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T equal_impl(const T v0, const T v1, real_type_tag)
|
||||
{
|
||||
|
@ -610,6 +623,28 @@ namespace exprtk
|
|||
return v0 ^ v1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T xnor_impl(const T v0, const T& v1, real_type_tag)
|
||||
{
|
||||
const bool v0_true = is_true_impl(v0);
|
||||
const bool v1_true = is_true_impl(v1);
|
||||
if ((v0_true && v1_true) || (!v0_true && !v1_true))
|
||||
return T(1);
|
||||
else
|
||||
return T(0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T xnor_impl(const T v0, const T& v1, int_type_tag)
|
||||
{
|
||||
const bool v0_true = is_true_impl(v0);
|
||||
const bool v1_true = is_true_impl(v1);
|
||||
if ((v0_true && v1_true) || (!v0_true && !v1_true))
|
||||
return T(1);
|
||||
else
|
||||
return T(0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T erf_impl(T v, real_type_tag)
|
||||
{
|
||||
|
@ -821,6 +856,13 @@ namespace exprtk
|
|||
return details::xor_impl(v0,v1,num_type);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T xnor_opr(const T v0, const T v1)
|
||||
{
|
||||
typename details::number_type<T>::type num_type;
|
||||
return details::xnor_impl(v0,v1,num_type);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool is_integer(const T v)
|
||||
{
|
||||
|
@ -2643,18 +2685,19 @@ namespace exprtk
|
|||
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_shr ,
|
||||
e_shl , e_abs , e_acos , e_asin ,
|
||||
e_atan , e_ceil , e_cos , e_cosh ,
|
||||
e_exp , e_floor , e_log , e_log10 ,
|
||||
e_log1p , e_logn , e_neg , e_pos ,
|
||||
e_round , e_roundn , e_root , e_sqrt ,
|
||||
e_sin , e_sinh , e_sec , e_csc ,
|
||||
e_tan , e_tanh , e_cot , e_clamp ,
|
||||
e_inrange, e_sgn , e_r2d , e_d2r ,
|
||||
e_d2g , e_g2d , e_hypot , e_notl ,
|
||||
e_erf , e_erfc , e_frac , e_trunc ,
|
||||
e_assign , e_in , e_like , e_ilike ,
|
||||
e_or , e_nor , e_xor , e_xnor ,
|
||||
e_shr , e_shl , e_abs , e_acos ,
|
||||
e_asin , e_atan , e_ceil , e_cos ,
|
||||
e_cosh , e_exp , e_floor , e_log ,
|
||||
e_log10 , e_log1p , e_logn , e_neg ,
|
||||
e_pos , e_round , e_roundn , e_root ,
|
||||
e_sqrt , e_sin , e_sinh , e_sec ,
|
||||
e_csc , e_tan , e_tanh , e_cot ,
|
||||
e_clamp , e_inrange, e_sgn , e_r2d ,
|
||||
e_d2r , e_d2g , e_g2d , e_hypot ,
|
||||
e_notl , e_erf , e_erfc , e_frac ,
|
||||
e_trunc , e_assign , e_in , e_like ,
|
||||
e_ilike ,
|
||||
|
||||
// Do not add new functions/operators after this point.
|
||||
e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
|
||||
|
@ -2692,7 +2735,8 @@ namespace exprtk
|
|||
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_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
|
||||
e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043
|
||||
};
|
||||
|
||||
struct base_operation_t
|
||||
|
@ -2797,6 +2841,7 @@ namespace exprtk
|
|||
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) ? T(1) : T(0);
|
||||
case e_xnor : return (arg0 != arg1) ? T(0) : T(1);
|
||||
case e_root : return root<T>(arg0,arg1);
|
||||
case e_roundn : return roundn<T>(arg0,arg1);
|
||||
case e_equal : return equal<T>(arg0,arg1);
|
||||
|
@ -2836,6 +2881,7 @@ namespace exprtk
|
|||
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;
|
||||
|
@ -2880,22 +2926,23 @@ namespace exprtk
|
|||
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_in , e_like , e_ilike ,
|
||||
e_inranges , e_ipow , e_ipowinv , e_abs ,
|
||||
e_acos , e_asin , e_atan , e_ceil ,
|
||||
e_cos , e_cosh , e_exp , e_floor ,
|
||||
e_log , e_log10 , e_log1p , e_neg ,
|
||||
e_pos , e_round , e_sin , 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_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_xor , e_xnor , e_in , e_like ,
|
||||
e_ilike , e_inranges , e_ipow , e_ipowinv ,
|
||||
e_abs , e_acos , e_asin , e_atan ,
|
||||
e_ceil , e_cos , e_cosh , e_exp ,
|
||||
e_floor , e_log , e_log10 , e_log1p ,
|
||||
e_neg , e_pos , e_round , e_sin ,
|
||||
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_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
|
||||
};
|
||||
|
||||
typedef T value_type;
|
||||
|
@ -3906,6 +3953,11 @@ namespace exprtk
|
|||
template <typename T> struct sfext37_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x / y) / (z - w); } static inline std::string id() { return "(t/t)/(t-t)";} };
|
||||
template <typename T> struct sfext38_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x * y) * (z - w); } static inline std::string id() { return "(t*t)*(t-t)";} };
|
||||
template <typename T> struct sfext39_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x / y) * (z - w); } static inline std::string id() { return "(t/t)*(t-t)";} };
|
||||
template <typename T> struct sfext40_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x + (y * (z / w)); } static inline std::string id() { return "t+(t*(t/t))";} };
|
||||
template <typename T> struct sfext41_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x - (y * (z / w)); } static inline std::string id() { return "t-(t*(t/t))";} };
|
||||
template <typename T> struct sfext42_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x + (y / (z * w)); } static inline std::string id() { return "t+(t/(t*t))";} };
|
||||
template <typename T> struct sfext43_op : public sf_base<T> { typedef typename sf_base<T>::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x - (y / (z * w)); } static inline std::string id() { return "t-(t/(t*t))";} };
|
||||
|
||||
|
||||
template <typename T, typename SpecialFunction>
|
||||
class sf3_node : public trinary_node<T>
|
||||
|
@ -4601,6 +4653,15 @@ namespace exprtk
|
|||
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>
|
||||
{
|
||||
|
@ -4776,6 +4837,8 @@ namespace exprtk
|
|||
public:
|
||||
|
||||
virtual std::string type_id() const = 0;
|
||||
|
||||
virtual std::string type_id2() const { return ""; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -5505,8 +5568,20 @@ namespace exprtk
|
|||
const tfunc_t f_;
|
||||
};
|
||||
|
||||
template <typename T, typename T0, typename T1, typename T2>
|
||||
class sf3ext_type_node : public T0oT1oT2_base_node<T>
|
||||
{
|
||||
public:
|
||||
|
||||
virtual T0 t0() const = 0;
|
||||
|
||||
virtual T1 t1() const = 0;
|
||||
|
||||
virtual T2 t2() const = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
|
||||
class T0oT1oT2_sf3ext : public T0oT1oT2_base_node<T>
|
||||
class T0oT1oT2_sf3ext : public sf3ext_type_node<T,T0,T1,T2>
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -5537,17 +5612,17 @@ namespace exprtk
|
|||
return SF3Operation::process(t0_,t1_,t2_);
|
||||
}
|
||||
|
||||
inline T0 t0() const
|
||||
T0 t0() const
|
||||
{
|
||||
return t0_;
|
||||
}
|
||||
|
||||
inline T1 t1() const
|
||||
T1 t1() const
|
||||
{
|
||||
return t1_;
|
||||
}
|
||||
|
||||
inline T2 t2() const
|
||||
T2 t2() const
|
||||
{
|
||||
return t2_;
|
||||
}
|
||||
|
@ -5557,6 +5632,30 @@ namespace exprtk
|
|||
return id();
|
||||
}
|
||||
|
||||
std::string type_id2() const
|
||||
{
|
||||
std::string t[] = {
|
||||
param_to_str<is_const_ref<T0>::result>::result(),
|
||||
param_to_str<is_const_ref<T1>::result>::result(),
|
||||
param_to_str<is_const_ref<T2>::result>::result()
|
||||
};
|
||||
|
||||
std::string sf3id = id();
|
||||
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
std::size_t index = std::string::npos;
|
||||
if (std::string::npos != (index = sf3id.find("t")))
|
||||
{
|
||||
sf3id[index] = t[i][0];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return sf3id;
|
||||
}
|
||||
|
||||
static inline std::string id()
|
||||
{
|
||||
return SF3Operation::id();
|
||||
|
@ -5578,6 +5677,20 @@ namespace exprtk
|
|||
T2 t2_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool is_sf3ext_node(const expression_node<T>* n)
|
||||
{
|
||||
switch(n->type())
|
||||
{
|
||||
case expression_node<T>::e_vovov : return true;
|
||||
case expression_node<T>::e_vovoc : return true;
|
||||
case expression_node<T>::e_vocov : return true;
|
||||
case expression_node<T>::e_covov : return true;
|
||||
case expression_node<T>::e_covoc : return true;
|
||||
default : return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename T0, typename T1, typename T2, typename T3>
|
||||
class T0oT1oT2oT3_sf4 : public T0oT1oT2_base_node<T>
|
||||
{
|
||||
|
@ -5745,6 +5858,24 @@ namespace exprtk
|
|||
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
|
||||
{
|
||||
|
@ -5757,6 +5888,7 @@ namespace exprtk
|
|||
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>
|
||||
|
@ -6819,11 +6951,118 @@ namespace exprtk
|
|||
{
|
||||
private:
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual value_ptr value_at(const std::size_t&) const = 0;
|
||||
|
||||
};
|
||||
|
||||
class array_vector_impl : public vector_holder_base
|
||||
{
|
||||
public:
|
||||
|
||||
array_vector_impl(const T* vec, const std::size_t& vec_size)
|
||||
: vec_(vec),
|
||||
size_(vec_size)
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
||||
value_ptr value_at(const std::size_t& index) const
|
||||
{
|
||||
if (index < size_)
|
||||
return const_cast<const_value_ptr>(vec_ + index);
|
||||
else
|
||||
return const_value_ptr(0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
array_vector_impl operator=(const array_vector_impl&);
|
||||
|
||||
const T* 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);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
sequence_vector_impl operator=(const sequence_vector_impl&);
|
||||
|
||||
sequence_t& sequence_;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
vector_holder(Type* vec, const std::size_t& vec_size)
|
||||
: vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
|
||||
{}
|
||||
|
||||
template <typename Allocator>
|
||||
vector_holder(std::vector<Type,Allocator>& vec)
|
||||
: vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
|
||||
{}
|
||||
|
||||
template <typename Allocator>
|
||||
vector_holder(std::deque<Type,Allocator>& deq)
|
||||
: vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::deque>(deq))
|
||||
{}
|
||||
|
||||
inline value_ptr operator[](const std::size_t& index) const
|
||||
{
|
||||
return (*vector_holder_base_)[index];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mutable vector_holder_base* vector_holder_base_;
|
||||
unsigned char buffer[64];
|
||||
};
|
||||
|
||||
template <typename Type, typename RawType>
|
||||
struct type_store
|
||||
{
|
||||
typedef typename details::variable_node<T> variable_node_t;
|
||||
typedef ifunction<T> ifunction_t;
|
||||
typedef vector_holder<T> vector_t;
|
||||
#ifndef exprtk_disable_string_capabilities
|
||||
typedef typename details::stringvar_node<T> stringvar_node_t;
|
||||
#endif
|
||||
|
@ -6873,6 +7112,71 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
template <typename Tie, typename RType>
|
||||
inline bool add_impl(const std::string& symbol_name, RType t, const bool is_constant)
|
||||
{
|
||||
if (1 == symbol_name.size())
|
||||
{
|
||||
short_type_lut[static_cast<std::size_t>(std::tolower(symbol_name[0]))] = Tie::make(t,is_constant);
|
||||
++size;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
|
||||
{
|
||||
if (details::imatch(symbol_name,details::reserved_symbols[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
tm_itr_t itr = map.find(symbol_name);
|
||||
if (map.end() == itr)
|
||||
{
|
||||
map[symbol_name] = Tie::make(t,is_constant);
|
||||
++size;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool add(const std::string& symbol_name, T* v, const std::size_t& v_size, const bool is_constant = false)
|
||||
{
|
||||
struct tie
|
||||
{
|
||||
static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_constant = false)
|
||||
{
|
||||
return std::make_pair(is_constant,new vector_t(v.first,v.second));
|
||||
}
|
||||
};
|
||||
return add_impl<tie,std::pair<T*,std::size_t> >(symbol_name,std::make_pair(v,v_size),is_constant);
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_constant = false)
|
||||
{
|
||||
struct tie
|
||||
{
|
||||
static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_constant = false)
|
||||
{
|
||||
return std::make_pair(is_constant,new vector_t(v));
|
||||
}
|
||||
};
|
||||
return add_impl<tie,std::vector<T,Allocator>&>(symbol_name,v,is_constant);
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_constant = false)
|
||||
{
|
||||
struct tie
|
||||
{
|
||||
static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_constant = false)
|
||||
{
|
||||
return std::make_pair(is_constant,new vector_t(v));
|
||||
}
|
||||
};
|
||||
return add_impl<tie,std::deque<T,Allocator>&>(symbol_name,v,is_constant);
|
||||
}
|
||||
|
||||
inline bool add(const std::string& symbol_name, RawType& t, const bool is_constant = false)
|
||||
{
|
||||
struct tie
|
||||
|
@ -6968,6 +7272,7 @@ namespace exprtk
|
|||
struct deleter
|
||||
{
|
||||
static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
|
||||
static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
|
||||
#ifndef exprtk_disable_string_capabilities
|
||||
static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
|
||||
#endif
|
||||
|
@ -7112,6 +7417,7 @@ namespace exprtk
|
|||
#endif
|
||||
typedef ifunction<T> function_t;
|
||||
typedef function_t* function_ptr;
|
||||
typedef vector_holder<T>* vector_ptr;
|
||||
|
||||
static const std::size_t lut_size = 256;
|
||||
|
||||
|
@ -7125,6 +7431,7 @@ namespace exprtk
|
|||
type_store<typename details::stringvar_node<T>,std::string> stringvar_store;
|
||||
#endif
|
||||
type_store<ifunction<T>,ifunction<T> > function_store;
|
||||
type_store<vector_holder<T>,vector_holder<T> > vector_store;
|
||||
|
||||
st_data()
|
||||
{
|
||||
|
@ -7253,6 +7560,14 @@ namespace exprtk
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline std::size_t vector_count() const
|
||||
{
|
||||
if (valid())
|
||||
return local_data().vector_store().size;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline variable_ptr get_variable(const std::string& variable_name)
|
||||
{
|
||||
if (!valid())
|
||||
|
@ -7285,6 +7600,16 @@ namespace exprtk
|
|||
return local_data().function_store.get(function_name);
|
||||
}
|
||||
|
||||
inline vector_ptr get_vector(const std::string& vector_name)
|
||||
{
|
||||
if (!valid())
|
||||
return reinterpret_cast<vector_ptr>(0);
|
||||
else if (!valid_symbol(vector_name))
|
||||
return reinterpret_cast<vector_ptr>(0);
|
||||
else
|
||||
return local_data().vector_store.get(vector_name);
|
||||
}
|
||||
|
||||
inline T& variable_ref(const std::string& symbol_name)
|
||||
{
|
||||
static T null_var = T(0);
|
||||
|
@ -7414,6 +7739,44 @@ namespace exprtk
|
|||
return local_data().function_store.add(function_name,function);
|
||||
}
|
||||
|
||||
inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
|
||||
{
|
||||
if (!valid())
|
||||
return false;
|
||||
else if (!valid_symbol(vector_name))
|
||||
return false;
|
||||
else if (symbol_exists(vector_name))
|
||||
return false;
|
||||
else
|
||||
return local_data().vector_store.add(vector_name,v,v_size);
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
|
||||
{
|
||||
if (!valid())
|
||||
return false;
|
||||
else if (!valid_symbol(vector_name))
|
||||
return false;
|
||||
else if (symbol_exists(vector_name))
|
||||
return false;
|
||||
else
|
||||
return local_data().vector_store.add(vector_name,v);
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
inline bool add_vector(const std::string& vector_name, std::deque<T,Allocator>& v)
|
||||
{
|
||||
if (!valid())
|
||||
return false;
|
||||
else if (!valid_symbol(vector_name))
|
||||
return false;
|
||||
else if (symbol_exists(vector_name))
|
||||
return false;
|
||||
else
|
||||
return local_data().vector_store.add(vector_name,v);
|
||||
}
|
||||
|
||||
inline bool remove_variable(const std::string& variable_name)
|
||||
{
|
||||
if (!valid())
|
||||
|
@ -7440,6 +7803,14 @@ namespace exprtk
|
|||
return local_data().function_store.remove(function_name);
|
||||
}
|
||||
|
||||
inline bool remove_vector(const std::string& vector_name)
|
||||
{
|
||||
if (!valid())
|
||||
return false;
|
||||
else
|
||||
return local_data().vector_store.remove(vector_name);
|
||||
}
|
||||
|
||||
inline bool add_constants()
|
||||
{
|
||||
return add_pi() &&
|
||||
|
@ -7507,6 +7878,16 @@ namespace exprtk
|
|||
}
|
||||
#endif
|
||||
|
||||
template <typename Allocator,
|
||||
template <typename, typename> class Sequence>
|
||||
inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vlist) const
|
||||
{
|
||||
if (!valid())
|
||||
return 0;
|
||||
else
|
||||
return local_data().vector_store.get_list(vlist);
|
||||
}
|
||||
|
||||
inline bool symbol_exists(const std::string& symbol_name) const
|
||||
{
|
||||
/*
|
||||
|
@ -8353,6 +8734,7 @@ namespace exprtk
|
|||
static const std::string s_or = "or";
|
||||
static const std::string s_nor = "nor";
|
||||
static const std::string s_xor = "xor";
|
||||
static const std::string s_xnor = "xnor";
|
||||
static const std::string s_in = "in";
|
||||
static const std::string s_like = "like";
|
||||
static const std::string s_ilike = "ilike";
|
||||
|
@ -8382,6 +8764,11 @@ namespace exprtk
|
|||
current_state.set(e_level03,e_level04,details::e_xor);
|
||||
break;
|
||||
}
|
||||
else if (details::imatch(current_token_.value,s_xnor))
|
||||
{
|
||||
current_state.set(e_level03,e_level04,details::e_xnor);
|
||||
break;
|
||||
}
|
||||
else if (details::imatch(current_token_.value,s_in))
|
||||
{
|
||||
current_state.set(e_level03,e_level04,details::e_in);
|
||||
|
@ -9285,6 +9672,7 @@ namespace exprtk
|
|||
case details::e_or : return "or";
|
||||
case details::e_nor : return "nor";
|
||||
case details::e_xor : return "xor";
|
||||
case details::e_xnor : return "xnor";
|
||||
default : return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
@ -9308,6 +9696,7 @@ namespace exprtk
|
|||
(details::e_or == operation) ||
|
||||
(details::e_nor == operation) ||
|
||||
(details::e_xor == operation) ||
|
||||
(details::e_xnor == operation) ||
|
||||
false;
|
||||
}
|
||||
|
||||
|
@ -9976,6 +10365,7 @@ namespace exprtk
|
|||
case_stmt(details:: e_or,details:: or_op) \
|
||||
case_stmt(details:: e_nor,details:: nor_op) \
|
||||
case_stmt(details:: e_xor,details:: xor_op) \
|
||||
case_stmt(details::e_xnor,details::xnor_op) \
|
||||
|
||||
#ifndef exprtk_disable_cardinal_pow_optimisation
|
||||
template <template <typename,typename> class IPowNode>
|
||||
|
@ -10059,6 +10449,15 @@ namespace exprtk
|
|||
expression_node_ptr (&branch)[2])
|
||||
{
|
||||
const Type& v = dynamic_cast<details::variable_node<Type>*>(branch[0])->ref();
|
||||
if (details::is_sf3ext_node(branch[1]))
|
||||
{
|
||||
expression_node_ptr result = error_node();
|
||||
if (synthesize_sf4ext_expression::template compile_right<vtype>(expr_gen,v,operation,branch[1],result))
|
||||
{
|
||||
free_node(*expr_gen.node_allocator_,branch[1]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
switch (operation)
|
||||
{
|
||||
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_rc<typename details::vob_node<Type,op1<Type> > >(v,branch[1]);
|
||||
|
@ -10077,6 +10476,15 @@ namespace exprtk
|
|||
expression_node_ptr (&branch)[2])
|
||||
{
|
||||
const Type& v = dynamic_cast<details::variable_node<Type>*>(branch[1])->ref();
|
||||
if (details::is_sf3ext_node(branch[0]))
|
||||
{
|
||||
expression_node_ptr result = error_node();
|
||||
if (synthesize_sf4ext_expression::template compile_left<vtype>(expr_gen,v,operation,branch[0],result))
|
||||
{
|
||||
free_node(*expr_gen.node_allocator_,branch[0]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
switch (operation)
|
||||
{
|
||||
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_cr<typename details::bov_node<Type,op1<Type> > >(branch[0],v);
|
||||
|
@ -10119,6 +10527,15 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (details::is_sf3ext_node(branch[1]))
|
||||
{
|
||||
expression_node_ptr result = error_node();
|
||||
if (synthesize_sf4ext_expression::template compile_right<ctype>(expr_gen,c,operation,branch[1],result))
|
||||
{
|
||||
free_node(*expr_gen.node_allocator_,branch[1]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
switch (operation)
|
||||
{
|
||||
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_rc<typename details::cob_node<Type,op1<Type> > >(c,branch[1]);
|
||||
|
@ -10161,6 +10578,15 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
}
|
||||
if (details::is_sf3ext_node(branch[0]))
|
||||
{
|
||||
expression_node_ptr result = error_node();
|
||||
if (synthesize_sf4ext_expression::template compile_left<ctype>(expr_gen,c,operation,branch[0],result))
|
||||
{
|
||||
free_node(*expr_gen.node_allocator_,branch[0]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
switch (operation)
|
||||
{
|
||||
#define case_stmt(op0,op1) case op0 : return expr_gen.node_allocator_->template allocate_cr<typename details::boc_node<Type,op1<Type> > >(branch[0],c);
|
||||
|
@ -10293,6 +10719,8 @@ namespace exprtk
|
|||
result = synthesize_sf3ext_expression::process<T0,T1,T2>(expr_gen,sf3opr,t0,t1,t2);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct synthesize_sf4ext_expression
|
||||
|
@ -10304,7 +10732,7 @@ namespace exprtk
|
|||
{
|
||||
switch (sf4opr)
|
||||
{
|
||||
#define case_stmt(op0,op1) case op0 : return details::T0oT1oT2oT3_sf4ext<T,T0,T1,T2,T3,op1<Type> >::allocate(*(expr_gen.node_allocator_),t0,t1,t2,t3);
|
||||
#define case_stmt(op0,op1) case op0 : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,op1<Type> >::allocate(*(expr_gen.node_allocator_),t0,t1,t2,t3);
|
||||
case_stmt(details::e_sf46,details::sf46_op) case_stmt(details::e_sf47,details::sf47_op)
|
||||
case_stmt(details::e_sf48,details::sf48_op) case_stmt(details::e_sf49,details::sf49_op)
|
||||
case_stmt(details::e_sf50,details::sf50_op) case_stmt(details::e_sf51,details::sf51_op)
|
||||
|
@ -10343,6 +10771,8 @@ namespace exprtk
|
|||
case_stmt(details::e_sf4ext34,details::sfext34_op) case_stmt(details::e_sf4ext35,details::sfext35_op)
|
||||
case_stmt(details::e_sf4ext36,details::sfext36_op) case_stmt(details::e_sf4ext37,details::sfext37_op)
|
||||
case_stmt(details::e_sf4ext38,details::sfext38_op) case_stmt(details::e_sf4ext39,details::sfext39_op)
|
||||
case_stmt(details::e_sf4ext40,details::sfext40_op) case_stmt(details::e_sf4ext41,details::sfext41_op)
|
||||
case_stmt(details::e_sf4ext42,details::sfext42_op) case_stmt(details::e_sf4ext43,details::sfext43_op)
|
||||
#undef case_stmt
|
||||
default : return error_node();
|
||||
}
|
||||
|
@ -10360,6 +10790,116 @@ namespace exprtk
|
|||
result = synthesize_sf4ext_expression::process<T0,T1,T2,T3>(expr_gen,sf4opr,t0,t1,t2,t3);
|
||||
return true;
|
||||
}
|
||||
|
||||
// T o (sf3ext)
|
||||
template <typename ExType>
|
||||
static inline bool compile_right(expression_generator<Type>& expr_gen,
|
||||
ExType t,
|
||||
const details::operator_type& operation,
|
||||
expression_node_ptr& sf3node,
|
||||
expression_node_ptr& result)
|
||||
{
|
||||
if (!details::is_sf3ext_node(sf3node))
|
||||
return false;
|
||||
|
||||
typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
|
||||
sf3ext_base_ptr n = dynamic_cast<sf3ext_base_ptr>(sf3node);
|
||||
std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
|
||||
switch (n->type())
|
||||
{
|
||||
case details::expression_node<Type>::e_covoc : return compile_right_impl
|
||||
<typename covoc_t::sf3_type_node,ExType,ctype,vtype,ctype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_covov : return compile_right_impl
|
||||
<typename covov_t::sf3_type_node,ExType,ctype,vtype,vtype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_vocov : return compile_right_impl
|
||||
<typename vocov_t::sf3_type_node,ExType,vtype,ctype,vtype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_vovoc : return compile_right_impl
|
||||
<typename vovoc_t::sf3_type_node,ExType,vtype,vtype,ctype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_vovov : return compile_right_impl
|
||||
<typename vovov_t::sf3_type_node,ExType,vtype,vtype,vtype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
default : return false;
|
||||
}
|
||||
}
|
||||
|
||||
// (sf3ext) o T
|
||||
template <typename ExType>
|
||||
static inline bool compile_left(expression_generator<Type>& expr_gen,
|
||||
ExType t,
|
||||
const details::operator_type& operation,
|
||||
expression_node_ptr& sf3node,
|
||||
expression_node_ptr& result)
|
||||
{
|
||||
if (!details::is_sf3ext_node(sf3node))
|
||||
return false;
|
||||
|
||||
typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
|
||||
sf3ext_base_ptr n = dynamic_cast<sf3ext_base_ptr>(sf3node);
|
||||
std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
|
||||
switch (n->type())
|
||||
{
|
||||
case details::expression_node<Type>::e_covoc : return compile_left_impl
|
||||
<typename covoc_t::sf3_type_node,ExType,ctype,vtype,ctype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_covov : return compile_left_impl
|
||||
<typename covov_t::sf3_type_node,ExType,ctype,vtype,vtype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_vocov : return compile_left_impl
|
||||
<typename vocov_t::sf3_type_node,ExType,vtype,ctype,vtype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_vovoc : return compile_left_impl
|
||||
<typename vovoc_t::sf3_type_node,ExType,vtype,vtype,ctype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
case details::expression_node<Type>::e_vovov : return compile_left_impl
|
||||
<typename vovov_t::sf3_type_node,ExType,vtype,vtype,vtype>(expr_gen,id,t,sf3node,result);
|
||||
|
||||
default : return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SF3TypeNode, typename ExType, typename T0, typename T1, typename T2>
|
||||
static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
|
||||
const std::string& id,
|
||||
ExType t,
|
||||
expression_node_ptr& node,
|
||||
expression_node_ptr& result)
|
||||
{
|
||||
SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
|
||||
if (n)
|
||||
{
|
||||
T0 t0 = n->t0();
|
||||
T1 t1 = n->t1();
|
||||
T2 t2 = n->t2();
|
||||
return synthesize_sf4ext_expression::
|
||||
template compile<ExType,T0,T1,T2>(expr_gen,id,t,t0,t1,t2,result);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename SF3TypeNode, typename ExType, typename T0, typename T1, typename T2>
|
||||
static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
|
||||
const std::string& id,
|
||||
ExType t,
|
||||
expression_node_ptr& node,
|
||||
expression_node_ptr& result)
|
||||
{
|
||||
SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
|
||||
if (n)
|
||||
{
|
||||
T0 t0 = n->t0();
|
||||
T1 t1 = n->t1();
|
||||
T2 t2 = n->t2();
|
||||
return synthesize_sf4ext_expression::
|
||||
template compile<ExType,T0,T1,T2>(expr_gen,id,t0,t1,t2,t,result);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct synthesize_vovov_expression0
|
||||
|
@ -12974,13 +13514,14 @@ namespace exprtk
|
|||
return branch[0];
|
||||
}
|
||||
else if (
|
||||
(details::e_lt == operation) || (details::e_lte == operation) ||
|
||||
(details::e_gt == operation) || (details::e_gte == operation) ||
|
||||
(details::e_eq == operation) || (details::e_ne == operation) ||
|
||||
(details::e_and == operation) || (details::e_nand == operation) ||
|
||||
(details::e_or == operation) || (details::e_nor == operation) ||
|
||||
(details::e_xor == operation) || (details::e_in == operation) ||
|
||||
(details::e_like == operation) || (details::e_ilike == operation)
|
||||
(details::e_lt == operation) || (details::e_lte == operation) ||
|
||||
(details::e_gt == operation) || (details::e_gte == operation) ||
|
||||
(details::e_eq == operation) || (details::e_ne == operation) ||
|
||||
(details::e_and == operation) || (details::e_nand == operation) ||
|
||||
(details::e_or == operation) || (details::e_nor == operation) ||
|
||||
(details::e_xor == operation) || (details::e_xnor == operation) ||
|
||||
(details::e_in == operation) || (details::e_like == operation) ||
|
||||
(details::e_ilike == operation)
|
||||
)
|
||||
{
|
||||
return node_allocator_->allocate_c<literal_node_t>(T(0));
|
||||
|
@ -13123,6 +13664,7 @@ namespace exprtk
|
|||
register_binary_op(details:: e_or,details:: or_op)
|
||||
register_binary_op(details:: e_nor,details:: nor_op)
|
||||
register_binary_op(details:: e_xor,details:: xor_op)
|
||||
register_binary_op(details::e_xnor,details::xnor_op)
|
||||
#undef register_binary_op
|
||||
}
|
||||
|
||||
|
@ -13146,6 +13688,7 @@ namespace exprtk
|
|||
register_binary_op(details:: e_or,details:: or_op)
|
||||
register_binary_op(details:: e_nor,details:: nor_op)
|
||||
register_binary_op(details:: e_xor,details:: xor_op)
|
||||
register_binary_op(details::e_xnor,details::xnor_op)
|
||||
#undef register_binary_op
|
||||
}
|
||||
|
||||
|
@ -13189,6 +13732,9 @@ namespace exprtk
|
|||
register_sf4ext(20) register_sf4ext(21) register_sf4ext(22) register_sf4ext(23)
|
||||
register_sf4ext(24) register_sf4ext(25) register_sf4ext(26) register_sf4ext(27)
|
||||
register_sf4ext(28) register_sf4ext(29) register_sf4ext(30) register_sf4ext(31)
|
||||
register_sf4ext(32) register_sf4ext(33) register_sf4ext(34) register_sf4ext(35)
|
||||
register_sf4ext(36) register_sf4ext(36) register_sf4ext(38) register_sf4ext(39)
|
||||
register_sf4ext(40) register_sf4ext(41) register_sf4ext(42) register_sf4ext(43)
|
||||
#undef register_sf4ext
|
||||
}
|
||||
|
||||
|
|
|
@ -743,6 +743,10 @@ static const test_t test_list[] =
|
|||
test_t("equal($f95(1.1,2.2,3.3,4.4),if(1.1 >= 2.2,3.3,4.4))",1.0),
|
||||
test_t("equal($f96(1.1,2.2,3.3,4.4),if(equal(1.1,2.2),3.3,4.4))",1.0),
|
||||
test_t("equal($f97(1.1,2.2,3.3,4.4),1.1*sin(2.2)+3.3*cos(4.4))",1.0),
|
||||
test_t("equal($f97(1.1,2.2,3.3,4.4),1.1*sin(2.2)+3.3*cos(4.4))",1.0),
|
||||
test_t("equal((48.0/2.0*(9.0+3.0)),288.0)",1.0),
|
||||
test_t("equal((48.0/2.0(9.0+3.0)),288.0)",1.0),
|
||||
test_t("equal((6.0/2.0(1.0+2.0)),9.0)",1.0),
|
||||
test_t("1+2+3+4+5+6+7+8+9+0",45.0),
|
||||
test_t("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0",45.0),
|
||||
test_t("1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 0.0",45.0),
|
||||
|
|
103
readme.txt
103
readme.txt
|
@ -13,32 +13,32 @@ extendible.
|
|||
The ExprTk evaluator supports the following fundamental mathematical
|
||||
operations, functions and processes:
|
||||
|
||||
(1) Basic operators: +, -, *, /, %, ^
|
||||
(0) Basic operators: +, -, *, /, %, ^
|
||||
|
||||
(2) Functions: min, max, avg, sum, abs, ceil, floor, round,
|
||||
(1) Functions: min, max, avg, sum, abs, ceil, floor, round,
|
||||
roundn, exp, log, log10, logn, log1p, root,
|
||||
sqrt, clamp, inrange, sgn, erf, erfc, frac,
|
||||
trunc
|
||||
|
||||
(3) Trigonometry: sin, cos, tan, acos, asin, atan, atan2, cosh,
|
||||
(2) Trigonometry: sin, cos, tan, acos, asin, atan, atan2, cosh,
|
||||
cot, csc, sec, sinh, tanh, rad2deg, deg2rad,
|
||||
deg2grad, grad2deg, hypot
|
||||
|
||||
(4) Equalities &
|
||||
(3) Equalities &
|
||||
Inequalities: =, ==, <>, !=, <, <=, >, >=
|
||||
|
||||
(5) Boolean logic: and, or, xor, not, nand, nor, shr, shl, true,
|
||||
false
|
||||
(4) Boolean logic: and, or, xor, xnor, not, nand, nor, shr, shl,
|
||||
true, false
|
||||
|
||||
(6) Conditional &
|
||||
(5) Conditional &
|
||||
Loop statement: if-then-else, while
|
||||
|
||||
(7) Assignment: :=
|
||||
(6) Assignment: :=
|
||||
|
||||
(8) String
|
||||
(7) String
|
||||
processing: in, like, ilike
|
||||
|
||||
(9) Calculus: numerical integration and differentiation
|
||||
(8) Calculus: numerical integration and differentiation
|
||||
|
||||
|
||||
|
||||
|
@ -106,6 +106,7 @@ Expression Library can be found at:
|
|||
(*) PGI C++ (10.x+)
|
||||
(*) Microsoft Visual Studio C++ Compiler (8.1+)
|
||||
(*) Comeau C++ Compiler (4.3+)
|
||||
(*) IBM XL C/C++ (10.x+)
|
||||
|
||||
|
||||
|
||||
|
@ -135,7 +136,7 @@ Expression Library can be found at:
|
|||
+-----------+--------------------------------------------------------+
|
||||
| OPERATOR | DEFINITION |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| == or = | True only if x is strictly equal to y. (eg: x == y) |
|
||||
| == or = | True only if x is strictly equal to y. (eg: x == y) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| <> or != | True only if x does not equal y (eg: x <> y or x != y) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
|
@ -170,9 +171,12 @@ Expression Library can be found at:
|
|||
+-----------+--------------------------------------------------------+
|
||||
| or | Logical OR, True if either x or y is true. (eg: x or y)|
|
||||
+-----------+--------------------------------------------------------+
|
||||
| xor | Local XOR, True only if the logical states of x and y |
|
||||
| xor | Logical XOR, True only if the logical states of x and y|
|
||||
| | differ. (eg: x xor y) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| xnor | Logical XNOR, True iff the biconditional of x and y is |
|
||||
| | satisfied. (eg: x xnor y) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| if | If x is true then return y else return z. |
|
||||
| | (eg: if(x, y, z) or if((x + 1) > 2y, z + 1, w / v)) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
|
@ -183,7 +187,7 @@ Expression Library can be found at:
|
|||
+-----------+--------------------------------------------------------+
|
||||
| abs | Absolute value of x. |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| avg | The average of all the inputs. |
|
||||
| avg | Average of all the inputs. |
|
||||
| | (eg: avg(x,y,z,w) == (x+y+z+w)/4) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| ceil | Smallest integer that is greater than or equal to x. |
|
||||
|
@ -203,18 +207,18 @@ Expression Library can be found at:
|
|||
+-----------+--------------------------------------------------------+
|
||||
| frac | Fractional portion of x |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| hypot | Hypotenuse of x and y (eg: hypot(x,y)) |
|
||||
| hypot | Hypotenuse of x and y (eg: hypot(x,y) = sqrt(x*x +y*y))|
|
||||
+-----------+--------------------------------------------------------+
|
||||
| log | Natural logarithm of x |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| log10 | Base 10 logarithm of x |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| log1p | Natural logarithm of 1 + x, where x is very small. |
|
||||
| | (eg: log1p(x)) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| logn | Base N logarithm of x (eg: logn(1235,8)) |
|
||||
| | where n > 0 and is an integer. |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| log1p | Natural logarithm of 1 + x (eg: log1p(x)) |
|
||||
| | where x is very small. |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| nequal | Not-equal test between x and y using normalized epsilon|
|
||||
+-----------+--------------------------------------------------------+
|
||||
| root | Nth-Root of x (eg: root(x,3)) |
|
||||
|
@ -229,7 +233,7 @@ Expression Library can be found at:
|
|||
+-----------+--------------------------------------------------------+
|
||||
| sqrt | Square root of x, where x > 0 |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| sum | The sum of all the inputs. |
|
||||
| sum | Sum of all the inputs. |
|
||||
| | (eg: sum(x,y,z,w,v) == (x+y+z+w+v)) |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| trunc | Integer portion of x |
|
||||
|
@ -265,12 +269,12 @@ Expression Library can be found at:
|
|||
+-----------+--------------------------------------------------------+
|
||||
| tanh | Hyperbolic tangent of x |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| rad2deg | Convert x from radians to degrees |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| deg2rad | Convert x from degrees to radians |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| deg2grad | Convert x from degrees to gradians |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| rad2deg | Convert x from radians to degrees |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| grad2deg | Convert x from gradians to degrees |
|
||||
+-----------+--------------------------------------------------------+
|
||||
|
||||
|
@ -284,25 +288,25 @@ Expression Library can be found at:
|
|||
| like | True only if the string x matches the pattern y. |
|
||||
| | Available wildcard characters are '*' and '?' denoting |
|
||||
| | zero or more and zero or one matches respectively. |
|
||||
| | (eg: x like y or 'abcdefgh' like 'a?d*') |
|
||||
| | (eg: x like y or 'abcdefgh' like 'a?d*h') |
|
||||
+-----------+--------------------------------------------------------+
|
||||
| like | True only if the string x matches the pattern y in a |
|
||||
| | case insensitive manner. Available wildcard characters |
|
||||
| | are '*' and '?' denoting zero or more and zero or one |
|
||||
| | matches respectively. |
|
||||
| | (eg: x ilike y or 'abcdefgh' like 'a?d*') |
|
||||
| | (eg: x ilike y or 'a1B2c3D4e5F6g7H' like 'a?d*h') |
|
||||
+-----------+--------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
[SPECIAL FUNCTIONS]
|
||||
The purpose of special functions in ExprTk is to provide compiler
|
||||
generated equivalents of common mathematical expressions which can be
|
||||
invoked by using the 'special function' syntax (eg: $f12(x,y,z) or
|
||||
$f24(x,y,z,w)). Where possible, for sub-expressions that are comprised
|
||||
of combinations of variables and literal values the ExprTk compiler
|
||||
will perform a best effort attempt to replace such expressions with
|
||||
special functions.
|
||||
Special functions dramatically decrease the total evaluation time of
|
||||
expressions, which would otherwise have been written using the common
|
||||
form, by reducing the total number of nodes in the evaluation tree of
|
||||
an expression and by also leveraging the C++ compiler's ability to
|
||||
select an appropriate set of instructions for the given expression and
|
||||
architecture so as to provide the most optimal and precision sensitive
|
||||
result.
|
||||
|
||||
Special functions dramatically decrease the total evaluation time of
|
||||
expressions which would otherwise have been written using the common
|
||||
|
@ -370,27 +374,42 @@ correctly optimize such expressions for a given architecture.
|
|||
|
||||
|
||||
[EXPRTK NOTES]
|
||||
(0) Supported types are float, double and long double.
|
||||
(00) Supported types are float, double and long double.
|
||||
|
||||
(1) Standard mathematical operator precedence is applied (BEDMAS).
|
||||
(01) Standard mathematical operator precedence is applied (BEDMAS).
|
||||
|
||||
(2) All variables and functions are case-insensitive
|
||||
(02) Supported user defined types are numeric and string variables
|
||||
and functions.
|
||||
|
||||
(3) Expression lengths are limited only by storage capacity.
|
||||
(03) All variable and function names are case-insensitive
|
||||
|
||||
(4) Equal/Nequal routines use epsilons of 0.00000000001 and 0.000001
|
||||
for double and float types respectively.
|
||||
(04) Variable and function names must begin with a letter
|
||||
(A-Z or a-z), then can be comprised of any combination of
|
||||
letters, digits and underscores. (eg: x, var1 or power_func99)
|
||||
|
||||
(5) All trigonometric functions assume radian input unless
|
||||
stated otherwise.
|
||||
(05) Expression lengths are limited only by storage capacity.
|
||||
|
||||
(6) Expressions can contain white-space characters such as
|
||||
space, tabs, new-lines, control-feed et al.
|
||||
('\n', '\r', '\t', '\b', '\v', '\f')
|
||||
(06) Equal/Nequal routines use epsilons of 0.0000000001 and 0.000001
|
||||
for double and float types respectively.
|
||||
|
||||
(7) User defined functions can have up to 20 parameters.
|
||||
(07) All trigonometric functions assume radian input unless
|
||||
stated otherwise.
|
||||
|
||||
(8) Polynomial functions can be at most of degree 10.
|
||||
(08) Expressions may contain white-space characters such as
|
||||
space, tabs, new-lines, control-feed et al.
|
||||
('\n', '\r', '\t', '\b', '\v', '\f')
|
||||
|
||||
(09) Strings may be constructed from any letters, digits or special
|
||||
characters such as (~!@#$%^&*()[]|=+ ,./?<>;:"`~_), and must
|
||||
be enclosed with single-quotes.
|
||||
eg: 'Frankly, my dear, I don't give a damn!'
|
||||
|
||||
(10) User defined functions can have up to 20 parameters.
|
||||
|
||||
(11) Polynomial functions can be at most of degree 10.
|
||||
|
||||
(12) Where appropriate constant folding optimisations will be
|
||||
applied. (eg: The expression '2+(3-(x/y))' becomes '5-(x/y)')
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue