C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
79a3a265ec
commit
98761d3a94
229
exprtk.hpp
229
exprtk.hpp
|
@ -4218,6 +4218,28 @@ namespace exprtk
|
|||
unsigned int num_params;
|
||||
};
|
||||
|
||||
namespace loop_unroll
|
||||
{
|
||||
#ifndef exprtk_disable_superscalar_unroll
|
||||
const std::size_t loop_batch_size = 8;
|
||||
#else
|
||||
const std::size_t loop_batch_size = 4;
|
||||
#endif
|
||||
|
||||
struct details
|
||||
{
|
||||
details(const std::size_t& vsize)
|
||||
: batch_size(loop_batch_size),
|
||||
remainder (vsize % batch_size),
|
||||
upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
|
||||
{}
|
||||
|
||||
int batch_size;
|
||||
int remainder;
|
||||
int upper_bound;
|
||||
};
|
||||
}
|
||||
|
||||
namespace numeric
|
||||
{
|
||||
namespace details
|
||||
|
@ -6747,7 +6769,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return (*value_).data();
|
||||
return &(*value_)[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -6827,7 +6849,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return (*value_).data();
|
||||
return &(*value_)[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -7036,7 +7058,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return value_.data();
|
||||
return &value_[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -7175,7 +7197,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return value_.data();
|
||||
return &value_[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -7293,6 +7315,143 @@ namespace exprtk
|
|||
strvar_node_ptr str1_node_ptr_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class swap_genstrings_node : public binary_node<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef expression_node <T>* expression_ptr;
|
||||
typedef string_base_node<T>* str_base_ptr;
|
||||
typedef range_pack <T> range_t;
|
||||
typedef range_t* range_ptr;
|
||||
typedef range_interface<T> irange_t;
|
||||
typedef irange_t* irange_ptr;
|
||||
|
||||
swap_genstrings_node(expression_ptr branch0,
|
||||
expression_ptr branch1)
|
||||
: 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)
|
||||
{
|
||||
if (is_generally_string_node(binary_node<T>::branch_[0].first))
|
||||
{
|
||||
str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
|
||||
|
||||
if (0 == str0_base_ptr_)
|
||||
return;
|
||||
|
||||
irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
|
||||
|
||||
if (0 == range_ptr)
|
||||
return;
|
||||
|
||||
str0_range_ptr_ = &(range_ptr->range_ref());
|
||||
}
|
||||
|
||||
if (is_generally_string_node(binary_node<T>::branch_[1].first))
|
||||
{
|
||||
str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
|
||||
|
||||
if (0 == str1_base_ptr_)
|
||||
return;
|
||||
|
||||
irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
|
||||
|
||||
if (0 == range_ptr)
|
||||
return;
|
||||
|
||||
str1_range_ptr_ = &(range_ptr->range_ref());
|
||||
}
|
||||
|
||||
initialised_ = str0_base_ptr_ &&
|
||||
str1_base_ptr_ &&
|
||||
str0_range_ptr_ &&
|
||||
str1_range_ptr_ ;
|
||||
}
|
||||
|
||||
inline T value() const
|
||||
{
|
||||
if (initialised_)
|
||||
{
|
||||
binary_node<T>::branch_[0].first->value();
|
||||
binary_node<T>::branch_[1].first->value();
|
||||
|
||||
std::size_t str0_r0 = 0;
|
||||
std::size_t str0_r1 = 0;
|
||||
|
||||
std::size_t str1_r0 = 0;
|
||||
std::size_t str1_r1 = 0;
|
||||
|
||||
range_t& range0 = (*str0_range_ptr_);
|
||||
range_t& range1 = (*str1_range_ptr_);
|
||||
|
||||
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* s0 = const_cast<char*>(str0_base_ptr_->base() + str0_r0);
|
||||
char* s1 = const_cast<char*>(str1_base_ptr_->base() + str1_r0);
|
||||
|
||||
loop_unroll::details lud(max_size);
|
||||
int i = 0;
|
||||
|
||||
for (; i < lud.upper_bound; i += lud.batch_size)
|
||||
{
|
||||
std::swap(s0[i ], s1[i ]);
|
||||
std::swap(s0[i + 1], s1[i + 1]);
|
||||
std::swap(s0[i + 2], s1[i + 2]);
|
||||
std::swap(s0[i + 3], s1[i + 3]);
|
||||
#ifndef exprtk_disable_superscalar_unroll
|
||||
std::swap(s0[i + 4], s1[i + 4]);
|
||||
std::swap(s0[i + 5], s1[i + 5]);
|
||||
std::swap(s0[i + 6], s1[i + 6]);
|
||||
std::swap(s0[i + 7], s1[i + 7]);
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (lud.remainder)
|
||||
{
|
||||
#ifndef exprtk_disable_superscalar_unroll
|
||||
case 7 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
case 6 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
case 5 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
case 4 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
#endif
|
||||
case 3 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
case 2 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
case 1 : { std::swap(s0[i],s1[i]); ++i; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
}
|
||||
|
||||
inline typename expression_node<T>::node_type type() const
|
||||
{
|
||||
return expression_node<T>::e_strswap;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
swap_genstrings_node(swap_genstrings_node<T>&);
|
||||
swap_genstrings_node<T>& operator=(swap_genstrings_node<T>&);
|
||||
|
||||
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>
|
||||
class stringvar_size_node : public expression_node<T>
|
||||
{
|
||||
|
@ -7765,7 +7924,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return value_.data();
|
||||
return &value_[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -7885,7 +8044,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return value_.data();
|
||||
return &value_[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -8491,28 +8650,6 @@ namespace exprtk
|
|||
vector_elem_node<T>* vec_node_ptr_;
|
||||
};
|
||||
|
||||
namespace loop_unroll
|
||||
{
|
||||
#ifndef exprtk_disable_superscalar_unroll
|
||||
const std::size_t loop_batch_size = 8;
|
||||
#else
|
||||
const std::size_t loop_batch_size = 4;
|
||||
#endif
|
||||
|
||||
struct details
|
||||
{
|
||||
details(const std::size_t& vsize)
|
||||
: batch_size(loop_batch_size),
|
||||
remainder (vsize % batch_size),
|
||||
upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
|
||||
{}
|
||||
|
||||
int batch_size;
|
||||
int remainder;
|
||||
int upper_bound;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class assignment_vec_node : public binary_node <T>,
|
||||
public vector_interface<T>
|
||||
|
@ -10519,7 +10656,7 @@ namespace exprtk
|
|||
|
||||
const char* base() const
|
||||
{
|
||||
return ret_string_.data();
|
||||
return &ret_string_[0];
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
|
@ -21185,6 +21322,22 @@ namespace exprtk
|
|||
{
|
||||
const std::string symbol = current_token().value;
|
||||
|
||||
typedef details::stringvar_node<T>* strvar_node_t;
|
||||
|
||||
expression_node_ptr result = error_node();
|
||||
strvar_node_t const_str_node = static_cast<strvar_node_t>(0);
|
||||
bool is_const_string = false;
|
||||
|
||||
scope_element& se = sem_.get_active_element(symbol);
|
||||
|
||||
if (scope_element::e_string == se.type)
|
||||
{
|
||||
se.active = true;
|
||||
result = se.str_node;
|
||||
lodge_symbol(symbol,e_st_local_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!symtab_store_.is_conststr_stringvar(symbol))
|
||||
{
|
||||
set_error(
|
||||
|
@ -21195,12 +21348,9 @@ namespace exprtk
|
|||
return error_node();
|
||||
}
|
||||
|
||||
expression_node_ptr result = symtab_store_.get_stringvar(symbol);
|
||||
result = symtab_store_.get_stringvar(symbol);
|
||||
|
||||
typedef details::stringvar_node<T>* strvar_node_t;
|
||||
strvar_node_t const_str_node = static_cast<strvar_node_t>(0);
|
||||
|
||||
const bool is_const_string = symtab_store_.is_constant_string(symbol);
|
||||
is_const_string = symtab_store_.is_constant_string(symbol);
|
||||
|
||||
if (is_const_string)
|
||||
{
|
||||
|
@ -21209,6 +21359,7 @@ namespace exprtk
|
|||
}
|
||||
|
||||
lodge_symbol(symbol,e_st_string);
|
||||
}
|
||||
|
||||
if (peek_token_is(token_t::e_lsqrbracket))
|
||||
{
|
||||
|
@ -23122,12 +23273,7 @@ namespace exprtk
|
|||
#ifndef exprtk_disable_string_capabilities
|
||||
else if (scope_element::e_string == se.type)
|
||||
{
|
||||
se.active = true;
|
||||
lodge_symbol(symbol,e_st_local_string);
|
||||
|
||||
next_token();
|
||||
|
||||
return se.str_node;
|
||||
return parse_string();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -25895,7 +26041,10 @@ namespace exprtk
|
|||
#ifndef exprtk_disable_string_capabilities
|
||||
else if (v0_is_str && v1_is_str)
|
||||
{
|
||||
if (is_string_node(branch[0]) && is_string_node(branch[1]))
|
||||
result = node_allocator_->allocate<details::swap_string_node<T> >(branch[0],branch[1]);
|
||||
else
|
||||
result = node_allocator_->allocate<details::swap_genstrings_node<T> >(branch[0],branch[1]);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
|
|
|
@ -44,8 +44,8 @@ void primes()
|
|||
.add(
|
||||
function_t(
|
||||
"is_prime_impl1",
|
||||
"if(y == 1,true, "
|
||||
" if(0 == (x % y),false, "
|
||||
"if (y == 1,true, "
|
||||
" if (0 == (x % y),false, "
|
||||
" is_prime_impl1(x,y - 1)))",
|
||||
"x","y"));
|
||||
|
||||
|
@ -53,8 +53,8 @@ void primes()
|
|||
.add(
|
||||
function_t(
|
||||
"is_prime1",
|
||||
"if(frac(x) != 0, false, "
|
||||
" if(x <= 0, false, "
|
||||
"if (frac(x) != 0, false, "
|
||||
" if (x <= 0, false, "
|
||||
" is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1))))",
|
||||
"x"));
|
||||
|
||||
|
|
|
@ -2313,7 +2313,69 @@ inline bool run_test02()
|
|||
|
||||
test_ab<T>("a[] > 2 and a like b ","abc","*bc",T(1.0)),
|
||||
test_ab<T>("a[] > 2 and a ilike b","abc","*Bc",T(1.0)),
|
||||
test_ab<T>("a[] > 2 and a in b ","abc","123abc123",T(1.0))
|
||||
test_ab<T>("a[] > 2 and a in b ","abc","123abc123",T(1.0)),
|
||||
|
||||
test_ab<T>("a[0:0] := b[ :]; a == '0XXXX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:1] := b[ :]; a == '01XXX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:2] := b[ :]; a == '012XX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:3] := b[ :]; a == '0123X'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:4] := b[ :]; a == '01234'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:0] := b[6:]; a == '6XXXX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:1] := b[6:]; a == '67XXX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:2] := b[6:]; a == '678XX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:3] := b[6:]; a == '6789X'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:4] := b[6:]; a == '67890'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:0] <=> b[ :]; (a == '0XXXX') and (b == 'X1234567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:1] <=> b[ :]; (a == '01XXX') and (b == 'XX234567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:2] <=> b[ :]; (a == '012XX') and (b == 'XXX34567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:3] <=> b[ :]; (a == '0123X') and (b == 'XXXX4567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:4] <=> b[ :]; (a == '01234') and (b == 'XXXXX567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:0] <=> b[6:]; (a == '6XXXX') and (b == '012345X7890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:1] <=> b[6:]; (a == '67XXX') and (b == '012345XX890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:2] <=> b[6:]; (a == '678XX') and (b == '012345XXX90')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:3] <=> b[6:]; (a == '6789X') and (b == '012345XXXX0')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("a[0:4] <=> b[6:]; (a == '67890') and (b == '012345XXXXX')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+0] := b[:]; a == '0XXXX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+1] := b[:]; a == '01XXX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+2] := b[:]; a == '012XX'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+3] := b[:]; a == '0123X'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+4] := b[:]; a == '01234'", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+0] <=> b[:]; (a == '0XXXX') and (b == 'X1234567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+1] <=> b[:]; (a == '01XXX') and (b == 'XX234567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+2] <=> b[:]; (a == '012XX') and (b == 'XXX34567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+3] <=> b[:]; (a == '0123X') and (b == 'XXXX4567890')", "XXXXX","01234567890",T(1.0)),
|
||||
test_ab<T>("var i := 0; a[0:i+4] <=> b[:]; (a == '01234') and (b == 'XXXXX567890')", "XXXXX","01234567890",T(1.0)),
|
||||
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:0] := y[:]; x == '0XXXX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:1] := y[:]; x == '01XXX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:2] := y[:]; x == '012XX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:3] := y[:]; x == '0123X'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:4] := y[:]; x == '01234'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:0] := y[6:]; x == '6XXXX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:1] := y[6:]; x == '67XXX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:2] := y[6:]; x == '678XX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:3] := y[6:]; x == '6789X'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:4] := y[6:]; x == '67890'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:0] <=> y[:]; (x == '0XXXX') and (y == 'X1234567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:1] <=> y[:]; (x == '01XXX') and (y == 'XX234567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:2] <=> y[:]; (x == '012XX') and (y == 'XXX34567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:3] <=> y[:]; (x == '0123X') and (y == 'XXXX4567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:4] <=> y[:]; (x == '01234') and (y == 'XXXXX567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:0] <=> y[6:]; (x == '6XXXX') and (y == '012345X7890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:1] <=> y[6:]; (x == '67XXX') and (y == '012345XX890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:2] <=> y[6:]; (x == '678XX') and (y == '012345XXX90')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:3] <=> y[6:]; (x == '6789X') and (y == '012345XXXX0')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; x[0:4] <=> y[6:]; (x == '67890') and (y == '012345XXXXX')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+0] := y[:]; x == '0XXXX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+1] := y[:]; x == '01XXX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+2] := y[:]; x == '012XX'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+3] := y[:]; x == '0123X'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+4] := y[:]; x == '01234'", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+0] <=> y[:]; (x == '0XXXX') and (y == 'X1234567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+1] <=> y[:]; (x == '01XXX') and (y == 'XX234567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+2] <=> y[:]; (x == '012XX') and (y == 'XXX34567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+3] <=> y[:]; (x == '0123X') and (y == 'XXXX4567890')", "","",T(1.0)),
|
||||
test_ab<T>("var x := 'XXXXX'; var y := '01234567890'; var i := 0; x[0:i+4] <=> y[:]; (x == '01234') and (y == 'XXXXX567890')", "","",T(1.0))
|
||||
};
|
||||
|
||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
|
||||
|
|
|
@ -849,8 +849,8 @@ The reason for the above complexity and restrictions of deep copies
|
|||
for the expression and symbol_table components is because expressions
|
||||
may include user defined variables or functions. These are embedded as
|
||||
references into the expression's AST. When copying an expression, said
|
||||
references need to also be copied. if the references are blindly
|
||||
copied, then it will result in two or more identical expressions
|
||||
references need to also be copied. If the references are blindly
|
||||
copied, it will then result in two or more identical expressions
|
||||
utilizing the exact same references for variables. This obviously is
|
||||
not the default assumed scenario and will give rise to non-obvious
|
||||
behaviours when using the expressions in various contexts such as
|
||||
|
|
Loading…
Reference in New Issue