C++ Mathematical Expression Library (ExprTk) https://www.partow.net/programming/exprtk/index.html
diff --git a/.circleci/config.yml b/.circleci/config.yml
index a0cba13..14a17a8 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,18 +1,18 @@
version: 2.1
jobs:
- build_gcc_6:
+ build_gcc_09:
docker:
- - image: gcc:6
+ - image: gcc:9
steps:
- checkout
- run: c++ --version
- run: make all -j 2
- run: ./exprtk_test
- build_gcc_7:
+ build_gcc_10:
docker:
- - image: gcc:7
+ - image: gcc:10
steps:
- checkout
- run: c++ --version
@@ -32,6 +32,6 @@
version: 2
build_and_test:
jobs:
- - build_gcc_6
- - build_gcc_7
+ - build_gcc_09
+ - build_gcc_10
- build_gcc_latest
diff --git a/Makefile b/Makefile
index dbb7697..54c776c 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@
# **************************************************************
# * C++ Mathematical Expression Toolkit Library *
# * *
-# * Author: Arash Partow (1999-2022) *
-# * URL: http://www.partow.net/programming/exprtk/index.html *
+# * Author: Arash Partow (1999-2023) *
+# * URL: https://www.partow.net/programming/exprtk/index.html *
# * *
# * Copyright notice: *
# * Free use of the Mathematical Expression Toolkit Library is *
diff --git a/exprtk.hpp b/exprtk.hpp
index 4a4db54..b4530ba 100644
--- a/exprtk.hpp
+++ b/exprtk.hpp
@@ -2,7 +2,7 @@
******************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
- * Author: Arash Partow (1999-2022) *
+ * Author: Arash Partow (1999-2023) *
* URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
@@ -38,7 +38,6 @@
#include <cassert>
#include <cctype>
#include <cmath>
-#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -298,7 +297,6 @@
std::reverse(result.begin(), result.end());
-
return result;
}
@@ -401,7 +399,7 @@
{
public:
- build_string(const std::size_t& initial_size = 64)
+ explicit build_string(const std::size_t& initial_size = 64)
{
data_.reserve(initial_size);
}
@@ -605,6 +603,8 @@
const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
const typename std::iterator_traits<Iterator>::value_type& exactly_one )
{
+ typedef typename std::iterator_traits<Iterator>::value_type type;
+
const Iterator null_itr(0);
Iterator p_itr = pattern_begin;
@@ -614,39 +614,45 @@
for ( ; ; )
{
- const bool pvalid = p_itr != pattern_end;
- const bool dvalid = d_itr != data_end;
-
- if (!pvalid && !dvalid)
- break;
-
- if (pvalid)
+ if (p_itr != pattern_end)
{
- const typename std::iterator_traits<Iterator>::value_type c = *(p_itr);
+ const type c = *(p_itr);
- if (zero_or_more == c)
+ if ((data_end != d_itr) && (Compare::cmp(c,*(d_itr)) || (exactly_one == c)))
{
- np_itr = p_itr;
- nd_itr = d_itr + 1;
- ++p_itr;
- continue;
- }
- else if (dvalid && ((exactly_one == c) || Compare::cmp(c,*(d_itr))))
- {
- ++p_itr;
++d_itr;
+ ++p_itr;
+ continue;
+ }
+ else if (zero_or_more == c)
+ {
+ while ((pattern_end != p_itr) && (zero_or_more == *(p_itr)))
+ {
+ ++p_itr;
+ }
+
+ const type d = *(p_itr);
+
+ while ((data_end != d_itr) && !(Compare::cmp(d,*(d_itr)) || (exactly_one == d)))
+ {
+ ++d_itr;
+ }
+
+ // set backtrack iterators
+ np_itr = p_itr - 1;
+ nd_itr = d_itr + 1;
+
continue;
}
}
+ else if (data_end == d_itr)
+ return true;
- if ((null_itr != nd_itr) && (nd_itr <= data_end))
- {
- p_itr = np_itr;
- d_itr = nd_itr;
- continue;
- }
+ if ((data_end == d_itr) || (null_itr == nd_itr))
+ return false;
- return false;
+ p_itr = np_itr;
+ d_itr = nd_itr;
}
return true;
@@ -774,7 +780,6 @@
{
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>
@@ -788,10 +793,6 @@
template <> struct number_type<T> \
{ typedef real_type_tag type; number_type() {} }; \
- #define exprtk_register_complex_type_tag(T) \
- template <> struct number_type<std::complex<T> > \
- { typedef complex_type_tag type; number_type() {} }; \
-
#define exprtk_register_int_type_tag(T) \
template <> struct number_type<T> \
{ typedef int_type_tag type; number_type() {} }; \
@@ -800,10 +801,6 @@
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 )
@@ -2063,6 +2060,11 @@
details::_uint64_t iteration_count;
};
+ virtual bool check()
+ {
+ return true;
+ }
+
virtual void handle_runtime_violation(const violation_context&)
{
throw std::runtime_error("ExprTk Loop run-time violation.");
@@ -3318,7 +3320,7 @@
ignore_set_.insert(symbol);
}
- inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token)
+ inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override
{
bool match = false;
new_token.type = lexer::token::e_mul;
@@ -3373,7 +3375,7 @@
: token_joiner(stride)
{}
- inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t)
+ inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override
{
// ': =' --> ':='
if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
@@ -3521,7 +3523,7 @@
inline bool join(const lexer::token& t0,
const lexer::token& t1,
const lexer::token& t2,
- lexer::token& t)
+ lexer::token& t) exprtk_override
{
// '[ * ]' --> '[*]'
if (
@@ -3626,7 +3628,8 @@
lexer::token error_token_;
};
- class numeric_checker : public lexer::token_scanner
+ template <typename T>
+ class numeric_checker exprtk_final : public lexer::token_scanner
{
public:
@@ -3652,7 +3655,7 @@
{
if (token::e_number == t.type)
{
- double v;
+ T v;
if (!exprtk::details::string_to_real(t.value,v))
{
@@ -3756,7 +3759,7 @@
replace_map_t replace_map_;
};
- class sequence_validator : public lexer::token_scanner
+ class sequence_validator exprtk_final : public lexer::token_scanner
{
private:
@@ -3928,7 +3931,7 @@
std::vector<std::pair<lexer::token,lexer::token> > error_list_;
};
- class sequence_validator_3tokens : public lexer::token_scanner
+ class sequence_validator_3tokens exprtk_final : public lexer::token_scanner
{
private:
@@ -4762,12 +4765,12 @@
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
+ exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr));
}
#else
inline void dump_ptr(const std::string&, const void*) {}
@@ -4811,7 +4814,7 @@
{
if (data && destruct && (0 == ref_count))
{
- dump_ptr("~control_block() data",data);
+ dump_ptr("~vec_data_store::control_block() data",data);
delete[] data;
data = reinterpret_cast<data_t>(0);
}
@@ -5225,12 +5228,6 @@
}
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());
@@ -5342,7 +5339,11 @@
template <typename T>
inline bool is_constant_node(const expression_node<T>* node)
{
- return node && (details::expression_node<T>::e_constant == node->type());
+ return node &&
+ (
+ details::expression_node<T>::e_constant == node->type() ||
+ details::expression_node<T>::e_stringconst == node->type()
+ );
}
template <typename T>
@@ -5942,16 +5943,16 @@
: vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
{}
- vector_holder(const vds_t& vds)
+ explicit 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)
+ explicit 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)
+ explicit vector_holder(exprtk::vector_view<Type>& vec)
: vector_holder_base_(new(buffer)vector_view_impl(vec))
{}
@@ -6069,9 +6070,9 @@
const bool result = details::numeric::is_nan(v);
if (result)
- return (equality_) ? T(1) : T(0);
+ return equality_ ? T(1) : T(0);
else
- return (equality_) ? T(0) : T(1);
+ return equality_ ? T(0) : T(1);
}
inline typename expression_node<T>::node_type type() const exprtk_override
@@ -6255,9 +6256,7 @@
inline T value() const exprtk_override
{
assert(branch_.first);
-
const T arg = branch_.first->value();
-
return numeric::process<T>(operation_,arg);
}
@@ -6286,12 +6285,12 @@
expression_node<T>::ndb_t::collect(branch_, node_delete_list);
}
- std::size_t node_depth() const exprtk_override exprtk_final
+ std::size_t node_depth() const exprtk_final
{
return expression_node<T>::ndb_t::compute_node_depth(branch_);
}
- protected:
+ private:
operator_type operation_;
branch_t branch_;
@@ -6321,7 +6320,7 @@
const T arg0 = branch_[0].first->value();
const T arg1 = branch_[1].first->value();
- return numeric::process<T>(operation_,arg0,arg1);
+ return numeric::process<T>(operation_, arg0, arg1);
}
inline typename expression_node<T>::node_type type() const exprtk_override
@@ -6349,12 +6348,12 @@
expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
}
- std::size_t node_depth() const exprtk_override exprtk_final
+ std::size_t node_depth() const exprtk_final
{
return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
}
- protected:
+ private:
operator_type operation_;
branch_t branch_[2];
@@ -6733,7 +6732,7 @@
{
if (
(0 == loop_runtime_check_) ||
- (++iteration_count_ <= max_loop_iterations_)
+ ((++iteration_count_ <= max_loop_iterations_) && loop_runtime_check_->check())
)
{
return true;
@@ -8169,6 +8168,8 @@
typedef vector_node <T>* vector_node_ptr;
typedef vec_data_store <T> vds_t;
+ using binary_node<T>::branch;
+
swap_vecvec_node(expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(details::e_swap, branch0, branch1)
@@ -8177,22 +8178,22 @@
, vec_size_ (0)
, initialised_ (false)
{
- if (is_ivector_node(binary_node<T>::branch_[0].first))
+ if (is_ivector_node(branch(0)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
{
vec0_node_ptr_ = vi->vec();
vds() = vi->vds();
}
}
- if (is_ivector_node(binary_node<T>::branch_[1].first))
+ if (is_ivector_node(branch(1)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
{
vec1_node_ptr_ = vi->vec();
}
@@ -8213,11 +8214,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ binary_node<T>::branch(0)->value();
+ binary_node<T>::branch(1)->value();
T* vec0 = vec0_node_ptr_->vds().data();
T* vec1 = vec1_node_ptr_->vds().data();
@@ -8678,6 +8679,8 @@
typedef expression_node <T>* expression_ptr;
typedef string_base_node<T>* str_base_ptr;
+ using binary_node<T>::branch;
+
string_concat_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -8694,27 +8697,27 @@
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))
+ if (is_generally_string_node(branch(0)))
{
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
+ str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
if (0 == str0_base_ptr_)
return;
- str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+ str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0));
if (0 == str0_range_ptr_)
return;
}
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
+ if (is_generally_string_node(branch(1)))
{
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
+ str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
if (0 == str1_base_ptr_)
return;
- str1_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+ str1_range_ptr_ = dynamic_cast<irange_ptr>(branch(1));
if (0 == str1_range_ptr_)
return;
@@ -8732,11 +8735,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
std::size_t str0_r0 = 0;
std::size_t str0_r1 = 0;
@@ -8823,20 +8826,22 @@
typedef stringvar_node <T>* strvar_node_ptr;
typedef string_base_node<T>* str_base_ptr;
+ using binary_node<T>::branch;
+
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))
+ if (is_string_node(branch(0)))
{
- str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
+ str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0));
}
- if (is_string_node(binary_node<T>::branch_[1].first))
+ if (is_string_node(branch(1)))
{
- str1_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[1].first);
+ str1_node_ptr_ = static_cast<strvar_node_ptr>(branch(1));
}
initialised_ = (str0_node_ptr_ && str1_node_ptr_);
@@ -8848,11 +8853,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref());
}
@@ -8909,6 +8914,8 @@
typedef expression_node <T>* expression_ptr;
typedef string_base_node<T>* str_base_ptr;
+ using binary_node<T>::branch;
+
swap_genstrings_node(expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(details::e_default, branch0, branch1)
@@ -8918,14 +8925,14 @@
, str1_range_ptr_(0)
, initialised_(false)
{
- if (is_generally_string_node(binary_node<T>::branch_[0].first))
+ if (is_generally_string_node(branch(0)))
{
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
+ str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
if (0 == str0_base_ptr_)
return;
- irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
if (0 == range)
return;
@@ -8933,14 +8940,14 @@
str0_range_ptr_ = &(range->range_ref());
}
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
+ if (is_generally_string_node(branch(1)))
{
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
+ str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
if (0 == str1_base_ptr_)
return;
- irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
if (0 == range)
return;
@@ -8960,11 +8967,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
std::size_t str0_r0 = 0;
std::size_t str0_r1 = 0;
@@ -9174,6 +9181,8 @@
typedef stringvar_node <T>* strvar_node_ptr;
typedef string_base_node<T>* str_base_ptr;
+ using binary_node<T>::branch;
+
assignment_string_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -9184,21 +9193,20 @@
, str0_node_ptr_ (0)
, str1_range_ptr_(0)
{
- if (is_string_node(binary_node<T>::branch_[0].first))
+ if (is_string_node(branch(0)))
{
- 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);
+ str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0));
+ str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
}
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
+ if (is_generally_string_node(branch(1)))
{
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
+ str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
if (0 == str1_base_ptr_)
return;
- irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
if (0 == range)
return;
@@ -9218,10 +9226,10 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[1].first->value();
+ branch(1)->value();
std::size_t r0 = 0;
std::size_t r1 = 0;
@@ -9234,7 +9242,7 @@
str1_base_ptr_->base() + r0,
(r1 - r0) + 1);
- binary_node<T>::branch_[0].first->value();
+ branch(0)->value();
}
}
@@ -9297,6 +9305,8 @@
typedef string_range_node<T>* str_rng_node_ptr;
typedef string_base_node <T>* str_base_ptr;
+ using binary_node<T>::branch;
+
assignment_string_range_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -9308,13 +9318,11 @@
, str0_range_ptr_ (0)
, str1_range_ptr_ (0)
{
- if (is_string_range_node(binary_node<T>::branch_[0].first))
+ if (is_string_range_node(branch(0)))
{
- 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);
+ str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(branch(0));
+ str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
if (0 == range)
return;
@@ -9322,14 +9330,14 @@
str0_range_ptr_ = &(range->range_ref());
}
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
+ if (is_generally_string_node(branch(1)))
{
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
+ str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
if (0 == str1_base_ptr_)
return;
- irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
if (0 == range)
return;
@@ -9350,11 +9358,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
std::size_t s0_r0 = 0;
std::size_t s0_r1 = 0;
@@ -9601,6 +9609,8 @@
typedef expression_node <T>* expression_ptr;
typedef string_base_node<T>* str_base_ptr;
+ using binary_node<T>::branch;
+
cons_conditional_str_node(expression_ptr condition,
expression_ptr consequent)
: binary_node<T>(details::e_default, consequent, condition)
@@ -9616,14 +9626,14 @@
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))
+ if (is_generally_string_node(branch(0)))
{
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
+ str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
if (0 == str0_base_ptr_)
return;
- str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+ str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0));
if (0 == str0_range_ptr_)
return;
@@ -10349,6 +10359,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_node(const operator_type& opr,
expression_ptr branch0,
@@ -10356,9 +10367,9 @@
: binary_node<T>(opr, branch0, branch1)
, var_node_ptr_(0)
{
- if (is_variable_node(binary_node<T>::branch_[0].first))
+ if (is_variable_node(branch(0)))
{
- var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
+ var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
}
}
@@ -10366,11 +10377,10 @@
{
if (var_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& result = var_node_ptr_->ref();
-
- result = binary_node<T>::branch_[1].first->value();
+ result = branch(1)->value();
return result;
}
@@ -10389,6 +10399,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_vec_elem_node(const operator_type& opr,
expression_ptr branch0,
@@ -10396,9 +10407,9 @@
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
{
- if (is_vector_elem_node(binary_node<T>::branch_[0].first))
+ if (is_vector_elem_node(branch(0)))
{
- vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
+ vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
}
}
@@ -10406,11 +10417,10 @@
{
if (vec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& result = vec_node_ptr_->ref();
-
- result = binary_node<T>::branch_[1].first->value();
+ result = branch(1)->value();
return result;
}
@@ -10429,6 +10439,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using expression_node<T>::branch;
assignment_rebasevec_elem_node(const operator_type& opr,
expression_ptr branch0,
@@ -10436,9 +10447,9 @@
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
{
- if (is_rebasevector_elem_node(binary_node<T>::branch_[0].first))
+ if (is_rebasevector_elem_node(branch(0)))
{
- rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(binary_node<T>::branch_[0].first);
+ rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0));
}
}
@@ -10446,11 +10457,11 @@
{
if (rbvec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& result = rbvec_node_ptr_->ref();
- result = binary_node<T>::branch_[1].first->value();
+ result = branch(1)->value();
return result;
}
@@ -10469,6 +10480,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_rebasevec_celem_node(const operator_type& opr,
expression_ptr branch0,
@@ -10476,9 +10488,9 @@
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
{
- if (is_rebasevector_celem_node(binary_node<T>::branch_[0].first))
+ if (is_rebasevector_celem_node(branch(0)))
{
- rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(binary_node<T>::branch_[0].first);
+ rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0));
}
}
@@ -10486,11 +10498,10 @@
{
if (rbvec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& result = rbvec_node_ptr_->ref();
-
- result = binary_node<T>::branch_[1].first->value();
+ result = branch(1)->value();
return result;
}
@@ -10514,15 +10525,17 @@
typedef vector_node<T>* vector_node_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
assignment_vec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
{
- if (is_vector_node(binary_node<T>::branch_[0].first))
+ if (is_vector_node(branch(0)))
{
- vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
+ vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
vds() = vec_node_ptr_->vds();
}
}
@@ -10531,9 +10544,9 @@
{
if (vec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
- const T v = binary_node<T>::branch_[1].first->value();
+ const T v = branch(1)->value();
T* vec = vds().data();
@@ -10634,6 +10647,8 @@
typedef vector_node<T>* vector_node_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
assignment_vecvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -10643,22 +10658,22 @@
, initialised_(false)
, src_is_ivec_(false)
{
- if (is_vector_node(binary_node<T>::branch_[0].first))
+ if (is_vector_node(branch(0)))
{
- vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
+ vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
vds() = vec0_node_ptr_->vds();
}
- if (is_vector_node(binary_node<T>::branch_[1].first))
+ if (is_vector_node(branch(1)))
{
- vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
+ vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1));
vds_t::match_sizes(vds(),vec1_node_ptr_->vds());
}
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
+ else if (is_ivector_node(branch(1)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
{
vec1_node_ptr_ = vi->vec();
@@ -10681,9 +10696,9 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
- binary_node<T>::branch_[1].first->value();
+ branch(1)->value();
if (src_is_ivec_)
return vec0_node_ptr_->value();
@@ -10787,6 +10802,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_op_node(const operator_type& opr,
expression_ptr branch0,
@@ -10794,9 +10810,9 @@
: binary_node<T>(opr, branch0, branch1)
, var_node_ptr_(0)
{
- if (is_variable_node(binary_node<T>::branch_[0].first))
+ if (is_variable_node(branch(0)))
{
- var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
+ var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
}
}
@@ -10804,10 +10820,10 @@
{
if (var_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& v = var_node_ptr_->ref();
- v = Operation::process(v,binary_node<T>::branch_[1].first->value());
+ v = Operation::process(v,branch(1)->value());
return v;
}
@@ -10826,6 +10842,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_vec_elem_op_node(const operator_type& opr,
expression_ptr branch0,
@@ -10833,9 +10850,9 @@
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
{
- if (is_vector_elem_node(binary_node<T>::branch_[0].first))
+ if (is_vector_elem_node(branch(0)))
{
- vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
+ vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
}
}
@@ -10843,10 +10860,10 @@
{
if (vec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& v = vec_node_ptr_->ref();
- v = Operation::process(v,binary_node<T>::branch_[1].first->value());
+ v = Operation::process(v,branch(1)->value());
return v;
}
@@ -10865,6 +10882,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_rebasevec_elem_op_node(const operator_type& opr,
expression_ptr branch0,
@@ -10872,9 +10890,9 @@
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
{
- if (is_rebasevector_elem_node(binary_node<T>::branch_[0].first))
+ if (is_rebasevector_elem_node(branch(0)))
{
- rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(binary_node<T>::branch_[0].first);
+ rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0));
}
}
@@ -10882,10 +10900,10 @@
{
if (rbvec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& v = rbvec_node_ptr_->ref();
- v = Operation::process(v,binary_node<T>::branch_[1].first->value());
+ v = Operation::process(v,branch(1)->value());
return v;
}
@@ -10904,6 +10922,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
assignment_rebasevec_celem_op_node(const operator_type& opr,
expression_ptr branch0,
@@ -10911,9 +10930,9 @@
: binary_node<T>(opr, branch0, branch1)
, rbvec_node_ptr_(0)
{
- if (is_rebasevector_celem_node(binary_node<T>::branch_[0].first))
+ if (is_rebasevector_celem_node(branch(0)))
{
- rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(binary_node<T>::branch_[0].first);
+ rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0));
}
}
@@ -10921,10 +10940,10 @@
{
if (rbvec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
T& v = rbvec_node_ptr_->ref();
- v = Operation::process(v,binary_node<T>::branch_[1].first->value());
+ v = Operation::process(v,branch(1)->value());
return v;
}
@@ -10948,15 +10967,17 @@
typedef vector_node<T>* vector_node_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
assignment_vec_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(opr, branch0, branch1)
, vec_node_ptr_(0)
{
- if (is_vector_node(binary_node<T>::branch_[0].first))
+ if (is_vector_node(branch(0)))
{
- vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
+ vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
vds() = vec_node_ptr_->vds();
}
}
@@ -10965,9 +10986,9 @@
{
if (vec_node_ptr_)
{
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(1));
- const T v = binary_node<T>::branch_[1].first->value();
+ const T v = branch(1)->value();
T* vec = vds().data();
@@ -11073,6 +11094,8 @@
typedef vector_node<T>* vector_node_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
assignment_vecvec_op_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -11081,22 +11104,22 @@
, vec1_node_ptr_(0)
, initialised_(false)
{
- if (is_vector_node(binary_node<T>::branch_[0].first))
+ if (is_vector_node(branch(0)))
{
- vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
+ vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
vds() = vec0_node_ptr_->vds();
}
- if (is_vector_node(binary_node<T>::branch_[1].first))
+ if (is_vector_node(branch(1)))
{
- vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
+ vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1));
vec1_node_ptr_->vds() = vds();
}
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
+ else if (is_ivector_node(branch(1)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
{
vec1_node_ptr_ = vi->vec();
vec1_node_ptr_->vds() = vds();
@@ -11114,11 +11137,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
T* vec0 = vec0_node_ptr_->vds().data();
const T* vec1 = vec1_node_ptr_->vds().data();
@@ -11231,6 +11254,8 @@
typedef vector_holder<T>* vector_holder_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
vec_binop_vecvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -11244,30 +11269,30 @@
bool v0_is_ivec = false;
bool v1_is_ivec = false;
- if (is_vector_node(binary_node<T>::branch_[0].first))
+ if (is_vector_node(branch(0)))
{
- vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
+ vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
}
- else if (is_ivector_node(binary_node<T>::branch_[0].first))
+ else if (is_ivector_node(branch(0)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
{
vec0_node_ptr_ = vi->vec();
v0_is_ivec = true;
}
}
- if (is_vector_node(binary_node<T>::branch_[1].first))
+ if (is_vector_node(branch(1)))
{
- vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
+ vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1));
}
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
+ else if (is_ivector_node(branch(1)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
{
vec1_node_ptr_ = vi->vec();
v1_is_ivec = true;
@@ -11305,11 +11330,11 @@
{
if (initialised_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
const T* vec0 = vec0_node_ptr_->vds().data();
const T* vec1 = vec1_node_ptr_->vds().data();
@@ -11421,6 +11446,8 @@
typedef vector_holder<T>* vector_holder_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
vec_binop_vecval_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -11431,15 +11458,15 @@
{
bool v0_is_ivec = false;
- if (is_vector_node(binary_node<T>::branch_[0].first))
+ if (is_vector_node(branch(0)))
{
- vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
+ vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
}
- else if (is_ivector_node(binary_node<T>::branch_[0].first))
+ else if (is_ivector_node(branch(0)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
{
vec0_node_ptr_ = vi->vec();
v0_is_ivec = true;
@@ -11468,11 +11495,11 @@
{
if (vec0_node_ptr_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- binary_node<T>::branch_[0].first->value();
- const T v = binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ const T v = branch(1)->value();
const T* vec0 = vec0_node_ptr_->vds().data();
T* vec1 = vds().data();
@@ -11580,6 +11607,8 @@
typedef vector_holder<T>* vector_holder_ptr;
typedef vec_data_store<T> vds_t;
+ using binary_node<T>::branch;
+
vec_binop_valvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -11590,15 +11619,15 @@
{
bool v1_is_ivec = false;
- if (is_vector_node(binary_node<T>::branch_[1].first))
+ if (is_vector_node(branch(1)))
{
- vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
+ vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1));
}
- else if (is_ivector_node(binary_node<T>::branch_[1].first))
+ else if (is_ivector_node(branch(1)))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
{
vec1_node_ptr_ = vi->vec();
v1_is_ivec = true;
@@ -11627,11 +11656,11 @@
{
if (vec1_node_ptr_)
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
- const T v = binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ const T v = branch(0)->value();
+ branch(1)->value();
T* vec0 = vds().data();
const T* vec1 = vec1_node_ptr_->vds().data();
@@ -11739,6 +11768,8 @@
typedef vector_holder<T>* vector_holder_ptr;
typedef vec_data_store<T> vds_t;
+ using expression_node<T>::branch;
+
unary_vector_node(const operator_type& opr, expression_ptr branch0)
: unary_node<T>(opr, branch0)
, vec0_node_ptr_(0)
@@ -11747,15 +11778,15 @@
{
bool vec0_is_ivec = false;
- if (is_vector_node(unary_node<T>::branch_.first))
+ if (is_vector_node(branch()))
{
- vec0_node_ptr_ = static_cast<vector_node_ptr>(unary_node<T>::branch_.first);
+ vec0_node_ptr_ = static_cast<vector_node_ptr>(branch());
}
- else if (is_ivector_node(unary_node<T>::branch_.first))
+ else if (is_ivector_node(branch()))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
- if (0 != (vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_.first)))
+ if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch())))
{
vec0_node_ptr_ = vi->vec();
vec0_is_ivec = true;
@@ -11782,9 +11813,9 @@
inline T value() const exprtk_override
{
- assert(unary_node<T>::branch_.first);
+ assert(branch());
- unary_node<T>::branch_.first->value();
+ branch()->value();
if (vec0_node_ptr_)
{
@@ -12048,6 +12079,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
scand_node(const operator_type& opr,
expression_ptr branch0,
@@ -12057,14 +12089,14 @@
inline T value() const exprtk_override
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
return (
std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[0].first->value()) &&
+ (T(0),branch(0)->value()) &&
std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[1].first->value())
+ (T(0),branch(1)->value())
) ? T(1) : T(0);
}
};
@@ -12075,6 +12107,7 @@
public:
typedef expression_node<T>* expression_ptr;
+ using binary_node<T>::branch;
scor_node(const operator_type& opr,
expression_ptr branch0,
@@ -12084,14 +12117,14 @@
inline T value() const exprtk_override
{
- assert(binary_node<T>::branch_[0].first);
- assert(binary_node<T>::branch_[1].first);
+ assert(branch(0));
+ assert(branch(1));
return (
std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[0].first->value()) ||
+ (T(0),branch(0)->value()) ||
std::not_equal_to<T>()
- (T(0),binary_node<T>::branch_[1].first->value())
+ (T(0),branch(1)->value())
) ? T(1) : T(0);
}
};
@@ -13518,7 +13551,7 @@
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();
+ default : return vararg_add_op<T>::process(arg_list) / T(arg_list.size());
}
}
@@ -14177,8 +14210,7 @@
static inline T process(const ivector_ptr v)
{
- const std::size_t vec_size = v->vec()->vds().size();
-
+ const T vec_size = T(v->vec()->vds().size());
return vec_add_op<T>::process(v) / vec_size;
}
};
@@ -14959,7 +14991,7 @@
private:
T0oT1oT2(const node_type&) exprtk_delete;
- node_type& operator=(const node_type&) { return (*this); }
+ node_type& operator=(const node_type&) exprtk_delete;
T0 t0_;
T1 t1_;
@@ -15056,7 +15088,7 @@
private:
T0oT1oT2oT3(const node_type&) exprtk_delete;
- node_type& operator=(const node_type&) { return (*this); }
+ node_type& operator=(const node_type&) exprtk_delete;
T0 t0_;
T1 t1_;
@@ -15141,7 +15173,7 @@
private:
T0oT1oT2_sf3(const node_type&) exprtk_delete;
- node_type& operator=(const node_type&) { return (*this); }
+ node_type& operator=(const node_type&) exprtk_delete;
T0 t0_;
T1 t1_;
@@ -15168,8 +15200,6 @@
{
public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::tfunc_t tfunc_t;
typedef T value_type;
typedef T0oT1oT2_sf3ext<T, T0, T1, T2, SF3Operation> node_type;
@@ -15231,7 +15261,7 @@
private:
T0oT1oT2_sf3ext(const node_type&) exprtk_delete;
- node_type& operator=(const node_type&) { return (*this); }
+ node_type& operator=(const node_type&) exprtk_delete;
T0 t0_;
T1 t1_;
@@ -15332,7 +15362,7 @@
private:
T0oT1oT2oT3_sf4(const node_type&) exprtk_delete;
- node_type& operator=(const node_type&) { return (*this); }
+ node_type& operator=(const node_type&) exprtk_delete;
T0 t0_;
T1 t1_;
@@ -15346,8 +15376,6 @@
{
public:
- typedef typename details::functor_t<T> functor_t;
- typedef typename functor_t::tfunc_t tfunc_t;
typedef T value_type;
typedef T0oT1oT2oT3_sf4ext<T, T0, T1, T2, T3, SF4Operation> node_type;
@@ -15410,7 +15438,7 @@
private:
T0oT1oT2oT3_sf4ext(const node_type&) exprtk_delete;
- node_type& operator=(const node_type&) { return (*this); }
+ node_type& operator=(const node_type&) exprtk_delete;
T0 t0_;
T1 t1_;
@@ -16111,6 +16139,8 @@
typedef range_interface <T> irange_t;
typedef irange_t* irange_ptr;
+ using binary_node<T>::branch;
+
str_sogens_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
@@ -16120,14 +16150,14 @@
, str0_range_ptr_(0)
, str1_range_ptr_(0)
{
- if (is_generally_string_node(binary_node<T>::branch_[0].first))
+ if (is_generally_string_node(branch(0)))
{
- str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
+ str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
if (0 == str0_base_ptr_)
return;
- irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
if (0 == range)
return;
@@ -16135,14 +16165,14 @@
str0_range_ptr_ = &(range->range_ref());
}
- if (is_generally_string_node(binary_node<T>::branch_[1].first))
+ if (is_generally_string_node(branch(1)))
{
- str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
+ str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
if (0 == str1_base_ptr_)
return;
- irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+ irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
if (0 == range)
return;
@@ -16160,8 +16190,8 @@
str1_range_ptr_
)
{
- binary_node<T>::branch_[0].first->value();
- binary_node<T>::branch_[1].first->value();
+ branch(0)->value();
+ branch(1)->value();
std::size_t str0_r0 = 0;
std::size_t str0_r1 = 0;
@@ -17281,22 +17311,29 @@
{
public:
- typedef T (*ff00_functor)();
- typedef T (*ff01_functor)(T);
- typedef T (*ff02_functor)(T, T);
- typedef T (*ff03_functor)(T, T, T);
- typedef T (*ff04_functor)(T, T, T, T);
- typedef T (*ff05_functor)(T, T, T, T, T);
- typedef T (*ff06_functor)(T, T, T, T, T, T);
- typedef T (*ff07_functor)(T, T, T, T, T, T, T);
- typedef T (*ff08_functor)(T, T, T, T, T, T, T, T);
- typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T);
- typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T);
- typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T);
- typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T);
- typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T);
- typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T);
- typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T);
+ enum symtab_mutability_type
+ {
+ e_unknown = 0,
+ e_mutable = 1,
+ e_immutable = 2
+ };
+
+ typedef T (*ff00_functor)();
+ typedef T (*ff01_functor)(T);
+ typedef T (*ff02_functor)(T, T);
+ typedef T (*ff03_functor)(T, T, T);
+ typedef T (*ff04_functor)(T, T, T, T);
+ typedef T (*ff05_functor)(T, T, T, T, T);
+ typedef T (*ff06_functor)(T, T, T, T, T, T);
+ typedef T (*ff07_functor)(T, T, T, T, T, T, T);
+ typedef T (*ff08_functor)(T, T, T, T, T, T, T, T);
+ typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T);
+ typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T);
+ typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T);
+ typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T);
+ typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T);
+ typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T);
+ typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T);
protected:
@@ -17938,11 +17975,13 @@
control_block()
: ref_count(1)
, data_(st_data::create())
+ , mutability_(e_mutable)
{}
explicit control_block(st_data* data)
: ref_count(1)
, data_(data)
+ , mutability_(e_mutable)
{}
~control_block()
@@ -17978,21 +18017,29 @@
}
}
+ void set_mutability(const symtab_mutability_type mutability)
+ {
+ mutability_ = mutability;
+ }
+
std::size_t ref_count;
st_data* data_;
+ symtab_mutability_type mutability_;
};
public:
- symbol_table()
+ symbol_table(const symtab_mutability_type mutability = e_mutable)
: control_block_(control_block::create())
{
+ control_block_->set_mutability(mutability);
clear();
}
~symbol_table()
{
- control_block::destroy(control_block_,this);
+ exprtk::details::dump_ptr("~symbol_table", this);
+ control_block::destroy(control_block_, this);
}
symbol_table(const symbol_table<T>& st)
@@ -18019,6 +18066,11 @@
return (this == &st) || (control_block_ == st.control_block_);
}
+ inline symtab_mutability_type mutability() const
+ {
+ return valid() ? control_block_->mutability_ : e_unknown;
+ }
+
inline void clear_variables(const bool delete_node = true)
{
local_data().variable_store.clear(delete_node);
@@ -19092,6 +19144,7 @@
inline expression<T>& release()
{
+ exprtk::details::dump_ptr("expression::release", this);
control_block::destroy(control_block_);
return (*this);
@@ -19127,6 +19180,14 @@
inline void register_symbol_table(symbol_table<T>& st)
{
+ for (std::size_t i = 0; i < symbol_table_list_.size(); ++i)
+ {
+ if (&st == &symbol_table_list_[i])
+ {
+ return;
+ }
+ }
+
symbol_table_list_.push_back(st);
}
@@ -19894,6 +19955,130 @@
parser_t& parser_;
};
+ template <typename T_>
+ struct halfopen_range_policy
+ {
+ static inline bool is_within(const T_& v, const T_& begin, const T_& end)
+ {
+ assert(begin <= end);
+ return (begin <= v) && (v < end);
+ }
+
+ static inline bool is_less(const T_& v, const T_& begin)
+ {
+ return (v < begin);
+ }
+
+ static inline bool is_greater(const T_& v, const T_& end)
+ {
+ return (end <= v);
+ }
+
+ static inline bool end_inclusive()
+ {
+ return false;
+ }
+ };
+
+ template <typename T_>
+ struct closed_range_policy
+ {
+ static inline bool is_within(const T_& v, const T_& begin, const T_& end)
+ {
+ assert(begin <= end);
+ return (begin <= v) && (v <= end);
+ }
+
+ static inline bool is_less(const T_& v, const T_& begin)
+ {
+ return (v < begin);
+ }
+
+ static inline bool is_greater(const T_& v, const T_& end)
+ {
+ return (end < v);
+ }
+
+ static inline bool end_inclusive()
+ {
+ return true;
+ }
+ };
+
+ template <typename IntervalPointType,
+ typename RangePolicy = halfopen_range_policy<IntervalPointType> >
+ class interval_container_t
+ {
+ public:
+
+ typedef IntervalPointType interval_point_t;
+ typedef std::pair<interval_point_t, interval_point_t> interval_t;
+ typedef std::map<interval_point_t, interval_t> interval_map_t;
+ typedef typename interval_map_t::const_iterator interval_map_citr_t;
+
+ std::size_t size() const
+ {
+ return interval_map_.size();
+ }
+
+ void reset()
+ {
+ interval_map_.clear();
+ }
+
+ bool in_interval(const interval_point_t point, interval_t& interval) const
+ {
+ interval_map_citr_t itr = RangePolicy::end_inclusive() ?
+ interval_map_.lower_bound(point):
+ interval_map_.upper_bound(point);
+
+ for (; itr != interval_map_.end(); ++itr)
+ {
+ const interval_point_t& begin = itr->second.first;
+ const interval_point_t& end = itr->second.second;
+
+ if (RangePolicy::is_within(point, begin, end))
+ {
+ interval = interval_t(begin,end);
+ return true;
+ }
+ else if (RangePolicy::is_greater(point, end))
+ {
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ bool in_interval(const interval_point_t point) const
+ {
+ interval_t interval;
+ return in_interval(point,interval);
+ }
+
+ bool add_interval(const interval_point_t begin, const interval_point_t end)
+ {
+ if ((end <= begin) || in_interval(begin) || in_interval(end))
+ {
+ return false;
+ }
+
+ interval_map_[end] = std::make_pair(begin, end);
+
+ return true;
+ }
+
+ bool add_interval(const interval_t interval)
+ {
+ return add_interval(interval.first, interval.second);
+ }
+
+ private:
+
+ interval_map_t interval_map_;
+ };
+
class stack_limit_handler
{
public:
@@ -19948,6 +20133,41 @@
typedef typename symbol_table_t::vararg_function_ptr vararg_function_ptr;
typedef typename symbol_table_t::generic_function_ptr generic_function_ptr;
+ struct variable_context
+ {
+ variable_context()
+ : symbol_table(0)
+ , variable(0)
+ {}
+
+ const symbol_table_t* symbol_table;
+ variable_ptr variable;
+ };
+
+ struct vector_context
+ {
+ vector_context()
+ : symbol_table(0)
+ , vector_holder(0)
+ {}
+
+ const symbol_table_t* symbol_table;
+ vector_holder_ptr vector_holder;
+ };
+
+ #ifndef exprtk_disable_string_capabilities
+ struct string_context
+ {
+ string_context()
+ : symbol_table(0)
+ , str_var(0)
+ {}
+
+ const symbol_table_t* symbol_table;
+ stringvar_ptr str_var;
+ };
+ #endif
+
inline bool empty() const
{
return symtab_list_.empty();
@@ -19988,6 +20208,31 @@
return false;
}
+ inline variable_context get_variable_context(const std::string& variable_name) const
+ {
+ variable_context result;
+ if (!valid_symbol(variable_name))
+ return result;
+
+ for (std::size_t i = 0; i < symtab_list_.size(); ++i)
+ {
+ if (!symtab_list_[i].valid())
+ {
+ continue;
+ }
+
+ result.variable = local_data(i)
+ .variable_store.get(variable_name);
+ if (result.variable)
+ {
+ result.symbol_table = &symtab_list_[i];
+ break;
+ }
+ }
+
+ return result;
+ }
+
inline variable_ptr get_variable(const std::string& variable_name) const
{
if (!valid_symbol(variable_name))
@@ -20028,6 +20273,32 @@
}
#ifndef exprtk_disable_string_capabilities
+ inline string_context get_string_context(const std::string& string_name) const
+ {
+ string_context result;
+
+ if (!valid_symbol(string_name))
+ return result;
+
+ for (std::size_t i = 0; i < symtab_list_.size(); ++i)
+ {
+ if (!symtab_list_[i].valid())
+ {
+ continue;
+ }
+
+ result.str_var = local_data(i).stringvar_store.get(string_name);
+
+ if (result.str_var)
+ {
+ result.symbol_table = &symtab_list_[i];
+ break;
+ }
+ }
+
+ return result;
+ }
+
inline stringvar_ptr get_stringvar(const std::string& string_name) const
{
if (!valid_symbol(string_name))
@@ -20155,6 +20426,31 @@
return result;
}
+ inline vector_context get_vector_context(const std::string& vector_name) const
+ {
+ vector_context result;
+ if (!valid_symbol(vector_name))
+ return result;
+
+ for (std::size_t i = 0; i < symtab_list_.size(); ++i)
+ {
+ if (!symtab_list_[i].valid())
+ {
+ continue;
+ }
+
+ result.vector_holder = local_data(i).vector_store.get(vector_name);
+
+ if (result.vector_holder)
+ {
+ result.symbol_table = &symtab_list_[i];
+ break;
+ }
+ }
+
+ return result;
+ }
+
inline vector_holder_ptr get_vector(const std::string& vector_name) const
{
if (!valid_symbol(vector_name))
@@ -21540,7 +21836,7 @@
if (helper_assembly_.error_token_scanner)
{
lexer::helper::bracket_checker* bracket_checker_ptr = 0;
- lexer::helper::numeric_checker* numeric_checker_ptr = 0;
+ lexer::helper::numeric_checker<T>* numeric_checker_ptr = 0;
lexer::helper::sequence_validator* sequence_validator_ptr = 0;
lexer::helper::sequence_validator_3tokens* sequence_validator3_ptr = 0;
@@ -21552,7 +21848,7 @@
"ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'",
exprtk_error_location));
}
- else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker*>(helper_assembly_.error_token_scanner)))
+ else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker<T>*>(helper_assembly_.error_token_scanner)))
{
for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i)
{
@@ -23204,6 +23500,12 @@
return parse_base_operation();
}
+ void handle_brkcnt_scope_exit()
+ {
+ assert(!brkcnt_list_.empty());
+ brkcnt_list_.pop_front();
+ }
+
inline expression_node_ptr parse_while_loop()
{
// Parse: [while][(][test expr][)][{][expression][}]
@@ -23252,7 +23554,7 @@
{
scoped_inc_dec sid(state_.parsing_loop_stmt_count);
- if (0 == (branch = parse_multi_sequence("while-loop")))
+ if (0 == (branch = parse_multi_sequence("while-loop", true)))
{
set_error(
make_error(parser_error::e_syntax,
@@ -23274,18 +23576,18 @@
}
}
+ handle_brkcnt_scope_exit();
+
if (!result)
{
free_node(node_allocator_, branch );
free_node(node_allocator_, condition );
free_node(node_allocator_, result_node);
- brkcnt_list_.pop_front();
-
return error_node();
}
- else
- return result_node;
+
+ return result_node;
}
inline expression_node_ptr parse_repeat_until_loop()
@@ -23364,8 +23666,6 @@
if (sdd.delete_ptr)
{
- brkcnt_list_.pop_front();
-
set_error(
make_error(parser_error::e_syntax,
current_token(),
@@ -23378,8 +23678,6 @@
if (!token_is(token_t::e_lbracket))
{
- brkcnt_list_.pop_front();
-
set_error(
make_error(parser_error::e_syntax,
current_token(),
@@ -23387,13 +23685,10 @@
exprtk_error_location));
free_node(node_allocator_,branch);
-
return error_node();
}
else if (0 == (condition = parse_expression()))
{
- brkcnt_list_.pop_front();
-
set_error(
make_error(parser_error::e_syntax,
current_token(),
@@ -23401,7 +23696,6 @@
exprtk_error_location));
free_node(node_allocator_,branch);
-
return error_node();
}
else if (!token_is(token_t::e_rbracket))
@@ -23415,8 +23709,6 @@
free_node(node_allocator_, branch );
free_node(node_allocator_, condition);
- brkcnt_list_.pop_front();
-
return error_node();
}
@@ -23435,15 +23727,12 @@
free_node(node_allocator_,condition);
- brkcnt_list_.pop_front();
-
return error_node();
}
- else
- {
- brkcnt_list_.pop_front();
- return result;
- }
+
+ handle_brkcnt_scope_exit();
+
+ return result;
}
inline expression_node_ptr parse_for_loop()
@@ -23635,7 +23924,7 @@
scoped_inc_dec sid(state_.parsing_loop_stmt_count);
- if (0 == (loop_body = parse_multi_sequence("for-loop")))
+ if (0 == (loop_body = parse_multi_sequence("for-loop", true)))
{
set_error(
make_error(parser_error::e_syntax,
@@ -23658,26 +23947,18 @@
free_node(node_allocator_, condition );
free_node(node_allocator_, incrementor);
free_node(node_allocator_, loop_body );
-
- if (!brkcnt_list_.empty())
- {
- brkcnt_list_.pop_front();
- }
-
return error_node();
}
- else
- {
- expression_node_ptr result_node =
- expression_generator_.for_loop(initialiser,
- condition,
- incrementor,
- loop_body,
- brkcnt_list_.front());
- brkcnt_list_.pop_front();
- return result_node;
- }
+ expression_node_ptr result_node =
+ expression_generator_.for_loop(initialiser,
+ condition,
+ incrementor,
+ loop_body,
+ brkcnt_list_.front());
+ handle_brkcnt_scope_exit();
+
+ return result_node;
}
inline expression_node_ptr parse_switch_statement()
@@ -23987,7 +24268,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR096 - Unsupported vararg function: " + symbol,
+ "ERR096 - Unsupported built-in vararg function: " + symbol,
exprtk_error_location));
return error_node();
@@ -24010,6 +24291,18 @@
return error_node();
}
+ if (token_is(token_t::e_rbracket))
+ {
+ set_error(
+ make_error(parser_error::e_syntax,
+ current_token(),
+ "ERR098 - vararg function: " + symbol +
+ " requires at least one input parameter",
+ exprtk_error_location));
+
+ return error_node();
+ }
+
for ( ; ; )
{
expression_node_ptr arg = parse_expression();
@@ -24026,7 +24319,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR098 - Expected ',' for call to vararg function: " + symbol,
+ "ERR099 - Expected ',' for call to vararg function: " + symbol,
exprtk_error_location));
return error_node();
@@ -24047,7 +24340,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR099 - Expected '[' as start of string range definition",
+ "ERR100 - Expected '[' as start of string range definition",
exprtk_error_location));
free_node(node_allocator_,expression);
@@ -24075,7 +24368,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR100 - Failed to generate string range node",
+ "ERR101 - Failed to generate string range node",
exprtk_error_location));
free_node(node_allocator_,expression);
@@ -24195,15 +24488,18 @@
return expression_generator_.vararg_function(details::e_multi,expression_list);
}
- inline expression_node_ptr parse_multi_sequence(const std::string& source = "")
+ inline expression_node_ptr parse_multi_sequence(const std::string& source = "",
+ const bool enforce_crlbrackets = false)
{
+ token_t::token_type open_bracket = token_t::e_lcrlbracket;
token_t::token_type close_bracket = token_t::e_rcrlbracket;
token_t::token_type seperator = token_t::e_eof;
- if (!token_is(token_t::e_lcrlbracket))
+ if (!token_is(open_bracket))
{
- if (token_is(token_t::e_lbracket))
+ if (!enforce_crlbrackets && token_is(token_t::e_lbracket))
{
+ open_bracket = token_t::e_lbracket;
close_bracket = token_t::e_rbracket;
seperator = token_t::e_comma;
}
@@ -24212,14 +24508,14 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR101 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
+ "ERR102 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" +
((!source.empty()) ? std::string(" section of " + source): ""),
exprtk_error_location));
return error_node();
}
}
- else if (token_is(token_t::e_rcrlbracket))
+ else if (token_is(close_bracket))
{
return node_allocator_.allocate<details::null_node<T> >();
}
@@ -24259,7 +24555,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR102 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
+ "ERR103 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
exprtk_error_location));
return error_node();
@@ -24269,7 +24565,7 @@
break;
}
- result = simplify(arg_list,side_effect_list,source.empty());
+ result = simplify(arg_list, side_effect_list, source.empty());
sdd.delete_ptr = (0 == result);
return result;
@@ -24293,7 +24589,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR103 - Expected '[' for start of range",
+ "ERR104 - Expected '[' for start of range",
exprtk_error_location));
return false;
@@ -24314,7 +24610,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR104 - Failed parse begin section of range",
+ "ERR105 - Failed parse begin section of range",
exprtk_error_location));
return false;
@@ -24337,7 +24633,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR105 - Range lower bound less than zero! Constraint: r0 >= 0",
+ "ERR106 - Range lower bound less than zero! Constraint: r0 >= 0",
exprtk_error_location));
return false;
@@ -24354,7 +24650,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR106 - Expected ':' for break in range",
+ "ERR107 - Expected ':' for break in range",
exprtk_error_location));
rp.free();
@@ -24377,7 +24673,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR107 - Failed parse end section of range",
+ "ERR108 - Failed parse end section of range",
exprtk_error_location));
rp.free();
@@ -24402,7 +24698,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR108 - Range upper bound less than zero! Constraint: r1 >= 0",
+ "ERR109 - Range upper bound less than zero! Constraint: r1 >= 0",
exprtk_error_location));
rp.free();
@@ -24421,7 +24717,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR109 - Expected ']' for start of range",
+ "ERR110 - Expected ']' for start of range",
exprtk_error_location));
rp.free();
@@ -24449,7 +24745,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR110 - Invalid range, Constraint: r0 <= r1",
+ "ERR111 - Invalid range, Constraint: r0 <= r1",
exprtk_error_location));
return false;
@@ -24485,24 +24781,36 @@
}
else
{
- if (!symtab_store_.is_conststr_stringvar(symbol))
+ typedef typename symtab_store::string_context str_ctxt_t;
+ str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol);
+
+ if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol))
{
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR111 - Unknown string symbol",
+ "ERR112 - Unknown string symbol",
exprtk_error_location));
return error_node();
}
- result = symtab_store_.get_stringvar(symbol);
+ assert(str_ctx.str_var != 0);
+ assert(str_ctx.symbol_table != 0);
+
+ result = str_ctx.str_var;
if (symtab_store_.is_constant_string(symbol))
{
const_str_node = static_cast<strvar_node_t>(result);
result = expression_generator_(const_str_node->str());
}
+ else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability())
+ {
+ lodge_immutable_symbol(
+ current_token(),
+ make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size()));
+ }
lodge_symbol(symbol, e_st_string);
}
@@ -24605,7 +24913,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR112 - Overflow in range for string: '" + const_str + "'[" +
+ "ERR113 - Overflow in range for string: '" + const_str + "'[" +
(rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" +
(rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]",
exprtk_error_location));
@@ -24646,20 +24954,37 @@
(scope_element::e_vector != se.type)
)
{
- if (0 == (vec = symtab_store_.get_vector(symbol)))
+ typedef typename symtab_store::vector_context vec_ctxt_t;
+ vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(symbol);
+
+ if (0 == vec_ctx.vector_holder)
{
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR113 - Symbol '" + symbol+ " not a vector",
+ "ERR114 - Symbol '" + symbol+ " not a vector",
exprtk_error_location));
return error_node();
}
+
+ assert(0 != vec_ctx.vector_holder);
+ assert(0 != vec_ctx.symbol_table );
+
+ vec = vec_ctx.vector_holder;
+
+ if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability())
+ {
+ lodge_immutable_symbol(
+ current_token(),
+ make_memory_range(vec->data(), vec->size()));
+ }
}
else
vec = se.vec_node;
+ assert(0 != vec);
+
expression_node_ptr index_expr = error_node();
next_token();
@@ -24677,7 +25002,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR114 - Failed to parse index for vector: '" + symbol + "'",
+ "ERR115 - Failed to parse index for vector: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -24687,7 +25012,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR115 - Expected ']' for index of vector: '" + symbol + "'",
+ "ERR116 - Expected ']' for index of vector: '" + symbol + "'",
exprtk_error_location));
free_node(node_allocator_,index_expr);
@@ -24706,7 +25031,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR116 - Index of " + details::to_str(index) + " out of range for "
+ "ERR117 - Index of " + details::to_str(index) + " out of range for "
"vector '" + symbol + "' of size " + details::to_str(vec_size),
exprtk_error_location));
@@ -24738,7 +25063,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR117 - Zero parameter call to vararg function: "
+ "ERR118 - Zero parameter call to vararg function: "
+ vararg_function_name + " not allowed",
exprtk_error_location));
@@ -24763,7 +25088,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR118 - Expected ',' for call to vararg function: "
+ "ERR119 - Expected ',' for call to vararg function: "
+ vararg_function_name,
exprtk_error_location));
@@ -24777,7 +25102,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR119 - Zero parameter call to vararg function: "
+ "ERR120 - Zero parameter call to vararg function: "
+ vararg_function_name + " not allowed",
exprtk_error_location));
@@ -24789,7 +25114,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR120 - Invalid number of parameters to call to vararg function: "
+ "ERR121 - Invalid number of parameters to call to vararg function: "
+ vararg_function_name + ", require at least "
+ details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters",
exprtk_error_location));
@@ -24801,7 +25126,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR121 - Invalid number of parameters to call to vararg function: "
+ "ERR122 - Invalid number of parameters to call to vararg function: "
+ vararg_function_name + ", require no more than "
+ details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters",
exprtk_error_location));
@@ -24879,7 +25204,7 @@
set_error(
make_error(parser_error::e_syntax,
parser_.current_token(),
- "ERR122 - Failed parameter type check for function '" + function_name_ + "', "
+ "ERR123 - Failed parameter type check for function '" + function_name_ + "', "
"Expected '" + function_definition_list_[0].param_seq +
"' call set: '" + param_seq + "'",
exprtk_error_location));
@@ -24901,7 +25226,7 @@
set_error(
make_error(parser_error::e_syntax,
parser_.current_token(),
- "ERR123 - Failed parameter type check for function '" + function_name_ + "', "
+ "ERR124 - Failed parameter type check for function '" + function_name_ + "', "
"Best match: '" + function_definition_list_[max_diff_index].param_seq +
"' call set: '" + param_seq + "'",
exprtk_error_location));
@@ -25043,7 +25368,7 @@
set_error(
make_error(parser_error::e_syntax,
parser_.current_token(),
- "ERR124 - Invalid parameter sequence of '" + param_seq_list[i] +
+ "ERR125 - Invalid parameter sequence of '" + param_seq_list[i] +
"' for function: " + function_name_,
exprtk_error_location));
return;
@@ -25059,7 +25384,7 @@
set_error(
make_error(parser_error::e_syntax,
parser_.current_token(),
- "ERR125 - Function '" + function_name_ + "' has a parameter sequence conflict between " +
+ "ERR126 - Function '" + function_name_ + "' has a parameter sequence conflict between " +
"pseq_idx[" + details::to_str(seq_itr->second) + "] and" +
"pseq_idx[" + details::to_str(i) + "] " +
"param seq: " + param_seq_list[i],
@@ -25091,14 +25416,18 @@
std::string param_type_list;
- type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string);
+ type_checker tc(
+ (*this),
+ function_name,
+ function->parameter_sequence,
+ type_checker::e_string);
if (tc.invalid())
{
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR126 - Type checker instantiation failure for generic function: " + function_name,
+ "ERR127 - Type checker instantiation failure for generic function: " + function_name,
exprtk_error_location));
return error_node();
@@ -25116,7 +25445,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR127 - Zero parameter call to generic function: "
+ "ERR128 - Zero parameter call to generic function: "
+ function_name + " not allowed",
exprtk_error_location));
@@ -25148,7 +25477,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR128 - Expected ',' for call to generic function: " + function_name,
+ "ERR129 - Expected ',' for call to generic function: " + function_name,
exprtk_error_location));
return error_node();
@@ -25165,7 +25494,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR129 - Zero parameter call to generic function: "
+ "ERR130 - Zero parameter call to generic function: "
+ function_name + " not allowed",
exprtk_error_location));
@@ -25182,7 +25511,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR130 - Invalid input parameter sequence for call to generic function: " + function_name,
+ "ERR131 - Invalid input parameter sequence for call to generic function: " + function_name,
exprtk_error_location));
return error_node();
@@ -25220,7 +25549,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR131 - Zero parameter call to generic function: "
+ "ERR132 - Zero parameter call to generic function: "
+ function_name + " not allowed",
exprtk_error_location));
@@ -25252,7 +25581,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR132 - Expected ',' for call to string function: " + function_name,
+ "ERR133 - Expected ',' for call to string function: " + function_name,
exprtk_error_location));
return false;
@@ -25299,7 +25628,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR133 - Invalid input parameter sequence for call to string function: " + function_name,
+ "ERR134 - Invalid input parameter sequence for call to string function: " + function_name,
exprtk_error_location));
return error_node();
@@ -25351,7 +25680,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR134 - Invalid input parameter sequence for call to overloaded function: " + function_name,
+ "ERR135 - Invalid input parameter sequence for call to overloaded function: " + function_name,
exprtk_error_location));
return error_node();
@@ -25382,7 +25711,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR135 - Invalid return type for call to overloaded function: " + function_name,
+ "ERR136 - Invalid return type for call to overloaded function: " + function_name,
exprtk_error_location));
}
@@ -25410,7 +25739,7 @@
p.set_error(
make_error(parser_error::e_syntax,
p.current_token(),
- "ERR136 - Expected '(' for special function '" + sf_name + "'",
+ "ERR137 - Expected '(' for special function '" + sf_name + "'",
exprtk_error_location));
return error_node();
@@ -25431,7 +25760,7 @@
p.set_error(
make_error(parser_error::e_syntax,
p.current_token(),
- "ERR137 - Expected ',' before next parameter of special function '" + sf_name + "'",
+ "ERR138 - Expected ',' before next parameter of special function '" + sf_name + "'",
exprtk_error_location));
return p.error_node();
@@ -25444,7 +25773,7 @@
p.set_error(
make_error(parser_error::e_syntax,
p.current_token(),
- "ERR138 - Invalid number of parameters for special function '" + sf_name + "'",
+ "ERR139 - Invalid number of parameters for special function '" + sf_name + "'",
exprtk_error_location));
return p.error_node();
@@ -25471,7 +25800,7 @@
set_error(
make_error(parser_error::e_token,
current_token(),
- "ERR139 - Invalid special function[1]: " + sf_name,
+ "ERR140 - Invalid special function[1]: " + sf_name,
exprtk_error_location));
return error_node();
@@ -25485,7 +25814,7 @@
set_error(
make_error(parser_error::e_token,
current_token(),
- "ERR140 - Invalid special function[2]: " + sf_name,
+ "ERR141 - Invalid special function[2]: " + sf_name,
exprtk_error_location));
return error_node();
@@ -25517,7 +25846,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR141 - Invoking 'break' within a break call is not allowed",
+ "ERR142 - Invoking 'break' within a break call is not allowed",
exprtk_error_location));
return error_node();
@@ -25527,7 +25856,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR142 - Invalid use of 'break', allowed only in the scope of a loop",
+ "ERR143 - Invalid use of 'break', allowed only in the scope of a loop",
exprtk_error_location));
return error_node();
@@ -25550,7 +25879,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR143 - Failed to parse return expression for 'break' statement",
+ "ERR144 - Failed to parse return expression for 'break' statement",
exprtk_error_location));
return error_node();
@@ -25560,7 +25889,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR144 - Expected ']' at the completion of break's return expression",
+ "ERR145 - Expected ']' at the completion of break's return expression",
exprtk_error_location));
free_node(node_allocator_,return_expr);
@@ -25578,7 +25907,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR145 - Invalid use of 'break', allowed only in the scope of a loop",
+ "ERR146 - Invalid use of 'break', allowed only in the scope of a loop",
exprtk_error_location));
}
@@ -25592,7 +25921,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR146 - Invalid use of 'continue', allowed only in the scope of a loop",
+ "ERR147 - Invalid use of 'continue', allowed only in the scope of a loop",
exprtk_error_location));
return error_node();
@@ -25618,7 +25947,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR147 - Expected '[' as part of vector size definition",
+ "ERR148 - Expected '[' as part of vector size definition",
exprtk_error_location));
return error_node();
@@ -25628,7 +25957,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR148 - Failed to determine size of vector '" + vec_name + "'",
+ "ERR149 - Failed to determine size of vector '" + vec_name + "'",
exprtk_error_location));
return error_node();
@@ -25640,7 +25969,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR149 - Expected a literal number as size of vector '" + vec_name + "'",
+ "ERR150 - Expected a literal number as size of vector '" + vec_name + "'",
exprtk_error_location));
return error_node();
@@ -25662,7 +25991,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR150 - Invalid vector size. Must be an integer in the range [0,2e9], size: " +
+ "ERR151 - Invalid vector size. Must be an integer in the range [0,2e9], size: " +
details::to_str(details::numeric::to_int32(vector_size)),
exprtk_error_location));
@@ -25682,7 +26011,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR151 - Expected ']' as part of vector size definition",
+ "ERR152 - Expected ']' as part of vector size definition",
exprtk_error_location));
return error_node();
@@ -25694,7 +26023,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR152 - Expected ':=' as part of vector definition",
+ "ERR153 - Expected ':=' as part of vector definition",
exprtk_error_location));
return error_node();
@@ -25708,7 +26037,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR153 - Failed to parse single vector initialiser",
+ "ERR154 - Failed to parse single vector initialiser",
exprtk_error_location));
return error_node();
@@ -25721,7 +26050,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR154 - Expected ']' to close single value vector initialiser",
+ "ERR155 - Expected ']' to close single value vector initialiser",
exprtk_error_location));
return error_node();
@@ -25768,7 +26097,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR155 - Expected '{' as part of vector initialiser list",
+ "ERR156 - Expected '{' as part of vector initialiser list",
exprtk_error_location));
return error_node();
@@ -25788,7 +26117,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR156 - Expected '{' as part of vector initialiser list",
+ "ERR157 - Expected '{' as part of vector initialiser list",
exprtk_error_location));
return error_node();
@@ -25806,7 +26135,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR157 - Expected ',' between vector initialisers",
+ "ERR158 - Expected ',' between vector initialisers",
exprtk_error_location));
return error_node();
@@ -25828,19 +26157,19 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR158 - Expected ';' at end of vector definition",
+ "ERR159 - Expected ';' at end of vector definition",
exprtk_error_location));
return error_node();
}
}
- if (vec_initilizer_list.size() > vector_size)
+ if (T(vec_initilizer_list.size()) > vector_size)
{
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR159 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
+ "ERR160 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
exprtk_error_location));
return error_node();
@@ -25860,7 +26189,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR160 - Illegal redefinition of local vector: '" + vec_name + "'",
+ "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'",
exprtk_error_location));
return error_node();
@@ -25894,7 +26223,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR161 - Failed to add new local vector '" + vec_name + "' to SEM",
+ "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM",
exprtk_error_location));
sem_.free_element(nse);
@@ -25953,7 +26282,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR162 - Illegal redefinition of local variable: '" + str_name + "'",
+ "ERR163 - Illegal redefinition of local variable: '" + str_name + "'",
exprtk_error_location));
free_node(node_allocator_,initialisation_expression);
@@ -25985,7 +26314,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR163 - Failed to add new local string variable '" + str_name + "' to SEM",
+ "ERR164 - Failed to add new local string variable '" + str_name + "' to SEM",
exprtk_error_location));
free_node(node_allocator_,initialisation_expression);
@@ -26031,7 +26360,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR164 - Illegal variable definition",
+ "ERR165 - Illegal variable definition",
exprtk_error_location));
return error_node();
@@ -26052,7 +26381,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR165 - Expected a symbol for variable definition",
+ "ERR166 - Expected a symbol for variable definition",
exprtk_error_location));
return error_node();
@@ -26062,7 +26391,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR166 - Illegal redefinition of reserved keyword: '" + var_name + "'",
+ "ERR167 - Illegal redefinition of reserved keyword: '" + var_name + "'",
exprtk_error_location));
return error_node();
@@ -26072,7 +26401,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR167 - Illegal redefinition of variable '" + var_name + "'",
+ "ERR168 - Illegal redefinition of variable '" + var_name + "'",
exprtk_error_location));
return error_node();
@@ -26082,7 +26411,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR168 - Illegal redefinition of local variable: '" + var_name + "'",
+ "ERR169 - Illegal redefinition of local variable: '" + var_name + "'",
exprtk_error_location));
return error_node();
@@ -26102,7 +26431,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR169 - Failed to parse initialisation expression",
+ "ERR170 - Failed to parse initialisation expression",
exprtk_error_location));
return error_node();
@@ -26120,7 +26449,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR170 - Expected ';' after variable definition",
+ "ERR171 - Expected ';' after variable definition",
exprtk_error_location));
free_node(node_allocator_,initialisation_expression);
@@ -26148,7 +26477,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR171 - Illegal redefinition of local variable: '" + var_name + "'",
+ "ERR172 - Illegal redefinition of local variable: '" + var_name + "'",
exprtk_error_location));
free_node(node_allocator_, initialisation_expression);
@@ -26180,7 +26509,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR172 - Failed to add new local variable '" + var_name + "' to SEM",
+ "ERR173 - Failed to add new local variable '" + var_name + "' to SEM",
exprtk_error_location));
free_node(node_allocator_, initialisation_expression);
@@ -26217,7 +26546,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR173 - Expected a '{}' for uninitialised var definition",
+ "ERR174 - Expected a '{}' for uninitialised var definition",
exprtk_error_location));
return error_node();
@@ -26227,7 +26556,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR174 - Expected ';' after uninitialised variable definition",
+ "ERR175 - Expected ';' after uninitialised variable definition",
exprtk_error_location));
return error_node();
@@ -26244,7 +26573,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR175 - Illegal redefinition of local variable: '" + var_name + "'",
+ "ERR176 - Illegal redefinition of local variable: '" + var_name + "'",
exprtk_error_location));
return error_node();
@@ -26274,7 +26603,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR176 - Failed to add new local variable '" + var_name + "' to SEM",
+ "ERR177 - Failed to add new local variable '" + var_name + "' to SEM",
exprtk_error_location));
sem_.free_element(nse);
@@ -26307,7 +26636,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR177 - Expected '(' at start of swap statement",
+ "ERR178 - Expected '(' at start of swap statement",
exprtk_error_location));
return error_node();
@@ -26326,7 +26655,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR178 - Expected a symbol for variable or vector element definition",
+ "ERR179 - Expected a symbol for variable or vector element definition",
exprtk_error_location));
return error_node();
@@ -26338,7 +26667,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR179 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
+ "ERR180 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
exprtk_error_location));
return error_node();
@@ -26371,7 +26700,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR180 - First parameter to swap is an invalid variable: '" + var0_name + "'",
+ "ERR181 - First parameter to swap is an invalid variable: '" + var0_name + "'",
exprtk_error_location));
return error_node();
@@ -26385,7 +26714,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR181 - Expected ',' between parameters to swap",
+ "ERR182 - Expected ',' between parameters to swap",
exprtk_error_location));
if (variable0_generated)
@@ -26403,7 +26732,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR182 - Expected a symbol for variable or vector element definition",
+ "ERR183 - Expected a symbol for variable or vector element definition",
exprtk_error_location));
if (variable0_generated)
@@ -26420,7 +26749,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR183 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
+ "ERR184 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
exprtk_error_location));
if (variable0_generated)
@@ -26458,7 +26787,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR184 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
+ "ERR185 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
exprtk_error_location));
if (variable0_generated)
@@ -26477,7 +26806,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR185 - Expected ')' at end of swap statement",
+ "ERR186 - Expected ')' at end of swap statement",
exprtk_error_location));
if (variable0_generated)
@@ -26534,7 +26863,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR186 - Return call within a return call is not allowed",
+ "ERR187 - Return call within a return call is not allowed",
exprtk_error_location));
return error_node();
@@ -26558,7 +26887,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR187 - Expected '[' at start of return statement",
+ "ERR188 - Expected '[' at start of return statement",
exprtk_error_location));
return error_node();
@@ -26581,7 +26910,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR188 - Expected ',' between values during call to return",
+ "ERR189 - Expected ',' between values during call to return",
exprtk_error_location));
return error_node();
@@ -26593,7 +26922,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR189 - Zero parameter return statement not allowed",
+ "ERR190 - Zero parameter return statement not allowed",
exprtk_error_location));
return error_node();
@@ -26608,7 +26937,7 @@
set_error(
make_error(parser_error::e_syntax,
prev_token,
- "ERR190 - Invalid ']' found during return call",
+ "ERR191 - Invalid ']' found during return call",
exprtk_error_location));
return error_node();
@@ -26661,7 +26990,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR191 - Invalid sequence of variable '"+ symbol + "' and bracket",
+ "ERR192 - Invalid sequence of variable '" + symbol + "' and bracket",
exprtk_error_location));
return false;
@@ -26709,7 +27038,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR192 - Invalid sequence of brackets",
+ "ERR193 - Invalid sequence of brackets",
exprtk_error_location));
return false;
@@ -26725,27 +27054,65 @@
return true;
}
+ typedef typename interval_container_t<const void*>::interval_t interval_t;
+ typedef interval_container_t<const void*> immutable_memory_map_t;
+ typedef std::map<interval_t,token_t> immutable_symtok_map_t;
+
+ inline interval_t make_memory_range(const T& t)
+ {
+ const T* begin = reinterpret_cast<const T*>(&t);
+ const T* end = begin + 1;
+ return interval_t(begin, end);
+ }
+
+ inline interval_t make_memory_range(const T* begin, const std::size_t size)
+ {
+ return interval_t(begin, begin + size);
+ }
+
+ inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size)
+ {
+ return interval_t(begin, begin + size);
+ }
+
+ void lodge_immutable_symbol(const lexer::token& token, const interval_t interval)
+ {
+ immutable_memory_map_.add_interval(interval);
+ immutable_symtok_map_[interval] = token;
+ }
+
inline expression_node_ptr parse_symtab_symbol()
{
const std::string symbol = current_token().value;
// Are we dealing with a variable or a special constant?
- expression_node_ptr variable = symtab_store_.get_variable(symbol);
+ typedef typename symtab_store::variable_context var_ctxt_t;
+ var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol);
- if (variable)
+ if (var_ctx.variable)
{
+ assert(var_ctx.symbol_table);
+
+ expression_node_ptr result_variable = var_ctx.variable;
+
if (symtab_store_.is_constant_node(symbol))
{
- variable = expression_generator_(variable->value());
+ result_variable = expression_generator_(var_ctx.variable->value());
+ }
+ else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability())
+ {
+ lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref()));
+ result_variable = var_ctx.variable;
}
if (!post_variable_process(symbol))
return error_node();
lodge_symbol(symbol, e_st_variable);
+
next_token();
- return variable;
+ return result_variable;
}
// Are we dealing with a locally defined variable, vector or string?
@@ -26806,7 +27173,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR193 - Failed to generate node for function: '" + symbol + "'",
+ "ERR194 - Failed to generate node for function: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -26832,7 +27199,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR194 - Failed to generate node for vararg function: '" + symbol + "'",
+ "ERR195 - Failed to generate node for vararg function: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -26858,7 +27225,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR195 - Failed to generate node for generic function: '" + symbol + "'",
+ "ERR196 - Failed to generate node for generic function: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -26885,7 +27252,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR196 - Failed to generate node for string function: '" + symbol + "'",
+ "ERR197 - Failed to generate node for string function: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -26911,7 +27278,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR197 - Failed to generate node for overload function: '" + symbol + "'",
+ "ERR198 - Failed to generate node for overload function: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -26937,7 +27304,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR198 - Invalid use of reserved symbol '" + symbol + "'",
+ "ERR199 - Invalid use of reserved symbol '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -27000,7 +27367,7 @@
set_error(
make_error(parser_error::e_symtab,
current_token(),
- "ERR199 - Failed to create variable: '" + symbol + "'" +
+ "ERR200 - Failed to create variable: '" + symbol + "'" +
(error_message.empty() ? "" : " - " + error_message),
exprtk_error_location));
@@ -27020,7 +27387,7 @@
set_error(
make_error(parser_error::e_symtab,
current_token(),
- "ERR200 - Failed to resolve symbol: '" + symbol + "'" +
+ "ERR201 - Failed to resolve symbol: '" + symbol + "'" +
(error_message.empty() ? "" : " - " + error_message),
exprtk_error_location));
}
@@ -27032,7 +27399,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR201 - Undefined symbol: '" + symbol + "'",
+ "ERR202 - Undefined symbol: '" + symbol + "'",
exprtk_error_location));
return error_node();
@@ -27146,7 +27513,7 @@
set_error(
make_error(parser_error::e_symtab,
current_token(),
- "ERR202 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol,
+ "ERR203 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol,
exprtk_error_location));
return error_node();
@@ -27177,7 +27544,7 @@
set_error(
make_error(parser_error::e_numeric,
current_token(),
- "ERR203 - Failed generate node for scalar: '" + current_token().value + "'",
+ "ERR204 - Failed generate node for scalar: '" + current_token().value + "'",
exprtk_error_location));
return error_node();
@@ -27191,7 +27558,7 @@
set_error(
make_error(parser_error::e_numeric,
current_token(),
- "ERR204 - Failed to convert '" + current_token().value + "' to a number",
+ "ERR205 - Failed to convert '" + current_token().value + "' to a number",
exprtk_error_location));
return error_node();
@@ -27218,7 +27585,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR205 - Expected ')' instead of: '" + current_token().value + "'",
+ "ERR206 - Expected ')' instead of: '" + current_token().value + "'",
exprtk_error_location));
details::free_node(node_allocator_,branch);
@@ -27243,7 +27610,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR206 - Expected ']' instead of: '" + current_token().value + "'",
+ "ERR207 - Expected ']' instead of: '" + current_token().value + "'",
exprtk_error_location));
details::free_node(node_allocator_,branch);
@@ -27268,7 +27635,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR207 - Expected '}' instead of: '" + current_token().value + "'",
+ "ERR208 - Expected '}' instead of: '" + current_token().value + "'",
exprtk_error_location));
details::free_node(node_allocator_,branch);
@@ -27317,7 +27684,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR208 - Premature end of expression[1]",
+ "ERR209 - Premature end of expression[1]",
exprtk_error_location));
return error_node();
@@ -27327,7 +27694,7 @@
set_error(
make_error(parser_error::e_syntax,
current_token(),
- "ERR209 - Premature end of expression[2]",
+ "ERR210 - Premature end of expression[2]",
exprtk_error_location));
return error_node();
@@ -29616,43 +29983,105 @@
}
}
+ const void* base_ptr(expression_node_ptr node)
+ {
+ if (node)
+ {
+ switch(node->type())
+ {
+ case details::expression_node<T>::e_variable:
+ return reinterpret_cast<const void*>(&static_cast<variable_node_t*>(node)->ref());
+
+ case details::expression_node<T>::e_vecelem:
+ return reinterpret_cast<const void*>(&static_cast<vector_elem_node_t*>(node)->ref());
+
+ case details::expression_node<T>::e_rbvecelem:
+ return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_node_t*>(node)->ref());
+
+ case details::expression_node<T>::e_rbveccelem:
+ return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_node_t*>(node)->ref());
+
+ case details::expression_node<T>::e_vector:
+ return reinterpret_cast<const void*>(static_cast<vector_node_t*>(node)->vec_holder().data());
+
+ #ifndef exprtk_disable_string_capabilities
+ case details::expression_node<T>::e_stringvar:
+ return reinterpret_cast<const void*>((static_cast<stringvar_node_t*>(node)->base()));
+
+ case details::expression_node<T>::e_stringvarrng:
+ return reinterpret_cast<const void*>((static_cast<string_range_node_t*>(node)->base()));
+ #endif
+ default : return reinterpret_cast<const void*>(0);
+ }
+ }
+
+ return reinterpret_cast<const void*>(0);
+ }
+
+ bool assign_immutable_symbol(expression_node_ptr node)
+ {
+ interval_t interval;
+ const void* baseptr_addr = base_ptr(node);
+
+ exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr));
+
+ if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval))
+ {
+ typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval);
+
+ if (parser_->immutable_symtok_map_.end() != itr)
+ {
+ token_t& token = itr->second;
+ parser_->set_error(
+ parser_error::make_error(parser_error::e_parser,
+ token,
+ "ERR211 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.",
+ exprtk_error_location));
+ }
+ else
+ parser_->set_synthesis_error("Unable to assign symbol is immutable.");
+
+ return true;
+ }
+
+ return false;
+ }
+
inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
{
- if (details::is_variable_node(branch[0]))
+ if (assign_immutable_symbol(branch[0]))
+ {
+ return error_node();
+ }
+ else if (details::is_variable_node(branch[0]))
{
lodge_assignment(e_st_variable,branch[0]);
-
return synthesize_expression<assignment_node_t,2>(operation,branch);
}
else if (details::is_vector_elem_node(branch[0]))
{
lodge_assignment(e_st_vecelem,branch[0]);
-
return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch);
}
else if (details::is_rebasevector_elem_node(branch[0]))
{
lodge_assignment(e_st_vecelem,branch[0]);
-
return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch);
}
else if (details::is_rebasevector_celem_node(branch[0]))
{
lodge_assignment(e_st_vecelem,branch[0]);
-
return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch);
}
#ifndef exprtk_disable_string_capabilities
else if (details::is_string_node(branch[0]))
{
lodge_assignment(e_st_string,branch[0]);
-
return synthesize_expression<assignment_string_node_t,2>(operation, branch);
}
else if (details::is_string_range_node(branch[0]))
{
lodge_assignment(e_st_string,branch[0]);
-
return synthesize_expression<assignment_string_range_node_t,2>(operation, branch);
}
#endif
@@ -29676,6 +30105,11 @@
inline expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type& operation,
expression_node_ptr (&branch)[2])
{
+ if (assign_immutable_symbol(branch[0]))
+ {
+ return error_node();
+ }
+
if (details::is_variable_node(branch[0]))
{
lodge_assignment(e_st_variable,branch[0]);
@@ -36995,6 +37429,9 @@
std::string synthesis_error_;
scope_element_manager sem_;
+ immutable_memory_map_t immutable_memory_map_;
+ immutable_symtok_map_t immutable_symtok_map_;
+
lexer::helper::helper_assembly helper_assembly_;
lexer::helper::commutative_inserter commutative_inserter_;
@@ -37002,7 +37439,7 @@
lexer::helper::operator_joiner operator_joiner_3_;
lexer::helper::symbol_replacer symbol_replacer_;
lexer::helper::bracket_checker bracket_checker_;
- lexer::helper::numeric_checker numeric_checker_;
+ lexer::helper::numeric_checker<T> numeric_checker_;
lexer::helper::sequence_validator sequence_validator_;
lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
@@ -38541,202 +38978,7 @@
std::vector<symbol_table_t*> auxiliary_symtab_list_;
}; // class function_compositor
- template <typename T>
- inline bool pgo_primer()
- {
- static const std::string expression_list[] =
- {
- "(y + x)",
- "2 * (y + x)",
- "(2 * y + 2 * x)",
- "(y + x / y) * (x - y / x)",
- "x / ((x + y) * (x - y)) / y",
- "1 - ((x * y) + (y / x)) - 3",
- "sin(2 * x) + cos(pi / y)",
- "1 - sin(2 * x) + cos(pi / y)",
- "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
- "(x^2 / sin(2 * pi / y)) -x / 2",
- "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
- "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
- "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
- "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
- "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
- "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
- "(yy + xx)",
- "2 * (yy + xx)",
- "(2 * yy + 2 * xx)",
- "(yy + xx / yy) * (xx - yy / xx)",
- "xx / ((xx + yy) * (xx - yy)) / yy",
- "1 - ((xx * yy) + (yy / xx)) - 3",
- "sin(2 * xx) + cos(pi / yy)",
- "1 - sin(2 * xx) + cos(pi / yy)",
- "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
- "(xx^2 / sin(2 * pi / yy)) -xx / 2",
- "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
- "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
- "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
- "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
- "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55",
- "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))",
- "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)",
- "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)",
- "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)",
- "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)",
- "(x + 2) * 3", "x + (2 * 3)",
- "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)",
- "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)",
- "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))",
- "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))",
- "2 + (x * (y / 3))", "x + (2 * (3 / y))",
- "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)",
- "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)",
- "x + ((2 * 3) / y)", "(((x + y) * z) / w)",
- "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)",
- "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)",
- "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)",
- "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)",
- "((x + (2 * 3)) / y)",
- "(xx + yy) * zz", "xx + (yy * zz)",
- "(xx + yy) * 7", "xx + (yy * 7)",
- "(xx + 7) * yy", "xx + (7 * yy)",
- "(7 + xx) * yy", "7 + (xx * yy)",
- "(2 + x) * 3", "2 + (x * 3)",
- "(2 + 3) * x", "2 + (3 * x)",
- "(x + 2) * 3", "x + (2 * 3)",
- "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)",
- "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)",
- "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)",
- "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)",
- "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))",
- "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))",
- "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))",
- "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))",
- "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))",
- "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)",
- "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)",
- "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)",
- "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)",
- "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)",
- "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)",
- "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)",
- "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)",
- "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)",
- "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)",
- "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)",
- "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)",
- "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)",
- "((xx + (2 * 3)) / yy)"
- };
-
- static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
-
- T x = T(0);
- T y = T(0);
- T z = T(0);
- T w = T(0);
- T xx = T(0);
- T yy = T(0);
- T zz = T(0);
- T ww = T(0);
-
- exprtk::symbol_table<T> symbol_table;
- symbol_table.add_constants();
- symbol_table.add_variable( "x", x);
- symbol_table.add_variable( "y", y);
- symbol_table.add_variable( "z", z);
- symbol_table.add_variable( "w", w);
- symbol_table.add_variable("xx",xx);
- symbol_table.add_variable("yy",yy);
- symbol_table.add_variable("zz",zz);
- symbol_table.add_variable("ww",ww);
-
- typedef typename std::deque<exprtk::expression<T> > expr_list_t;
- expr_list_t expr_list;
-
- const std::size_t rounds = 50;
-
- {
- for (std::size_t r = 0; r < rounds; ++r)
- {
- expr_list.clear();
- exprtk::parser<T> parser;
-
- for (std::size_t i = 0; i < expression_list_size; ++i)
- {
- exprtk::expression<T> expression;
- expression.register_symbol_table(symbol_table);
-
- if (!parser.compile(expression_list[i],expression))
- {
- return false;
- }
-
- expr_list.push_back(expression);
- }
- }
- }
-
- struct execute
- {
- static inline T process(T& x, T& y, expression<T>& expression)
- {
- static const T lower_bound = T(-20);
- static const T upper_bound = T(+20);
- static const T delta = T(0.1);
-
- T total = T(0);
-
- for (x = lower_bound; x <= upper_bound; x += delta)
- {
- for (y = lower_bound; y <= upper_bound; y += delta)
- {
- total += expression.value();
- }
- }
-
- return total;
- }
- };
-
- for (std::size_t i = 0; i < expr_list.size(); ++i)
- {
- execute::process( x, y, expr_list[i]);
- execute::process(xx, yy, expr_list[i]);
- }
-
- {
- for (std::size_t i = 0; i < 10000; ++i)
- {
- const T v = T(123.456 + i);
-
- if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 1>::result(v),details::numeric::pow(v,T(1)))))
- return false;
-
- #define else_stmt(N) \
- else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,N>::result(v),details::numeric::pow(v,T(N))))) \
- return false; \
-
- else_stmt( 2) else_stmt( 3) else_stmt( 4) else_stmt( 5)
- else_stmt( 6) else_stmt( 7) else_stmt( 8) else_stmt( 9)
- else_stmt(10) else_stmt(11) else_stmt(12) else_stmt(13)
- else_stmt(14) else_stmt(15) else_stmt(16) else_stmt(17)
- else_stmt(18) else_stmt(19) else_stmt(20) else_stmt(21)
- else_stmt(22) else_stmt(23) else_stmt(24) else_stmt(25)
- else_stmt(26) else_stmt(27) else_stmt(28) else_stmt(29)
- else_stmt(30) else_stmt(31) else_stmt(32) else_stmt(33)
- else_stmt(34) else_stmt(35) else_stmt(36) else_stmt(37)
- else_stmt(38) else_stmt(39) else_stmt(40) else_stmt(41)
- else_stmt(42) else_stmt(43) else_stmt(44) else_stmt(45)
- else_stmt(46) else_stmt(47) else_stmt(48) else_stmt(49)
- else_stmt(50) else_stmt(51) else_stmt(52) else_stmt(53)
- else_stmt(54) else_stmt(55) else_stmt(56) else_stmt(57)
- else_stmt(58) else_stmt(59) else_stmt(60) else_stmt(61)
- }
- }
-
- return true;
- }
-}
+} // namespace exprtk
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# ifndef NOMINMAX
@@ -39012,6 +39254,9 @@
{
namespace rtl { namespace io { namespace file { namespace details
{
+ using ::exprtk::details::char_ptr;
+ using ::exprtk::details::char_cptr;
+
enum file_mode
{
e_error = 0,
@@ -39120,11 +39365,11 @@
switch (mode)
{
case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)->
- write(reinterpret_cast<const char*>(view.begin() + offset), amount * sizeof(typename View::value_t));
+ write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
break;
case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
- write(reinterpret_cast<const char*>(view.begin() + offset) , amount * sizeof(typename View::value_t));
+ write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
break;
default : return false;
@@ -39139,11 +39384,11 @@
switch (mode)
{
case e_read : reinterpret_cast<std::ifstream*>(stream_ptr)->
- read(reinterpret_cast<char*>(view.begin() + offset), amount * sizeof(typename View::value_t));
+ read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
break;
case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
- read(reinterpret_cast<char*>(view.begin() + offset) , amount * sizeof(typename View::value_t));
+ read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
break;
default : return false;
@@ -39207,12 +39452,11 @@
template <typename T>
file_descriptor* make_handle(T v)
{
+ const std::size_t fd_size = sizeof(details::file_descriptor*);
details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
- const std::size_t fd_size = sizeof(details::file_descriptor*);
-
- std::memcpy(reinterpret_cast<char*>(&fd),
- reinterpret_cast<const char*>(&v),
+ std::memcpy(reinterpret_cast<char_ptr >(&fd),
+ reinterpret_cast<char_cptr>(&v ),
fd_size);
return fd;
}
@@ -39253,18 +39497,18 @@
inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
{
- std::string file_name = to_str(string_t(parameters[0]));
- std::string access;
+ const std::string file_name = to_str(string_t(parameters[0]));
if (file_name.empty())
return T(0);
- if (0 == ps_index)
- access = "r";
- else if (0 == string_t(parameters[1]).size())
+ if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
+ {
return T(0);
- else
- access = to_str(string_t(parameters[1]));
+ }
+
+ const std::string access =
+ (0 == ps_index) ? "r" : to_str(string_t(parameters[1]));
details::file_descriptor* fd = new details::file_descriptor(file_name,access);
@@ -40685,18 +40929,22 @@
{
namespace information
{
- static const char* library = "Mathematical Expression Toolkit";
- static const char* version = "2.7182818284590452353602874713526"
- "624977572470936999595749669676277"
- "240766303535475945713821785251664"
- "274274663919320030599218174135966";
- static const char* date = "20220101";
+ using ::exprtk::details::char_cptr;
+
+ static char_cptr library = "Mathematical Expression Toolkit";
+ static char_cptr version = "2.71828182845904523536028747135266"
+ "2497757247093699959574966967627724"
+ "0766303535475945713821785251664274"
+ "2746639193200305992181741359662904";
+ static char_cptr date = "20230101";
+ static char_cptr min_cpp = "199711L";
static inline std::string data()
{
static const std::string info_str = std::string(library) +
std::string(" v") + std::string(version) +
- std::string(" (") + date + std::string(")");
+ std::string(" (") + date + std::string(")") +
+ std::string(" (") + min_cpp + std::string(")");
return info_str;
}
diff --git a/exprtk_benchmark.cpp b/exprtk_benchmark.cpp
index 09472fb..54bbcc2 100644
--- a/exprtk_benchmark.cpp
+++ b/exprtk_benchmark.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* ExprTk vs Native Benchmarks *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
@@ -361,8 +361,6 @@
double pgo_primer()
{
- exprtk::pgo_primer<double>();
-
static const double lower_bound_x = -50.0;
static const double lower_bound_y = -50.0;
static const double upper_bound_x = +50.0;
diff --git a/exprtk_functional_test.txt b/exprtk_functional_test.txt
index 9d9f8e9..9ec9488 100644
--- a/exprtk_functional_test.txt
+++ b/exprtk_functional_test.txt
@@ -8303,4 +8303,8 @@
equal(true,~{var v0[3] := {1,2,3}; var v1[4] := {6,7,8,9}; var x_ := 1; var y_ := 2; ((x_ < y_) ? v0 : v1) == v0})
equal(true,~{var v0[3] := {1,2,3}; var v1[4] := {6,7,8,9}; var x_ := 1; var y_ := 2; ((x_ > y_) ? v0 : v1) == v1})
equal(true,~{var v0[3] := {1,2,3}; var v1[4] := {6,7,8,9}; var x_ := 1; var y_ := 2; ((x_ < y_) ? v0 - v1 : v1 - v0) == (v0 - v1)})
-equal(true,~{var v0[3] := {1,2,3}; var v1[4] := {6,7,8,9}; var x_ := 1; var y_ := 2; ((x_ > y_) ? v0 - v1 : v1 - v0) == (v1 - v0)})
\ No newline at end of file
+equal(true,~{var v0[3] := {1,2,3}; var v1[4] := {6,7,8,9}; var x_ := 1; var y_ := 2; ((x_ > y_) ? v0 - v1 : v1 - v0) == (v1 - v0)})
+equal(true,~{var xx := 0; for(var i:= 0; i < 10; i+=1) { for(var j:= 0; j < 100; j+=1) { if (j > i) break; xx += 1; } }; xx == 55})
+equal(true,~{var xx := 0; for(var i:= 0; i < 10; i+=1) { for(var j:= 0; j < 100; j+=1) { xx += 1; if (j > i) break; } }; xx == 65})
+equal(true,~{var xx := 0; var i := 0; while(i < 10) { var j := 0; while(j < 100) { if (j > i) break; xx += 1; j+=1 }; i+=1 }; xx == 55})
+equal(true,~{var xx := 0; var i := 0; while(i < 10) { var j := 0; while(j < 100) { xx += 1; if (j > i) break; j+=1 }; i+=1 }; xx == 65})
\ No newline at end of file
diff --git a/exprtk_simple_example_01.cpp b/exprtk_simple_example_01.cpp
index fa6d661..d20e2ed 100644
--- a/exprtk_simple_example_01.cpp
+++ b/exprtk_simple_example_01.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 1 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_02.cpp b/exprtk_simple_example_02.cpp
index 927c431..77c8c60 100644
--- a/exprtk_simple_example_02.cpp
+++ b/exprtk_simple_example_02.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 2 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_03.cpp b/exprtk_simple_example_03.cpp
index 709b9bf..e133df0 100644
--- a/exprtk_simple_example_03.cpp
+++ b/exprtk_simple_example_03.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 3 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_04.cpp b/exprtk_simple_example_04.cpp
index 15cbc39..69a663e 100644
--- a/exprtk_simple_example_04.cpp
+++ b/exprtk_simple_example_04.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 4 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_05.cpp b/exprtk_simple_example_05.cpp
index e185ee0..fdbabc9 100644
--- a/exprtk_simple_example_05.cpp
+++ b/exprtk_simple_example_05.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 5 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_06.cpp b/exprtk_simple_example_06.cpp
index 395ec76..b50660b 100644
--- a/exprtk_simple_example_06.cpp
+++ b/exprtk_simple_example_06.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 6 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_07.cpp b/exprtk_simple_example_07.cpp
index a5fcdaf..845b158 100644
--- a/exprtk_simple_example_07.cpp
+++ b/exprtk_simple_example_07.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 7 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_08.cpp b/exprtk_simple_example_08.cpp
index 338bbf4..bfacb1e 100644
--- a/exprtk_simple_example_08.cpp
+++ b/exprtk_simple_example_08.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 8 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_09.cpp b/exprtk_simple_example_09.cpp
index 6b385cd..8934523 100644
--- a/exprtk_simple_example_09.cpp
+++ b/exprtk_simple_example_09.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 9 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_10.cpp b/exprtk_simple_example_10.cpp
index 36669dc..0a0add4 100644
--- a/exprtk_simple_example_10.cpp
+++ b/exprtk_simple_example_10.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 10 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_11.cpp b/exprtk_simple_example_11.cpp
index 86c245e..fdf123c 100644
--- a/exprtk_simple_example_11.cpp
+++ b/exprtk_simple_example_11.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 11 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_12.cpp b/exprtk_simple_example_12.cpp
index 9297224..aafeebb 100644
--- a/exprtk_simple_example_12.cpp
+++ b/exprtk_simple_example_12.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 12 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_13.cpp b/exprtk_simple_example_13.cpp
index b865406..29ac239 100644
--- a/exprtk_simple_example_13.cpp
+++ b/exprtk_simple_example_13.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 13 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_14.cpp b/exprtk_simple_example_14.cpp
index 887ce57..259067b 100644
--- a/exprtk_simple_example_14.cpp
+++ b/exprtk_simple_example_14.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 14 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_15.cpp b/exprtk_simple_example_15.cpp
index 011514a..7affeb7 100644
--- a/exprtk_simple_example_15.cpp
+++ b/exprtk_simple_example_15.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 15 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_16.cpp b/exprtk_simple_example_16.cpp
index e7e8ef4..2480500 100644
--- a/exprtk_simple_example_16.cpp
+++ b/exprtk_simple_example_16.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 16 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_17.cpp b/exprtk_simple_example_17.cpp
index 9345eeb..24ae15b 100644
--- a/exprtk_simple_example_17.cpp
+++ b/exprtk_simple_example_17.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 17 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_18.cpp b/exprtk_simple_example_18.cpp
index de8ee31..ad4631e 100644
--- a/exprtk_simple_example_18.cpp
+++ b/exprtk_simple_example_18.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 18 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_simple_example_19.cpp b/exprtk_simple_example_19.cpp
index 8401582..7929b8b 100644
--- a/exprtk_simple_example_19.cpp
+++ b/exprtk_simple_example_19.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 19 *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
diff --git a/exprtk_test.cpp b/exprtk_test.cpp
index 1aa78ad..65661d7 100644
--- a/exprtk_test.cpp
+++ b/exprtk_test.cpp
@@ -3,14 +3,14 @@
* C++ Mathematical Expression Toolkit Library *
* *
* Examples and Unit-Tests *
- * Author: Arash Partow (1999-2022) *
- * URL: http://www.partow.net/programming/exprtk/index.html *
+ * Author: Arash Partow (1999-2023) *
+ * URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
- * http://www.opensource.org/licenses/MIT *
+ * https://www.opensource.org/licenses/MIT *
* *
**************************************************************
*/
@@ -5072,12 +5072,6 @@
}
}
- if (!exprtk::pgo_primer<T>())
- {
- printf("run_test11() - Failed PGO primer\n");
- return false;
- }
-
return true;
}
@@ -7206,7 +7200,7 @@
{
v.rebase(v0.data() + i);
- T sum = expression.value();
+ const T sum = expression.value();
if (not_equal(sum,s[i]))
{
@@ -7259,7 +7253,7 @@
return false;
}
- const T expected_result0 = std::accumulate(v0, v0 + v0_size,T(0));
+ const T expected_result0 = std::accumulate(v0, v0 + v0_size, T(0));
if (expression.value() != expected_result0)
{
@@ -7273,7 +7267,7 @@
v.rebase(v1);
- const T expected_result1 = std::accumulate(v1, v1 + v1_size,T(0));
+ const T expected_result1 = std::accumulate(v1, v1 + v1_size, T(0));
if (expression.value() != expected_result1)
{
@@ -8436,7 +8430,7 @@
const T result = expression.value();
- if (not_equal(result,std::sqrt(x),T(0.0000001)))
+ if (not_equal(result, std::sqrt(x), T(0.0000001)))
{
printf("run_test19() - Computation Error "
"Expression: [%s]\tExpected: %12.8f\tResult: %12.8f\n",
@@ -9060,17 +9054,17 @@
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
- T x = T(1.1);
- T y = T(2.2);
- T z = T(3.3);
-
- symbol_table_t symbol_table;
- symbol_table.add_constants();
- symbol_table.add_variable("x",x);
- symbol_table.add_variable("y",y);
- symbol_table.add_variable("z",z);
-
{
+ T x = T(1.1);
+ T y = T(2.2);
+ T z = T(3.3);
+
+ symbol_table_t symbol_table;
+ symbol_table.add_constants();
+ symbol_table.add_variable("x",x);
+ symbol_table.add_variable("y",y);
+ symbol_table.add_variable("z",z);
+
static const std::string expression_list[] =
{
"return[]; x;",
@@ -9169,6 +9163,16 @@
}
{
+ T x = T(1.1);
+ T y = T(2.2);
+ T z = T(3.3);
+
+ symbol_table_t symbol_table;
+ symbol_table.add_constants();
+ symbol_table.add_variable("x",x);
+ symbol_table.add_variable("y",y);
+ symbol_table.add_variable("z",z);
+
static const std::string expression_list[] =
{
"x := 1; x + 1; x + 2; x + 3; x + 5; x + 7; return [x + 1]; ",
@@ -9260,6 +9264,86 @@
return false;
}
+ {
+ const std::string invalid_expressions[] =
+ {
+ "x := 1",
+ "x += 1",
+ "v := 1 + v",
+ "v += 1",
+ "v += x + 1",
+ "v += v",
+ "v[0] += x",
+ "v[1] += x",
+ "v[2] += x",
+ "v[3] += x",
+ "v[4] += x",
+ "var i := 2; v[i] := x",
+ "var i := 2; v[i] += x",
+ "s := 'abc' + s",
+ "s[0:2] := 'abc'",
+ "s[1:3] := 'abc'",
+ "aa[4:4] := bb",
+ "aa[1:3] := bb",
+ "var i := 2; aa[i:3] := bb",
+ "var i := 2; aa[i+1:3] := bb",
+ "var i := 2; aa[0:i] := bb",
+ "var i := 2; aa[0:i+1] := bb",
+ "var i := 1; var j := 3; aa[i:j] := bb",
+ "var i := 1; var j := 3; aa[i+1:j] := bb",
+ "var i := 1; var j := 3; aa[i:j+1] := bb",
+ "var i := 1; var j := 3; aa[i+1:j+1] := bb",
+ };
+
+ const std::size_t invalid_expressions_size = sizeof(invalid_expressions) / sizeof(std::string);
+
+ for (std::size_t i = 0; i < invalid_expressions_size; ++i)
+ {
+ symbol_table_t mutable_symbol_table;
+ symbol_table_t immutable_symbol_table(symbol_table_t::e_immutable);
+
+ T x = 0.0;
+ T v[5];
+ std::string s = "xyz";
+ std::string aa = "0123456789";
+ std::string bb = "A";
+
+ T x_ = 0.0;
+ T v_[5];
+ std::string s_ = "xyz";
+
+ std::string a_ = "0123456789";
+ std::string b_ = "A";
+
+ immutable_symbol_table.add_variable ("x" , x );
+ immutable_symbol_table.add_vector ("v" , v );
+ immutable_symbol_table.add_stringvar("s" , s );
+ immutable_symbol_table.add_stringvar("aa", aa);
+ immutable_symbol_table.add_stringvar("bb", bb);
+
+ mutable_symbol_table.add_variable ("x_", x_);
+ mutable_symbol_table.add_vector ("v_", v_);
+ mutable_symbol_table.add_stringvar ("s_", s_);
+ mutable_symbol_table.add_stringvar ("a_", a_);
+ mutable_symbol_table.add_stringvar ("b_", b_);
+
+ const std::string& expression_str = invalid_expressions[i];
+ expression_t expression;
+ expression.register_symbol_table(immutable_symbol_table);
+ expression.register_symbol_table(mutable_symbol_table );
+
+ parser_t parser;
+ const bool compile_result = parser.compile(expression_str, expression);
+
+ if (compile_result)
+ {
+ expression.value();
+ printf("run_test21() - Invalid expression due to immutability was successfully compiled. Expression: %s\n",
+ expression_str.c_str());
+ }
+ }
+ }
+
return true;
}
diff --git a/readme.txt b/readme.txt
index f0d363c..e1e0275 100644
--- a/readme.txt
+++ b/readme.txt
@@ -115,7 +115,7 @@
permitted under the guidelines and in accordance with the most current
version of the MIT License.
-http://www.opensource.org/licenses/MIT
+https://www.opensource.org/licenses/MIT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -707,7 +707,7 @@
evaluated using the current value of the element.
Note: Any variable reference provided to a given symbol_table
-instance, must have a life time at least as long as the life-time of
+instance, must have a life-time at least as long as the life-time of
the symbol_table instance. In the event the variable reference is
invalidated before the symbol_table or any dependent expression
instances have been destructed, then any associated expression
@@ -868,6 +868,66 @@
6. The symbol_table instance is in an invalid state
+A further property of symbol tables is that they can be classified at
+instantiation as either being mutable (by default) or immutable. The
+following demonstrates construction of an immutable symbol table
+instance:
+
+ symbol_table_t immutable_symbol_table
+ (symbol_table_t::symtab_mutability_type::e_immutable);
+
+
+When a symbol table, that has been constructed as being immutable, is
+registered with an expression, any statements in the expression string
+that modify the variables that are managed by the immutable symbol
+table will result in a compilation error. The operations that trigger
+the mutability constraint are the following assignment operators:
+
+ 1. Assignment: :=
+ 2. Assign operation: +=, -=, *=, /= , %=
+
+
+The main reason for this functionality is that, one may want the
+immutability properties that come with constness of a variable such as
+scalars, vectors and strings, but not necessarily the accompanying
+compile time const-folding optimisations, that would result in the
+value of the variables being retrieved only once at compile time,
+causing external updates to the variables to not be part of the
+expression evaluation.
+
+ symbol_table_t immutable_symbol_table
+ (symbol_table_t::symtab_mutability_type::e_immutable);
+
+ T x = 0.0;
+
+ const std::string expression_str = "x + (y + y)";
+
+ immutable_symbol_table.add_variable("x" , x );
+ immutable_symbol_table.add_constant("y" , 123.0);
+
+ expression_t expression;
+ expression.register_symbol_table(immutabile_symbol_table);
+
+ parser_t parser;
+ parser.compile(expression_str, expression)
+
+ for (; x < 10.0; ++x)
+ {
+ const auto expected_value = x + (123.0 + 123.0);
+ const auto result_value = expression.value();
+ assert(expression.value() != expected_value);
+ }
+
+
+In the above example, there are two variables X and Y. Where Y is a
+constant and X is a normal variable. Both are registered with a symbol
+table that is immutable. The expression when compiled will result in
+the "(y + y)" part being const-folded at compile time to the literal
+value of 246. Whereas the current value of X, being updated via the
+for-loop, externally to the expression and the symbol table will be
+available to the expression upon each evaluation.
+
+
(2) Expression
A structure that holds an Abstract Syntax Tree or AST for a specified
expression and is used to evaluate said expression. Evaluation of the
@@ -1020,7 +1080,7 @@
references into the expression's AST. When copying an expression, said
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
+utilising 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
multi-threading et al.
@@ -1110,6 +1170,7 @@
(5) Sequence Check
(6) Commutative Check
(7) Strength Reduction Check
+ (8) Stack And Node Depth Check
(1) Replacer (e_replacer)
@@ -1218,6 +1279,43 @@
to turn off strength reduction optimisations or to use a type with a
larger numerical bound.
+
+(8) Stack And Node Depth Check
+ExprTk incorporates a recursive descent parser. When parsing
+expressions comprising inner sub-expressions, the recursive nature of
+the parsing process causes the stack to grow. If the expression causes
+the stack to grow beyond the stack size limit, this would lead to a
+stackoverflow and its associated stack corruption and security
+vulnerability issues.
+
+Similarly to parsing, evaluating an expression may cause the stack to
+grow. Such things like user defined functions, composite functions and
+the general nature of the AST being evaluated can cause the stack to
+grow, and may result in potential stackoverflow issues as denoted
+above.
+
+ExprTk provides a set of checks that prevent both of the above denoted
+problems at compile time. These check rely on two specific limits
+being set on the parser instance, these limits are:
+
+ 1. max_stack_depth (default: 400)
+ 2. max_node_depth (default: 10000)
+
+
+The following demonstrates how these two parser parameters can be set:
+
+ parser_t parser;
+
+ parser.set_max_stack_depth(100);
+ parser.set_max_node_depth(200);
+
+
+In the above code, during parsing if the stack depth reaches or
+exceeds 100 levels, the parsing process will immediately halt and
+return with a failure. Similarly, during synthesizing the AST nodes,
+if the compilation process detects an AST tree depth exceeding 200
+levels the parsing process will halt and return a parsing failure.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[SECTION 12 - EXPRESSION STRUCTURES]
@@ -1780,7 +1878,7 @@
sum(x > 0 and x < 5) == x[]
-When utilizing external user defined vectors via the symbol table as
+When utilising external user defined vectors via the symbol table as
opposed to expression local defined vectors, the typical 'add_vector'
method from the symbol table will register the entirety of the vector
that is passed. The following example attempts to evaluate the sum of
@@ -3489,7 +3587,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[SECTION 20 - EXPRESSION RETURN VALUES]
-ExprTk expressions can return immediately from any point by utilizing
+ExprTk expressions can return immediately from any point by utilising
the return call. Furthermore the return call can be used to transfer
out multiple return values from within the expression.
@@ -4591,52 +4689,58 @@
the ExprTk header. The defines are as follows:
(01) exprtk_enable_debugging
- (02) exprtk_disable_comments
- (03) exprtk_disable_break_continue
- (04) exprtk_disable_sc_andor
- (05) exprtk_disable_return_statement
- (06) exprtk_disable_enhanced_features
- (07) exprtk_disable_string_capabilities
- (08) exprtk_disable_superscalar_unroll
- (09) exprtk_disable_rtl_io_file
- (10) exprtk_disable_rtl_vecops
- (11) exprtk_disable_caseinsensitivity
-
+ (02) exprtk_disable_cardinal_pow_optimisation
+ (03) exprtk_disable_comments
+ (04) exprtk_disable_break_continue
+ (05) exprtk_disable_sc_andor
+ (06) exprtk_disable_return_statement
+ (07) exprtk_disable_enhanced_features
+ (08) exprtk_disable_string_capabilities
+ (09) exprtk_disable_superscalar_unroll
+ (10) exprtk_disable_rtl_io
+ (11) exprtk_disable_rtl_io_file
+ (12) exprtk_disable_rtl_vecops
+ (13) exprtk_disable_caseinsensitivity
+ (14) exprtk_enable_range_runtime_checks
(01) exprtk_enable_debugging
This define will enable printing of debug information to stdout during
the compilation process.
-(02) exprtk_disable_comments
+(02) exprtk_disable_cardinal_pow_optimisation
+This define will disable the optimisation invoked when constant
+integers are used as powers in exponentiation expressions (eg: x^7).
+
+(03) exprtk_disable_comments
This define will disable the ability for expressions to have comments.
Expressions that have comments when parsed with a build that has this
option, will result in a compilation failure.
-(03) exprtk_disable_break_continue
+(04) exprtk_disable_break_continue
This define will disable the loop-wise 'break' and 'continue'
capabilities. Any expression that contains those keywords will result
in a compilation failure.
-(04) exprtk_disable_sc_andor
+(05) exprtk_disable_sc_andor
This define will disable the short-circuit '&' (and) and '|' (or)
operators
-(05) exprtk_disable_return_statement
+(06) exprtk_disable_return_statement
This define will disable use of return statements within expressions.
-(06) exprtk_disable_enhanced_features
+(07) exprtk_disable_enhanced_features
This define will disable all enhanced features such as strength
reduction and special function optimisations and expression specific
type instantiations. This feature will reduce compilation times and
binary sizes but will also result in massive performance degradation
of expression evaluations.
-(07) exprtk_disable_string_capabilities
+(08) exprtk_disable_string_capabilities
This define will disable all string processing capabilities. Any
expression that contains a string or string related syntax will result
in a compilation failure.
-(08) exprtk_disable_superscalar_unroll
+(09) exprtk_disable_superscalar_unroll
This define will set the loop unroll batch size to 4 operations per
loop instead of the default 8 operations. This define is used in
operations that involve vectors and aggregations over vectors. When
@@ -4644,22 +4748,32 @@
build using this particular option if efficiency of evaluations is of
concern.
-(09) exprtk_disable_rtl_io_file
+(10) exprtk_disable_rtl_io
+This define will disable all of basic IO RTL package features. When
+present, any attempt to register the basic IO RTL package with a given
+symbol table will fail causing a compilation error.
+
+(11) exprtk_disable_rtl_io_file
This define will disable the file I/O RTL package features. When
present, any attempts to register the file I/O package with a given
symbol table will fail causing a compilation error.
-(10) exprtk_disable_rtl_vecops
+(12) exprtk_disable_rtl_vecops
This define will disable the extended vector operations RTL package
features. When present, any attempts to register the vector operations
package with a given symbol table will fail causing a compilation
error.
-(11) exprtk_disable_caseinsensitivity
+(13) exprtk_disable_caseinsensitivity
This define will disable case-insensitivity when matching variables
and functions. Furthermore all reserved and keywords will only be
acknowledged when in all lower-case.
+(14) exprtk_enable_range_runtime_checks
+This define will enable run-time checks pertaining to vector indexing
+operations used in any of the vector-to-vector and vector-to-scalar
+operations.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[SECTION 28 - FILES]