C++ Mathematical Expression Library (ExprTk)  https://www.partow.net/programming/exprtk/index.html
diff --git a/exprtk.hpp b/exprtk.hpp
index 9abf311..0da0960 100644
--- a/exprtk.hpp
+++ b/exprtk.hpp
@@ -66,7 +66,10 @@
 
    namespace details
    {
-      inline bool is_whitespace(const char c)
+      typedef unsigned char uchar_t;
+      typedef char           char_t;
+
+      inline bool is_whitespace(const char_t c)
       {
          return (' '  == c) || ('\n' == c) ||
                 ('\r' == c) || ('\t' == c) ||
@@ -74,7 +77,7 @@
                 ('\f' == c) ;
       }
 
-      inline bool is_operator_char(const char c)
+      inline bool is_operator_char(const char_t c)
       {
          return ('+' == c) || ('-' == c) ||
                 ('*' == c) || ('/' == c) ||
@@ -89,43 +92,43 @@
                 ('|' == c) || (';' == c) ;
       }
 
-      inline bool is_letter(const char c)
+      inline bool is_letter(const char_t c)
       {
          return (('a' <= c) && (c <= 'z')) ||
                 (('A' <= c) && (c <= 'Z')) ;
       }
 
-      inline bool is_digit(const char c)
+      inline bool is_digit(const char_t c)
       {
          return ('0' <= c) && (c <= '9');
       }
 
-      inline bool is_letter_or_digit(const char c)
+      inline bool is_letter_or_digit(const char_t c)
       {
          return is_letter(c) || is_digit(c);
       }
 
-      inline bool is_left_bracket(const char c)
+      inline bool is_left_bracket(const char_t c)
       {
          return ('(' == c) || ('[' == c) || ('{' == c);
       }
 
-      inline bool is_right_bracket(const char c)
+      inline bool is_right_bracket(const char_t c)
       {
          return (')' == c) || (']' == c) || ('}' == c);
       }
 
-      inline bool is_bracket(const char c)
+      inline bool is_bracket(const char_t c)
       {
          return is_left_bracket(c) || is_right_bracket(c);
       }
 
-      inline bool is_sign(const char c)
+      inline bool is_sign(const char_t c)
       {
          return ('+' == c) || ('-' == c);
       }
 
-      inline bool is_invalid(const char c)
+      inline bool is_invalid(const char_t c)
       {
          return !is_whitespace   (c) &&
                 !is_operator_char(c) &&
@@ -138,7 +141,7 @@
                 ('\'' != c);
       }
 
-      inline bool imatch(const char c1, const char c2)
+      inline bool imatch(const char_t c1, const char_t c2)
       {
          return std::tolower(c1) == std::tolower(c2);
       }
@@ -217,7 +220,7 @@
                 (('a' <= digit) && (digit <= 'f')) ;
       }
 
