C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
6385bd7c90
commit
5631cc5b8e
163
exprtk.hpp
163
exprtk.hpp
|
@ -4033,7 +4033,10 @@ namespace exprtk
|
|||
{
|
||||
if (0 != node)
|
||||
{
|
||||
if (is_variable_node(node) && !force_delete)
|
||||
if (
|
||||
(is_variable_node(node) || is_string_node(node)) ||
|
||||
force_delete
|
||||
)
|
||||
return;
|
||||
|
||||
node_allocator.free(node);
|
||||
|
@ -6407,9 +6410,11 @@ namespace exprtk
|
|||
|
||||
range_t& range = str_range_ptr_->range_ref();
|
||||
|
||||
const std::size_t base_str_size = str_base_ptr_->str().size();
|
||||
|
||||
if (
|
||||
range (str_r0,str_r1,str_base_ptr_->str().size()) &&
|
||||
base_range_(r0,r1)
|
||||
range (str_r0,str_r1,base_str_size) &&
|
||||
base_range_( r0, r1,base_str_size)
|
||||
)
|
||||
{
|
||||
const std::size_t size = (r1 - r0) + 1;
|
||||
|
@ -7293,7 +7298,19 @@ namespace exprtk
|
|||
variable_node<T>* var_node_ptr_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct asn_assignment
|
||||
{
|
||||
static inline void execute(std::string& s, const char* data, const std::size_t size)
|
||||
{ s.assign(data,size); }
|
||||
};
|
||||
|
||||
struct asn_addassignment
|
||||
{
|
||||
static inline void execute(std::string& s, const char* data, const std::size_t size)
|
||||
{ s.append(data,size); }
|
||||
};
|
||||
|
||||
template <typename T, typename AssignmentProcess = asn_assignment>
|
||||
class assignment_string_node : public binary_node <T>,
|
||||
public string_base_node<T>,
|
||||
public range_interface <T>
|
||||
|
@ -7359,7 +7376,9 @@ namespace exprtk
|
|||
|
||||
if (range(r0,r1,str1_base_ptr_->str().size()))
|
||||
{
|
||||
str0_node_ptr_->ref().assign(str1_base_ptr_->str().data() + r0, (r1 - r0) + 1);
|
||||
AssignmentProcess::execute(str0_node_ptr_->ref(),
|
||||
str1_base_ptr_->str().data() + r0,
|
||||
(r1 - r0) + 1);
|
||||
|
||||
binary_node<T>::branch_[0].first->value();
|
||||
}
|
||||
|
@ -19627,6 +19646,7 @@ namespace exprtk
|
|||
(details::e_like == operation) ||
|
||||
(details::e_ilike == operation) ||
|
||||
(details::e_assign == operation) ||
|
||||
(details::e_addass == operation) ||
|
||||
(details::e_swap == operation) ;
|
||||
}
|
||||
#else
|
||||
|
@ -19836,15 +19856,22 @@ namespace exprtk
|
|||
|
||||
inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
|
||||
{
|
||||
return is_assignment_operation(operation) &&
|
||||
(
|
||||
(
|
||||
!details::is_variable_node (branch[0]) &&
|
||||
!details::is_vector_elem_node(branch[0]) &&
|
||||
!details::is_vector_node (branch[0])
|
||||
) ||
|
||||
is_generally_string_node(branch[1])
|
||||
);
|
||||
if (is_assignment_operation(operation))
|
||||
{
|
||||
const bool b1_is_genstring = details::is_generally_string_node(branch[1]);
|
||||
|
||||
if (details::is_string_node(branch[0]))
|
||||
return !b1_is_genstring;
|
||||
else
|
||||
return (
|
||||
!details::is_variable_node (branch[0]) &&
|
||||
!details::is_vector_elem_node(branch[0]) &&
|
||||
!details::is_vector_node (branch[0])
|
||||
)
|
||||
|| b1_is_genstring;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2])
|
||||
|
@ -20170,8 +20197,8 @@ namespace exprtk
|
|||
#endif
|
||||
}
|
||||
|
||||
inline expression_node_ptr repeat_until_loop(expression_node_ptr condition,
|
||||
expression_node_ptr branch,
|
||||
inline expression_node_ptr repeat_until_loop(expression_node_ptr& condition,
|
||||
expression_node_ptr& branch,
|
||||
const bool brkcont = false) const
|
||||
{
|
||||
if (!brkcont && details::is_constant_node(condition))
|
||||
|
@ -20204,10 +20231,10 @@ namespace exprtk
|
|||
#endif
|
||||
}
|
||||
|
||||
inline expression_node_ptr for_loop(expression_node_ptr initialiser,
|
||||
expression_node_ptr condition,
|
||||
expression_node_ptr incrementor,
|
||||
expression_node_ptr loop_body,
|
||||
inline expression_node_ptr for_loop(expression_node_ptr& initialiser,
|
||||
expression_node_ptr& condition,
|
||||
expression_node_ptr& incrementor,
|
||||
expression_node_ptr& loop_body,
|
||||
bool brkcont = false) const
|
||||
{
|
||||
if (!brkcont && details::is_constant_node(condition))
|
||||
|
@ -20935,7 +20962,7 @@ namespace exprtk
|
|||
alloc_type* genfunc_node_ptr = static_cast<alloc_type*>(result);
|
||||
|
||||
if (
|
||||
!arg_list.empty() &&
|
||||
!arg_list.empty() &&
|
||||
!gf->has_side_effects &&
|
||||
is_constant_foldable(arg_list)
|
||||
)
|
||||
|
@ -20971,7 +20998,7 @@ namespace exprtk
|
|||
alloc_type* genfunc_node_ptr = static_cast<alloc_type*>(result);
|
||||
|
||||
if (
|
||||
!arg_list.empty() &&
|
||||
!arg_list.empty() &&
|
||||
!gf->has_side_effects &&
|
||||
is_constant_foldable(arg_list)
|
||||
)
|
||||
|
@ -21169,6 +21196,15 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (
|
||||
(details::e_addass == operation) &&
|
||||
details::is_string_node(branch[0])
|
||||
)
|
||||
{
|
||||
typedef details::assignment_string_node<T,details::asn_addassignment> addass_t;
|
||||
|
||||
return synthesize_expression<addass_t,2>(operation,branch);
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_->set_synthesis_error("Invalid assignment operation[2]");
|
||||
|
@ -28917,6 +28953,89 @@ namespace exprtk
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace helper
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
template <typename T>
|
||||
struct print_impl
|
||||
{
|
||||
typedef typename igeneric_function<T>::generic_type generic_type;
|
||||
typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
|
||||
typedef typename generic_type::scalar_view scalar_t;
|
||||
typedef typename generic_type::vector_view vector_t;
|
||||
typedef typename generic_type::string_view string_t;
|
||||
|
||||
static void process(const std::string& scalar_format, parameter_list_t parameters)
|
||||
{
|
||||
for (std::size_t i = 0; i < parameters.size(); ++i)
|
||||
{
|
||||
generic_type& gt = parameters[i];
|
||||
|
||||
switch (gt.type)
|
||||
{
|
||||
case generic_type::e_scalar : printf(scalar_format.c_str(),scalar_t(gt)());
|
||||
break;
|
||||
|
||||
case generic_type::e_vector : {
|
||||
vector_t vector(gt);
|
||||
|
||||
for (std::size_t x = 0; x < vector.size(); ++x)
|
||||
{
|
||||
printf(scalar_format.c_str(),vector[x]);
|
||||
if ((x + 1) < vector.size())
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case generic_type::e_string : printf("%s",to_str(string_t(gt)).c_str());
|
||||
break;
|
||||
|
||||
default : continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct print : public exprtk::igeneric_function<T>
|
||||
{
|
||||
typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
|
||||
|
||||
print(const std::string& scalar_format = "%10.5f")
|
||||
: scalar_format_(scalar_format)
|
||||
{}
|
||||
|
||||
inline T operator()(parameter_list_t parameters)
|
||||
{
|
||||
details::print_impl<T>::process(scalar_format_,parameters);
|
||||
return T(0);
|
||||
}
|
||||
|
||||
std::string scalar_format_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct println : public exprtk::igeneric_function<T>
|
||||
{
|
||||
typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
|
||||
|
||||
println(const std::string& scalar_format = "%10.5f")
|
||||
: scalar_format_(scalar_format)
|
||||
{}
|
||||
|
||||
inline T operator()(parameter_list_t parameters)
|
||||
{
|
||||
details::print_impl<T>::process(scalar_format_,parameters);
|
||||
printf("\n");
|
||||
return T(0);
|
||||
}
|
||||
|
||||
std::string scalar_format_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
|
|
108
exprtk_test.cpp
108
exprtk_test.cpp
|
@ -130,16 +130,16 @@ static const test_t test_list[] =
|
|||
test_t("-7.7",-7.7),
|
||||
test_t("-8.8",-8.8),
|
||||
test_t("-9.9",-9.9),
|
||||
test_t("0.0e+0",+0.0e+0),
|
||||
test_t("1.1e+1",+1.1e+1),
|
||||
test_t("2.2e+2",+2.2e+2),
|
||||
test_t("3.3e+3",+3.3e+3),
|
||||
test_t("4.4e+4",+4.4e+4),
|
||||
test_t("5.5e+5",+5.5e+5),
|
||||
test_t("6.6e+6",+6.6e+6),
|
||||
test_t("7.7e+7",+7.7e+7),
|
||||
test_t("8.8e+8",+8.8e+8),
|
||||
test_t("9.9e+9",+9.9e+9),
|
||||
test_t("0.0e+0" ,+0.0e+0),
|
||||
test_t("1.1e+1" ,+1.1e+1),
|
||||
test_t("2.2e+2" ,+2.2e+2),
|
||||
test_t("3.3e+3" ,+3.3e+3),
|
||||
test_t("4.4e+4" ,+4.4e+4),
|
||||
test_t("5.5e+5" ,+5.5e+5),
|
||||
test_t("6.6e+6" ,+6.6e+6),
|
||||
test_t("7.7e+7" ,+7.7e+7),
|
||||
test_t("8.8e+8" ,+8.8e+8),
|
||||
test_t("9.9e+9" ,+9.9e+9),
|
||||
test_t("-0.0e+0",-0.0e+0),
|
||||
test_t("-1.1e+1",-1.1e+1),
|
||||
test_t("-2.2e+2",-2.2e+2),
|
||||
|
@ -150,16 +150,16 @@ static const test_t test_list[] =
|
|||
test_t("-7.7e+7",-7.7e+7),
|
||||
test_t("-8.8e+8",-8.8e+8),
|
||||
test_t("-9.9e+9",-9.9e+9),
|
||||
test_t("0.0E+0",+0.0E+0),
|
||||
test_t("1.1E+1",+1.1E+1),
|
||||
test_t("2.2E+2",+2.2E+2),
|
||||
test_t("3.3E+3",+3.3E+3),
|
||||
test_t("4.4E+4",+4.4E+4),
|
||||
test_t("5.5E+5",+5.5E+5),
|
||||
test_t("6.6E+6",+6.6E+6),
|
||||
test_t("7.7E+7",+7.7E+7),
|
||||
test_t("8.8E+8",+8.8E+8),
|
||||
test_t("9.9E+9",+9.9E+9),
|
||||
test_t("0.0E+0" ,+0.0E+0),
|
||||
test_t("1.1E+1" ,+1.1E+1),
|
||||
test_t("2.2E+2" ,+2.2E+2),
|
||||
test_t("3.3E+3" ,+3.3E+3),
|
||||
test_t("4.4E+4" ,+4.4E+4),
|
||||
test_t("5.5E+5" ,+5.5E+5),
|
||||
test_t("6.6E+6" ,+6.6E+6),
|
||||
test_t("7.7E+7" ,+7.7E+7),
|
||||
test_t("8.8E+8" ,+8.8E+8),
|
||||
test_t("9.9E+9" ,+9.9E+9),
|
||||
test_t("-0.0E+0",-0.0E+0),
|
||||
test_t("-1.1E+1",-1.1E+1),
|
||||
test_t("-2.2E+2",-2.2E+2),
|
||||
|
@ -200,16 +200,16 @@ static const test_t test_list[] =
|
|||
test_t("(7.7)",7.7),
|
||||
test_t("(8.8)",8.8),
|
||||
test_t("(9.9)",9.9),
|
||||
test_t("(+0)",0.0),
|
||||
test_t("(+1)",1.0),
|
||||
test_t("(+2)",2.0),
|
||||
test_t("(+3)",3.0),
|
||||
test_t("(+4)",4.0),
|
||||
test_t("(+5)",5.0),
|
||||
test_t("(+6)",6.0),
|
||||
test_t("(+7)",7.0),
|
||||
test_t("(+8)",8.0),
|
||||
test_t("(+9)",9.0),
|
||||
test_t("(+0)" ,0.0),
|
||||
test_t("(+1)" ,1.0),
|
||||
test_t("(+2)" ,2.0),
|
||||
test_t("(+3)" ,3.0),
|
||||
test_t("(+4)" ,4.0),
|
||||
test_t("(+5)" ,5.0),
|
||||
test_t("(+6)" ,6.0),
|
||||
test_t("(+7)" ,7.0),
|
||||
test_t("(+8)" ,8.0),
|
||||
test_t("(+9)" ,9.0),
|
||||
test_t("(+0.0)",0.0),
|
||||
test_t("(+1.0)",1.0),
|
||||
test_t("(+2.0)",2.0),
|
||||
|
@ -230,16 +230,16 @@ static const test_t test_list[] =
|
|||
test_t("(+7.7)",7.7),
|
||||
test_t("(+8.8)",8.8),
|
||||
test_t("(+9.9)",9.9),
|
||||
test_t("(-0)",-0.0),
|
||||
test_t("(-1)",-1.0),
|
||||
test_t("(-2)",-2.0),
|
||||
test_t("(-3)",-3.0),
|
||||
test_t("(-4)",-4.0),
|
||||
test_t("(-5)",-5.0),
|
||||
test_t("(-6)",-6.0),
|
||||
test_t("(-7)",-7.0),
|
||||
test_t("(-8)",-8.0),
|
||||
test_t("(-9)",-9.0),
|
||||
test_t("(-0)" ,-0.0),
|
||||
test_t("(-1)" ,-1.0),
|
||||
test_t("(-2)" ,-2.0),
|
||||
test_t("(-3)" ,-3.0),
|
||||
test_t("(-4)" ,-4.0),
|
||||
test_t("(-5)" ,-5.0),
|
||||
test_t("(-6)" ,-6.0),
|
||||
test_t("(-7)" ,-7.0),
|
||||
test_t("(-8)" ,-8.0),
|
||||
test_t("(-9)" ,-9.0),
|
||||
test_t("(-0.0)",-0.0),
|
||||
test_t("(-1.0)",-1.0),
|
||||
test_t("(-2.0)",-2.0),
|
||||
|
@ -2086,7 +2086,33 @@ inline bool run_test02()
|
|||
test_ab<T>("(a[r0:r0] + b[r3:r0+1]) == 'c3' ","abc","0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a[r0+1:] + b) == 'defghij0123' ","abcdefghij","0123",T(1.0)),
|
||||
test_ab<T>("a[r0+1: ] + '123' == 'abc' + b[r0+1: ]","XYZabc", "XYZ123", T(1.0)),
|
||||
test_ab<T>("a[r0+1:a[] - 1] + '123' == 'abc' + b[r0+1:b[] - 1]","XYZabc", "XYZ123", T(1.0))
|
||||
test_ab<T>("a[r0+1:a[] - 1] + '123' == 'abc' + b[r0+1:b[] - 1]","XYZabc", "XYZ123", T(1.0)),
|
||||
test_ab<T>("(a + b)[ :13] == 'abcdefghij0123' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[ 6: ] == 'ghij0123456789' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[ 2:3r1-1] == 'cdefghij01234567' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a[2:7] + b[2:7]) == 'cdefgh234567' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a[2:7] + b[2:7])[3:8] == 'fgh234' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[r0 - 2: r1 + r2] == 'abcdefghij0123' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[r0*r3:] == 'ghij0123456789' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[3r0: ] == 'ghij0123456789' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[2r3: ] == 'ghij0123456789' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a + b)[2:3r1 - 1] == 'cdefghij01234567' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a[r0:7] + b[r0:r2])== 'cdefgh234567' ", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a[r1 / r3:7] + b[r0:r2])[3:r2 + 1] == 'fgh234'", "abcdefghij", "0123456789" ,T(1.0)),
|
||||
test_ab<T>("(a += b) == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += '123') == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += b[3:5]) == 'abc123' ", "abc","XXX123XXX" ,T(1.0)),
|
||||
test_ab<T>("(a += 'XXX123XXX'[3:5]) == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += b)[:] == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += '123')[:] == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += b[3:5])[:] == 'abc123' ", "abc","XXX123XXX" ,T(1.0)),
|
||||
test_ab<T>("(a += 'XXX123XXX'[3:5])[:] == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += b[r1/2:r1-1]) == 'abc123' ", "abc","XXX123XXX" ,T(1.0)),
|
||||
test_ab<T>("(a += 'XXX123XXX'[r0+1:r1-1]) == 'abc123' ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += b)[] == 6 ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += '123')[] == 6 ", "abc","123" ,T(1.0)),
|
||||
test_ab<T>("(a += b[3:5])[] == 6 ", "abc","XXX123XXX" ,T(1.0)),
|
||||
test_ab<T>("(a += b[r0+1:r1-1])[] == 6 ", "abc","XXX123XXX" ,T(1.0))
|
||||
};
|
||||
|
||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
|
||||
|
|
|
@ -419,6 +419,13 @@ of C++ compilers:
|
|||
| | 6. 'abc' + '1234567' |
|
||||
| | 7. (x + 'a1B2c3D4' + y)[i:2j] |
|
||||
+----------+---------------------------------------------------------+
|
||||
| += | Append to x the value of y. Where x is a mutable string |
|
||||
| | and y is either a string or a string range. eg: |
|
||||
| | 1. x += y |
|
||||
| | 2. x += 'abc' |
|
||||
| | 3. x += y[:i + j] + 'abc' |
|
||||
| | 4. x += '0123456789'[2:7] |
|
||||
+----------+---------------------------------------------------------+
|
||||
| [] | The string size operator returns the size of the string |
|
||||
| | being actioned. |
|
||||
| | eg: |
|
||||
|
|
Loading…
Reference in New Issue