-      inline unsigned char hex_to_bin(unsigned char h)
+      inline uchar_t hex_to_bin(uchar_t h)
       {
          if (('0' <= h) && (h <= '9'))
             return (h - '0');
@@ -339,8 +342,8 @@
 
             for (std::size_t i = 0; i < length;  ++i)
             {
-               const char c1 = static_cast<char>(std::tolower(s1[i]));
-               const char c2 = static_cast<char>(std::tolower(s2[i]));
+               const char_t c1 = static_cast<char>(std::tolower(s1[i]));
+               const char_t c2 = static_cast<char>(std::tolower(s2[i]));
 
                if (c1 > c2)
                   return false;
@@ -502,7 +505,7 @@
 
       struct cs_match
       {
-         static inline bool cmp(const char c0, const char c1)
+         static inline bool cmp(const char_t c0, const char_t c1)
          {
             return (c0 == c1);
          }
@@ -510,7 +513,7 @@
 
       struct cis_match
       {
-         static inline bool cmp(const char c0, const char c1)
+         static inline bool cmp(const char_t c0, const char_t c1)
          {
             return (std::tolower(c0) == std::tolower(c1));
          }
@@ -621,7 +624,7 @@
          {
             if ('*' == (*p_itr))
             {
-               const char target = static_cast<char>(std::toupper(*(p_itr - 1)));
+               const char_t target = static_cast<char>(std::toupper(*(p_itr - 1)));
 
                if ('*' == target)
                {
@@ -1697,8 +1700,8 @@
       template <typename Iterator, typename T>
       static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
       {
-         static const char inf_uc[] = "INFINITY";
-         static const char inf_lc[] = "infinity";
+         static const char_t inf_uc[] = "INFINITY";
+         static const char_t inf_lc[] = "infinity";
          static const std::size_t inf_length = 8;
 
          const std::size_t length = std::distance(itr,end);
@@ -2091,6 +2094,7 @@
          typedef token token_t;
          typedef std::vector<token_t> token_list_t;
          typedef std::vector<token_t>::iterator token_list_itr_t;
+         typedef details::char_t char_t;
 
          generator()
          : base_itr_(0),
@@ -2255,7 +2259,7 @@
             // 3. /* .... */
             struct test
             {
-               static inline bool comment_start(const char c0, const char c1, int& mode, int& incr)
+               static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr)
                {
                   mode = 0;
                        if ('#' == c0)    { mode = 1; incr = 1; }
@@ -2267,7 +2271,7 @@
                   return (0 != mode);
                }
 
-               static inline bool comment_end(const char c0, const char c1, const int mode)
+               static inline bool comment_end(const char_t c0, const char_t c1, const int mode)
                {
                   return (
                            ((1 == mode) && ('\n' == c0)) ||
@@ -2358,15 +2362,15 @@
          {
             token_t t;
 
-            const char c0 = s_itr_[0];
+            const char_t c0 = s_itr_[0];
 
             if (!is_end(s_itr_ + 1))
             {
-               const char c1 = s_itr_[1];
+               const char_t c1 = s_itr_[1];
 
                if (!is_end(s_itr_ + 2))
                {
-                  const char c2 = s_itr_[2];
+                  const char_t c2 = s_itr_[2];
 
                   if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
                   {
@@ -3283,7 +3287,7 @@
                     exprtk::details::is_bracket(t.value[0])
                   )
                {
-                  char c = t.value[0];
+                  details::char_t c = t.value[0];
 
                        if (t.type == lexer::token::e_lbracket)    stack_.push(std::make_pair(')',t.position));
                   else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
@@ -4142,16 +4146,40 @@
          : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
          {}
 
-         value_t& operator()()
+         inline value_t& operator()()
          {
             return v_;
          }
 
-         const value_t& operator()() const
+         inline const value_t& operator()() const
          {
             return v_;
          }
 
+         template <typename IntType>
+         inline bool to_int(IntType& i) const
+         {
+            if (!exprtk::details::numeric::is_integer(v_))
+               return false;
+
+            i = static_cast<IntType>(v_);
+
+            return true;
+         }
+
+         template <typename UIntType>
+         inline bool to_uint(UIntType& u) const
+         {
+            if (v_ < T(0))
+               return false;
+            else if (!exprtk::details::numeric::is_integer(v_))
+               return false;
+
+            u = static_cast<UIntType>(v_);
+
+            return true;
+         }
+
          T& v_;
       };
    };
@@ -5252,7 +5280,7 @@
       private:
 
          mutable vector_holder_base* vector_holder_base_;
-         unsigned char buffer[64];
+         uchar_t buffer[64];
       };
 
       template <typename T>
@@ -17557,7 +17585,7 @@
 
          for (std::size_t i = error.token.position; i > 0; --i)
          {
-            const char c = expression[i];
+            const details::char_t c = expression[i];
 
             if (('\n' == c) || ('\r' == c))
             {
@@ -18455,12 +18483,9 @@
       struct parser_state
       {
          parser_state()
-         : parsing_return_stmt(false),
-           parsing_break_stmt (false),
-           return_stmt_present(false),
-           side_effect_present(false),
-           scope_depth(0)
-         {}
+         {
+            reset();
+         }
 
          void reset()
          {
@@ -21225,7 +21250,7 @@
                      nse.type      = scope_element::e_variable;
                      nse.depth     = state_.scope_depth;
                      nse.data      = new T(T(0));
-                     nse.var_node  = new variable_node_t(*(T*)(nse.data));
+                     nse.var_node  = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
 
                      if (!sem_.add_element(nse))
                      {
@@ -22429,8 +22454,8 @@
 
             for (std::size_t i = 0; i < param_seq_list_.size(); ++i)
             {
-               std::size_t diff_index = 0;
-               char        diff_value = 0;
+               details::char_t diff_value = 0;
+               std::size_t     diff_index = 0;
 
                bool result = details::sequence_match(param_seq_list_[i],
                                                      param_seq,
@@ -23519,7 +23544,7 @@
             nse.type      = scope_element::e_variable;
             nse.depth     = state_.scope_depth;
             nse.data      = new T(T(0));
-            nse.var_node  = new variable_node_t(*(T*)(nse.data));
+            nse.var_node  = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
 
             if (!sem_.add_element(nse))
             {
@@ -23609,7 +23634,7 @@
             nse.depth     = state_.scope_depth;
             nse.ip_index  = sem_.next_ip_index();
             nse.data      = new T(T(0));
-            nse.var_node  = new variable_node_t(*(T*)(nse.data));
+            nse.var_node  = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
 
             if (!sem_.add_element(nse))
             {
@@ -26535,7 +26560,7 @@
                                     }
                                     break;
 
-               case e_st_vecelem   : {
+               case e_st_vecelem  : {
                                        typedef details::vector_holder<T> vector_holder_t;
 
                                        vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder();
diff --git a/exprtk_simple_example_18.cpp b/exprtk_simple_example_18.cpp
index 4cf4b79..a6ac9e4 100644
--- a/exprtk_simple_example_18.cpp
+++ b/exprtk_simple_example_18.cpp
@@ -56,12 +56,12 @@
                 "   return [false];                                    "
                 " }                                                    ";
 
+   exprtk::rtl::io::file::package<T> fileio_package;
    exprtk::rtl::io::println<T>       println;
-   exprtk::rtl::io::file::package<T> package;
 
    symbol_table_t symbol_table;
    symbol_table.add_function("println",println);
-   symbol_table.add_package (package);
+   symbol_table.add_package (fileio_package   );
 
    expression_t expression;
    expression.register_symbol_table(symbol_table);
diff --git a/exprtk_test.cpp b/exprtk_test.cpp
index 9792186..d161ca8 100644
--- a/exprtk_test.cpp
+++ b/exprtk_test.cpp
@@ -6336,6 +6336,132 @@
          return false;
    }
 
+   {
+      bool failure = false;
+
+      typedef exprtk::symbol_table<T> symbol_table_t;
+      typedef exprtk::expression<T>     expression_t;
+      typedef exprtk::parser<T>             parser_t;
+
+      std::vector<T> v0;
+      std::vector<T> s;
+
+      #define pb(v,N)    \
+      v.push_back(T(N)); \
+
+      pb(v0,0) pb(v0,1) pb(v0,2) pb(v0,3) pb(v0,4)
+      pb(v0,5) pb(v0,6) pb(v0,7) pb(v0,8) pb(v0,9)
+
+      pb(s, 3) pb(s, 6) pb(s, 9) pb(s,12)
+      pb(s,15) pb(s,18) pb(s,21)
+      #undef pb
+
+      const std::string expr_string = "var i := 0; var j := 1; var k := 2; v[i] + v[j] + v[k]";
+
+      exprtk::vector_view<T> v = exprtk::make_vector_view(v0,4);
+
+      symbol_table_t symbol_table;
+      symbol_table.add_vector("v",v);
+
+      expression_t expression;
+      expression.register_symbol_table(symbol_table);
+
+      parser_t parser;
+
+      if (!parser.compile(expr_string,expression))
+      {
+         printf("run_test18() - Error: %s\tExpression: %s\n",
+                parser.error().c_str(),
+                expr_string.c_str());
+
+         failure = true;
+      }
+
+      for (std::size_t i = 0; i < v0.size() - 4; ++i)
+      {
+         v.rebase(v0.data() + i);
+
+         T sum = expression.value();
+
+         if (not_equal(sum,s[i]))
+         {
+            printf("run_test18() - Error in evaluation! (8) Expression: %s  Expected: %5.3f  Computed: %5.3f\n",
+                   expr_string.c_str(),
+                   s[i],
+                   sum);
+
+            failure = true;
+         }
+
+      }
+
+      if (failure)
+         return false;
+   }
+
+   {
+      bool failure = false;
+
+      typedef exprtk::symbol_table<T> symbol_table_t;
+      typedef exprtk::expression<T>     expression_t;
+      typedef exprtk::parser<T>             parser_t;
+
+      std::vector<T> v0;
+      std::vector<T> s;
+
+      #define pb(v,N)    \
+      v.push_back(T(N)); \
+
+      pb(v0,0) pb(v0,1) pb(v0,2) pb(v0,3) pb(v0,4)
+      pb(v0,5) pb(v0,6) pb(v0,7) pb(v0,8) pb(v0,9)
+
+      pb(s, 3) pb(s, 6) pb(s, 9) pb(s,12)
+      pb(s,15) pb(s,18) pb(s,21)
+      #undef pb
+
+      const std::string expr_string = "var i := 0; v[i + 0] + v[i + 1] + v[i + 2]";
+
+      exprtk::vector_view<T> v = exprtk::make_vector_view(v0,4);
+
+      symbol_table_t symbol_table;
+      symbol_table.add_vector("v",v);
+
+      expression_t expression;
+      expression.register_symbol_table(symbol_table);
+
+      parser_t parser;
+
+      if (!parser.compile(expr_string,expression))
+      {
+         printf("run_test18() - Error: %s\tExpression: %s\n",
+                parser.error().c_str(),
+                expr_string.c_str());
+
+         failure = true;
+      }
+
+      for (std::size_t i = 0; i < v0.size() - 4; ++i)
+      {
+         v.rebase(v0.data() + i);
+
+         T sum = expression.value();
+
+         if (not_equal(sum,s[i]))
+         {
+            printf("run_test18() - Error in evaluation! (9) Expression: %s  Expected: %5.3f  Computed: %5.3f\n",
+                   expr_string.c_str(),
+                   s[i],
+                   sum);
+
+            failure = true;
+         }
+
+      }
+
+      if (failure)
+         return false;
+   }
+
    return true;
 }