diff --git a/server/src/exprtk.hpp b/server/src/exprtk.hpp
index b4530ba..da493c5 100644
--- a/server/src/exprtk.hpp
+++ b/server/src/exprtk.hpp
@@ -2,7 +2,7 @@
  ******************************************************************
  *           C++ Mathematical Expression Toolkit Library          *
  *                                                                *
- * Author: Arash Partow (1999-2023)                               *
+ * Author: Arash Partow (1999-2024)                               *
  * URL: https://www.partow.net/programming/exprtk/index.html      *
  *                                                                *
  * Copyright notice:                                              *
@@ -10,6 +10,7 @@
  * permitted under the guidelines and in accordance with the most *
  * current version of the MIT License.                            *
  * https://www.opensource.org/licenses/MIT                        *
+ * SPDX-License-Identifier: MIT                                   *
  *                                                                *
  * Example expressions:                                           *
  * (00) (y + x / y) * (x - y / x)                                 *
@@ -17,12 +18,12 @@
  * (02) sqrt(1 - (x^2))                                           *
  * (03) 1 - sin(2 * x) + cos(pi / y)                              *
  * (04) a * exp(2 * t) + c                                        *
- * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z)        *
+ * (05) if(((x + 2) == 3) and ((y + 5) <= 9), 1 + w, 2 / z)       *
  * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x          *
  * (07) z := x + sin(2 * pi / y)                                  *
  * (08) u := 2 * (pi * z) / (w := x + cos(y / pi))                *
- * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1)            *
- * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0)     *
+ * (09) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1)          *
+ * (10) inrange(-2, m, +2) == if(({-2 <= m} and [m <= +2]), 1, 0) *
  * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1)  *
  * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)]                  *
  *                                                                *
@@ -42,7 +43,6 @@
 #include <cstdlib>
 #include <cstring>
 #include <deque>
-#include <exception>
 #include <functional>
 #include <iterator>
 #include <limits>
@@ -67,20 +67,6 @@ namespace exprtk
    #define exprtk_error_location             \
    "exprtk.hpp:" + details::to_str(__LINE__) \
 
-   #if defined(__GNUC__) && (__GNUC__  >= 7)
-
-      #define exprtk_disable_fallthrough_begin                      \
-      _Pragma ("GCC diagnostic push")                               \
-      _Pragma ("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
-
-      #define exprtk_disable_fallthrough_end                        \
-      _Pragma ("GCC diagnostic pop")                                \
-
-   #else
-      #define exprtk_disable_fallthrough_begin (void)0;
-      #define exprtk_disable_fallthrough_end   (void)0;
-   #endif
-
    #if __cplusplus >= 201103L
       #define exprtk_override override
       #define exprtk_final    final
@@ -91,6 +77,18 @@ namespace exprtk
       #define exprtk_delete
    #endif
 
+   #if __cplusplus >= 201603L
+      #define exprtk_fallthrough [[fallthrough]];
+   #elif __cplusplus >= 201103L
+      #define exprtk_fallthrough [[gnu::fallthrough]];
+   #else
+      #ifndef _MSC_VER
+      #define exprtk_fallthrough __attribute__ ((fallthrough));
+      #else
+      #define exprtk_fallthrough
+      #endif
+   #endif
+
    namespace details
    {
       typedef char                   char_t;
@@ -218,15 +216,15 @@ namespace exprtk
          {
             const std::size_t length = std::min(s1.size(),s2.size());
 
-            for (std::size_t i = 0; i < length;  ++i)
+            for (std::size_t i = 0; i < length; ++i)
             {
                const char_t c1 = static_cast<char_t>(std::tolower(s1[i]));
                const char_t c2 = static_cast<char_t>(std::tolower(s2[i]));
 
-               if (c1 > c2)
-                  return false;
-               else if (c1 < c2)
+               if (c1 < c2)
                   return true;
+               else if (c2 < c1)
+                  return false;
             }
 
             return s1.size() < s2.size();
@@ -364,9 +362,9 @@ namespace exprtk
                }
                else if (parse_hex(itr1, end, *itr2))
                {
-                  itr1+= 4;
-                  itr2+= 1;
-                  removal_count +=4;
+                  itr1 += 4;
+                  itr2 += 1;
+                  removal_count += 4;
                }
                else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; }
                else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; }
@@ -381,6 +379,7 @@ namespace exprtk
                   (*itr2++) = (*itr1++);
                   ++removal_count;
                }
+
                continue;
             }
             else
@@ -432,85 +431,85 @@ namespace exprtk
       };
 
       static const std::string reserved_words[] =
-                                  {
-                                    "break",  "case",  "continue",  "default",  "false",  "for",
-                                    "if", "else", "ilike",  "in", "like", "and",  "nand", "nor",
-                                    "not",  "null",  "or",   "repeat", "return",  "shl",  "shr",
-                                    "swap", "switch", "true",  "until", "var",  "while", "xnor",
-                                    "xor", "&", "|"
-                                  };
+      {
+         "assert",  "break", "case", "continue", "const",  "default",
+         "false", "for", "if", "else", "ilike", "in", "like",  "and",
+         "nand",  "nor",  "not",  "null",  "or",  "repeat", "return",
+         "shl",  "shr",  "swap",  "switch",  "true",  "until", "var",
+         "while", "xnor", "xor", "&", "|"
+      };
 
       static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
 
       static const std::string reserved_symbols[] =
-                                  {
-                                    "abs",  "acos",  "acosh",  "and",  "asin",  "asinh", "atan",
-                                    "atanh", "atan2", "avg",  "break", "case", "ceil",  "clamp",
-                                    "continue",   "cos",   "cosh",   "cot",   "csc",  "default",
-                                    "deg2grad",  "deg2rad",   "equal",  "erf",   "erfc",  "exp",
-                                    "expm1",  "false",   "floor",  "for",   "frac",  "grad2deg",
-                                    "hypot", "iclamp", "if",  "else", "ilike", "in",  "inrange",
-                                    "like",  "log",  "log10", "log2",  "logn",  "log1p", "mand",
-                                    "max", "min",  "mod", "mor",  "mul", "ncdf",  "nand", "nor",
-                                    "not",   "not_equal",   "null",   "or",   "pow",  "rad2deg",
-                                    "repeat", "return", "root", "round", "roundn", "sec", "sgn",
-                                    "shl", "shr", "sin", "sinc", "sinh", "sqrt",  "sum", "swap",
-                                    "switch", "tan",  "tanh", "true",  "trunc", "until",  "var",
-                                    "while", "xnor", "xor", "&", "|"
-                                  };
+      {
+         "abs", "acos",  "acosh", "and",  "asin", "asinh",  "assert",
+         "atan", "atanh",  "atan2", "avg",  "break", "case",  "ceil",
+         "clamp", "continue", "const",  "cos", "cosh", "cot",  "csc",
+         "default",  "deg2grad", "deg2rad",  "equal", "erf",  "erfc",
+         "exp", "expm1", "false", "floor", "for", "frac", "grad2deg",
+         "hypot", "iclamp", "if",  "else", "ilike", "in",  "inrange",
+         "like",  "log",  "log10", "log2",  "logn",  "log1p", "mand",
+         "max", "min",  "mod", "mor",  "mul", "ncdf",  "nand", "nor",
+         "not",   "not_equal",   "null",   "or",   "pow",  "rad2deg",
+         "repeat", "return", "root", "round", "roundn", "sec", "sgn",
+         "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum",  "swap",
+         "switch", "tan",  "tanh", "true",  "trunc", "until",  "var",
+         "while", "xnor", "xor", "&", "|"
+      };
 
       static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
 
       static const std::string base_function_list[] =
-                                  {
-                                    "abs", "acos",  "acosh", "asin",  "asinh", "atan",  "atanh",
-                                    "atan2",  "avg",  "ceil",  "clamp",  "cos",  "cosh",  "cot",
-                                    "csc",  "equal",  "erf",  "erfc",  "exp",  "expm1", "floor",
-                                    "frac", "hypot", "iclamp",  "like", "log", "log10",  "log2",
-                                    "logn", "log1p", "mand", "max", "min", "mod", "mor",  "mul",
-                                    "ncdf",  "pow",  "root",  "round",  "roundn",  "sec", "sgn",
-                                    "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
-                                    "trunc",  "not_equal",  "inrange",  "deg2grad",   "deg2rad",
-                                    "rad2deg", "grad2deg"
-                                  };
+      {
+         "abs", "acos",  "acosh", "asin",  "asinh", "atan",  "atanh",
+         "atan2",  "avg",  "ceil",  "clamp",  "cos",  "cosh",  "cot",
+         "csc",  "equal",  "erf",  "erfc",  "exp",  "expm1", "floor",
+         "frac", "hypot", "iclamp",  "like", "log", "log10",  "log2",
+         "logn", "log1p", "mand", "max", "min", "mod", "mor",  "mul",
+         "ncdf",  "pow",  "root",  "round",  "roundn",  "sec", "sgn",
+         "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
+         "trunc",  "not_equal",  "inrange",  "deg2grad",   "deg2rad",
+         "rad2deg", "grad2deg"
+      };
 
       static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
 
       static const std::string logic_ops_list[] =
-                                  {
-                                    "and", "nand", "nor", "not", "or",  "xnor", "xor", "&", "|"
-                                  };
+      {
+         "and", "nand", "nor", "not", "or",  "xnor", "xor", "&", "|"
+      };
 
       static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
 
       static const std::string cntrl_struct_list[] =
-                                  {
-                                     "if", "switch", "for", "while", "repeat", "return"
-                                  };
+      {
+         "if", "switch", "for", "while", "repeat", "return"
+      };
 
       static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
 
       static const std::string arithmetic_ops_list[] =
-                                  {
-                                    "+", "-", "*", "/", "%", "^"
-                                  };
+      {
+         "+", "-", "*", "/", "%", "^"
+      };
 
       static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
 
       static const std::string assignment_ops_list[] =
-                                  {
-                                    ":=", "+=", "-=",
-                                    "*=", "/=", "%="
-                                  };
+      {
+         ":=", "+=", "-=",
+         "*=", "/=", "%="
+      };
 
       static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
 
       static const std::string inequality_ops_list[] =
-                                  {
-                                     "<",  "<=", "==",
-                                     "=",  "!=", "<>",
-                                    ">=",  ">"
-                                  };
+      {
+         "<",  "<=", "==",
+         "=",  "!=", "<>",
+         ">=",  ">"
+      };
 
       static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string);
 
@@ -646,7 +645,7 @@ namespace exprtk
                }
             }
             else if (data_end == d_itr)
-               return true;
+               break;
 
             if ((data_end == d_itr) || (null_itr == nd_itr))
                 return false;
@@ -661,23 +660,27 @@ namespace exprtk
       inline bool wc_match(const std::string& wild_card,
                            const std::string& str)
       {
-         return match_impl<char_cptr,cs_match>(
+         return match_impl<char_cptr,cs_match>
+                (
                    wild_card.data(),
                    wild_card.data() + wild_card.size(),
                    str.data(),
                    str.data() + str.size(),
-                   '*', '?');
+                   '*', '?'
+                );
       }
 
       inline bool wc_imatch(const std::string& wild_card,
                             const std::string& str)
       {
-         return match_impl<char_cptr,cis_match>(
+         return match_impl<char_cptr,cis_match>
+                (
                    wild_card.data(),
                    wild_card.data() + wild_card.size(),
                    str.data(),
                    str.data() + str.size(),
-                   '*', '?');
+                   '*', '?'
+                );
       }
 
       inline bool sequence_match(const std::string& pattern,
@@ -750,13 +753,55 @@ namespace exprtk
                 );
       }
 
-      static const double pow10[] = {
-                                      1.0,
-                                      1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
-                                      1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
-                                      1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
-                                      1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
-                                    };
+      template<typename T>
+      struct set_zero_value_impl
+      {
+         static inline void process(T* base_ptr, const std::size_t size)
+         {
+            const T zero = T(0);
+            for (std::size_t i = 0; i < size; ++i)
+            {
+               base_ptr[i] = zero;
+            }
+         }
+      };
+
+      #define pod_set_zero_value(T)                                      \
+      template <>                                                        \
+      struct set_zero_value_impl<T>                                      \
+      {                                                                  \
+         static inline void process(T* base_ptr, const std::size_t size) \
+         { std::memset(base_ptr, 0x00, size * sizeof(T)); }              \
+      };                                                                 \
+
+      pod_set_zero_value(float      )
+      pod_set_zero_value(double     )
+      pod_set_zero_value(long double)
+
+      #ifdef pod_set_zero_value
+      #undef pod_set_zero_value
+      #endif
+
+      template<typename T>
+      inline void set_zero_value(T* data, const std::size_t size)
+      {
+         set_zero_value_impl<T>::process(data,size);
+      }
+
+      template<typename T>
+      inline void set_zero_value(std::vector<T>& v)
+      {
+         set_zero_value(v.data(),v.size());
+      }
+
+      static const double pow10[] =
+      {
+         1.0,
+         1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
+         1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
+         1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
+         1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
+      };
 
       static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
 
@@ -789,17 +834,17 @@ namespace exprtk
                number_type() {}
             };
 
-            #define exprtk_register_real_type_tag(T)             \
-            template <> struct number_type<T>                    \
-            { typedef real_type_tag type; number_type() {} };    \
+            #define exprtk_register_real_type_tag(T)          \
+            template <> struct number_type<T>                 \
+            { typedef real_type_tag type; number_type() {} }; \
 
-            #define exprtk_register_int_type_tag(T)              \
-            template <> struct number_type<T>                    \
-            { typedef int_type_tag type; number_type() {} };     \
+            #define exprtk_register_int_type_tag(T)           \
+            template <> struct number_type<T>                 \
+            { typedef int_type_tag type; number_type() {} };  \
 
+            exprtk_register_real_type_tag(float      )
             exprtk_register_real_type_tag(double     )
             exprtk_register_real_type_tag(long double)
-            exprtk_register_real_type_tag(float      )
 
             exprtk_register_int_type_tag(short         )
             exprtk_register_int_type_tag(int           )
@@ -848,6 +893,12 @@ namespace exprtk
                return static_cast<_int64_t>(v);
             }
 
+            template <typename T>
+            inline _uint64_t to_uint64_impl(const T v, real_type_tag)
+            {
+               return static_cast<_uint64_t>(v);
+            }
+
             template <typename T>
             inline bool is_true_impl(const T v)
             {
@@ -982,8 +1033,8 @@ namespace exprtk
                   else
                      return (T(-0.5) * v + T(1)) * v;
                }
-               else
-                  return std::numeric_limits<T>::quiet_NaN();
+
+               return std::numeric_limits<T>::quiet_NaN();
             }
 
             template <typename T>
@@ -993,8 +1044,8 @@ namespace exprtk
                {
                   return std::log(T(1) + v);
                }
-               else
-                  return std::numeric_limits<T>::quiet_NaN();
+
+               return std::numeric_limits<T>::quiet_NaN();
             }
 
             template <typename T>
@@ -1193,9 +1244,9 @@ namespace exprtk
             #define exprtk_define_erf(TT, impl)                \
             inline TT erf_impl(const TT v) { return impl(v); } \
 
-            exprtk_define_erf(      float,::erff)
-            exprtk_define_erf(     double,::erf )
-            exprtk_define_erf(long double,::erfl)
+            exprtk_define_erf(float      , ::erff)
+            exprtk_define_erf(double     , ::erf )
+            exprtk_define_erf(long double, ::erfl)
             #undef exprtk_define_erf
             #endif
 
@@ -1204,13 +1255,14 @@ namespace exprtk
             {
                #if defined(_MSC_VER) && (_MSC_VER < 1900)
                // Credits: Abramowitz & Stegun Equations 7.1.25-28
-               static const T c[] = {
-                                      T( 1.26551223), T(1.00002368),
-                                      T( 0.37409196), T(0.09678418),
-                                      T(-0.18628806), T(0.27886807),
-                                      T(-1.13520398), T(1.48851587),
-                                      T(-0.82215223), T(0.17087277)
-                                    };
+               static const T c[] =
+               {
+                  T( 1.26551223), T(1.00002368),
+                  T( 0.37409196), T(0.09678418),
+                  T(-0.18628806), T(0.27886807),
+                  T(-1.13520398), T(1.48851587),
+                  T(-0.82215223), T(0.17087277)
+               };
 
                const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
 
@@ -1262,10 +1314,7 @@ namespace exprtk
             template <typename T>
             inline T ncdf_impl(const T v, real_type_tag)
             {
-               const T cnd = T(0.5) * (T(1) +
-                             erf_impl(abs_impl(v,real_type_tag()) /
-                                      T(numeric::constant::sqrt2),real_type_tag()));
-               return  (v < T(0)) ? (T(1) - cnd) : cnd;
+               return T(0.5) * erfc_impl(-(v / T(numeric::constant::sqrt2)),real_type_tag());
             }
 
             template <typename T>
@@ -1289,12 +1338,47 @@ namespace exprtk
                return sinc_impl(static_cast<double>(v),real_type_tag());
             }
 
+            #if __cplusplus >= 201103L
+            template <typename T>
+            inline T acosh_impl(const T v, real_type_tag)
+            {
+               return std::acosh(v);
+            }
+
+            template <typename T>
+            inline T asinh_impl(const T v, real_type_tag)
+            {
+               return std::asinh(v);
+            }
+
+            template <typename T>
+            inline T atanh_impl(const T v, real_type_tag)
+            {
+               return std::atanh(v);
+            }
+            #else
+            template <typename T>
+            inline T acosh_impl(const T v, real_type_tag)
+            {
+               return std::log(v + std::sqrt((v * v) - T(1)));
+            }
+
+            template <typename T>
+            inline T asinh_impl(const T v, real_type_tag)
+            {
+               return std::log(v + std::sqrt((v * v) + T(1)));
+            }
+
+            template <typename T>
+            inline T atanh_impl(const T v, real_type_tag)
+            {
+               return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2);
+            }
+            #endif
+
             template <typename T> inline T  acos_impl(const T v, real_type_tag) { return std::acos (v); }
-            template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
             template <typename T> inline T  asin_impl(const T v, real_type_tag) { return std::asin (v); }
-            template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
             template <typename T> inline T  atan_impl(const T v, real_type_tag) { return std::atan (v); }
-            template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); }
             template <typename T> inline T  ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
             template <typename T> inline T   cos_impl(const T v, real_type_tag) { return std::cos  (v); }
             template <typename T> inline T  cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
@@ -1390,6 +1474,13 @@ namespace exprtk
             return to_int64_impl(v, num_type);
          }
 
+         template <typename T>
+         inline _uint64_t to_uint64(const T v)
+         {
+            const typename details::number_type<T>::type num_type;
+            return to_uint64_impl(v, num_type);
+         }
+
          template <typename T>
          inline bool is_nan(const T v)
          {
@@ -1629,38 +1720,38 @@ namespace exprtk
       {
          static const double fract10[] =
          {
-           0.0,
-           1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010,
-           1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020,
-           1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030,
-           1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040,
-           1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050,
-           1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060,
-           1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070,
-           1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080,
-           1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090,
-           1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100,
-           1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110,
-           1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120,
-           1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130,
-           1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140,
-           1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150,
-           1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160,
-           1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170,
-           1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180,
-           1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190,
-           1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200,
-           1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
-           1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
-           1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230,
-           1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240,
-           1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250,
-           1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260,
-           1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270,
-           1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280,
-           1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290,
-           1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300,
-           1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
+            0.0,
+            1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010,
+            1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020,
+            1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030,
+            1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040,
+            1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050,
+            1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060,
+            1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070,
+            1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080,
+            1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090,
+            1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100,
+            1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110,
+            1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120,
+            1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130,
+            1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140,
+            1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150,
+            1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160,
+            1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170,
+            1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180,
+            1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190,
+            1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200,
+            1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
+            1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
+            1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230,
+            1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240,
+            1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250,
+            1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260,
+            1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270,
+            1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280,
+            1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290,
+            1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300,
+            1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
          };
 
          static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
@@ -1710,7 +1801,6 @@ namespace exprtk
 
          if (length <= 4)
          {
-            exprtk_disable_fallthrough_begin
             switch (length)
             {
                #ifdef exprtk_use_lut
@@ -1723,17 +1813,19 @@ namespace exprtk
                   return_result = false;                             \
                   break;                                             \
                }                                                     \
+               exprtk_fallthrough                                    \
 
                #else
 
-               #define exprtk_process_digit         \
-               if ((digit = (*itr++ - zero)) < 10)  \
-                  result = result * T(10) + digit;  \
-               else                                 \
-               {                                    \
-                  return_result = false;            \
-                  break;                            \
-               }                                    \
+               #define exprtk_process_digit        \
+               if ((digit = (*itr++ - zero)) < 10) \
+                  result = result * T(10) + digit; \
+               else                                \
+               {                                   \
+                  return_result = false;           \
+                  break;                           \
+               }                                   \
+               exprtk_fallthrough                  \
 
                #endif
 
@@ -1748,7 +1840,6 @@ namespace exprtk
 
                #undef exprtk_process_digit
             }
-            exprtk_disable_fallthrough_end
          }
          else
             return_result = false;
@@ -2067,14 +2158,74 @@ namespace exprtk
 
       virtual void handle_runtime_violation(const violation_context&)
       {
-         throw std::runtime_error("ExprTk Loop run-time violation.");
+         throw std::runtime_error("ExprTk Loop runtime violation.");
       }
 
-      virtual ~loop_runtime_check() {}
+      virtual ~loop_runtime_check()
+      {}
    };
 
    typedef loop_runtime_check* loop_runtime_check_ptr;
 
+   struct vector_access_runtime_check
+   {
+      struct violation_context
+      {
+         void* base_ptr;
+         void* end_ptr;
+         void* access_ptr;
+         std::size_t type_size;
+      };
+
+      virtual ~vector_access_runtime_check()
+      {}
+
+      virtual bool handle_runtime_violation(violation_context& /*context*/)
+      {
+         throw std::runtime_error("ExprTk runtime vector access violation.");
+         #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
+         return false;
+         #endif
+      }
+   };
+
+   typedef vector_access_runtime_check* vector_access_runtime_check_ptr;
+
+   struct assert_check
+   {
+      struct assert_context
+      {
+         std::string condition;
+         std::string message;
+         std::string id;
+         std::size_t offet;
+      };
+
+      virtual ~assert_check()
+      {}
+
+      virtual void handle_assert(const assert_context& /*context*/)
+      {
+      }
+   };
+
+   typedef assert_check* assert_check_ptr;
+
+   struct compilation_check
+   {
+      struct compilation_context
+      {
+         std::string error_message;
+      };
+
+      virtual bool continue_compilation(compilation_context& /*context*/) = 0;
+
+      virtual ~compilation_check()
+      {}
+   };
+
+   typedef compilation_check* compilation_check_ptr;
+
    namespace lexer
    {
       struct token
@@ -2233,6 +2384,19 @@ namespace exprtk
             }
          }
 
+         static inline std::string seperator_to_str(const token_type t)
+         {
+            switch (t)
+            {
+               case e_comma : return ",";
+               case e_colon : return ":";
+               case e_eof   : return ";";
+               default      : return "UNKNOWN";
+            }
+
+            return "UNKNOWN";
+         }
+
          inline bool is_error() const
          {
             return (
@@ -2282,7 +2446,7 @@ namespace exprtk
             s_itr_    = str.data();
             s_end_    = str.data() + str.size();
 
-            eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
+            eof_token_.set_operator(token_t::e_eof, s_end_, s_end_, base_itr_);
             token_list_.clear();
 
             while (!is_end(s_itr_))
@@ -2345,7 +2509,9 @@ namespace exprtk
          inline token_t& operator[](const std::size_t& index)
          {
             if (index < token_list_.size())
+            {
                return token_list_[index];
+            }
             else
                return eof_token_;
          }
@@ -2353,7 +2519,9 @@ namespace exprtk
          inline token_t operator[](const std::size_t& index) const
          {
             if (index < token_list_.size())
+            {
                return token_list_[index];
+            }
             else
                return eof_token_;
          }
@@ -2497,7 +2665,7 @@ namespace exprtk
                   }
                }
 
-                ++s_itr_;
+               ++s_itr_;
             }
 
             if (2 == mode)
@@ -2509,9 +2677,17 @@ namespace exprtk
             #endif
          }
 
+         inline bool next_is_digit(const details::char_cptr itr) const
+         {
+            return ((itr + 1) != s_end_) &&
+                   details::is_digit(*(itr + 1));
+         }
+
          inline void scan_token()
          {
-            if (details::is_whitespace(*s_itr_))
+            const char_t c = *s_itr_;
+
+            if (details::is_whitespace(c))
             {
                skip_whitespace();
                return;
@@ -2521,34 +2697,39 @@ namespace exprtk
                skip_comments();
                return;
             }
-            else if (details::is_operator_char(*s_itr_))
+            else if (details::is_operator_char(c))
             {
                scan_operator();
                return;
             }
-            else if (details::is_letter(*s_itr_))
+            else if (details::is_letter(c))
             {
                scan_symbol();
                return;
             }
-            else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_)))
+            else if (('.' == c) && !next_is_digit(s_itr_))
+            {
+               scan_operator();
+               return;
+            }
+            else if (details::is_digit(c) || ('.' == c))
             {
                scan_number();
                return;
             }
-            else if ('$' == (*s_itr_))
+            else if ('$' == c)
             {
                scan_special_function();
                return;
             }
             #ifndef exprtk_disable_string_capabilities
-            else if ('\'' == (*s_itr_))
+            else if ('\'' == c)
             {
                scan_string();
                return;
             }
             #endif
-            else if ('~' == (*s_itr_))
+            else if ('~' == c)
             {
                token_t t;
                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
@@ -2658,7 +2839,7 @@ namespace exprtk
             }
 
             token_t t;
-            t.set_symbol(initial_itr,s_itr_,base_itr_);
+            t.set_symbol(initial_itr, s_itr_, base_itr_);
             token_list_.push_back(t);
          }
 
@@ -2858,12 +3039,12 @@ namespace exprtk
                        ((s_itr_ + 4) <= s_end_)
                      )
                   {
-                     const bool x_seperator = ('X' == std::toupper(*(s_itr_ + 1)));
+                     const bool x_separator = ('X' == std::toupper(*(s_itr_ + 1)));
 
                      const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
                                               details::is_hex_digit(*(s_itr_ + 3)) ;
 
-                     if (!(x_seperator && both_digits))
+                     if (!(x_separator && both_digits))
                      {
                         t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
                         token_list_.push_back(t);
@@ -2903,8 +3084,8 @@ namespace exprtk
                }
 
                t.set_string(
-                    parsed_string,
-                    static_cast<std::size_t>(std::distance(base_itr_,initial_itr)));
+                  parsed_string,
+                  static_cast<std::size_t>(std::distance(base_itr_,initial_itr)));
             }
 
             token_list_.push_back(t);
@@ -2945,7 +3126,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~token_scanner() {}
+         virtual ~token_scanner()
+         {}
 
          explicit token_scanner(const std::size_t& stride)
          : stride_(stride)
@@ -2972,7 +3154,7 @@ namespace exprtk
 
                                  if (!operator()(t0))
                                  {
-                                    return i;
+                                    return 0;
                                  }
                               }
                               break;
@@ -2984,7 +3166,7 @@ namespace exprtk
 
                                  if (!operator()(t0, t1))
                                  {
-                                    return i;
+                                    return 0;
                                  }
                               }
                               break;
@@ -2997,7 +3179,7 @@ namespace exprtk
 
                                  if (!operator()(t0, t1, t2))
                                  {
-                                    return i;
+                                    return 0;
                                  }
                               }
                               break;
@@ -3011,7 +3193,7 @@ namespace exprtk
 
                                  if (!operator()(t0, t1, t2, t3))
                                  {
-                                    return i;
+                                    return 0;
                                  }
                               }
                               break;
@@ -3019,7 +3201,7 @@ namespace exprtk
                }
             }
 
-            return (g.token_list_.size() - stride_ + 1);
+            return 0;
          }
 
          virtual bool operator() (const token&)
@@ -3211,7 +3393,7 @@ namespace exprtk
             generator::token_list_t token_list;
             token_list.reserve(10000);
 
-            for (int i = 0;  i < static_cast<int>(g.token_list_.size() - 1); ++i)
+            for (int i = 0; i < static_cast<int>(g.token_list_.size() - 1); ++i)
             {
                token t;
 
@@ -3227,7 +3409,7 @@ namespace exprtk
 
                   ++changes;
 
-                  i+=2;
+                  i += 2;
 
                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1))
                      break;
@@ -3253,7 +3435,7 @@ namespace exprtk
             generator::token_list_t token_list;
             token_list.reserve(10000);
 
-            for (int i = 0;  i < static_cast<int>(g.token_list_.size() - 2); ++i)
+            for (int i = 0; i < static_cast<int>(g.token_list_.size() - 2); ++i)
             {
                token t;
 
@@ -3269,7 +3451,7 @@ namespace exprtk
 
                   ++changes;
 
-                  i+=3;
+                  i += 3;
 
                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2))
                      break;
@@ -3367,7 +3549,7 @@ namespace exprtk
             std::set<std::string,details::ilesscompare> ignore_set_;
          };
 
-         class operator_joiner : public token_joiner
+         class operator_joiner exprtk_final : public token_joiner
          {
          public:
 
@@ -3543,7 +3725,7 @@ namespace exprtk
             }
          };
 
-         class bracket_checker : public lexer::token_scanner
+         class bracket_checker exprtk_final : public lexer::token_scanner
          {
          public:
 
@@ -3554,7 +3736,7 @@ namespace exprtk
             , state_(true)
             {}
 
-            bool result()
+            bool result() exprtk_override
             {
                if (!stack_.empty())
                {
@@ -3575,7 +3757,7 @@ namespace exprtk
                return error_token_;
             }
 
-            void reset()
+            void reset() exprtk_override
             {
                // Why? because msvc doesn't support swap properly.
                stack_ = std::stack<std::pair<char,std::size_t> >();
@@ -3583,7 +3765,7 @@ namespace exprtk
                error_token_.clear();
             }
 
-            bool operator() (const lexer::token& t)
+            bool operator() (const lexer::token& t) exprtk_override
             {
                if (
                     !t.value.empty()                       &&
@@ -3640,18 +3822,18 @@ namespace exprtk
             , current_index_(0)
             {}
 
-            bool result()
+            bool result() exprtk_override
             {
                return error_list_.empty();
             }
 
-            void reset()
+            void reset() exprtk_override
             {
                error_list_.clear();
                current_index_ = 0;
             }
 
-            bool operator() (const lexer::token& t)
+            bool operator() (const lexer::token& t) exprtk_override
             {
                if (token::e_number == t.type)
                {
@@ -3692,7 +3874,7 @@ namespace exprtk
             std::vector<std::size_t> error_list_;
          };
 
-         class symbol_replacer : public lexer::token_modifier
+         class symbol_replacer exprtk_final : public lexer::token_modifier
          {
          private:
 
@@ -3735,7 +3917,7 @@ namespace exprtk
 
          private:
 
-            bool modify(lexer::token& t)
+            bool modify(lexer::token& t) exprtk_override
             {
                if (lexer::token::e_symbol == t.type)
                {
@@ -3798,12 +3980,12 @@ namespace exprtk
                add_invalid_set1(lexer::token::e_ternary);
             }
 
-            bool result()
+            bool result() exprtk_override
             {
                return error_list_.empty();
             }
 
-            bool operator() (const lexer::token& t0, const lexer::token& t1)
+            bool operator() (const lexer::token& t0, const lexer::token& t1) exprtk_override
             {
                const set_t::value_type p = std::make_pair(t0.type,t1.type);
 
@@ -3965,12 +4147,12 @@ namespace exprtk
                add_invalid(lexer::token::e_pow    , lexer::token::e_mod    , lexer::token::e_pow   );
             }
 
-            bool result()
+            bool result() exprtk_override
             {
                return error_list_.empty();
             }
 
-            bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2)
+            bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2) exprtk_override
             {
                const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type));
 
@@ -4227,6 +4409,11 @@ namespace exprtk
             return current_token_;
          }
 
+         inline const token_t& peek_next_token()
+         {
+            return lexer_.peek_next_token();
+         }
+
          enum token_advance_mode
          {
             e_hold    = 0,
@@ -4270,6 +4457,110 @@ namespace exprtk
             return true;
          }
 
+         inline bool token_is(const std::string& value,
+                              const token_advance_mode mode = e_advance)
+         {
+            if (!exprtk::details::imatch(value,current_token().value))
+            {
+               return false;
+            }
+
+            advance_token(mode);
+
+            return true;
+         }
+
+         inline bool token_is_arithmetic_opr(const token_advance_mode mode = e_advance)
+         {
+            switch (current_token().type)
+            {
+               case token_t::e_add :
+               case token_t::e_sub :
+               case token_t::e_div :
+               case token_t::e_mul :
+               case token_t::e_mod :
+               case token_t::e_pow : break;
+               default             : return false;
+            }
+
+            advance_token(mode);
+
+            return true;
+         }
+
+         inline bool token_is_ineq_opr(const token_advance_mode mode = e_advance)
+         {
+            switch (current_token().type)
+            {
+               case token_t::e_eq  :
+               case token_t::e_lte :
+               case token_t::e_ne  :
+               case token_t::e_gte :
+               case token_t::e_lt  :
+               case token_t::e_gt  : break;
+               default             : return false;
+            }
+
+            advance_token(mode);
+
+            return true;
+         }
+
+         inline bool token_is_left_bracket(const token_advance_mode mode = e_advance)
+         {
+            switch (current_token().type)
+            {
+               case token_t::e_lbracket    :
+               case token_t::e_lcrlbracket :
+               case token_t::e_lsqrbracket : break;
+               default                     : return false;
+            }
+
+            advance_token(mode);
+
+            return true;
+         }
+
+         inline bool token_is_right_bracket(const token_advance_mode mode = e_advance)
+         {
+            switch (current_token().type)
+            {
+               case token_t::e_rbracket    :
+               case token_t::e_rcrlbracket :
+               case token_t::e_rsqrbracket : break;
+               default                     : return false;
+            }
+
+            advance_token(mode);
+
+            return true;
+         }
+
+         inline bool token_is_bracket(const token_advance_mode mode = e_advance)
+         {
+            switch (current_token().type)
+            {
+               case token_t::e_rbracket    :
+               case token_t::e_rcrlbracket :
+               case token_t::e_rsqrbracket :
+               case token_t::e_lbracket    :
+               case token_t::e_lcrlbracket :
+               case token_t::e_lsqrbracket : break;
+               default                     : return false;
+            }
+
+            advance_token(mode);
+
+            return true;
+         }
+
+         inline bool token_is_loop(const token_advance_mode mode = e_advance)
+         {
+            return token_is("for"   , mode) ||
+                   token_is("while" , mode) ||
+                   token_is("repeat", mode) ;
+         }
+
          inline bool peek_token_is(const token_t::token_type& ttype)
          {
             return (lexer_.peek_next_token().type == ttype);
@@ -4296,16 +4587,22 @@ namespace exprtk
       typedef T* data_ptr_t;
 
       vector_view(data_ptr_t data, const std::size_t& size)
-      : size_(size)
+      : base_size_(size)
+      , size_(size)
       , data_(data)
       , data_ref_(0)
-      {}
+      {
+         assert(size_ > 0);
+      }
 
       vector_view(const vector_view<T>& vv)
-      : size_(vv.size_)
+      : base_size_(vv.base_size_)
+      , size_(vv.size_)
       , data_(vv.data_)
       , data_ref_(0)
-      {}
+      {
+         assert(size_ > 0);
+      }
 
       inline void rebase(data_ptr_t data)
       {
@@ -4325,6 +4622,11 @@ namespace exprtk
          return data_;
       }
 
+      inline std::size_t base_size() const
+      {
+         return base_size_;
+      }
+
       inline std::size_t size() const
       {
          return size_;
@@ -4332,22 +4634,55 @@ namespace exprtk
 
       inline const T& operator[](const std::size_t index) const
       {
+         assert(index < size_);
          return data_[index];
       }
 
       inline T& operator[](const std::size_t index)
       {
+         assert(index < size_);
          return data_[index];
       }
 
       void set_ref(data_ptr_t* data_ref)
       {
          data_ref_.push_back(data_ref);
+         exprtk_debug(("vector_view::set_ref() - data_ref: %p data_ref_.size(): %d\n",
+                       reinterpret_cast<void*>(data_ref),
+                       static_cast<int>(data_ref_.size())));
+      }
+
+      void remove_ref(data_ptr_t* data_ref)
+      {
+         data_ref_.erase(
+            std::remove(data_ref_.begin(), data_ref_.end(), data_ref),
+            data_ref_.end());
+         exprtk_debug(("vector_view::remove_ref() - data_ref: %p data_ref_.size(): %d\n",
+                       reinterpret_cast<void*>(data_ref),
+                       static_cast<int>(data_ref_.size())));
+      }
+
+      bool set_size(const std::size_t new_size)
+      {
+         if ((new_size > 0) && (new_size <= base_size_))
+         {
+            size_ = new_size;
+            exprtk_debug(("vector_view::set_size() - data_: %p size: %lu\n",
+                          reinterpret_cast<void*>(data_),
+                          size_));
+            return true;
+         }
+
+         exprtk_debug(("vector_view::set_size() - error invalid new_size: %lu  base_size: %lu\n",
+                       new_size,
+                       base_size_));
+         return false;
       }
 
    private:
 
-      const std::size_t size_;
+      const std::size_t base_size_;
+      std::size_t size_;
       data_ptr_t  data_;
       std::vector<data_ptr_t*> data_ref_;
    };
@@ -4523,6 +4858,16 @@ namespace exprtk
             return v_;
          }
 
+         inline operator value_t() const
+         {
+            return v_;
+         }
+
+         inline operator value_t()
+         {
+            return v_;
+         }
+
          template <typename IntType>
          inline bool to_int(IntType& i) const
          {
@@ -4571,6 +4916,9 @@ namespace exprtk
    public:
 
       typedef type_store<T> type_store_t;
+      typedef typename type_store_t::scalar_view scalar_t;
+      typedef typename type_store_t::vector_view vector_t;
+      typedef typename type_store_t::string_view string_t;
 
       results_context()
       : results_available_(false)
@@ -4594,6 +4942,61 @@ namespace exprtk
          return parameter_list_[index];
       }
 
+      inline bool get_scalar(const std::size_t& index, T& out) const
+      {
+         if (
+              (index < parameter_list_.size()) &&
+              (parameter_list_[index].type == type_store_t::e_scalar)
+            )
+         {
+            const scalar_t scalar(parameter_list_[index]);
+            out = scalar();
+            return true;
+         }
+
+         return false;
+      }
+
+      template <typename OutputIterator>
+      inline bool get_vector(const std::size_t& index, OutputIterator out_itr) const
+      {
+         if (
+              (index < parameter_list_.size()) &&
+              (parameter_list_[index].type == type_store_t::e_vector)
+            )
+         {
+            const vector_t vector(parameter_list_[index]);
+            for (std::size_t i = 0; i < vector.size(); ++i)
+            {
+               *(out_itr++) = vector[i];
+            }
+
+            return true;
+         }
+
+         return false;
+      }
+
+      inline bool get_vector(const std::size_t& index, std::vector<T>& out) const
+      {
+         return get_vector(index,std::back_inserter(out));
+      }
+
+      inline bool get_string(const std::size_t& index, std::string& out) const
+      {
+         if (
+              (index < parameter_list_.size()) &&
+              (parameter_list_[index].type == type_store_t::e_string)
+            )
+         {
+            const string_t str(parameter_list_[index]);
+            out.assign(str.begin(),str.size());
+            return true;
+         }
+
+         return false;
+      }
+
    private:
 
       inline void clear()
@@ -4740,10 +5143,11 @@ namespace exprtk
 
       namespace loop_unroll
       {
+         const unsigned int global_loop_batch_size =
          #ifndef exprtk_disable_superscalar_unroll
-         const unsigned int global_loop_batch_size = 16;
+         16;
          #else
-         const unsigned int global_loop_batch_size = 4;
+          4;
          #endif
 
          struct details
@@ -4770,11 +5174,28 @@ namespace exprtk
                           ptr,
                           static_cast<unsigned int>(size)));
          else
-            exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr));
+            exprtk_debug(("%s - addr: %p\n", s.c_str(), ptr));
+      }
+
+      template <typename T>
+      inline void dump_vector(const std::string& vec_name, const T* data, const std::size_t size)
+      {
+         printf("----- %s (%p) -----\n",
+                vec_name.c_str(),
+                static_cast<const void*>(data));
+         printf("[ ");
+         for (std::size_t i = 0; i <  size; ++i)
+         {
+            printf("%8.3f\t", data[i]);
+         }
+         printf(" ]\n");
+         printf("---------------------\n");
       }
       #else
       inline void dump_ptr(const std::string&, const void*) {}
       inline void dump_ptr(const std::string&, const void*, const std::size_t) {}
+      template <typename T>
+      inline void dump_vector(const std::string&, const T*, const std::size_t) {}
       #endif
 
       template <typename T>
@@ -4897,7 +5318,7 @@ namespace exprtk
          {
             if (this != &vds)
             {
-               std::size_t final_size = min_size(control_block_, vds.control_block_);
+               const std::size_t final_size = min_size(control_block_, vds.control_block_);
 
                vds.control_block_->size = final_size;
                    control_block_->size = final_size;
@@ -4947,7 +5368,7 @@ namespace exprtk
                if (5 == i)
                   exprtk_debug(("\n"));
 
-               exprtk_debug(("%15.10f ",data()[i]));
+               exprtk_debug(("%15.10f ", data()[i]));
             }
             exprtk_debug(("\n"));
             #endif
@@ -5060,8 +5481,8 @@ namespace exprtk
                   case e_xnor   : return xnor_opr<T>(arg0,arg1);
                   case e_root   : return root    <T>(arg0,arg1);
                   case e_roundn : return roundn  <T>(arg0,arg1);
-                  case e_equal  : return equal      (arg0,arg1);
-                  case e_nequal : return nequal     (arg0,arg1);
+                  case e_equal  : return equal   <T>(arg0,arg1);
+                  case e_nequal : return nequal  <T>(arg0,arg1);
                   case e_hypot  : return hypot   <T>(arg0,arg1);
                   case e_shr    : return shr     <T>(arg0,arg1);
                   case e_shl    : return shl     <T>(arg0,arg1);
@@ -5130,17 +5551,19 @@ namespace exprtk
          typedef Node** node_pp_t;
          typedef std::vector<node_pp_t> noderef_list_t;
 
-         virtual ~node_collector_interface() {}
+         virtual ~node_collector_interface()
+         {}
 
-         virtual void collect_nodes(noderef_list_t&) {}
+         virtual void collect_nodes(noderef_list_t&)
+         {}
       };
 
       template <typename Node>
       struct node_depth_base;
 
       template <typename T>
-      class expression_node : public node_collector_interface<expression_node<T> >,
-                              public node_depth_base<expression_node<T> >
+      class expression_node : public node_collector_interface<expression_node<T> >
+                            , public node_depth_base<expression_node<T> >
       {
       public:
 
@@ -5177,12 +5600,14 @@ namespace exprtk
             e_vovovoc       , e_vovocov       , e_vocovov     , e_covovov      ,
             e_covocov       , e_vocovoc       , e_covovoc     , e_vococov      ,
             e_sf3ext        , e_sf4ext        , e_nulleq      , e_strass       ,
-            e_vector        , e_vecelem       , e_rbvecelem   , e_rbveccelem   ,
-            e_vecdefass     , e_vecvalass     , e_vecvecass   , e_vecopvalass  ,
-            e_vecopvecass   , e_vecfunc       , e_vecvecswap  , e_vecvecineq   ,
-            e_vecvalineq    , e_valvecineq    , e_vecvecarith , e_vecvalarith  ,
-            e_valvecarith   , e_vecunaryop    , e_vecondition , e_break        ,
-            e_continue      , e_swap
+            e_vector        , e_vecsize       , e_vecelem     , e_veccelem     ,
+            e_vecelemrtc    , e_veccelemrtc   , e_rbvecelem   , e_rbvecelemrtc ,
+            e_rbveccelem    , e_rbveccelemrtc , e_vecinit     , e_vecvalass    ,
+            e_vecvecass     , e_vecopvalass   , e_vecopvecass , e_vecfunc      ,
+            e_vecvecswap    , e_vecvecineq    , e_vecvalineq  , e_valvecineq   ,
+            e_vecvecarith   , e_vecvalarith   , e_valvecarith , e_vecunaryop   ,
+            e_vecondition   , e_break         , e_continue    , e_swap         ,
+            e_assert
          };
 
          typedef T value_type;
@@ -5191,7 +5616,8 @@ namespace exprtk
          typedef typename nci_t::noderef_list_t noderef_list_t;
          typedef node_depth_base<expression_node<T> > ndb_t;
 
-         virtual ~expression_node() {}
+         virtual ~expression_node()
+         {}
 
          inline virtual T value() const
          {
@@ -5207,6 +5633,11 @@ namespace exprtk
          {
             return e_none;
          }
+
+         inline virtual bool valid() const
+         {
+            return true;
+         }
       }; // class expression_node
 
       template <typename T>
@@ -5251,6 +5682,12 @@ namespace exprtk
          return std::equal_to<T>()(T(0),node.first->value());
       }
 
+      template <typename T>
+      inline bool is_literal_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_constant == node->type());
+      }
+
       template <typename T>
       inline bool is_unary_node(const expression_node<T>* node)
       {
@@ -5280,10 +5717,15 @@ namespace exprtk
       {
          return node &&
                 (
-                  details::expression_node<T>::e_variable   == node->type() ||
-                  details::expression_node<T>::e_vecelem    == node->type() ||
-                  details::expression_node<T>::e_rbvecelem  == node->type() ||
-                  details::expression_node<T>::e_rbveccelem == node->type()
+                  details::expression_node<T>::e_variable      == node->type() ||
+                  details::expression_node<T>::e_vecelem       == node->type() ||
+                  details::expression_node<T>::e_veccelem      == node->type() ||
+                  details::expression_node<T>::e_vecelemrtc    == node->type() ||
+                  details::expression_node<T>::e_veccelemrtc   == node->type() ||
+                  details::expression_node<T>::e_rbvecelem     == node->type() ||
+                  details::expression_node<T>::e_rbveccelem    == node->type() ||
+                  details::expression_node<T>::e_rbvecelemrtc  == node->type() ||
+                  details::expression_node<T>::e_rbveccelemrtc == node->type()
                 );
       }
 
@@ -5293,12 +5735,42 @@ namespace exprtk
          return node && (details::expression_node<T>::e_vecelem == node->type());
       }
 
+      template <typename T>
+      inline bool is_vector_celem_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_veccelem == node->type());
+      }
+
+      template <typename T>
+      inline bool is_vector_elem_rtc_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_vecelemrtc == node->type());
+      }
+
+      template <typename T>
+      inline bool is_vector_celem_rtc_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_veccelemrtc == node->type());
+      }
+
       template <typename T>
       inline bool is_rebasevector_elem_node(const expression_node<T>* node)
       {
          return node && (details::expression_node<T>::e_rbvecelem == node->type());
       }
 
+      template <typename T>
+      inline bool is_rebasevector_elem_rtc_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_rbvecelemrtc == node->type());
+      }
+
+      template <typename T>
+      inline bool is_rebasevector_celem_rtc_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_rbveccelemrtc == node->type());
+      }
+
       template <typename T>
       inline bool is_rebasevector_celem_node(const expression_node<T>* node)
       {
@@ -5376,6 +5848,12 @@ namespace exprtk
          return node && (details::expression_node<T>::e_function == node->type());
       }
 
+      template <typename T>
+      inline bool is_vararg_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_vararg == node->type());
+      }
+
       template <typename T>
       inline bool is_return_node(const expression_node<T>* node)
       {
@@ -5396,7 +5874,13 @@ namespace exprtk
       }
 
       template <typename T>
-      inline bool branch_deletable(expression_node<T>* node)
+      inline bool is_assert_node(const expression_node<T>* node)
+      {
+         return node && (details::expression_node<T>::e_assert == node->type());
+      }
+
+      template <typename T>
+      inline bool branch_deletable(const expression_node<T>* node)
       {
          return (0 != node)             &&
                 !is_variable_node(node) &&
@@ -5404,7 +5888,7 @@ namespace exprtk
       }
 
       template <std::size_t N, typename T>
-      inline bool all_nodes_valid(expression_node<T>* (&b)[N])
+      inline bool all_nodes_valid(expression_node<T>* const (&b)[N])
       {
          for (std::size_t i = 0; i < N; ++i)
          {
@@ -5428,7 +5912,7 @@ namespace exprtk
       }
 
       template <std::size_t N, typename T>
-      inline bool all_nodes_variables(expression_node<T>* (&b)[N])
+      inline bool all_nodes_variables(expression_node<T>* const (&b)[N])
       {
          for (std::size_t i = 0; i < N; ++i)
          {
@@ -5444,7 +5928,7 @@ namespace exprtk
       template <typename T,
                 typename Allocator,
                 template <typename, typename> class Sequence>
-      inline bool all_nodes_variables(Sequence<expression_node<T>*,Allocator>& b)
+      inline bool all_nodes_variables(const Sequence<expression_node<T>*,Allocator>& b)
       {
          for (std::size_t i = 0; i < b.size(); ++i)
          {
@@ -5478,7 +5962,7 @@ namespace exprtk
             for (std::size_t i = 0; i < node_delete_list.size(); ++i)
             {
                node_ptr_t& node = *node_delete_list[i];
-               exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", static_cast<void*>(node)));
+               exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", reinterpret_cast<void*>(node)));
                delete node;
                node = reinterpret_cast<node_ptr_t>(0);
             }
@@ -5583,7 +6067,8 @@ namespace exprtk
          , depth(0)
          {}
 
-         virtual ~node_depth_base() {}
+         virtual ~node_depth_base()
+         {}
 
          virtual std::size_t node_depth() const { return 1; }
 
@@ -5615,6 +6100,7 @@ namespace exprtk
             if (!depth_set)
             {
                depth = 0;
+
                for (std::size_t i = 0; i < N; ++i)
                {
                   if (branch[i].first)
@@ -5622,6 +6108,7 @@ namespace exprtk
                      depth = std::max(depth,branch[i].first->node_depth());
                   }
                }
+
                depth += 1;
                depth_set = true;
             }
@@ -5629,12 +6116,34 @@ namespace exprtk
             return depth;
          }
 
+         template <typename BranchType>
+         std::size_t max_node_depth(const BranchType& n0, const BranchType& n1) const
+         {
+            return std::max(compute_node_depth(n0), compute_node_depth(n1));
+         }
+
+         template <typename BranchType>
+         std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, const BranchType& n2) const
+         {
+            return std::max(compute_node_depth(n0),
+                   std::max(compute_node_depth(n1), compute_node_depth(n2)));
+         }
+
+         template <typename BranchType>
+         std::size_t max_node_depth(const BranchType& n0, const BranchType& n1,
+                                    const BranchType& n2, const BranchType& n3) const
+         {
+            return std::max(
+                     std::max(compute_node_depth(n0), compute_node_depth(n1)),
+                     std::max(compute_node_depth(n2), compute_node_depth(n3)));
+         }
+
          template <typename BranchType>
          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const
          {
             if (!depth_set)
             {
-               depth = 1 + std::max(compute_node_depth(n0), compute_node_depth(n1));
+               depth = 1 + max_node_depth(n0, n1);
                depth_set = true;
             }
 
@@ -5647,9 +6156,7 @@ namespace exprtk
          {
             if (!depth_set)
             {
-               depth = 1 + std::max(
-                              std::max(compute_node_depth(n0), compute_node_depth(n1)),
-                              compute_node_depth(n2));
+               depth = 1 + max_node_depth(n0, n1, n2);
                depth_set = true;
             }
 
@@ -5662,9 +6169,7 @@ namespace exprtk
          {
             if (!depth_set)
             {
-               depth = 1 + std::max(
-                           std::max(compute_node_depth(n0), compute_node_depth(n1)),
-                           std::max(compute_node_depth(n2), compute_node_depth(n3)));
+               depth = 1 + max_node_depth(n0, n1, n2, n3);
                depth_set = true;
             }
 
@@ -5684,6 +6189,7 @@ namespace exprtk
                      depth = std::max(depth, compute_node_depth(branch_list[i]));
                   }
                }
+
                depth_set = true;
             }
 
@@ -5703,6 +6209,7 @@ namespace exprtk
                      depth = std::max(depth, compute_node_depth(branch_list[i].first));
                   }
                }
+
                depth_set = true;
             }
 
@@ -5795,12 +6302,14 @@ namespace exprtk
          typedef Type value_type;
          typedef value_type* value_ptr;
          typedef const value_ptr const_value_ptr;
+         typedef vector_holder<Type> vector_holder_t;
 
          class vector_holder_base
          {
          public:
 
-            virtual ~vector_holder_base() {}
+            virtual ~vector_holder_base()
+            {}
 
             inline value_ptr operator[](const std::size_t& index) const
             {
@@ -5812,6 +6321,11 @@ namespace exprtk
                return vector_size();
             }
 
+            inline std::size_t base_size() const
+            {
+               return vector_base_size();
+            }
+
             inline value_ptr data() const
             {
                return value_at(0);
@@ -5822,15 +6336,25 @@ namespace exprtk
                return false;
             }
 
-            virtual void set_ref(value_ptr*) {}
+            virtual void set_ref(value_ptr*)
+            {}
+
+            virtual void remove_ref(value_ptr*)
+            {}
+
+            virtual vector_view<Type>* rebaseable_instance()
+            {
+               return reinterpret_cast<vector_view<Type>*>(0);
+            }
 
          protected:
 
             virtual value_ptr value_at(const std::size_t&) const = 0;
             virtual std::size_t vector_size()              const = 0;
+            virtual std::size_t vector_base_size()         const = 0;
          };
 
-         class array_vector_impl : public vector_holder_base
+         class array_vector_impl exprtk_final : public vector_holder_base
          {
          public:
 
@@ -5841,19 +6365,22 @@ namespace exprtk
 
          protected:
 
-            value_ptr value_at(const std::size_t& index) const
+            value_ptr value_at(const std::size_t& index) const exprtk_override
             {
-               if (index < size_)
-                  return const_cast<const_value_ptr>(vec_ + index);
-               else
-                  return const_value_ptr(0);
+               assert(index < size_);
+               return const_cast<const_value_ptr>(vec_ + index);
             }
 
-            std::size_t vector_size() const
+            std::size_t vector_size() const exprtk_override
             {
                return size_;
             }
 
+            std::size_t vector_base_size() const exprtk_override
+            {
+               return vector_size();
+            }
+
          private:
 
             array_vector_impl(const array_vector_impl&) exprtk_delete;
@@ -5865,28 +6392,34 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         class sequence_vector_impl : public vector_holder_base
+         class sequence_vector_impl exprtk_final : public vector_holder_base
          {
          public:
 
             typedef Sequence<Type,Allocator> sequence_t;
 
-            sequence_vector_impl(sequence_t& seq)
+            explicit sequence_vector_impl(sequence_t& seq)
             : sequence_(seq)
             {}
 
          protected:
 
-            value_ptr value_at(const std::size_t& index) const
+            value_ptr value_at(const std::size_t& index) const exprtk_override
             {
-               return (index < sequence_.size()) ? (&sequence_[index]) : const_value_ptr(0);
+               assert(index < sequence_.size());
+               return (&sequence_[index]);
             }
 
-            std::size_t vector_size() const
+            std::size_t vector_size() const exprtk_override
             {
                return sequence_.size();
             }
 
+            std::size_t vector_base_size() const exprtk_override
+            {
+               return vector_size();
+            }
+
          private:
 
             sequence_vector_impl(const sequence_vector_impl&) exprtk_delete;
@@ -5895,7 +6428,7 @@ namespace exprtk
             sequence_t& sequence_;
          };
 
-         class vector_view_impl : public vector_holder_base
+         class vector_view_impl exprtk_final : public vector_holder_base
          {
          public:
 
@@ -5903,30 +6436,48 @@ namespace exprtk
 
             vector_view_impl(vector_view_t& vec_view)
             : vec_view_(vec_view)
-            {}
+            {
+               assert(vec_view_.size() > 0);
+            }
 
-            void set_ref(value_ptr* ref)
+            void set_ref(value_ptr* ref) exprtk_override
             {
                vec_view_.set_ref(ref);
             }
 
-            virtual inline bool rebaseable() const
+            void remove_ref(value_ptr* ref) exprtk_override
+            {
+               vec_view_.remove_ref(ref);
+            }
+
+            bool rebaseable() const exprtk_override
             {
                return true;
             }
 
-         protected:
-
-            value_ptr value_at(const std::size_t& index) const
+            vector_view<Type>* rebaseable_instance() exprtk_override
             {
-               return (index < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0);
+               return &vec_view_;
             }
 
-            std::size_t vector_size() const
+         protected:
+
+            value_ptr value_at(const std::size_t& index) const exprtk_override
+            {
+               assert(index < vec_view_.size());
+               return (&vec_view_[index]);
+            }
+
+            std::size_t vector_size() const exprtk_override
             {
                return vec_view_.size();
             }
 
+            std::size_t vector_base_size() const exprtk_override
+            {
+               return vec_view_.base_size();
+            }
+
          private:
 
             vector_view_impl(const vector_view_impl&) exprtk_delete;
@@ -5935,6 +6486,62 @@ namespace exprtk
             vector_view_t& vec_view_;
          };
 
+         class resizable_vector_impl exprtk_final : public vector_holder_base
+         {
+         public:
+
+            resizable_vector_impl(vector_holder& vec_view_holder,
+                                  const Type* vec,
+                                  const std::size_t& vec_size)
+            : vec_(vec)
+            , size_(vec_size)
+            , vec_view_holder_(*vec_view_holder.rebaseable_instance())
+            {
+               assert(vec_view_holder.rebaseable_instance());
+               assert(size_ <= vector_base_size());
+            }
+
+            virtual ~resizable_vector_impl()
+            {}
+
+         protected:
+
+            value_ptr value_at(const std::size_t& index) const exprtk_override
+            {
+               assert(index < vector_size());
+               return const_cast<const_value_ptr>(vec_ + index);
+            }
+
+            std::size_t vector_size() const exprtk_override
+            {
+               return vec_view_holder_.size();
+            }
+
+            std::size_t vector_base_size() const exprtk_override
+            {
+               return vec_view_holder_.base_size();
+            }
+
+            bool rebaseable() const exprtk_override
+            {
+               return true;
+            }
+
+            virtual vector_view<Type>* rebaseable_instance() exprtk_override
+            {
+               return &vec_view_holder_;
+            }
+
+         private:
+
+            resizable_vector_impl(const resizable_vector_impl&) exprtk_delete;
+            resizable_vector_impl& operator=(const resizable_vector_impl&) exprtk_delete;
+
+            const Type* vec_;
+            const std::size_t size_;
+            vector_view<Type>& vec_view_holder_;
+         };
+
       public:
 
          typedef typename details::vec_data_store<Type> vds_t;
@@ -5956,6 +6563,10 @@ namespace exprtk
          : vector_holder_base_(new(buffer)vector_view_impl(vec))
          {}
 
+         explicit vector_holder(vector_holder_t& vec_holder, const vds_t& vds)
+         : vector_holder_base_(new(buffer)resizable_vector_impl(vec_holder, vds.data(), vds.size()))
+         {}
+
          inline value_ptr operator[](const std::size_t& index) const
          {
             return (*vector_holder_base_)[index];
@@ -5966,6 +6577,11 @@ namespace exprtk
             return vector_holder_base_->size();
          }
 
+         inline std::size_t base_size() const
+         {
+            return vector_holder_base_->base_size();
+         }
+
          inline value_ptr data() const
          {
             return vector_holder_base_->data();
@@ -5973,7 +6589,18 @@ namespace exprtk
 
          void set_ref(value_ptr* ref)
          {
-            vector_holder_base_->set_ref(ref);
+            if (rebaseable())
+            {
+               vector_holder_base_->set_ref(ref);
+            }
+         }
+
+         void remove_ref(value_ptr* ref)
+         {
+            if (rebaseable())
+            {
+               vector_holder_base_->remove_ref(ref);
+            }
          }
 
          bool rebaseable() const
@@ -5981,8 +6608,16 @@ namespace exprtk
             return vector_holder_base_->rebaseable();
          }
 
+         vector_view<Type>* rebaseable_instance()
+         {
+            return vector_holder_base_->rebaseable_instance();
+         }
+
       private:
 
+         vector_holder(const vector_holder<Type>&) exprtk_delete;
+         vector_holder<Type>& operator=(const vector_holder<Type>&) exprtk_delete;
+
          mutable vector_holder_base* vector_holder_base_;
          uchar_t buffer[64];
       };
@@ -6060,12 +6695,11 @@ namespace exprtk
          : equality_(equality)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
-
             const T v = branch_.first->value();
             const bool result = details::numeric::is_nan(v);
 
@@ -6085,6 +6719,11 @@ namespace exprtk
             return branch_.first;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(branch_, node_delete_list);
@@ -6146,7 +6785,8 @@ namespace exprtk
 
          typedef range_pack<T> range_t;
 
-         virtual ~range_interface() {}
+         virtual ~range_interface()
+         {}
 
          virtual range_t& range_ref() = 0;
 
@@ -6161,7 +6801,8 @@ namespace exprtk
 
          typedef range_data_type<T> range_data_type_t;
 
-         virtual ~string_base_node() {}
+         virtual ~string_base_node()
+         {}
 
          virtual std::string str () const = 0;
 
@@ -6172,9 +6813,9 @@ namespace exprtk
 
       template <typename T>
       class string_literal_node exprtk_final
-                                : public expression_node <T>,
-                                  public string_base_node<T>,
-                                  public range_interface <T>
+                                : public expression_node <T>
+                                , public string_base_node<T>
+                                , public range_interface <T>
       {
       public:
 
@@ -6183,8 +6824,8 @@ namespace exprtk
          explicit string_literal_node(const std::string& v)
          : value_(v)
          {
-            rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
-            rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
+            rp_.n0_c = std::make_pair<bool,std::size_t>(true, 0);
+            rp_.n1_c = std::make_pair<bool,std::size_t>(true, v.size());
             rp_.cache.first  = rp_.n0_c.second;
             rp_.cache.second = rp_.n1_c.second;
          }
@@ -6251,13 +6892,13 @@ namespace exprtk
          : operation_(opr)
          {
             construct_branch_pair(branch_,branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
-            const T arg = branch_.first->value();
-            return numeric::process<T>(operation_,arg);
+            return numeric::process<T>
+                     (operation_,branch_.first->value());
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -6275,6 +6916,11 @@ namespace exprtk
             return branch_.first;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline void release()
          {
             branch_.second = false;
@@ -6310,17 +6956,17 @@ namespace exprtk
          : operation_(opr)
          {
             init_branches<2>(branch_, branch0, branch1);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_[0].first);
-            assert(branch_[1].first);
-
-            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_,
+                      branch_[0].first->value(),
+                      branch_[1].first->value()
+                   );
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -6335,17 +6981,20 @@ namespace exprtk
 
          inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
          {
-            if (0 == index)
-               return branch_[0].first;
-            else if (1 == index)
-               return branch_[1].first;
-            else
-               return reinterpret_cast<expression_ptr>(0);
+            assert(index < 2);
+            return branch_[index].first;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               branch_[0].first && branch_[0].first->valid() &&
+               branch_[1].first && branch_[1].first->valid() ;
          }
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_final
@@ -6370,16 +7019,13 @@ namespace exprtk
          binary_ext_node(expression_ptr branch0, expression_ptr branch1)
          {
             init_branches<2>(branch_, branch0, branch1);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_[0].first);
-            assert(branch_[1].first);
-
             const T arg0 = branch_[0].first->value();
             const T arg1 = branch_[1].first->value();
-
             return Operation::process(arg0,arg1);
          }
 
@@ -6395,17 +7041,20 @@ namespace exprtk
 
          inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
          {
-            if (0 == index)
-               return branch_[0].first;
-            else if (1 == index)
-               return branch_[1].first;
-            else
-               return reinterpret_cast<expression_ptr>(0);
+            assert(index < 2);
+            return branch_[index].first;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               branch_[0].first && branch_[0].first->valid() &&
+               branch_[1].first && branch_[1].first->valid() ;
          }
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -6433,14 +7082,11 @@ namespace exprtk
          : operation_(opr)
          {
             init_branches<3>(branch_, branch0, branch1, branch2);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_[0].first);
-            assert(branch_[1].first);
-            assert(branch_[2].first);
-
             const T arg0 = branch_[0].first->value();
             const T arg1 = branch_[1].first->value();
             const T arg2 = branch_[2].first->value();
@@ -6466,9 +7112,17 @@ namespace exprtk
             return expression_node<T>::e_trinary;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               branch_[0].first && branch_[0].first->valid() &&
+               branch_[1].first && branch_[1].first->valid() &&
+               branch_[2].first && branch_[2].first->valid() ;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override exprtk_final
@@ -6512,7 +7166,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override exprtk_final
@@ -6520,6 +7174,15 @@ namespace exprtk
             return expression_node<T>::ndb_t::template compute_node_depth<4>(branch_);
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               branch_[0].first && branch_[0].first->valid() &&
+               branch_[1].first && branch_[1].first->valid() &&
+               branch_[2].first && branch_[2].first->valid() &&
+               branch_[3].first && branch_[3].first->valid() ;
+         }
+
       protected:
 
          operator_type operation_;
@@ -6541,14 +7204,11 @@ namespace exprtk
             construct_branch_pair(condition_  , condition  );
             construct_branch_pair(consequent_ , consequent );
             construct_branch_pair(alternative_, alternative);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(condition_  .first);
-            assert(consequent_ .first);
-            assert(alternative_.first);
-
             if (is_true(condition_))
                return consequent_.first->value();
             else
@@ -6560,6 +7220,14 @@ namespace exprtk
             return expression_node<T>::e_conditional;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               condition_  .first && condition_  .first->valid() &&
+               consequent_ .first && consequent_ .first->valid() &&
+               alternative_.first && alternative_.first->valid() ;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(condition_   , node_delete_list);
@@ -6594,13 +7262,11 @@ namespace exprtk
          {
             construct_branch_pair(condition_ , condition );
             construct_branch_pair(consequent_, consequent);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(condition_ .first);
-            assert(consequent_.first);
-
             if (is_true(condition_))
                return consequent_.first->value();
             else
@@ -6612,6 +7278,13 @@ namespace exprtk
             return expression_node<T>::e_conditional;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               condition_ .first && condition_ .first->valid() &&
+               consequent_.first && consequent_.first->valid() ;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(condition_  , node_delete_list);
@@ -6653,7 +7326,7 @@ namespace exprtk
          typedef expression_node<T>* expression_ptr;
          typedef std::pair<expression_ptr,bool> branch_t;
 
-         break_node(expression_ptr ret = expression_ptr(0))
+         explicit break_node(expression_ptr ret = expression_ptr(0))
          {
             construct_branch_pair(return_, ret);
          }
@@ -6666,7 +7339,7 @@ namespace exprtk
 
             throw break_exception<T>(result);
 
-            #ifndef _MSC_VER
+            #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
             return std::numeric_limits<T>::quiet_NaN();
             #endif
          }
@@ -6699,7 +7372,7 @@ namespace exprtk
          inline T value() const exprtk_override
          {
             throw continue_exception();
-            #ifndef _MSC_VER
+            #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
             return std::numeric_limits<T>::quiet_NaN();
             #endif
          }
@@ -6730,9 +7403,11 @@ namespace exprtk
 
          inline bool check() const
          {
+            assert(loop_runtime_check_);
+
             if (
-                 (0 == loop_runtime_check_) ||
-                 ((++iteration_count_ <= max_loop_iterations_) && loop_runtime_check_->check())
+                 (++iteration_count_ <= max_loop_iterations_) &&
+                 loop_runtime_check_->check()
                )
             {
                return true;
@@ -6747,6 +7422,11 @@ namespace exprtk
             return false;
          }
 
+         bool valid() const
+         {
+            return 0 != loop_runtime_check_;
+         }
+
          mutable _uint64_t iteration_count_;
          mutable loop_runtime_check_ptr loop_runtime_check_;
          const details::_uint64_t& max_loop_iterations_;
@@ -6766,13 +7446,11 @@ namespace exprtk
          {
             construct_branch_pair(condition_, condition);
             construct_branch_pair(loop_body_, loop_body);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(condition_.first);
-            assert(loop_body_.first);
-
             T result = T(0);
 
             while (is_true(condition_))
@@ -6788,6 +7466,13 @@ namespace exprtk
             return expression_node<T>::e_while;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               condition_.first && condition_.first->valid() &&
+               loop_body_.first && loop_body_.first->valid() ;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
@@ -6820,12 +7505,12 @@ namespace exprtk
                              loop_runtime_check_ptr loop_rt_chk)
          : parent_t(condition, loop_body)
          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
 
             T result = T(0);
 
@@ -6838,6 +7523,14 @@ namespace exprtk
 
             return result;
          }
+
+         using parent_t::valid;
+
+         bool valid() const exprtk_override exprtk_final
+         {
+            return parent_t::valid() &&
+                   loop_runtime_checker::valid();
+         }
       };
 
       template <typename T>
@@ -6853,13 +7546,11 @@ namespace exprtk
          {
             construct_branch_pair(condition_, condition);
             construct_branch_pair(loop_body_, loop_body);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(condition_.first);
-            assert(loop_body_.first);
-
             T result = T(0);
 
             do
@@ -6876,6 +7567,13 @@ namespace exprtk
             return expression_node<T>::e_repeat;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               condition_.first && condition_.first->valid() &&
+               loop_body_.first && loop_body_.first->valid() ;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
@@ -6908,13 +7606,12 @@ namespace exprtk
                                     loop_runtime_check_ptr loop_rt_chk)
          : parent_t(condition, loop_body)
          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             loop_runtime_checker::reset(1);
@@ -6927,6 +7624,14 @@ namespace exprtk
 
             return result;
          }
+
+         using parent_t::valid;
+
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            return parent_t::valid() &&
+                   loop_runtime_checker::valid();
+         }
       };
 
       template <typename T>
@@ -6946,13 +7651,11 @@ namespace exprtk
             construct_branch_pair(condition_  , condition  );
             construct_branch_pair(incrementor_, incrementor);
             construct_branch_pair(loop_body_  , loop_body  );
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(condition_.first);
-            assert(loop_body_.first);
-
             T result = T(0);
 
             if (initialiser_.first)
@@ -6982,6 +7685,11 @@ namespace exprtk
             return expression_node<T>::e_for;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return condition_.first && loop_body_.first;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(initialiser_ , node_delete_list);
@@ -7021,13 +7729,12 @@ namespace exprtk
                            loop_runtime_check_ptr loop_rt_chk)
          : parent_t(initialiser, condition, incrementor, loop_body)
          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             loop_runtime_checker::reset();
@@ -7053,6 +7760,14 @@ namespace exprtk
 
             return result;
          }
+
+         using parent_t::valid;
+
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            return parent_t::valid() &&
+                   loop_runtime_checker::valid();
+         }
       };
 
       #ifndef exprtk_disable_break_continue
@@ -7067,13 +7782,12 @@ namespace exprtk
          while_loop_bc_node(expression_ptr condition,
                             expression_ptr loop_body)
          : parent_t(condition, loop_body)
-         {}
+         {
+            assert(parent_t::valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             while (is_true(parent_t::condition_))
@@ -7109,13 +7823,12 @@ namespace exprtk
                                 loop_runtime_check_ptr loop_rt_chk)
          : parent_t(condition, loop_body)
          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             loop_runtime_checker::reset();
@@ -7136,6 +7849,14 @@ namespace exprtk
 
             return result;
          }
+
+         using parent_t::valid;
+
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            return parent_t::valid() &&
+                   loop_runtime_checker::valid();
+         }
       };
 
       template <typename T>
@@ -7149,13 +7870,12 @@ namespace exprtk
          repeat_until_loop_bc_node(expression_ptr condition,
                                    expression_ptr loop_body)
          : parent_t(condition, loop_body)
-         {}
+         {
+            assert(parent_t::valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             do
@@ -7179,8 +7899,8 @@ namespace exprtk
 
       template <typename T>
       class repeat_until_loop_bc_rtc_node exprtk_final
-                                          : public repeat_until_loop_bc_node<T>,
-                                            public loop_runtime_checker
+                                          : public repeat_until_loop_bc_node<T>
+                                          , public loop_runtime_checker
       {
       public:
 
@@ -7192,13 +7912,12 @@ namespace exprtk
                                        loop_runtime_check_ptr loop_rt_chk)
          : parent_t(condition, loop_body)
          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             loop_runtime_checker::reset();
@@ -7220,6 +7939,14 @@ namespace exprtk
 
             return result;
          }
+
+         using parent_t::valid;
+
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            return parent_t::valid() &&
+                   loop_runtime_checker::valid();
+         }
       };
 
       template <typename T>
@@ -7235,13 +7962,12 @@ namespace exprtk
                           expression_ptr incrementor,
                           expression_ptr loop_body)
          : parent_t(initialiser, condition, incrementor, loop_body)
-         {}
+         {
+            assert(parent_t::valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             if (parent_t::initialiser_.first)
@@ -7303,13 +8029,12 @@ namespace exprtk
                               loop_runtime_check_ptr loop_rt_chk)
          : parent_t(initialiser, condition, incrementor, loop_body)
          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
-
             T result = T(0);
 
             loop_runtime_checker::reset();
@@ -7354,6 +8079,14 @@ namespace exprtk
 
             return result;
          }
+
+         using parent_t::valid;
+
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            return parent_t::valid() &&
+                   loop_runtime_checker::valid();
+         }
       };
       #endif
 
@@ -7376,7 +8109,7 @@ namespace exprtk
 
             for (std::size_t i = 0; i < arg_list.size(); ++i)
             {
-               if (arg_list[i])
+               if (arg_list[i] && arg_list[i]->valid())
                {
                   construct_branch_pair(arg_list_[i], arg_list[i]);
                }
@@ -7386,29 +8119,26 @@ namespace exprtk
                   return;
                }
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (!arg_list_.empty())
+            const std::size_t upper_bound = (arg_list_.size() - 1);
+
+            for (std::size_t i = 0; i < upper_bound; i += 2)
             {
-               const std::size_t upper_bound = (arg_list_.size() - 1);
+               expression_ptr condition  = arg_list_[i    ].first;
+               expression_ptr consequent = arg_list_[i + 1].first;
 
-               for (std::size_t i = 0; i < upper_bound; i += 2)
+               if (is_true(condition))
                {
-                  expression_ptr condition  = arg_list_[i    ].first;
-                  expression_ptr consequent = arg_list_[i + 1].first;
-
-                  if (is_true(condition))
-                  {
-                     return consequent->value();
-                  }
+                  return consequent->value();
                }
-
-               return arg_list_[upper_bound].first->value();
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            return arg_list_[upper_bound].first->value();
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final
@@ -7416,6 +8146,11 @@ namespace exprtk
             return expression_node<T>::e_switch;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return !arg_list_.empty();
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
@@ -7469,7 +8204,7 @@ namespace exprtk
 
             for (std::size_t i = 0; i < arg_list.size(); ++i)
             {
-               if (arg_list[i])
+               if (arg_list[i] && arg_list[i]->valid())
                {
                   construct_branch_pair(arg_list_[i], arg_list[i]);
                }
@@ -7479,19 +8214,16 @@ namespace exprtk
                   return;
                }
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            T result = T(0);
-
-            if (arg_list_.empty())
-            {
-               return std::numeric_limits<T>::quiet_NaN();
-            }
-
             const std::size_t upper_bound = (arg_list_.size() - 1);
 
+            T result = T(0);
+
             for (std::size_t i = 0; i < upper_bound; i += 2)
             {
                expression_ptr condition  = arg_list_[i    ].first;
@@ -7511,6 +8243,11 @@ namespace exprtk
             return expression_node<T>::e_mswitch;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return !arg_list_.empty() && (0 == (arg_list_.size() % 2));
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
@@ -7531,7 +8268,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~ivariable() {}
+         virtual ~ivariable()
+         {}
 
          virtual T& ref() = 0;
          virtual const T& ref() const = 0;
@@ -7539,8 +8277,8 @@ namespace exprtk
 
       template <typename T>
       class variable_node exprtk_final
-                          : public expression_node<T>,
-                            public ivariable      <T>
+                          : public expression_node<T>
+                          , public ivariable      <T>
       {
       public:
 
@@ -7677,7 +8415,7 @@ namespace exprtk
                  (std::numeric_limits<std::size_t>::max() == r1  )
                )
             {
-               r1 = size - 1;
+               r1 = size;
             }
 
             cache.first  = r0;
@@ -7692,12 +8430,12 @@ namespace exprtk
 
          inline std::size_t const_size() const
          {
-            return (n1_c.second - n0_c.second + 1);
+            return (n1_c.second - n0_c.second);
          }
 
          inline std::size_t cache_size() const
          {
-            return (cache.second - cache.first + 1);
+            return (cache.second - cache.first);
          }
 
          std::pair<bool,expression_node_ptr> n0_e;
@@ -7711,16 +8449,20 @@ namespace exprtk
                                   const std::size_t r1,
                                   const std::size_t size) const
          {
-            if (r0 >= size)
+            if (r0 > size)
             {
-               throw std::runtime_error("range error: (r0 < 0) || (r0 >= size)");
+               throw std::runtime_error("range error: (r0 < 0) || (r0 > size)");
+               #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
                return false;
+               #endif
             }
 
-            if (r1 >= size)
+            if (r1 > size)
             {
-               throw std::runtime_error("range error: (r1 < 0) || (r1 >= size)");
+               throw std::runtime_error("range error: (r1 < 0) || (r1 > size)");
+               #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
                return false;
+               #endif
             }
 
             return (r0 <= r1);
@@ -7762,19 +8504,22 @@ namespace exprtk
          typedef vector_node<T>*   vector_node_ptr;
          typedef vec_data_store<T> vds_t;
 
-         virtual ~vector_interface() {}
+         virtual ~vector_interface()
+         {}
 
-         virtual std::size_t size   () const = 0;
+         virtual std::size_t size     () const = 0;
 
-         virtual vector_node_ptr vec() const = 0;
+         virtual std::size_t base_size() const = 0;
 
-         virtual vector_node_ptr vec()       = 0;
+         virtual vector_node_ptr vec  () const = 0;
 
-         virtual       vds_t& vds   ()       = 0;
+         virtual vector_node_ptr vec  ()       = 0;
 
-         virtual const vds_t& vds   () const = 0;
+         virtual       vds_t& vds     ()       = 0;
 
-         virtual bool side_effect   () const { return false; }
+         virtual const vds_t& vds     () const = 0;
+
+         virtual bool side_effect     () const { return false; }
       };
 
       template <typename T>
@@ -7801,6 +8546,12 @@ namespace exprtk
          , vds_(vds)
          {}
 
+        ~vector_node()
+         {
+            assert(valid());
+            vector_holder_->remove_ref(&vds_.ref());
+         }
+
          inline T value() const exprtk_override
          {
             return vds().data()[0];
@@ -7821,9 +8572,19 @@ namespace exprtk
             return expression_node<T>::e_vector;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return vector_holder_;
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return vec_holder().size();
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return vec_holder().base_size();
          }
 
          vds_t& vds() exprtk_override
@@ -7841,16 +8602,65 @@ namespace exprtk
             return (*vector_holder_);
          }
 
+         inline vector_holder_t& vec_holder() const
+         {
+            return (*vector_holder_);
+         }
+
       private:
 
          vector_holder_t* vector_holder_;
          vds_t                      vds_;
       };
 
+      template <typename T>
+      class vector_size_node exprtk_final
+                        : public expression_node <T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         typedef vector_holder<T>    vector_holder_t;
+
+         explicit vector_size_node(vector_holder_t* vh)
+         : vector_holder_(vh)
+         {}
+
+        ~vector_size_node()
+         {
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            assert(vector_holder_);
+            return static_cast<T>(vector_holder_->size());
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecsize;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_holder_ && vector_holder_->size();
+         }
+
+         inline vector_holder_t* vec_holder()
+         {
+            return vector_holder_;
+         }
+
+      private:
+
+         vector_holder_t* vector_holder_;
+      };
+
       template <typename T>
       class vector_elem_node exprtk_final
-                             : public expression_node<T>,
-                               public ivariable      <T>
+                             : public expression_node<T>
+                             , public ivariable      <T>
       {
       public:
 
@@ -7859,26 +8669,30 @@ namespace exprtk
          typedef vector_holder_t*               vector_holder_ptr;
          typedef std::pair<expression_ptr,bool> branch_t;
 
-         vector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
-         : vec_holder_(vec_holder)
+         vector_elem_node(expression_ptr vec_node,
+                          expression_ptr index,
+                          vector_holder_ptr vec_holder)
+         : vector_holder_(vec_holder)
          , vector_base_((*vec_holder)[0])
          {
-            construct_branch_pair(index_, index);
+            construct_branch_pair(vector_node_, vec_node);
+            construct_branch_pair(index_      , index   );
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
+            return *access_vector();
          }
 
          inline T& ref() exprtk_override
          {
-            return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
+            return *access_vector();
          }
 
          inline const T& ref() const exprtk_override
          {
-            return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
+            return *access_vector();
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -7886,32 +8700,338 @@ namespace exprtk
             return expression_node<T>::e_vecelem;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_        &&
+               index_.first          &&
+               vector_node_.first    &&
+               index_.first->valid() &&
+               vector_node_.first->valid();
+         }
+
          inline vector_holder_t& vec_holder()
          {
-            return (*vec_holder_);
+            return (*vector_holder_);
          }
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::collect(index_, node_delete_list);
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+            expression_node<T>::ndb_t::collect(index_      , node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
          {
-            return expression_node<T>::ndb_t::compute_node_depth(index_);
+            return expression_node<T>::ndb_t::compute_node_depth
+               (vector_node_, index_);
          }
 
       private:
 
-         vector_holder_ptr vec_holder_;
+         inline T* access_vector() const
+         {
+            vector_node_.first->value();
+            return (vector_base_ + details::numeric::to_uint64(index_.first->value()));
+         }
+
+         vector_holder_ptr vector_holder_;
          T* vector_base_;
+         branch_t vector_node_;
          branch_t index_;
       };
 
+      template <typename T>
+      class vector_celem_node exprtk_final
+                              : public expression_node<T>
+                              , public ivariable      <T>
+      {
+      public:
+
+         typedef expression_node<T>*            expression_ptr;
+         typedef vector_holder<T>               vector_holder_t;
+         typedef vector_holder_t*               vector_holder_ptr;
+         typedef std::pair<expression_ptr,bool> branch_t;
+
+         vector_celem_node(expression_ptr vec_node,
+                           const std::size_t index,
+                           vector_holder_ptr vec_holder)
+         : index_(index)
+         , vector_holder_(vec_holder)
+         , vector_base_((*vec_holder)[0])
+         {
+            construct_branch_pair(vector_node_, vec_node);
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline T& ref() exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline const T& ref() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_veccelem;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_     &&
+               vector_node_.first &&
+               vector_node_.first->valid();
+         }
+
+         inline vector_holder_t& vec_holder()
+         {
+            return (*vector_holder_);
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
+         }
+
+      private:
+
+         inline T* access_vector() const
+         {
+            vector_node_.first->value();
+            return (vector_base_ + index_);
+         }
+
+         const std::size_t index_;
+         vector_holder_ptr vector_holder_;
+         T* vector_base_;
+         branch_t vector_node_;
+      };
+
+      template <typename T>
+      class vector_elem_rtc_node exprtk_final
+                                 : public expression_node<T>
+                                 , public ivariable      <T>
+      {
+      public:
+
+         typedef expression_node<T>*            expression_ptr;
+         typedef vector_holder<T>               vector_holder_t;
+         typedef vector_holder_t*               vector_holder_ptr;
+         typedef std::pair<expression_ptr,bool> branch_t;
+
+         vector_elem_rtc_node(expression_ptr vec_node,
+                              expression_ptr index,
+                              vector_holder_ptr vec_holder,
+                              vector_access_runtime_check_ptr vec_rt_chk)
+         : vector_holder_(vec_holder)
+         , vector_base_((*vec_holder)[0])
+         , vec_rt_chk_(vec_rt_chk)
+         , max_vector_index_(vector_holder_->size() - 1)
+         {
+            construct_branch_pair(vector_node_, vec_node);
+            construct_branch_pair(index_      , index   );
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline T& ref() exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline const T& ref() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecelemrtc;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_        &&
+               index_.first          &&
+               vector_node_.first    &&
+               index_.first->valid() &&
+               vector_node_.first->valid();
+         }
+
+         inline vector_holder_t& vec_holder()
+         {
+            return (*vector_holder_);
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+            expression_node<T>::ndb_t::collect(index_,       node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth
+               (vector_node_, index_);
+         }
+
+      private:
+
+         inline T* access_vector() const
+         {
+            const _uint64_t index = details::numeric::to_uint64(index_.first->value());
+            vector_node_.first->value();
+
+            if (index <= max_vector_index_)
+            {
+               return (vector_holder_->data() + index);
+            }
+
+            assert(vec_rt_chk_);
+
+            vector_access_runtime_check::violation_context context;
+            context.base_ptr   = reinterpret_cast<void*>(vector_base_);
+            context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
+            context.access_ptr = reinterpret_cast<void*>(vector_base_ + index);
+            context.type_size  = sizeof(T);
+
+            return vec_rt_chk_->handle_runtime_violation(context) ?
+               reinterpret_cast<T*>(context.access_ptr) :
+               vector_base_ ;
+         }
+
+         vector_holder_ptr vector_holder_;
+         T*                vector_base_;
+         branch_t          vector_node_;
+         branch_t          index_;
+         vector_access_runtime_check_ptr vec_rt_chk_;
+         const std::size_t max_vector_index_;
+      };
+
+      template <typename T>
+      class vector_celem_rtc_node exprtk_final
+                                 : public expression_node<T>
+                                 , public ivariable      <T>
+      {
+      public:
+
+         typedef expression_node<T>*            expression_ptr;
+         typedef vector_holder<T>               vector_holder_t;
+         typedef vector_holder_t*               vector_holder_ptr;
+         typedef std::pair<expression_ptr,bool> branch_t;
+
+         vector_celem_rtc_node(expression_ptr vec_node,
+                               const std::size_t index,
+                               vector_holder_ptr vec_holder,
+                               vector_access_runtime_check_ptr vec_rt_chk)
+         : index_(index)
+         , max_vector_index_(vec_holder->size() - 1)
+         , vector_holder_(vec_holder)
+         , vector_base_((*vec_holder)[0])
+         , vec_rt_chk_(vec_rt_chk)
+         {
+            construct_branch_pair(vector_node_, vec_node);
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline T& ref() exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline const T& ref() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_veccelemrtc;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_     &&
+               vector_node_.first &&
+               vector_node_.first->valid();
+         }
+
+         inline vector_holder_t& vec_holder()
+         {
+            return (*vector_holder_);
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
+         }
+
+      private:
+
+         inline T* access_vector() const
+         {
+            vector_node_.first->value();
+
+            if (index_ <= max_vector_index_)
+            {
+               return (vector_holder_->data() + index_);
+            }
+
+            assert(vec_rt_chk_);
+
+            vector_access_runtime_check::violation_context context;
+            context.base_ptr   = reinterpret_cast<void*>(vector_base_);
+            context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
+            context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_);
+            context.type_size  = sizeof(T);
+
+            return vec_rt_chk_->handle_runtime_violation(context) ?
+               reinterpret_cast<T*>(context.access_ptr) :
+               vector_base_ ;
+         }
+
+         const std::size_t index_;
+         const std::size_t max_vector_index_;
+         vector_holder_ptr vector_holder_;
+         T*                vector_base_;
+         branch_t          vector_node_;
+         vector_access_runtime_check_ptr vec_rt_chk_;
+      };
+
       template <typename T>
       class rebasevector_elem_node exprtk_final
-                                   : public expression_node<T>,
-                                     public ivariable      <T>
+                                   : public expression_node<T>
+                                   , public ivariable      <T>
       {
       public:
 
@@ -7921,27 +9041,29 @@ namespace exprtk
          typedef vec_data_store<T>              vds_t;
          typedef std::pair<expression_ptr,bool> branch_t;
 
-         rebasevector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
+         rebasevector_elem_node(expression_ptr vec_node,
+                                expression_ptr index,
+                                vector_holder_ptr vec_holder)
          : vector_holder_(vec_holder)
-         , vds_((*vector_holder_).size(),(*vector_holder_)[0])
          {
-            vector_holder_->set_ref(&vds_.ref());
-            construct_branch_pair(index_, index);
+            construct_branch_pair(vector_node_, vec_node);
+            construct_branch_pair(index_      , index   );
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
+            return *access_vector();
          }
 
          inline T& ref() exprtk_override
          {
-            return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
+            return *access_vector();
          }
 
          inline const T& ref() const exprtk_override
          {
-            return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_.first->value())));
+            return *access_vector();
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -7949,6 +9071,16 @@ namespace exprtk
             return expression_node<T>::e_rbvecelem;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_        &&
+               index_.first          &&
+               vector_node_.first    &&
+               index_.first->valid() &&
+               vector_node_.first->valid();
+         }
+
          inline vector_holder_t& vec_holder()
          {
             return (*vector_holder_);
@@ -7956,54 +9088,65 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(index_, node_delete_list);
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+            expression_node<T>::ndb_t::collect(index_,       node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
          {
-            return expression_node<T>::ndb_t::compute_node_depth(index_);
+            return expression_node<T>::ndb_t::compute_node_depth
+               (vector_node_, index_);
          }
 
       private:
 
+         inline T* access_vector() const
+         {
+            vector_node_.first->value();
+            return (vector_holder_->data() + details::numeric::to_uint64(index_.first->value()));
+         }
+
          vector_holder_ptr vector_holder_;
-         vds_t             vds_;
+         branch_t          vector_node_;
          branch_t          index_;
       };
 
       template <typename T>
       class rebasevector_celem_node exprtk_final
-                                    : public expression_node<T>,
-                                      public ivariable      <T>
+                                    : public expression_node<T>
+                                    , public ivariable      <T>
       {
       public:
 
          typedef expression_node<T>* expression_ptr;
          typedef vector_holder<T>    vector_holder_t;
          typedef vector_holder_t*    vector_holder_ptr;
-         typedef vec_data_store<T>   vds_t;
+         typedef std::pair<expression_ptr,bool> branch_t;
 
-         rebasevector_celem_node(const std::size_t index, vector_holder_ptr vec_holder)
+         rebasevector_celem_node(expression_ptr vec_node,
+                                 const std::size_t index,
+                                 vector_holder_ptr vec_holder)
          : index_(index)
          , vector_holder_(vec_holder)
-         , vds_((*vector_holder_).size(),(*vector_holder_)[0])
          {
-            vector_holder_->set_ref(&vds_.ref());
+            construct_branch_pair(vector_node_, vec_node);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            return *(vds_.data() + index_);
+            vector_node_.first->value();
+            return ref();;
          }
 
          inline T& ref() exprtk_override
          {
-            return *(vds_.data() + index_);
+            return *(vector_holder_->data() + index_);
          }
 
          inline const T& ref() const exprtk_override
          {
-            return *(vds_.data() + index_);
+            return *(vector_holder_->data() + index_);
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -8011,42 +9154,303 @@ namespace exprtk
             return expression_node<T>::e_rbveccelem;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_     &&
+               vector_node_.first &&
+               vector_node_.first->valid();
+         }
+
          inline vector_holder_t& vec_holder()
          {
             return (*vector_holder_);
          }
 
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
+         }
+
       private:
 
          const std::size_t index_;
          vector_holder_ptr vector_holder_;
-         vds_t vds_;
+         branch_t          vector_node_;
       };
 
       template <typename T>
-      class vector_assignment_node exprtk_final : public expression_node<T>
+      class rebasevector_elem_rtc_node exprtk_final
+                                       : public expression_node<T>
+                                       , public ivariable      <T>
+      {
+      public:
+
+         typedef expression_node<T>*            expression_ptr;
+         typedef vector_holder<T>               vector_holder_t;
+         typedef vector_holder_t*               vector_holder_ptr;
+         typedef std::pair<expression_ptr,bool> branch_t;
+
+         rebasevector_elem_rtc_node(expression_ptr vec_node,
+                                    expression_ptr index,
+                                    vector_holder_ptr vec_holder,
+                                    vector_access_runtime_check_ptr vec_rt_chk)
+         : vector_holder_(vec_holder)
+         , vec_rt_chk_(vec_rt_chk)
+         {
+            construct_branch_pair(vector_node_, vec_node);
+            construct_branch_pair(index_      , index   );
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline T& ref() exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline const T& ref() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_rbvecelemrtc;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_        &&
+               index_.first          &&
+               vector_node_.first    &&
+               index_.first->valid() &&
+               vector_node_.first->valid();
+         }
+
+         inline vector_holder_t& vec_holder()
+         {
+            return (*vector_holder_);
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+            expression_node<T>::ndb_t::collect(index_      , node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth
+               (vector_node_, index_);
+         }
+
+      private:
+
+         inline T* access_vector() const
+         {
+            vector_node_.first->value();
+            const _uint64_t index = details::numeric::to_uint64(index_.first->value());
+
+            if (index <= (vector_holder_->size() - 1))
+            {
+               return (vector_holder_->data() + index);
+            }
+
+            assert(vec_rt_chk_);
+
+            vector_access_runtime_check::violation_context context;
+            context.base_ptr   = reinterpret_cast<void*>(vector_holder_->data());
+            context.end_ptr    = reinterpret_cast<void*>(vector_holder_->data() + vector_holder_->size());
+            context.access_ptr = reinterpret_cast<void*>(vector_holder_->data() + index);
+            context.type_size  = sizeof(T);
+
+            return vec_rt_chk_->handle_runtime_violation(context) ?
+                   reinterpret_cast<T*>(context.access_ptr) :
+                   vector_holder_->data() ;
+         }
+
+         vector_holder_ptr vector_holder_;
+         branch_t          vector_node_;
+         branch_t          index_;
+         vector_access_runtime_check_ptr vec_rt_chk_;
+      };
+
+      template <typename T>
+      class rebasevector_celem_rtc_node exprtk_final
+                                    : public expression_node<T>
+                                    , public ivariable      <T>
+      {
+      public:
+
+         typedef expression_node<T>*            expression_ptr;
+         typedef vector_holder<T>               vector_holder_t;
+         typedef vector_holder_t*               vector_holder_ptr;
+         typedef std::pair<expression_ptr,bool> branch_t;
+
+         rebasevector_celem_rtc_node(expression_ptr vec_node,
+                                     const std::size_t index,
+                                     vector_holder_ptr vec_holder,
+                                     vector_access_runtime_check_ptr vec_rt_chk)
+         : index_(index)
+         , vector_holder_(vec_holder)
+         , vector_base_((*vec_holder)[0])
+         , vec_rt_chk_(vec_rt_chk)
+         {
+            construct_branch_pair(vector_node_, vec_node);
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline T& ref() exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline const T& ref() const exprtk_override
+         {
+            return *access_vector();
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_rbveccelemrtc;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return
+               vector_holder_     &&
+               vector_node_.first &&
+               vector_node_.first->valid();
+         }
+
+         inline vector_holder_t& vec_holder()
+         {
+            return (*vector_holder_);
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
+         }
+
+      private:
+
+         inline T* access_vector() const
+         {
+            vector_node_.first->value();
+
+            if (index_ <= vector_holder_->size() - 1)
+            {
+               return (vector_holder_->data() + index_);
+            }
+
+            assert(vec_rt_chk_);
+
+            vector_access_runtime_check::violation_context context;
+            context.base_ptr   = reinterpret_cast<void*>(vector_base_);
+            context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
+            context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_);
+            context.type_size  = sizeof(T);
+
+            return vec_rt_chk_->handle_runtime_violation(context) ?
+               reinterpret_cast<T*>(context.access_ptr) :
+               vector_base_ ;
+         }
+
+         const std::size_t index_;
+         vector_holder_ptr vector_holder_;
+         T*                vector_base_;
+         branch_t          vector_node_;
+         vector_access_runtime_check_ptr vec_rt_chk_;
+      };
+
+      template <typename T>
+      class vector_initialisation_node exprtk_final : public expression_node<T>
       {
       public:
 
          typedef expression_node<T>* expression_ptr;
 
-         vector_assignment_node(T* vector_base,
-                                const std::size_t& size,
-                                const std::vector<expression_ptr>& initialiser_list,
-                                const bool single_value_initialse)
+         vector_initialisation_node(T* vector_base,
+                                    const std::size_t& size,
+                                    const std::vector<expression_ptr>& initialiser_list,
+                                    const bool single_value_initialse)
          : vector_base_(vector_base)
          , initialiser_list_(initialiser_list)
          , size_(size)
          , single_value_initialse_(single_value_initialse)
-         {}
+         , zero_value_initialse_(false)
+         , const_nonzero_literal_value_initialse_(false)
+         , single_initialiser_value_(T(0))
+         {
+            if (single_value_initialse_)
+            {
+               if (initialiser_list_.empty())
+                  zero_value_initialse_ = true;
+               else if (
+                         (initialiser_list_.size() == 1) &&
+                         details::is_constant_node(initialiser_list_[0]) &&
+                         (T(0) == initialiser_list_[0]->value())
+                       )
+               {
+                  zero_value_initialse_ = true;
+               }
+               else
+               {
+                  assert(initialiser_list_.size() == 1);
+
+                  if (details::is_constant_node(initialiser_list_[0]))
+                  {
+                     const_nonzero_literal_value_initialse_ = true;
+                     single_initialiser_value_ = initialiser_list_[0]->value();
+                     assert(T(0) != single_initialiser_value_);
+                  }
+               }
+            }
+         }
 
          inline T value() const exprtk_override
          {
             if (single_value_initialse_)
             {
-               for (std::size_t i = 0; i < size_; ++i)
+               if (zero_value_initialse_)
                {
-                  *(vector_base_ + i) = initialiser_list_[0]->value();
+                  details::set_zero_value(vector_base_, size_);
+               }
+               else if (const_nonzero_literal_value_initialse_)
+               {
+                  for (std::size_t i = 0; i < size_; ++i)
+                  {
+                     *(vector_base_ + i) = single_initialiser_value_;
+                  }
+               }
+               else
+               {
+                  for (std::size_t i = 0; i < size_; ++i)
+                  {
+                     *(vector_base_ + i) = initialiser_list_[0]->value();
+                  }
                }
             }
             else
@@ -8060,10 +9464,9 @@ namespace exprtk
 
                if (initialiser_list_size < size_)
                {
-                  for (std::size_t i = initialiser_list_size; i < size_; ++i)
-                  {
-                     *(vector_base_ + i) = T(0);
-                  }
+                  details::set_zero_value(
+                     vector_base_ + initialiser_list_size,
+                     (size_ - initialiser_list_size));
                }
             }
 
@@ -8072,7 +9475,12 @@ namespace exprtk
 
          inline typename expression_node<T>::node_type type() const exprtk_override
          {
-            return expression_node<T>::e_vecdefass;
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_;
          }
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
@@ -8087,13 +9495,448 @@ namespace exprtk
 
       private:
 
-         vector_assignment_node(const vector_assignment_node<T>&) exprtk_delete;
-         vector_assignment_node<T>& operator=(const vector_assignment_node<T>&) exprtk_delete;
+         vector_initialisation_node(const vector_initialisation_node<T>&) exprtk_delete;
+         vector_initialisation_node<T>& operator=(const vector_initialisation_node<T>&) exprtk_delete;
 
          mutable T* vector_base_;
          std::vector<expression_ptr> initialiser_list_;
          const std::size_t size_;
          const bool single_value_initialse_;
+         bool zero_value_initialse_;
+         bool const_nonzero_literal_value_initialse_;
+         T single_initialiser_value_;
+      };
+
+      template <typename T>
+      class vector_init_zero_value_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_zero_value_node(T* vector_base,
+                                     const std::size_t& size,
+                                     const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {}
+
+         inline T value() const exprtk_override
+         {
+            details::set_zero_value(vector_base_, size_);
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_;
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_zero_value_node(const vector_init_zero_value_node<T>&) exprtk_delete;
+         vector_init_zero_value_node<T>& operator=(const vector_init_zero_value_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
+      };
+
+      template <typename T>
+      class vector_init_single_constvalue_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_single_constvalue_node(T* vector_base,
+                                            const std::size_t& size,
+                                            const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {
+            single_initialiser_value_ = initialiser_list_[0]->value();
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            for (std::size_t i = 0; i < size_; ++i)
+            {
+               *(vector_base_ + i) = single_initialiser_value_;
+            }
+
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_ &&
+                   (initialiser_list_.size() == 1) &&
+                   (details::is_constant_node(initialiser_list_[0])) &&
+                   (single_initialiser_value_ != T(0));
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_single_constvalue_node(const vector_init_single_constvalue_node<T>&) exprtk_delete;
+         vector_init_single_constvalue_node<T>& operator=(const vector_init_single_constvalue_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
+         T single_initialiser_value_;
+      };
+
+      template <typename T>
+      class vector_init_single_value_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_single_value_node(T* vector_base,
+                                       const std::size_t& size,
+                                       const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            expression_node<T>& node = *initialiser_list_[0];
+
+            for (std::size_t i = 0; i < size_; ++i)
+            {
+               *(vector_base_ + i) = node.value();
+            }
+
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_ &&
+                   (initialiser_list_.size() == 1) &&
+                   !details::is_constant_node(initialiser_list_[0]);
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_single_value_node(const vector_init_single_value_node<T>&) exprtk_delete;
+         vector_init_single_value_node<T>& operator=(const vector_init_single_value_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
+      };
+
+      template <typename T>
+      class vector_init_iota_constconst_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_iota_constconst_node(T* vector_base,
+                                          const std::size_t& size,
+                                          const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {
+            base_value_      = initialiser_list_[0]->value();
+            increment_value_ = initialiser_list_[1]->value();
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T value = base_value_;
+
+            for (std::size_t i = 0; i < size_; ++i, value += increment_value_)
+            {
+               *(vector_base_ + i) = value;
+            }
+
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_ &&
+                   (initialiser_list_.size() == 2) &&
+                   (details::is_constant_node(initialiser_list_[0])) &&
+                   (details::is_constant_node(initialiser_list_[1])) ;
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_iota_constconst_node(const vector_init_iota_constconst_node<T>&) exprtk_delete;
+         vector_init_iota_constconst_node<T>& operator=(const vector_init_iota_constconst_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
+         T base_value_;
+         T increment_value_;
+      };
+
+      template <typename T>
+      class vector_init_iota_constnconst_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_iota_constnconst_node(T* vector_base,
+                                           const std::size_t& size,
+                                           const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {
+            assert(valid());
+            base_value_ = initialiser_list_[0]->value();
+         }
+
+         inline T value() const exprtk_override
+         {
+            T value = base_value_;
+            expression_node<T>& increment = *initialiser_list_[1];
+
+            for (std::size_t i = 0; i < size_; ++i, value += increment.value())
+            {
+               *(vector_base_ + i) = value;
+            }
+
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_ &&
+                  (initialiser_list_.size() == 2) &&
+                  ( details::is_constant_node(initialiser_list_[0])) &&
+                  (!details::is_constant_node(initialiser_list_[1]));
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_iota_constnconst_node(const vector_init_iota_constnconst_node<T>&) exprtk_delete;
+         vector_init_iota_constnconst_node<T>& operator=(const vector_init_iota_constnconst_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
+         T base_value_;
+      };
+
+      template <typename T>
+      class vector_init_iota_nconstconst_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_iota_nconstconst_node(T* vector_base,
+                                           const std::size_t& size,
+                                           const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T value = initialiser_list_[0]->value();
+            const T increment = initialiser_list_[1]->value();
+
+            for (std::size_t i = 0; i < size_; ++i, value += increment)
+            {
+               *(vector_base_ + i) = value;
+            }
+
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_ &&
+                   (initialiser_list_.size() == 2) &&
+                   (!details::is_constant_node(initialiser_list_[0])) &&
+                   (details::is_constant_node(initialiser_list_[1]));
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_iota_nconstconst_node(const vector_init_iota_nconstconst_node<T>&) exprtk_delete;
+         vector_init_iota_nconstconst_node<T>& operator=(const vector_init_iota_nconstconst_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
+      };
+
+      template <typename T>
+      class vector_init_iota_nconstnconst_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+
+         vector_init_iota_nconstnconst_node(T* vector_base,
+                                            const std::size_t& size,
+                                            const std::vector<expression_ptr>& initialiser_list)
+         : vector_base_(vector_base)
+         , size_(size)
+         , initialiser_list_(initialiser_list)
+         {
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T value = initialiser_list_[0]->value();
+            expression_node<T>& increment = *initialiser_list_[1];
+
+            for (std::size_t i = 0; i < size_; ++i, value += increment.value())
+            {
+               *(vector_base_ + i) = value;
+            }
+
+            return *(vector_base_);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_vecinit;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vector_base_ &&
+                   (initialiser_list_.size() == 2) &&
+                   (!details::is_constant_node(initialiser_list_[0])) &&
+                   (!details::is_constant_node(initialiser_list_[1]));
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
+         }
+
+      private:
+
+         vector_init_iota_nconstnconst_node(const vector_init_iota_nconstnconst_node<T>&) exprtk_delete;
+         vector_init_iota_nconstnconst_node<T>& operator=(const vector_init_iota_nconstnconst_node<T>&) exprtk_delete;
+
+         mutable T* vector_base_;
+         const std::size_t size_;
+         std::vector<expression_ptr> initialiser_list_;
       };
 
       template <typename T>
@@ -8175,7 +10018,6 @@ namespace exprtk
          : binary_node<T>(details::e_swap, branch0, branch1)
          , vec0_node_ptr_(0)
          , vec1_node_ptr_(0)
-         , vec_size_     (0)
          , initialised_  (false)
          {
             if (is_ivector_node(branch(0)))
@@ -8201,37 +10043,29 @@ namespace exprtk
 
             if (vec0_node_ptr_ && vec1_node_ptr_)
             {
-               vec_size_ = std::min(vec0_node_ptr_->vds().size(),
-                                    vec1_node_ptr_->vds().size());
-
-               initialised_ = true;
+               initialised_ = size() <= base_size();
             }
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            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();
+
+            assert(size() <= base_size());
+            const std::size_t n = size();
+
+            for (std::size_t i = 0; i < n; ++i)
             {
-               assert(branch(0));
-               assert(branch(1));
-
-               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();
-
-               for (std::size_t i = 0; i < vec_size_; ++i)
-               {
-                  std::swap(vec0[i],vec1[i]);
-               }
-
-               return vec1_node_ptr_->value();
+               std::swap(vec0[i],vec1[i]);
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            return vec1_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -8249,9 +10083,23 @@ namespace exprtk
             return expression_node<T>::e_vecvecswap;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vec_size_;
+            return std::min(
+               vec0_node_ptr_->vec_holder().size(),
+               vec1_node_ptr_->vec_holder().size());
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return std::min(
+               vec0_node_ptr_->vec_holder().base_size(),
+               vec1_node_ptr_->vec_holder().base_size());
          }
 
          vds_t& vds() exprtk_override
@@ -8268,7 +10116,6 @@ namespace exprtk
 
          vector_node<T>* vec0_node_ptr_;
          vector_node<T>* vec1_node_ptr_;
-         std::size_t     vec_size_;
          bool            initialised_;
          vds_t           vds_;
       };
@@ -8276,9 +10123,9 @@ namespace exprtk
       #ifndef exprtk_disable_string_capabilities
       template <typename T>
       class stringvar_node exprtk_final
-                           : public expression_node <T>,
-                             public string_base_node<T>,
-                             public range_interface <T>
+                           : public expression_node <T>
+                           , public string_base_node<T>
+                           , public range_interface <T>
       {
       public:
 
@@ -8294,7 +10141,7 @@ namespace exprtk
          : value_(&v)
          {
             rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
-            rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
+            rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size());
             rp_.cache.first  = rp_.n0_c.second;
             rp_.cache.second = rp_.n1_c.second;
          }
@@ -8306,7 +10153,7 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            rp_.n1_c.second  = (*value_).size() - 1;
+            rp_.n1_c.second  = (*value_).size();
             rp_.cache.second = rp_.n1_c.second;
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -8372,9 +10219,9 @@ namespace exprtk
 
       template <typename T>
       class string_range_node exprtk_final
-                              : public expression_node <T>,
-                                public string_base_node<T>,
-                                public range_interface <T>
+                              : public expression_node <T>
+                              , public string_base_node<T>
+                              , public range_interface <T>
       {
       public:
 
@@ -8458,9 +10305,9 @@ namespace exprtk
 
       template <typename T>
       class const_string_range_node exprtk_final
-                                    : public expression_node <T>,
-                                      public string_base_node<T>,
-                                      public range_interface <T>
+                                    : public expression_node <T>
+                                    , public string_base_node<T>
+                                    , public range_interface <T>
       {
       public:
 
@@ -8527,9 +10374,9 @@ namespace exprtk
 
       template <typename T>
       class generic_string_range_node exprtk_final
-                                      : public expression_node <T>,
-                                        public string_base_node<T>,
-                                        public range_interface <T>
+                                      : public expression_node <T>
+                                      , public string_base_node<T>
+                                      , public range_interface <T>
       {
       public:
 
@@ -8569,8 +10416,7 @@ namespace exprtk
             }
 
             initialised_ = (str_base_ptr_ && str_range_ptr_);
-
-            assert(initialised_);
+            assert(valid());
          }
 
         ~generic_string_range_node()
@@ -8580,34 +10426,29 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch_.first->value();
+
+            std::size_t str_r0 = 0;
+            std::size_t str_r1 = 0;
+
+            std::size_t r0 = 0;
+            std::size_t r1 = 0;
+
+            const range_t& range = str_range_ptr_->range_ref();
+
+            const std::size_t base_str_size = str_base_ptr_->size();
+
+            if (
+                  range      (str_r0, str_r1, base_str_size         ) &&
+                  base_range_(r0    , r1    , base_str_size - str_r0)
+               )
             {
-               assert(branch_.first);
+               const std::size_t size = r1 - r0;
 
-               branch_.first->value();
+               range_.n1_c.second  = size;
+               range_.cache.second = range_.n1_c.second;
 
-               std::size_t str_r0 = 0;
-               std::size_t str_r1 = 0;
-
-               std::size_t r0 = 0;
-               std::size_t r1 = 0;
-
-               const range_t& range = str_range_ptr_->range_ref();
-
-               const std::size_t base_str_size = str_base_ptr_->size();
-
-               if (
-                    range      (str_r0, str_r1, base_str_size) &&
-                    base_range_(    r0,     r1, base_str_size - str_r0)
-                  )
-               {
-                  const std::size_t size = (r1 - r0) + 1;
-
-                  range_.n1_c.second  = size - 1;
-                  range_.cache.second = range_.n1_c.second;
-
-                  value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
-               }
+               value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -8643,6 +10484,11 @@ namespace exprtk
             return expression_node<T>::e_strgenrange;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && branch_.first;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(branch_, node_delete_list);
@@ -8666,9 +10512,9 @@ namespace exprtk
 
       template <typename T>
       class string_concat_node exprtk_final
-                               : public binary_node     <T>,
-                                 public string_base_node<T>,
-                                 public range_interface <T>
+                               : public binary_node     <T>
+                               , public string_base_node<T>
+                               , public range_interface <T>
       {
       public:
 
@@ -8728,42 +10574,36 @@ namespace exprtk
                            str0_range_ptr_ &&
                            str1_range_ptr_ ;
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch(0)->value();
+            branch(1)->value();
+
+            std::size_t str0_r0 = 0;
+            std::size_t str0_r1 = 0;
+
+            std::size_t str1_r0 = 0;
+            std::size_t str1_r1 = 0;
+
+            const range_t& range0 = str0_range_ptr_->range_ref();
+            const range_t& range1 = str1_range_ptr_->range_ref();
+
+            if (
+                  range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
+                  range1(str1_r0, str1_r1, str1_base_ptr_->size())
+               )
             {
-               assert(branch(0));
-               assert(branch(1));
+               const std::size_t size0 = (str0_r1 - str0_r0);
+               const std::size_t size1 = (str1_r1 - str1_r0);
 
-               branch(0)->value();
-               branch(1)->value();
+               value_.assign(str0_base_ptr_->base() + str0_r0, size0);
+               value_.append(str1_base_ptr_->base() + str1_r0, size1);
 
-               std::size_t str0_r0 = 0;
-               std::size_t str0_r1 = 0;
-
-               std::size_t str1_r0 = 0;
-               std::size_t str1_r1 = 0;
-
-               const range_t& range0 = str0_range_ptr_->range_ref();
-               const range_t& range1 = str1_range_ptr_->range_ref();
-
-               if (
-                    range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
-                    range1(str1_r0, str1_r1, str1_base_ptr_->size())
-                  )
-               {
-                  const std::size_t size0 = (str0_r1 - str0_r0) + 1;
-                  const std::size_t size1 = (str1_r1 - str1_r0) + 1;
-
-                  value_.assign(str0_base_ptr_->base() + str0_r0, size0);
-                  value_.append(str1_base_ptr_->base() + str1_r0, size1);
-
-                  range_.n1_c.second  = value_.size() - 1;
-                  range_.cache.second = range_.n1_c.second;
-               }
+               range_.n1_c.second  = value_.size();
+               range_.cache.second = range_.n1_c.second;
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -8799,6 +10639,11 @@ namespace exprtk
             return expression_node<T>::e_strconcat;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool                initialised_;
@@ -8812,9 +10657,9 @@ namespace exprtk
 
       template <typename T>
       class swap_string_node exprtk_final
-                             : public binary_node     <T>,
-                               public string_base_node<T>,
-                               public range_interface <T>
+                             : public binary_node     <T>
+                             , public string_base_node<T>
+                             , public range_interface <T>
       {
       public:
 
@@ -8829,10 +10674,10 @@ namespace exprtk
          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)
+         : binary_node<T>(details::e_swap, branch0, branch1)
+         , initialised_(false)
+         , str0_node_ptr_(0)
+         , str1_node_ptr_(0)
          {
             if (is_string_node(branch(0)))
             {
@@ -8845,22 +10690,15 @@ namespace exprtk
             }
 
             initialised_ = (str0_node_ptr_ && str1_node_ptr_);
-
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
-            {
-               assert(branch(0));
-               assert(branch(1));
+            branch(0)->value();
+            branch(1)->value();
 
-               branch(0)->value();
-               branch(1)->value();
-
-               std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref());
-            }
+            std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref());
 
             return std::numeric_limits<T>::quiet_NaN();
          }
@@ -8895,6 +10733,11 @@ namespace exprtk
             return expression_node<T>::e_strswap;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool initialised_;
@@ -8960,87 +10803,81 @@ namespace exprtk
                            str0_range_ptr_ &&
                            str1_range_ptr_ ;
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch(0)->value();
+            branch(1)->value();
+
+            std::size_t str0_r0 = 0;
+            std::size_t str0_r1 = 0;
+
+            std::size_t str1_r0 = 0;
+            std::size_t str1_r1 = 0;
+
+            const range_t& range0 = (*str0_range_ptr_);
+            const range_t& range1 = (*str1_range_ptr_);
+
+            if (
+                  range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
+                  range1(str1_r0, str1_r1, str1_base_ptr_->size())
+               )
             {
-               assert(branch(0));
-               assert(branch(1));
+               const std::size_t size0    = range0.cache_size();
+               const std::size_t size1    = range1.cache_size();
+               const std::size_t max_size = std::min(size0,size1);
 
-               branch(0)->value();
-               branch(1)->value();
+               char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
+               char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
 
-               std::size_t str0_r0 = 0;
-               std::size_t str0_r1 = 0;
+               loop_unroll::details lud(max_size);
+               char_cptr upper_bound = s0 + lud.upper_bound;
 
-               std::size_t str1_r0 = 0;
-               std::size_t str1_r1 = 0;
-
-               const range_t& range0 = (*str0_range_ptr_);
-               const range_t& range1 = (*str1_range_ptr_);
-
-               if (
-                    range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
-                    range1(str1_r0, str1_r1, str1_base_ptr_->size())
-                  )
+               while (s0 < upper_bound)
                {
-                  const std::size_t size0    = range0.cache_size();
-                  const std::size_t size1    = range1.cache_size();
-                  const std::size_t max_size = std::min(size0,size1);
+                  #define exprtk_loop(N)   \
+                  std::swap(s0[N], s1[N]); \
 
-                  char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
-                  char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
+                  exprtk_loop( 0) exprtk_loop( 1)
+                  exprtk_loop( 2) exprtk_loop( 3)
+                  #ifndef exprtk_disable_superscalar_unroll
+                  exprtk_loop( 4) exprtk_loop( 5)
+                  exprtk_loop( 6) exprtk_loop( 7)
+                  exprtk_loop( 8) exprtk_loop( 9)
+                  exprtk_loop(10) exprtk_loop(11)
+                  exprtk_loop(12) exprtk_loop(13)
+                  exprtk_loop(14) exprtk_loop(15)
+                  #endif
 
-                  loop_unroll::details lud(max_size);
-                  char_cptr upper_bound = s0 + lud.upper_bound;
-
-                  while (s0 < upper_bound)
-                  {
-                     #define exprtk_loop(N)   \
-                     std::swap(s0[N], s1[N]); \
-
-                     exprtk_loop( 0) exprtk_loop( 1)
-                     exprtk_loop( 2) exprtk_loop( 3)
-                     #ifndef exprtk_disable_superscalar_unroll
-                     exprtk_loop( 4) exprtk_loop( 5)
-                     exprtk_loop( 6) exprtk_loop( 7)
-                     exprtk_loop( 8) exprtk_loop( 9)
-                     exprtk_loop(10) exprtk_loop(11)
-                     exprtk_loop(12) exprtk_loop(13)
-                     exprtk_loop(14) exprtk_loop(15)
-                     #endif
-
-                     s0 += lud.batch_size;
-                     s1 += lud.batch_size;
-                  }
-
-                  int i = 0;
-
-                  exprtk_disable_fallthrough_begin
-                  switch (lud.remainder)
-                  {
-                     #define case_stmt(N)                       \
-                     case N : { std::swap(s0[i], s1[i]); ++i; } \
-
-                     #ifndef exprtk_disable_superscalar_unroll
-                     case_stmt(15) case_stmt(14)
-                     case_stmt(13) case_stmt(12)
-                     case_stmt(11) case_stmt(10)
-                     case_stmt( 9) case_stmt( 8)
-                     case_stmt( 7) case_stmt( 6)
-                     case_stmt( 5) case_stmt( 4)
-                     #endif
-                     case_stmt( 3) case_stmt( 2)
-                     case_stmt( 1)
-                  }
-                  exprtk_disable_fallthrough_end
-
-                  #undef exprtk_loop
-                  #undef case_stmt
+                  s0 += lud.batch_size;
+                  s1 += lud.batch_size;
                }
+
+               int i = 0;
+
+               switch (lud.remainder)
+               {
+                  #define case_stmt(N)                       \
+                  case N : { std::swap(s0[i], s1[i]); ++i; } \
+                  exprtk_fallthrough                         \
+
+                  #ifndef exprtk_disable_superscalar_unroll
+                  case_stmt(15) case_stmt(14)
+                  case_stmt(13) case_stmt(12)
+                  case_stmt(11) case_stmt(10)
+                  case_stmt( 9) case_stmt( 8)
+                  case_stmt( 7) case_stmt( 6)
+                  case_stmt( 5) case_stmt( 4)
+                  #endif
+                  case_stmt( 3) case_stmt( 2)
+                  case_stmt( 1)
+                  default: break;
+               }
+
+               #undef exprtk_loop
+               #undef case_stmt
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -9051,6 +10888,11 @@ namespace exprtk
             return expression_node<T>::e_strswap;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          swap_genstrings_node(const swap_genstrings_node<T>&) exprtk_delete;
@@ -9068,7 +10910,7 @@ namespace exprtk
       {
       public:
 
-         static std::string null_value;
+         static const std::string null_value;
 
          explicit stringvar_size_node()
          : value_(&null_value)
@@ -9090,11 +10932,11 @@ namespace exprtk
 
       private:
 
-         std::string* value_;
+         const std::string* value_;
       };
 
       template <typename T>
-      std::string stringvar_size_node<T>::null_value = std::string("");
+      const std::string stringvar_size_node<T>::null_value = std::string("");
 
       template <typename T>
       class string_size_node exprtk_final : public expression_node<T>
@@ -9113,23 +10955,15 @@ namespace exprtk
             if (is_generally_string_node(branch_.first))
             {
                str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
-
-               if (0 == str_base_ptr_)
-                  return;
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            T result = std::numeric_limits<T>::quiet_NaN();
-
-            if (str_base_ptr_)
-            {
-               branch_.first->value();
-               result = T(str_base_ptr_->size());
-            }
-
-            return result;
+            branch_.first->value();
+            return T(str_base_ptr_->size());
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -9137,6 +10971,11 @@ namespace exprtk
             return expression_node<T>::e_stringsize;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return str_base_ptr_;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(branch_, node_delete_list);
@@ -9149,7 +10988,7 @@ namespace exprtk
 
       private:
 
-         branch_t           branch_;
+         branch_t     branch_;
          str_base_ptr str_base_ptr_;
       };
 
@@ -9167,9 +11006,9 @@ namespace exprtk
 
       template <typename T, typename AssignmentProcess = asn_assignment>
       class assignment_string_node exprtk_final
-                                   : public binary_node     <T>,
-                                     public string_base_node<T>,
-                                     public range_interface <T>
+                                   : public binary_node     <T>
+                                   , public string_base_node<T>
+                                   , public range_interface <T>
       {
       public:
 
@@ -9219,31 +11058,25 @@ namespace exprtk
                            str0_node_ptr_  &&
                            str1_range_ptr_ ;
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch(1)->value();
+
+            std::size_t r0 = 0;
+            std::size_t r1 = 0;
+
+            const range_t& range = (*str1_range_ptr_);
+
+            if (range(r0, r1, str1_base_ptr_->size()))
             {
-               assert(branch(0));
-               assert(branch(1));
+               AssignmentProcess::execute(
+                  str0_node_ptr_->ref(),
+                  str1_base_ptr_->base() + r0, (r1 - r0));
 
-               branch(1)->value();
-
-               std::size_t r0 = 0;
-               std::size_t r1 = 0;
-
-               const range_t& range = (*str1_range_ptr_);
-
-               if (range(r0, r1, str1_base_ptr_->size()))
-               {
-                  AssignmentProcess::execute(str0_node_ptr_->ref(),
-                                             str1_base_ptr_->base() + r0,
-                                             (r1 - r0) + 1);
-
-                  branch(0)->value();
-               }
+               branch(0)->value();
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -9279,6 +11112,11 @@ namespace exprtk
             return expression_node<T>::e_strass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool            initialised_;
@@ -9290,9 +11128,9 @@ namespace exprtk
 
       template <typename T, typename AssignmentProcess = asn_assignment>
       class assignment_string_range_node exprtk_final
-                                         : public binary_node     <T>,
-                                           public string_base_node<T>,
-                                           public range_interface <T>
+                                         : public binary_node     <T>
+                                         , public string_base_node<T>
+                                         , public range_interface <T>
       {
       public:
 
@@ -9351,39 +11189,34 @@ namespace exprtk
                            str0_range_ptr_    &&
                            str1_range_ptr_    ;
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch(0)->value();
+            branch(1)->value();
+
+            std::size_t s0_r0 = 0;
+            std::size_t s0_r1 = 0;
+
+            std::size_t s1_r0 = 0;
+            std::size_t s1_r1 = 0;
+
+            const range_t& range0 = (*str0_range_ptr_);
+            const range_t& range1 = (*str1_range_ptr_);
+
+            if (
+                  range0(s0_r0, s0_r1, str0_base_ptr_->size()) &&
+                  range1(s1_r0, s1_r1, str1_base_ptr_->size())
+               )
             {
-               assert(branch(0));
-               assert(branch(1));
+               const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0));
 
-               branch(0)->value();
-               branch(1)->value();
-
-               std::size_t s0_r0 = 0;
-               std::size_t s0_r1 = 0;
-
-               std::size_t s1_r0 = 0;
-               std::size_t s1_r1 = 0;
-
-               const range_t& range0 = (*str0_range_ptr_);
-               const range_t& range1 = (*str1_range_ptr_);
-
-               if (
-                    range0(s0_r0, s0_r1, str0_base_ptr_->size()) &&
-                    range1(s1_r0, s1_r1, str1_base_ptr_->size())
-                  )
-               {
-                  const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0)) + 1;
-
-                  std::copy(str1_base_ptr_->base() + s1_r0,
-                            str1_base_ptr_->base() + s1_r0 + size,
-                            const_cast<char_ptr>(base() + s0_r0));
-               }
+               std::copy(
+                  str1_base_ptr_->base() + s1_r0,
+                  str1_base_ptr_->base() + s1_r0 + size,
+                  const_cast<char_ptr>(base() + s0_r0));
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -9419,6 +11252,11 @@ namespace exprtk
             return expression_node<T>::e_strass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool             initialised_;
@@ -9431,9 +11269,9 @@ namespace exprtk
 
       template <typename T>
       class conditional_string_node exprtk_final
-                                    : public trinary_node    <T>,
-                                      public string_base_node<T>,
-                                      public range_interface <T>
+                                    : public trinary_node    <T>
+                                    , public string_base_node<T>
+                                    , public range_interface <T>
       {
       public:
 
@@ -9494,55 +11332,48 @@ namespace exprtk
                            str0_range_ptr_ &&
                            str1_range_ptr_ ;
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            std::size_t r0 = 0;
+            std::size_t r1 = 0;
+
+            if (is_true(condition_))
             {
-               assert(condition_  );
-               assert(consequent_ );
-               assert(alternative_);
+               consequent_->value();
 
-               std::size_t r0 = 0;
-               std::size_t r1 = 0;
+               const range_t& range = str0_range_ptr_->range_ref();
 
-               if (is_true(condition_))
+               if (range(r0, r1, str0_base_ptr_->size()))
                {
-                  consequent_->value();
+                  const std::size_t size = (r1 - r0);
 
-                  const range_t& range = str0_range_ptr_->range_ref();
+                  value_.assign(str0_base_ptr_->base() + r0, size);
 
-                  if (range(r0, r1, str0_base_ptr_->size()))
-                  {
-                     const std::size_t size = (r1 - r0) + 1;
+                  range_.n1_c.second  = value_.size();
+                  range_.cache.second = range_.n1_c.second;
 
-                     value_.assign(str0_base_ptr_->base() + r0, size);
-
-                     range_.n1_c.second  = value_.size() - 1;
-                     range_.cache.second = range_.n1_c.second;
-
-                     return T(1);
-                  }
+                  return T(1);
                }
-               else
+            }
+            else
+            {
+               alternative_->value();
+
+               const range_t& range = str1_range_ptr_->range_ref();
+
+               if (range(r0, r1, str1_base_ptr_->size()))
                {
-                  alternative_->value();
+                  const std::size_t size = (r1 - r0);
 
-                  const range_t& range = str1_range_ptr_->range_ref();
+                  value_.assign(str1_base_ptr_->base() + r0, size);
 
-                  if (range(r0, r1, str1_base_ptr_->size()))
-                  {
-                     const std::size_t size = (r1 - r0) + 1;
+                  range_.n1_c.second  = value_.size();
+                  range_.cache.second = range_.n1_c.second;
 
-                     value_.assign(str1_base_ptr_->base() + r0, size);
-
-                     range_.n1_c.second  = value_.size() - 1;
-                     range_.cache.second = range_.n1_c.second;
-
-                     return T(0);
-                  }
+                  return T(0);
                }
             }
 
@@ -9579,6 +11410,15 @@ namespace exprtk
             return expression_node<T>::e_strcondition;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               initialised_                         &&
+               condition_  && condition_  ->valid() &&
+               consequent_ && consequent_ ->valid() &&
+               alternative_&& alternative_->valid() ;
+         }
+
       private:
 
          bool initialised_;
@@ -9596,9 +11436,9 @@ namespace exprtk
 
       template <typename T>
       class cons_conditional_str_node exprtk_final
-                                      : public binary_node     <T>,
-                                        public string_base_node<T>,
-                                        public range_interface <T>
+                                      : public binary_node     <T>
+                                      , public string_base_node<T>
+                                      , public range_interface <T>
       {
       public:
 
@@ -9640,37 +11480,30 @@ namespace exprtk
             }
 
             initialised_ = str0_base_ptr_ && str0_range_ptr_ ;
-
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            if (is_true(condition_))
             {
-               assert(condition_ );
-               assert(consequent_);
+               consequent_->value();
 
-               if (is_true(condition_))
+               const range_t& range = str0_range_ptr_->range_ref();
+
+               std::size_t r0 = 0;
+               std::size_t r1 = 0;
+
+               if (range(r0, r1, str0_base_ptr_->size()))
                {
-                  consequent_->value();
+                  const std::size_t size = (r1 - r0);
 
-                  const range_t& range = str0_range_ptr_->range_ref();
+                  value_.assign(str0_base_ptr_->base() + r0, size);
 
-                  std::size_t r0 = 0;
-                  std::size_t r1 = 0;
+                  range_.n1_c.second  = value_.size();
+                  range_.cache.second = range_.n1_c.second;
 
-                  if (range(r0, r1, str0_base_ptr_->size()))
-                  {
-                     const std::size_t size = (r1 - r0) + 1;
-
-                     value_.assign(str0_base_ptr_->base() + r0, size);
-
-                     range_.n1_c.second  = value_.size() - 1;
-                     range_.cache.second = range_.n1_c.second;
-
-                     return T(1);
-                  }
+                  return T(1);
                }
             }
 
@@ -9707,6 +11540,14 @@ namespace exprtk
             return expression_node<T>::e_strccondition;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               initialised_                         &&
+               condition_  && condition_  ->valid() &&
+               consequent_ && consequent_ ->valid() ;
+         }
+
       private:
 
          bool initialised_;
@@ -9721,9 +11562,9 @@ namespace exprtk
 
       template <typename T, typename VarArgFunction>
       class str_vararg_node exprtk_final
-                            : public expression_node <T>,
-                              public string_base_node<T>,
-                              public range_interface <T>
+                            : public expression_node <T>
+                            , public string_base_node<T>
+                            , public range_interface <T>
       {
       public:
 
@@ -9759,8 +11600,6 @@ namespace exprtk
             if (0 == str_range_ptr_)
                return;
 
-            initialised_ = str_base_ptr_  && str_range_ptr_;
-
             if (arg_list.size() > 1)
             {
                const std::size_t arg_list_size = arg_list.size() - 1;
@@ -9769,7 +11608,7 @@ namespace exprtk
 
                for (std::size_t i = 0; i < arg_list_size; ++i)
                {
-                  if (arg_list[i])
+                  if (arg_list[i] && arg_list[i]->valid())
                   {
                      construct_branch_pair(arg_list_[i], arg_list[i]);
                   }
@@ -9779,7 +11618,12 @@ namespace exprtk
                      return;
                   }
                }
+
+               initialised_ = true;
             }
+
+            initialised_ &= str_base_ptr_ && str_range_ptr_;
+            assert(valid());
          }
 
          inline T value() const exprtk_override
@@ -9824,6 +11668,13 @@ namespace exprtk
             return expression_node<T>::e_stringvararg;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               initialised_ &&
+               final_node_.first && final_node_.first->valid();
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(final_node_ , node_delete_list);
@@ -9847,6 +11698,104 @@ namespace exprtk
       };
       #endif
 
+      template <typename T>
+      class assert_node exprtk_final : public expression_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         typedef std::pair<expression_ptr,bool> branch_t;
+         typedef string_base_node<T>* str_base_ptr;
+         typedef assert_check::assert_context assert_context_t;
+
+         assert_node(expression_ptr   assert_condition_node,
+                     expression_ptr   assert_message_node,
+                     assert_check_ptr assert_check,
+                     assert_context_t context)
+         : assert_message_str_base_(0)
+         , assert_check_(assert_check)
+         , context_(context)
+         {
+            construct_branch_pair(assert_condition_node_, assert_condition_node);
+            construct_branch_pair(assert_message_node_  , assert_message_node  );
+
+            #ifndef exprtk_disable_string_capabilities
+            if (
+                  assert_message_node_.first &&
+                  details::is_generally_string_node(assert_message_node_.first)
+               )
+            {
+               assert_message_str_base_ = dynamic_cast<str_base_ptr>(assert_message_node_.first);
+            }
+            #endif
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            if (details::is_true(assert_condition_node_.first->value()))
+            {
+               return T(1);
+            }
+
+            #ifndef exprtk_disable_string_capabilities
+            if (assert_message_node_.first)
+            {
+               assert_message_node_.first->value();
+               assert(assert_message_str_base_);
+               context_.message = assert_message_str_base_->str();
+            }
+            #endif
+
+            assert_check_->handle_assert(context_);
+            return T(0);
+         }
+
+         inline typename expression_node<T>::node_type type() const exprtk_override
+         {
+            return expression_node<T>::e_assert;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return (
+                     assert_check_ &&
+                     assert_condition_node_.first &&
+                     assert_condition_node_.first->valid()
+                   ) &&
+                   (
+                     (0 == assert_message_node_.first) ||
+                     (
+                       assert_message_node_.first &&
+                       assert_message_str_base_   &&
+                       assert_message_node_.first->valid() &&
+                       details::is_generally_string_node(assert_message_node_.first)
+                     )
+                   );
+         }
+
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
+         {
+            expression_node<T>::ndb_t::collect(assert_condition_node_, node_delete_list);
+            expression_node<T>::ndb_t::collect(assert_message_node_  , node_delete_list);
+         }
+
+         std::size_t node_depth() const exprtk_override
+         {
+            return expression_node<T>::ndb_t::compute_node_depth
+               (assert_condition_node_, assert_message_node_);
+         }
+
+      private:
+
+         branch_t         assert_condition_node_;
+         branch_t         assert_message_node_;
+         str_base_ptr     assert_message_str_base_;
+         assert_check_ptr assert_check_;
+         mutable assert_context_t context_;
+      };
+
       template <typename T, std::size_t N>
       inline T axn(const T a, const T x)
       {
@@ -10087,10 +12036,6 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            assert(trinary_node<T>::branch_[0].first);
-            assert(trinary_node<T>::branch_[1].first);
-            assert(trinary_node<T>::branch_[2].first);
-
             const T x = trinary_node<T>::branch_[0].first->value();
             const T y = trinary_node<T>::branch_[1].first->value();
             const T z = trinary_node<T>::branch_[2].first->value();
@@ -10116,11 +12061,6 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            assert(quaternary_node<T>::branch_[0].first);
-            assert(quaternary_node<T>::branch_[1].first);
-            assert(quaternary_node<T>::branch_[2].first);
-            assert(quaternary_node<T>::branch_[3].first);
-
             const T x = quaternary_node<T>::branch_[0].first->value();
             const T y = quaternary_node<T>::branch_[1].first->value();
             const T z = quaternary_node<T>::branch_[2].first->value();
@@ -10209,12 +12149,13 @@ namespace exprtk
          template <typename Allocator,
                    template <typename, typename> class Sequence>
          explicit vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
+         : initialised_(false)
          {
             arg_list_.resize(arg_list.size());
 
             for (std::size_t i = 0; i < arg_list.size(); ++i)
             {
-               if (arg_list[i])
+               if (arg_list[i] && arg_list[i]->valid())
                {
                   construct_branch_pair(arg_list_[i],arg_list[i]);
                }
@@ -10224,6 +12165,9 @@ namespace exprtk
                   return;
                }
             }
+
+            initialised_ = (arg_list_.size() == arg_list.size());
+            assert(valid());
          }
 
          inline T value() const exprtk_override
@@ -10236,6 +12180,11 @@ namespace exprtk
             return expression_node<T>::e_vararg;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
@@ -10246,9 +12195,20 @@ namespace exprtk
             return expression_node<T>::ndb_t::compute_node_depth(arg_list_);
          }
 
+         std::size_t size() const
+         {
+            return arg_list_.size();
+         }
+
+         expression_ptr operator[](const std::size_t& index) const
+         {
+            return arg_list_[index].first;
+         }
+
       private:
 
          std::vector<branch_t> arg_list_;
+         bool initialised_;
       };
 
       template <typename T, typename VarArgFunction>
@@ -10261,12 +12221,13 @@ namespace exprtk
          template <typename Allocator,
                    template <typename, typename> class Sequence>
          explicit vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
+         : initialised_(false)
          {
             arg_list_.resize(arg_list.size());
 
             for (std::size_t i = 0; i < arg_list.size(); ++i)
             {
-               if (arg_list[i] && is_variable_node(arg_list[i]))
+               if (arg_list[i] && arg_list[i]->valid() && is_variable_node(arg_list[i]))
                {
                   variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]);
                   arg_list_[i] = (&var_node_ptr->ref());
@@ -10277,14 +12238,14 @@ namespace exprtk
                   return;
                }
             }
+
+            initialised_ = (arg_list.size() == arg_list_.size());
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (!arg_list_.empty())
-               return VarArgFunction::process(arg_list_);
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return VarArgFunction::process(arg_list_);
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -10292,9 +12253,15 @@ namespace exprtk
             return expression_node<T>::e_vararg;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
       private:
 
          std::vector<const T*> arg_list_;
+         bool initialised_;
       };
 
       template <typename T, typename VecFunction>
@@ -10314,22 +12281,12 @@ namespace exprtk
             {
                ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v_.first);
             }
-            else
-               ivec_ptr_ = 0;
          }
 
          inline T value() const exprtk_override
          {
-            if (ivec_ptr_)
-            {
-               assert(v_.first);
-
-               v_.first->value();
-
-               return VecFunction::process(ivec_ptr_);
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            v_.first->value();
+            return VecFunction::process(ivec_ptr_);
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -10337,6 +12294,11 @@ namespace exprtk
             return expression_node<T>::e_vecfunc;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return ivec_ptr_ && v_.first && v_.first->valid();
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(v_, node_delete_list);
@@ -10375,17 +12337,15 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (var_node_ptr_)
-            {
-               assert(branch(1));
-
-               T& result = var_node_ptr_->ref();
+            T& result = var_node_ptr_->ref();
                result = branch(1)->value();
 
-               return result;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return result;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return var_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10411,21 +12371,21 @@ namespace exprtk
             {
                vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (vec_node_ptr_)
-            {
-               assert(branch(1));
-
-               T& result = vec_node_ptr_->ref();
+            T& result = vec_node_ptr_->ref();
                result = branch(1)->value();
 
-               return result;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return result;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vec_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10433,6 +12393,46 @@ namespace exprtk
          vector_elem_node<T>* vec_node_ptr_;
       };
 
+      template <typename T>
+      class assignment_vec_elem_rtc_node exprtk_final : public binary_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         using binary_node<T>::branch;
+
+         assignment_vec_elem_rtc_node(const operator_type& opr,
+                                      expression_ptr branch0,
+                                      expression_ptr branch1)
+         : binary_node<T>(opr, branch0, branch1)
+         , vec_node_ptr_(0)
+         {
+            if (is_vector_elem_rtc_node(branch(0)))
+            {
+               vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
+            }
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T& result = vec_node_ptr_->ref();
+               result = branch(1)->value();
+
+            return result;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vec_node_ptr_ && binary_node<T>::valid();
+         }
+
+      private:
+
+         vector_elem_rtc_node<T>* vec_node_ptr_;
+      };
+
       template <typename T>
       class assignment_rebasevec_elem_node exprtk_final : public binary_node<T>
       {
@@ -10451,22 +12451,21 @@ namespace exprtk
             {
                rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (rbvec_node_ptr_)
-            {
-               assert(branch(1));
-
-               T& result = rbvec_node_ptr_->ref();
-
+            T& result = rbvec_node_ptr_->ref();
                result = branch(1)->value();
 
-               return result;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return result;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10474,6 +12473,46 @@ namespace exprtk
          rebasevector_elem_node<T>* rbvec_node_ptr_;
       };
 
+      template <typename T>
+      class assignment_rebasevec_elem_rtc_node exprtk_final : public binary_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         using expression_node<T>::branch;
+
+         assignment_rebasevec_elem_rtc_node(const operator_type& opr,
+                                            expression_ptr branch0,
+                                            expression_ptr branch1)
+         : binary_node<T>(opr, branch0, branch1)
+         , rbvec_node_ptr_(0)
+         {
+            if (is_rebasevector_elem_rtc_node(branch(0)))
+            {
+               rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0));
+            }
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T& result = rbvec_node_ptr_->ref();
+               result = branch(1)->value();
+
+            return result;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
+         }
+
+      private:
+
+         rebasevector_elem_rtc_node<T>* rbvec_node_ptr_;
+      };
+
       template <typename T>
       class assignment_rebasevec_celem_node exprtk_final : public binary_node<T>
       {
@@ -10492,21 +12531,21 @@ namespace exprtk
             {
                rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (rbvec_node_ptr_)
-            {
-               assert(branch(1));
-
-               T& result = rbvec_node_ptr_->ref();
+            T& result = rbvec_node_ptr_->ref();
                result = branch(1)->value();
 
-               return result;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return result;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10538,66 +12577,60 @@ namespace exprtk
                vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
                vds()         = vec_node_ptr_->vds();
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (vec_node_ptr_)
+            const T v = branch(1)->value();
+
+            T* vec = vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec + lud.upper_bound;
+
+            while (vec < upper_bound)
             {
-               assert(branch(1));
+               #define exprtk_loop(N) \
+               vec[N] = v;            \
 
-               const T v = branch(1)->value();
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-               T* vec = vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec + lud.upper_bound;
-
-               while (vec < upper_bound)
-               {
-                  #define exprtk_loop(N) \
-                  vec[N] = v;            \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec += lud.batch_size;
-               }
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N) \
-                  case N : *vec++ = v; \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return vec_node_ptr_->value();
+               vec += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N) \
+               case N : *vec++ = v; \
+               exprtk_fallthrough   \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15) case_stmt(14)
+               case_stmt(13) case_stmt(12)
+               case_stmt(11) case_stmt(10)
+               case_stmt( 9) case_stmt( 8)
+               case_stmt( 7) case_stmt( 6)
+               case_stmt( 5) case_stmt( 4)
+               #endif
+               case_stmt( 3) case_stmt( 2)
+               case 1 : *vec++ = v;
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return vec_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -10615,9 +12648,22 @@ namespace exprtk
             return expression_node<T>::e_vecvalass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vec_node_ptr_ &&
+               (vds().size() <= vec_node_ptr_->vec_holder().base_size()) &&
+               binary_node<T>::valid();
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return vec_node_ptr_->vec_holder().size();
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return vec_node_ptr_->vec_holder().base_size();
          }
 
          vds_t& vds() exprtk_override
@@ -10687,74 +12733,71 @@ namespace exprtk
                }
             }
 
-            initialised_ = (vec0_node_ptr_ && vec1_node_ptr_);
+            initialised_ =
+               vec0_node_ptr_               &&
+               vec1_node_ptr_               &&
+               (size() <= base_size())      &&
+               (vds_.size() <= base_size()) &&
+               binary_node<T>::valid();
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
-            {
-               assert(branch(1));
-
-               branch(1)->value();
-
-               if (src_is_ivec_)
-                  return vec0_node_ptr_->value();
-
-               T* vec0 = vec0_node_ptr_->vds().data();
-               T* vec1 = vec1_node_ptr_->vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec0 + lud.upper_bound;
-
-               while (vec0 < upper_bound)
-               {
-                  #define exprtk_loop(N) \
-                  vec0[N] = vec1[N];     \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec0 += lud.batch_size;
-                  vec1 += lud.batch_size;
-               }
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)        \
-                  case N : *vec0++ = *vec1++; \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
+            branch(1)->value();
 
+            if (src_is_ivec_)
                return vec0_node_ptr_->value();
+
+            T* vec0 = vec0_node_ptr_->vds().data();
+            T* vec1 = vec1_node_ptr_->vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec0 + lud.upper_bound;
+
+            while (vec0 < upper_bound)
+            {
+               #define exprtk_loop(N) \
+               vec0[N] = vec1[N];     \
+
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
+
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N,fall_through) \
+               case N : *vec0++ = *vec1++;       \
+               fall_through                      \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
+               #endif
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return vec0_node_ptr_->value();
          }
 
          vector_node_ptr vec() exprtk_override
@@ -10772,9 +12815,23 @@ namespace exprtk
             return expression_node<T>::e_vecvecass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return std::min(
+               vec0_node_ptr_->vec_holder().size(),
+               vec1_node_ptr_->vec_holder().size());
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return std::min(
+               vec0_node_ptr_->vec_holder().base_size(),
+               vec1_node_ptr_->vec_holder().base_size());
          }
 
          vds_t& vds() exprtk_override
@@ -10814,21 +12871,21 @@ namespace exprtk
             {
                var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (var_node_ptr_)
-            {
-               assert(branch(1));
+            T& v = var_node_ptr_->ref();
+            v = Operation::process(v,branch(1)->value());
 
-               T& v = var_node_ptr_->ref();
-               v = Operation::process(v,branch(1)->value());
+            return v;
+         }
 
-               return v;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+         inline bool valid() const exprtk_override
+         {
+            return var_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10854,21 +12911,21 @@ namespace exprtk
             {
                vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (vec_node_ptr_)
-            {
-               assert(branch(1));
+            T& v = vec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
 
-               T& v = vec_node_ptr_->ref();
-                  v = Operation::process(v,branch(1)->value());
+            return v;
+         }
 
-               return v;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+         inline bool valid() const exprtk_override
+         {
+            return vec_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10876,6 +12933,86 @@ namespace exprtk
          vector_elem_node<T>* vec_node_ptr_;
       };
 
+      template <typename T, typename Operation>
+      class assignment_vec_elem_op_rtc_node exprtk_final : public binary_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         using binary_node<T>::branch;
+
+         assignment_vec_elem_op_rtc_node(const operator_type& opr,
+                                         expression_ptr branch0,
+                                         expression_ptr branch1)
+         : binary_node<T>(opr, branch0, branch1)
+         , vec_node_ptr_(0)
+         {
+            if (is_vector_elem_rtc_node(branch(0)))
+            {
+               vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
+            }
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T& v = vec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
+
+            return v;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vec_node_ptr_ && binary_node<T>::valid();
+         }
+
+      private:
+
+         vector_elem_rtc_node<T>* vec_node_ptr_;
+      };
+
+      template <typename T, typename Operation>
+      class assignment_vec_celem_op_rtc_node exprtk_final : public binary_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         using binary_node<T>::branch;
+
+         assignment_vec_celem_op_rtc_node(const operator_type& opr,
+                                          expression_ptr branch0,
+                                          expression_ptr branch1)
+         : binary_node<T>(opr, branch0, branch1)
+         , vec_node_ptr_(0)
+         {
+            if (is_vector_celem_rtc_node(branch(0)))
+            {
+               vec_node_ptr_ = static_cast<vector_celem_rtc_node<T>*>(branch(0));
+            }
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T& v = vec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
+
+            return v;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return vec_node_ptr_ && binary_node<T>::valid();
+         }
+
+      private:
+
+         vector_celem_rtc_node<T>* vec_node_ptr_;
+      };
+
       template <typename T, typename Operation>
       class assignment_rebasevec_elem_op_node exprtk_final : public binary_node<T>
       {
@@ -10894,21 +13031,21 @@ namespace exprtk
             {
                rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (rbvec_node_ptr_)
-            {
-               assert(branch(1));
+            T& v = rbvec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
 
-               T& v = rbvec_node_ptr_->ref();
-                  v = Operation::process(v,branch(1)->value());
+            return v;
+         }
 
-               return v;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10934,21 +13071,21 @@ namespace exprtk
             {
                rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0));
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (rbvec_node_ptr_)
-            {
-               assert(branch(1));
+            T& v = rbvec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
 
-               T& v = rbvec_node_ptr_->ref();
-                  v = Operation::process(v,branch(1)->value());
+            return v;
+         }
 
-               return v;
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
          }
 
       private:
@@ -10956,6 +13093,86 @@ namespace exprtk
          rebasevector_celem_node<T>* rbvec_node_ptr_;
       };
 
+      template <typename T, typename Operation>
+      class assignment_rebasevec_elem_op_rtc_node exprtk_final : public binary_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         using binary_node<T>::branch;
+
+         assignment_rebasevec_elem_op_rtc_node(const operator_type& opr,
+                                               expression_ptr branch0,
+                                               expression_ptr branch1)
+         : binary_node<T>(opr, branch0, branch1)
+         , rbvec_node_ptr_(0)
+         {
+            if (is_rebasevector_elem_rtc_node(branch(0)))
+            {
+               rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0));
+            }
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T& v = rbvec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
+
+            return v;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
+         }
+
+      private:
+
+         rebasevector_elem_rtc_node<T>* rbvec_node_ptr_;
+      };
+
+      template <typename T, typename Operation>
+      class assignment_rebasevec_celem_op_rtc_node exprtk_final : public binary_node<T>
+      {
+      public:
+
+         typedef expression_node<T>* expression_ptr;
+         using binary_node<T>::branch;
+
+         assignment_rebasevec_celem_op_rtc_node(const operator_type& opr,
+                                                expression_ptr branch0,
+                                                expression_ptr branch1)
+         : binary_node<T>(opr, branch0, branch1)
+         , rbvec_node_ptr_(0)
+         {
+            if (is_rebasevector_celem_rtc_node(branch(0)))
+            {
+               rbvec_node_ptr_ = static_cast<rebasevector_celem_rtc_node<T>*>(branch(0));
+            }
+
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            T& v = rbvec_node_ptr_->ref();
+               v = Operation::process(v,branch(1)->value());
+
+            return v;
+         }
+
+         inline bool valid() const exprtk_override
+         {
+            return rbvec_node_ptr_ && binary_node<T>::valid();
+         }
+
+      private:
+
+         rebasevector_celem_rtc_node<T>* rbvec_node_ptr_;
+      };
+
       template <typename T, typename Operation>
       class assignment_vec_op_node exprtk_final
                                    : public binary_node     <T>
@@ -10980,66 +13197,60 @@ namespace exprtk
                vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
                vds()         = vec_node_ptr_->vds();
             }
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (vec_node_ptr_)
+            const T v = branch(1)->value();
+
+            T* vec = vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec + lud.upper_bound;
+
+            while (vec < upper_bound)
             {
-               assert(branch(1));
+               #define exprtk_loop(N)       \
+               Operation::assign(vec[N],v); \
 
-               const T v = branch(1)->value();
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-               T* vec = vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec + lud.upper_bound;
-
-               while (vec < upper_bound)
-               {
-                  #define exprtk_loop(N)       \
-                  Operation::assign(vec[N],v); \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec += lud.batch_size;
-               }
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                  \
-                  case N : Operation::assign(*vec++,v); \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return vec_node_ptr_->value();
+               vec += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N,fall_through)     \
+               case N : Operation::assign(*vec++,v); \
+               fall_through                          \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
+               #endif
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return vec_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -11057,9 +13268,22 @@ namespace exprtk
             return expression_node<T>::e_vecopvalass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vec_node_ptr_           &&
+               (size() <= base_size()) &&
+               binary_node<T>::valid() ;
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return vec_node_ptr_->vec_holder().size();
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return vec_node_ptr_->vec_holder().base_size();
          }
 
          vds_t& vds() exprtk_override
@@ -11122,81 +13346,76 @@ namespace exprtk
                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
                {
                   vec1_node_ptr_ = vi->vec();
-                  vec1_node_ptr_->vds() = vds();
+                  vec1_node_ptr_->vds() = vi->vds();
                }
                else
                   vds_t::match_sizes(vds(),vec1_node_ptr_->vds());
             }
 
-            initialised_ = (vec0_node_ptr_ && vec1_node_ptr_);
+            initialised_ =
+               vec0_node_ptr_          &&
+               vec1_node_ptr_          &&
+               (size() <= base_size()) &&
+               binary_node<T>::valid();
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch(0)->value();
+            branch(1)->value();
+
+                  T* vec0 = vec0_node_ptr_->vds().data();
+            const T* vec1 = vec1_node_ptr_->vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec0 + lud.upper_bound;
+
+            while (vec0 < upper_bound)
             {
-               assert(branch(0));
-               assert(branch(1));
+               #define exprtk_loop(N)                          \
+               vec0[N] = Operation::process(vec0[N], vec1[N]); \
 
-               branch(0)->value();
-               branch(1)->value();
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-                     T* vec0 = vec0_node_ptr_->vds().data();
-               const T* vec1 = vec1_node_ptr_->vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec0 + lud.upper_bound;
-
-               while (vec0 < upper_bound)
-               {
-                  #define exprtk_loop(N)                          \
-                  vec0[N] = Operation::process(vec0[N], vec1[N]); \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec0 += lud.batch_size;
-                  vec1 += lud.batch_size;
-               }
-
-               int i = 0;
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                              \
-                  case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return vec0_node_ptr_->value();
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            int i = 0;
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N,fall_through)                                 \
+               case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
+               fall_through                                                      \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
+               #endif
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return vec0_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -11214,9 +13433,23 @@ namespace exprtk
             return expression_node<T>::e_vecopvecass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return std::min(
+               vec0_node_ptr_->vec_holder().size(),
+               vec1_node_ptr_->vec_holder().size());
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return std::min(
+               vec0_node_ptr_->vec_holder().base_size(),
+               vec1_node_ptr_->vec_holder().base_size());
          }
 
          vds_t& vds() exprtk_override
@@ -11242,6 +13475,64 @@ namespace exprtk
          vds_t           vds_;
       };
 
+      template <typename T>
+      struct memory_context_t
+      {
+         typedef vector_node<T>*  vector_node_ptr;
+         typedef vector_holder<T> vector_holder_t;
+         typedef vector_holder_t* vector_holder_ptr;
+
+         memory_context_t()
+         : temp_(0)
+         , temp_vec_node_(0)
+         {}
+
+         void clear()
+         {
+            delete temp_vec_node_;
+            delete temp_;
+         }
+
+         vector_holder_ptr temp_;
+         vector_node_ptr   temp_vec_node_;
+      };
+
+      template <typename T>
+      inline memory_context_t<T> make_memory_context(vector_holder<T>& vec_holder,
+                                                     vec_data_store<T>& vds)
+      {
+         memory_context_t<T> result_ctxt;
+         result_ctxt.temp_  = (vec_holder.rebaseable()) ?
+                              new vector_holder<T>(vec_holder,vds) :
+                              new vector_holder<T>(vds) ;
+         result_ctxt.temp_vec_node_ = new vector_node  <T>(vds,result_ctxt.temp_);
+         return result_ctxt;
+      }
+
+      template <typename T>
+      inline memory_context_t<T> make_memory_context(vector_holder<T>& vec_holder0,
+                                                     vector_holder<T>& vec_holder1,
+                                                     vec_data_store<T>& vds)
+      {
+         memory_context_t<T> result_ctxt;
+
+         if (!vec_holder0.rebaseable() && !vec_holder1.rebaseable())
+            result_ctxt.temp_ = new vector_holder<T>(vds);
+         else if (vec_holder0.rebaseable() && !vec_holder1.rebaseable())
+            result_ctxt.temp_ = new vector_holder<T>(vec_holder0,vds);
+         else if (!vec_holder0.rebaseable() && vec_holder1.rebaseable())
+            result_ctxt.temp_ = new vector_holder<T>(vec_holder1,vds);
+         else
+         {
+            result_ctxt.temp_ = (vec_holder0.base_size() >= vec_holder1.base_size()) ?
+                                new vector_holder<T>(vec_holder0, vds) :
+                                new vector_holder<T>(vec_holder1, vds) ;
+         }
+
+         result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_);
+         return result_ctxt;
+      }
+
       template <typename T, typename Operation>
       class vec_binop_vecvec_node exprtk_final
                                   : public binary_node     <T>
@@ -11251,8 +13542,10 @@ namespace exprtk
 
          typedef expression_node<T>* expression_ptr;
          typedef vector_node<T>*     vector_node_ptr;
-         typedef vector_holder<T>*   vector_holder_ptr;
+         typedef vector_holder<T>    vector_holder_t;
+         typedef vector_holder_t*    vector_holder_ptr;
          typedef vec_data_store<T>   vds_t;
+         typedef memory_context_t<T> memory_context;
 
          using binary_node<T>::branch;
 
@@ -11262,8 +13555,6 @@ namespace exprtk
          : binary_node<T>(opr, branch0, branch1)
          , vec0_node_ptr_(0)
          , vec1_node_ptr_(0)
-         , temp_         (0)
-         , temp_vec_node_(0)
          , initialised_(false)
          {
             bool v0_is_ivec = false;
@@ -11304,104 +13595,102 @@ namespace exprtk
                vector_holder<T>& vec0 = vec0_node_ptr_->vec_holder();
                vector_holder<T>& vec1 = vec1_node_ptr_->vec_holder();
 
-               if (v0_is_ivec && (vec0.size() <= vec1.size()))
+               if (v0_is_ivec && (vec0.base_size() <= vec1.base_size()))
+               {
                   vds_ = vds_t(vec0_node_ptr_->vds());
-               else if (v1_is_ivec && (vec1.size() <= vec0.size()))
+               }
+               else if (v1_is_ivec && (vec1.base_size() <= vec0.base_size()))
+               {
                   vds_ = vds_t(vec1_node_ptr_->vds());
+               }
                else
-                  vds_ = vds_t(std::min(vec0.size(),vec1.size()));
+               {
+                  vds_ = vds_t(std::min(vec0.base_size(),vec1.base_size()));
+               }
 
-               temp_          = new vector_holder<T>(vds().data(),vds().size());
-               temp_vec_node_ = new vector_node  <T>(vds(),temp_);
+               memory_context_ = make_memory_context(vec0, vec1, vds());
 
-               initialised_ = true;
+               initialised_ =
+                  (size() <= base_size()) &&
+                  binary_node<T>::valid();
             }
 
-            assert(initialised_);
+            assert(valid());
          }
 
         ~vec_binop_vecvec_node()
          {
-            delete temp_;
-            delete temp_vec_node_;
+            memory_context_.clear();
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            branch(0)->value();
+            branch(1)->value();
+
+            const T* vec0 = vec0_node_ptr_->vds().data();
+            const T* vec1 = vec1_node_ptr_->vds().data();
+                  T* vec2 = vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec2 + lud.upper_bound;
+
+            while (vec2 < upper_bound)
             {
-               assert(branch(0));
-               assert(branch(1));
+               #define exprtk_loop(N)                          \
+               vec2[N] = Operation::process(vec0[N], vec1[N]); \
 
-               branch(0)->value();
-               branch(1)->value();
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-               const T* vec0 = vec0_node_ptr_->vds().data();
-               const T* vec1 = vec1_node_ptr_->vds().data();
-                     T* vec2 = vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec2 + lud.upper_bound;
-
-               while (vec2 < upper_bound)
-               {
-                  #define exprtk_loop(N)                          \
-                  vec2[N] = Operation::process(vec0[N], vec1[N]); \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec0 += lud.batch_size;
-                  vec1 += lud.batch_size;
-                  vec2 += lud.batch_size;
-               }
-
-               int i = 0;
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                              \
-                  case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return (vds().data())[0];
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+               vec2 += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            int i = 0;
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N)                                              \
+               case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
+               exprtk_fallthrough                                                \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15) case_stmt(14)
+               case_stmt(13) case_stmt(12)
+               case_stmt(11) case_stmt(10)
+               case_stmt( 9) case_stmt( 8)
+               case_stmt( 7) case_stmt( 6)
+               case_stmt( 5) case_stmt( 4)
+               #endif
+               case_stmt( 3) case_stmt( 2)
+               case_stmt( 1)
+               default: break;
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return (vds().data())[0];
          }
 
          vector_node_ptr vec() const exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          vector_node_ptr vec() exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -11409,9 +13698,23 @@ namespace exprtk
             return expression_node<T>::e_vecvecarith;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds_.size();
+            return std::min(
+               vec0_node_ptr_->vec_holder().size(),
+               vec1_node_ptr_->vec_holder().size());
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return std::min(
+               vec0_node_ptr_->vec_holder().base_size(),
+               vec1_node_ptr_->vec_holder().base_size());
          }
 
          vds_t& vds() exprtk_override
@@ -11426,12 +13729,11 @@ namespace exprtk
 
       private:
 
-         vector_node_ptr   vec0_node_ptr_;
-         vector_node_ptr   vec1_node_ptr_;
-         vector_holder_ptr temp_;
-         vector_node_ptr   temp_vec_node_;
-         bool              initialised_;
-         vds_t             vds_;
+         vector_node_ptr vec0_node_ptr_;
+         vector_node_ptr vec1_node_ptr_;
+         bool            initialised_;
+         vds_t           vds_;
+         memory_context  memory_context_;
       };
 
       template <typename T, typename Operation>
@@ -11443,8 +13745,10 @@ namespace exprtk
 
          typedef expression_node<T>* expression_ptr;
          typedef vector_node<T>*     vector_node_ptr;
-         typedef vector_holder<T>*   vector_holder_ptr;
+         typedef vector_holder<T>    vector_holder_t;
+         typedef vector_holder_t*    vector_holder_ptr;
          typedef vec_data_store<T>   vds_t;
+         typedef memory_context_t<T> memory_context;
 
          using binary_node<T>::branch;
 
@@ -11453,8 +13757,6 @@ namespace exprtk
                                expression_ptr branch1)
          : binary_node<T>(opr, branch0, branch1)
          , vec0_node_ptr_(0)
-         , temp_         (0)
-         , temp_vec_node_(0)
          {
             bool v0_is_ivec = false;
 
@@ -11478,93 +13780,84 @@ namespace exprtk
                if (v0_is_ivec)
                   vds() = vec0_node_ptr_->vds();
                else
-                  vds() = vds_t(vec0_node_ptr_->size());
+                  vds() = vds_t(vec0_node_ptr_->base_size());
 
-               temp_          = new vector_holder<T>(vds());
-               temp_vec_node_ = new vector_node  <T>(vds(),temp_);
+               memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds());
             }
+
+            assert(valid());
          }
 
         ~vec_binop_vecval_node()
          {
-            delete temp_;
-            delete temp_vec_node_;
+            memory_context_.clear();
          }
 
          inline T value() const exprtk_override
          {
-            if (vec0_node_ptr_)
+                        branch(0)->value();
+            const T v = branch(1)->value();
+
+            const T* vec0 = vec0_node_ptr_->vds().data();
+                  T* vec1 = vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec0 + lud.upper_bound;
+
+            while (vec0 < upper_bound)
             {
-               assert(branch(0));
-               assert(branch(1));
+               #define exprtk_loop(N)                    \
+               vec1[N] = Operation::process(vec0[N], v); \
 
-                           branch(0)->value();
-               const T v = branch(1)->value();
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-               const T* vec0 = vec0_node_ptr_->vds().data();
-                     T* vec1 = vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec0 + lud.upper_bound;
-
-               while (vec0 < upper_bound)
-               {
-                  #define exprtk_loop(N)                    \
-                  vec1[N] = Operation::process(vec0[N], v); \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec0 += lud.batch_size;
-                  vec1 += lud.batch_size;
-               }
-
-               int i = 0;
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                        \
-                  case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return (vds().data())[0];
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            int i = 0;
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N,fall_through)                           \
+               case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
+               fall_through                                                \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
+               #endif
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return (vds().data())[0];
          }
 
          vector_node_ptr vec() const exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          vector_node_ptr vec() exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -11572,9 +13865,22 @@ namespace exprtk
             return expression_node<T>::e_vecvalarith;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vec0_node_ptr_          &&
+               (size() <= base_size()) &&
+               binary_node<T>::valid();
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return vec0_node_ptr_->size();
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return vec0_node_ptr_->vec_holder().base_size();
          }
 
          vds_t& vds() exprtk_override
@@ -11590,9 +13896,8 @@ namespace exprtk
       private:
 
          vector_node_ptr   vec0_node_ptr_;
-         vector_holder_ptr temp_;
-         vector_node_ptr   temp_vec_node_;
          vds_t             vds_;
+         memory_context    memory_context_;
       };
 
       template <typename T, typename Operation>
@@ -11604,8 +13909,10 @@ namespace exprtk
 
          typedef expression_node<T>* expression_ptr;
          typedef vector_node<T>*     vector_node_ptr;
-         typedef vector_holder<T>*   vector_holder_ptr;
+         typedef vector_holder<T>    vector_holder_t;
+         typedef vector_holder_t*    vector_holder_ptr;
          typedef vec_data_store<T>   vds_t;
+         typedef memory_context_t<T> memory_context;
 
          using binary_node<T>::branch;
 
@@ -11614,8 +13921,6 @@ namespace exprtk
                                expression_ptr branch1)
          : binary_node<T>(opr, branch0, branch1)
          , vec1_node_ptr_(0)
-         , temp_         (0)
-         , temp_vec_node_(0)
          {
             bool v1_is_ivec = false;
 
@@ -11639,93 +13944,84 @@ namespace exprtk
                if (v1_is_ivec)
                   vds() = vec1_node_ptr_->vds();
                else
-                  vds() = vds_t(vec1_node_ptr_->size());
+                  vds() = vds_t(vec1_node_ptr_->base_size());
 
-               temp_          = new vector_holder<T>(vds());
-               temp_vec_node_ = new vector_node  <T>(vds(),temp_);
+               memory_context_ = make_memory_context(vec1_node_ptr_->vec_holder(), vds());
             }
+
+            assert(valid());
          }
 
         ~vec_binop_valvec_node()
          {
-            delete temp_;
-            delete temp_vec_node_;
+            memory_context_.clear();
          }
 
          inline T value() const exprtk_override
          {
-            if (vec1_node_ptr_)
+            const T v = branch(0)->value();
+                        branch(1)->value();
+
+                  T* vec0 = vds().data();
+            const T* vec1 = vec1_node_ptr_->vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec0 + lud.upper_bound;
+
+            while (vec0 < upper_bound)
             {
-               assert(branch(0));
-               assert(branch(1));
+               #define exprtk_loop(N)                    \
+               vec0[N] = Operation::process(v, vec1[N]); \
 
-               const T v = branch(0)->value();
-                           branch(1)->value();
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-                     T* vec0 = vds().data();
-               const T* vec1 = vec1_node_ptr_->vds().data();
-
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec0 + lud.upper_bound;
-
-               while (vec0 < upper_bound)
-               {
-                  #define exprtk_loop(N)                    \
-                  vec0[N] = Operation::process(v, vec1[N]); \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec0 += lud.batch_size;
-                  vec1 += lud.batch_size;
-               }
-
-               int i = 0;
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                        \
-                  case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return (vds().data())[0];
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            int i = 0;
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N,fall_through)                           \
+               case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
+               fall_through                                                \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
+               #endif
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return (vds().data())[0];
          }
 
          vector_node_ptr vec() const exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          vector_node_ptr vec() exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -11733,9 +14029,23 @@ namespace exprtk
             return expression_node<T>::e_vecvalarith;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               vec1_node_ptr_               &&
+               (size() <= base_size())      &&
+               (vds_.size() <= base_size()) &&
+               binary_node<T>::valid();
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return vec1_node_ptr_->vec_holder().size();
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return vec1_node_ptr_->vec_holder().base_size();
          }
 
          vds_t& vds() exprtk_override
@@ -11751,9 +14061,8 @@ namespace exprtk
       private:
 
          vector_node_ptr   vec1_node_ptr_;
-         vector_holder_ptr temp_;
-         vector_node_ptr   temp_vec_node_;
          vds_t             vds_;
+         memory_context    memory_context_;
       };
 
       template <typename T, typename Operation>
@@ -11765,28 +14074,28 @@ namespace exprtk
 
          typedef expression_node<T>* expression_ptr;
          typedef vector_node<T>*     vector_node_ptr;
-         typedef vector_holder<T>*   vector_holder_ptr;
+         typedef vector_holder<T>    vector_holder_t;
+         typedef vector_holder_t*    vector_holder_ptr;
          typedef vec_data_store<T>   vds_t;
+         typedef memory_context_t<T> memory_context;
 
          using expression_node<T>::branch;
 
          unary_vector_node(const operator_type& opr, expression_ptr branch0)
          : unary_node<T>(opr, branch0)
          , vec0_node_ptr_(0)
-         , temp_         (0)
-         , temp_vec_node_(0)
          {
             bool vec0_is_ivec = false;
 
-            if (is_vector_node(branch()))
+            if (is_vector_node(branch(0)))
             {
-               vec0_node_ptr_ = static_cast<vector_node_ptr>(branch());
+               vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
             }
-            else if (is_ivector_node(branch()))
+            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>*>(branch())))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
                {
                   vec0_node_ptr_ = vi->vec();
                   vec0_is_ivec   = true;
@@ -11798,91 +14107,84 @@ namespace exprtk
                if (vec0_is_ivec)
                   vds_ = vec0_node_ptr_->vds();
                else
-                  vds_ = vds_t(vec0_node_ptr_->size());
+                  vds_ = vds_t(vec0_node_ptr_->base_size());
 
-               temp_          = new vector_holder<T>(vds());
-               temp_vec_node_ = new vector_node  <T>(vds(),temp_);
+               memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds());
             }
+
+            assert(valid());
          }
 
         ~unary_vector_node()
          {
-            delete temp_;
-            delete temp_vec_node_;
+            memory_context_.clear();
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch());
-
             branch()->value();
 
-            if (vec0_node_ptr_)
+            const T* vec0 = vec0_node_ptr_->vds().data();
+                  T* vec1 = vds().data();
+
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec0 + lud.upper_bound;
+
+            while (vec0 < upper_bound)
             {
-               const T* vec0 = vec0_node_ptr_->vds().data();
-                     T* vec1 = vds().data();
+               #define exprtk_loop(N)                 \
+               vec1[N] = Operation::process(vec0[N]); \
 
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec0 + lud.upper_bound;
+               exprtk_loop( 0) exprtk_loop( 1)
+               exprtk_loop( 2) exprtk_loop( 3)
+               #ifndef exprtk_disable_superscalar_unroll
+               exprtk_loop( 4) exprtk_loop( 5)
+               exprtk_loop( 6) exprtk_loop( 7)
+               exprtk_loop( 8) exprtk_loop( 9)
+               exprtk_loop(10) exprtk_loop(11)
+               exprtk_loop(12) exprtk_loop(13)
+               exprtk_loop(14) exprtk_loop(15)
+               #endif
 
-               while (vec0 < upper_bound)
-               {
-                  #define exprtk_loop(N)                 \
-                  vec1[N] = Operation::process(vec0[N]); \
-
-                  exprtk_loop( 0) exprtk_loop( 1)
-                  exprtk_loop( 2) exprtk_loop( 3)
-                  #ifndef exprtk_disable_superscalar_unroll
-                  exprtk_loop( 4) exprtk_loop( 5)
-                  exprtk_loop( 6) exprtk_loop( 7)
-                  exprtk_loop( 8) exprtk_loop( 9)
-                  exprtk_loop(10) exprtk_loop(11)
-                  exprtk_loop(12) exprtk_loop(13)
-                  exprtk_loop(14) exprtk_loop(15)
-                  #endif
-
-                  vec0 += lud.batch_size;
-                  vec1 += lud.batch_size;
-               }
-
-               int i = 0;
-
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                     \
-                  case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
-
-                  #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(15) case_stmt(14)
-                  case_stmt(13) case_stmt(12)
-                  case_stmt(11) case_stmt(10)
-                  case_stmt( 9) case_stmt( 8)
-                  case_stmt( 7) case_stmt( 6)
-                  case_stmt( 5) case_stmt( 4)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
-
-               #undef exprtk_loop
-               #undef case_stmt
-
-               return (vds().data())[0];
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            int i = 0;
+
+            switch (lud.remainder)
+            {
+               #define case_stmt(N)                                     \
+               case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
+               exprtk_fallthrough                                       \
+
+               #ifndef exprtk_disable_superscalar_unroll
+               case_stmt(15) case_stmt(14)
+               case_stmt(13) case_stmt(12)
+               case_stmt(11) case_stmt(10)
+               case_stmt( 9) case_stmt( 8)
+               case_stmt( 7) case_stmt( 6)
+               case_stmt( 5) case_stmt( 4)
+               #endif
+               case_stmt( 3) case_stmt( 2)
+               case_stmt( 1)
+               default: break;
+            }
+
+            #undef exprtk_loop
+            #undef case_stmt
+
+            return (vds().data())[0];
          }
 
          vector_node_ptr vec() const exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          vector_node_ptr vec() exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -11890,9 +14192,19 @@ namespace exprtk
             return expression_node<T>::e_vecunaryop;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return vec0_node_ptr_ && unary_node<T>::valid();
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vds().size();
+            return vec0_node_ptr_->vec_holder().size();
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return vec0_node_ptr_->vec_holder().base_size();
          }
 
          vds_t& vds() exprtk_override
@@ -11907,10 +14219,9 @@ namespace exprtk
 
       private:
 
-         vector_node_ptr   vec0_node_ptr_;
-         vector_holder_ptr temp_;
-         vector_node_ptr   temp_vec_node_;
-         vds_t             vds_;
+         vector_node_ptr vec0_node_ptr_;
+         vds_t           vds_;
+         memory_context  memory_context_;
       };
 
       template <typename T>
@@ -11923,8 +14234,10 @@ namespace exprtk
          typedef expression_node <T>* expression_ptr;
          typedef vector_interface<T>* vec_interface_ptr;
          typedef vector_node     <T>* vector_node_ptr;
-         typedef vector_holder   <T>* vector_holder_ptr;
+         typedef vector_holder   <T>  vector_holder_t;
+         typedef vector_holder_t*     vector_holder_ptr;
          typedef vec_data_store  <T>  vds_t;
+         typedef memory_context_t<T> memory_context;
          typedef std::pair<expression_ptr,bool> branch_t;
 
          conditional_vector_node(expression_ptr condition,
@@ -11934,7 +14247,7 @@ namespace exprtk
          , alternative_node_ptr_(0)
          , temp_vec_node_       (0)
          , temp_                (0)
-         , vec_size_            (0)
+         , result_vec_size_     (0)
          , initialised_         (false)
          {
             construct_branch_pair(condition_  , condition  );
@@ -11963,67 +14276,62 @@ namespace exprtk
 
             if (consequent_node_ptr_ && alternative_node_ptr_)
             {
-               vec_size_ = std::min(consequent_node_ptr_ ->vds().size(),
-                                    alternative_node_ptr_->vds().size());
+               const std::size_t vec_size =
+                  std::max(consequent_node_ptr_ ->vec_holder().base_size(),
+                           alternative_node_ptr_->vec_holder().base_size());
 
-               vds_           = vds_t(vec_size_);
-               temp_          = new vector_holder<T>(vds_);
-               temp_vec_node_ = new vector_node  <T>(vds(),temp_);
+               vds_            = vds_t(vec_size);
+               memory_context_ = make_memory_context(
+                  consequent_node_ptr_ ->vec_holder(),
+                  alternative_node_ptr_->vec_holder(),
+                  vds());
 
-               initialised_ = true;
+               initialised_ = (vec_size > 0);
             }
 
-            assert(initialised_ && (vec_size_ > 0));
+            assert(initialised_);
          }
 
         ~conditional_vector_node()
          {
-            delete temp_;
-            delete temp_vec_node_;
+            memory_context_.clear();
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
+            T result = T(0);
+            T* source_vector = 0;
+            T* result_vector = vds().data();
+
+            if (is_true(condition_))
             {
-               assert(condition_  .first);
-               assert(consequent_ .first);
-               assert(alternative_.first);
-
-               T result = T(0);
-               T* source_vector = 0;
-               T* result_vector = vds().data();
-
-               if (is_true(condition_))
-               {
-                  result        = consequent_.first->value();
-                  source_vector = consequent_node_ptr_->vds().data();
-               }
-               else
-               {
-                  result        = alternative_.first->value();
-                  source_vector = alternative_node_ptr_->vds().data();
-               }
-
-               for (std::size_t i = 0; i < vec_size_; ++i)
-               {
-                  result_vector[i] = source_vector[i];
-               }
-
-               return result;
+               result           = consequent_.first->value();
+               source_vector    = consequent_node_ptr_->vds().data();
+               result_vec_size_ = consequent_node_ptr_->size();
+            }
+            else
+            {
+               result           = alternative_.first->value();
+               source_vector    = alternative_node_ptr_->vds().data();
+               result_vec_size_ = alternative_node_ptr_->size();
             }
 
-            return std::numeric_limits<T>::quiet_NaN();
+            for (std::size_t i = 0; i < result_vec_size_; ++i)
+            {
+               result_vector[i] = source_vector[i];
+            }
+
+            return result;
          }
 
          vector_node_ptr vec() const exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          vector_node_ptr vec() exprtk_override
          {
-            return temp_vec_node_;
+            return memory_context_.temp_vec_node_;
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -12031,9 +14339,26 @@ namespace exprtk
             return expression_node<T>::e_vecondition;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return
+               initialised_                                      &&
+               condition_  .first && condition_  .first->valid() &&
+               consequent_ .first && consequent_ .first->valid() &&
+               alternative_.first && alternative_.first->valid() &&
+               size() <= base_size();
+         }
+
          std::size_t size() const exprtk_override
          {
-            return vec_size_;
+            return result_vec_size_;
+         }
+
+         std::size_t base_size() const exprtk_override
+         {
+            return std::min(
+               consequent_node_ptr_ ->vec_holder().base_size(),
+               alternative_node_ptr_->vec_holder().base_size());
          }
 
          vds_t& vds() exprtk_override
@@ -12061,16 +14386,17 @@ namespace exprtk
 
       private:
 
-         branch_t condition_;
-         branch_t consequent_;
-         branch_t alternative_;
-         vector_node_ptr   consequent_node_ptr_;
-         vector_node_ptr   alternative_node_ptr_;
-         vector_node_ptr   temp_vec_node_;
-         vector_holder_ptr temp_;
-         vds_t vds_;
-         std::size_t vec_size_;
-         bool        initialised_;
+         branch_t            condition_;
+         branch_t            consequent_;
+         branch_t            alternative_;
+         vector_node_ptr     consequent_node_ptr_;
+         vector_node_ptr     alternative_node_ptr_;
+         vector_node_ptr     temp_vec_node_;
+         vector_holder_ptr   temp_;
+         vds_t               vds_;
+         mutable std::size_t result_vec_size_;
+         bool                initialised_;
+         memory_context      memory_context_;
       };
 
       template <typename T>
@@ -12085,13 +14411,12 @@ namespace exprtk
                     expression_ptr branch0,
                     expression_ptr branch1)
          : binary_node<T>(opr, branch0, branch1)
-         {}
+         {
+            assert(binary_node<T>::valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(branch(0));
-            assert(branch(1));
-
             return (
                      std::not_equal_to<T>()
                         (T(0),branch(0)->value()) &&
@@ -12113,13 +14438,12 @@ namespace exprtk
                    expression_ptr branch0,
                    expression_ptr branch1)
          : binary_node<T>(opr, branch0, branch1)
-         {}
+         {
+            assert(binary_node<T>::valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(branch(0));
-            assert(branch(1));
-
             return (
                      std::not_equal_to<T>()
                         (T(0),branch(0)->value()) ||
@@ -12134,7 +14458,7 @@ namespace exprtk
       {
       public:
 
-         // Function of N paramters.
+         // Function of N parameters.
          typedef expression_node<T>* expression_ptr;
          typedef std::pair<expression_ptr,bool> branch_t;
          typedef IFunction ifunction;
@@ -12142,6 +14466,7 @@ namespace exprtk
          explicit function_N_node(ifunction* func)
          : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
          , parameter_count_(func->param_count)
+         , initialised_(false)
          {}
 
          template <std::size_t NumBranches>
@@ -12152,19 +14477,24 @@ namespace exprtk
              #pragma warning(push)
              #pragma warning(disable: 4127)
             #endif
+
             if (N != NumBranches)
-               return false;
-            else
             {
-               for (std::size_t i = 0; i < NumBranches; ++i)
-               {
-                  if (b[i])
-                     branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
-                  else
-                     return false;
-               }
-               return true;
+               return false;
             }
+
+            for (std::size_t i = 0; i < NumBranches; ++i)
+            {
+               if (b[i] && b[i]->valid())
+                  branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
+               else
+                  return false;
+            }
+
+            initialised_ = function_;
+            assert(valid());
+            return initialised_;
+
             #ifdef _MSC_VER
              #pragma warning(pop)
             #endif
@@ -12182,14 +14512,11 @@ namespace exprtk
              #pragma warning(push)
              #pragma warning(disable: 4127)
             #endif
-            if ((0 == function_) || (0 == N))
-               return std::numeric_limits<T>::quiet_NaN();
-            else
-            {
-               T v[N];
-               evaluate_branches<T,N>::execute(v,branch_);
-               return invoke<T,N>::execute(*function_,v);
-            }
+
+            T v[N];
+            evaluate_branches<T,N>::execute(v,branch_);
+            return invoke<T,N>::execute(*function_,v);
+
             #ifdef _MSC_VER
              #pragma warning(pop)
             #endif
@@ -12200,9 +14527,14 @@ namespace exprtk
             return expression_node<T>::e_function;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -12222,6 +14554,20 @@ namespace exprtk
             }
          };
 
+         template <typename T_>
+         struct evaluate_branches <T_,6>
+         {
+            static inline void execute(T_ (&v)[6], const branch_t (&b)[6])
+            {
+               v[0] = b[0].first->value();
+               v[1] = b[1].first->value();
+               v[2] = b[2].first->value();
+               v[3] = b[3].first->value();
+               v[4] = b[4].first->value();
+               v[5] = b[5].first->value();
+            }
+         };
+
          template <typename T_>
          struct evaluate_branches <T_,5>
          {
@@ -12425,6 +14771,7 @@ namespace exprtk
          ifunction*  function_;
          std::size_t parameter_count_;
          branch_t    branch_[N];
+         bool        initialised_;
       };
 
       template <typename T, typename IFunction>
@@ -12437,7 +14784,9 @@ namespace exprtk
 
          explicit function_N_node(ifunction* func)
          : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
-         {}
+         {
+            assert(valid());
+         }
 
          inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
          {
@@ -12446,10 +14795,7 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (function_)
-               return (*function_)();
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return (*function_)();
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -12457,6 +14803,11 @@ namespace exprtk
             return expression_node<T>::e_function;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return function_;
+         }
+
       private:
 
          ifunction* function_;
@@ -12475,6 +14826,7 @@ namespace exprtk
          , arg_list_(arg_list)
          {
             value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
+            assert(valid());
          }
 
          inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
@@ -12484,13 +14836,8 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (function_)
-            {
-               populate_value_list();
-               return (*function_)(value_list_);
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            populate_value_list();
+            return (*function_)(value_list_);
          }
 
          inline typename expression_node<T>::node_type type() const exprtk_override
@@ -12498,6 +14845,11 @@ namespace exprtk
             return expression_node<T>::e_vafunction;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return function_;
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             for (std::size_t i = 0; i < arg_list_.size(); ++i)
@@ -12545,7 +14897,8 @@ namespace exprtk
          typedef typename range_interface<T>::range_t range_t;
 
          typedef std::pair<expression_ptr,bool> branch_t;
-         typedef std::pair<void*,std::size_t>   void_t;
+         typedef vector_holder<T>* vh_t;
+         typedef vector_view<T>*   vecview_t;
 
          typedef std::vector<T>                 tmp_vs_t;
          typedef std::vector<type_store_t>      typestore_list_t;
@@ -12557,7 +14910,18 @@ namespace exprtk
          , arg_list_(arg_list)
          {}
 
-         virtual ~generic_function_node() {}
+         virtual ~generic_function_node()
+         {
+            for (std::size_t i = 0; i < vv_list_.size(); ++i)
+            {
+               vecview_t& vv = vv_list_[i];
+               if (vv && typestore_list_[i].vec_data)
+               {
+                  vv->remove_ref(&typestore_list_[i].vec_data);
+                  typestore_list_[i].vec_data = 0;
+               }
+            }
+         }
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
@@ -12571,10 +14935,11 @@ namespace exprtk
 
          virtual bool init_branches()
          {
-            expr_as_vec1_store_.resize(arg_list_.size(),T(0)               );
-            typestore_list_    .resize(arg_list_.size(),type_store_t()     );
-            range_list_        .resize(arg_list_.size(),range_data_type_t());
-            branch_            .resize(arg_list_.size(),branch_t(reinterpret_cast<expression_ptr>(0),false));
+            expr_as_vec1_store_.resize(arg_list_.size(), T(0)               );
+            typestore_list_    .resize(arg_list_.size(), type_store_t()     );
+            range_list_        .resize(arg_list_.size(), range_data_type_t());
+            branch_            .resize(arg_list_.size(), branch_t(reinterpret_cast<expression_ptr>(0),false));
+            vv_list_           .resize(arg_list_.size(), vecview_t(0));
 
             for (std::size_t i = 0; i < arg_list_.size(); ++i)
             {
@@ -12592,7 +14957,15 @@ namespace exprtk
                   ts.size = vi->size();
                   ts.data = vi->vds().data();
                   ts.type = type_store_t::e_vector;
-                  vi->vec()->vec_holder().set_ref(&ts.vec_data);
+
+                  if (
+                       vi->vec()->vec_holder().rebaseable() &&
+                       vi->vec()->vec_holder().rebaseable_instance()
+                     )
+                  {
+                     vv_list_[i] = vi->vec()->vec_holder().rebaseable_instance();
+                     vv_list_[i]->set_ref(&ts.vec_data);
+                  }
                }
                #ifndef exprtk_disable_string_capabilities
                else if (is_generally_string_node(arg_list_[i]))
@@ -12628,7 +15001,10 @@ namespace exprtk
                      range_list_[i].range = reinterpret_cast<range_t*>(0);
                   }
                   else
+                  {
                      range_list_[i].range = &(ri->range_ref());
+                     range_param_list_.push_back(i);
+                  }
                }
                #endif
                else if (is_variable_node(arg_list_[i]))
@@ -12662,14 +15038,11 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (function_)
+            if (populate_value_list())
             {
-               if (populate_value_list())
-               {
-                  typedef typename GenericFunction::parameter_list_t parameter_list_t;
+               typedef typename GenericFunction::parameter_list_t parameter_list_t;
 
-                  return (*function_)(parameter_list_t(typestore_list_));
-               }
+               return (*function_)(parameter_list_t(typestore_list_));
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -12680,6 +15053,11 @@ namespace exprtk
             return expression_node<T>::e_genfunction;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return function_;
+         }
+
       protected:
 
          inline virtual bool populate_value_list() const
@@ -12689,30 +15067,40 @@ namespace exprtk
                expr_as_vec1_store_[i] = branch_[i].first->value();
             }
 
-            for (std::size_t i = 0; i < branch_.size(); ++i)
+            if (!range_param_list_.empty())
             {
-               range_data_type_t& rdt = range_list_[i];
+               assert(range_param_list_.size() <= branch_.size());
 
-               if (rdt.range)
+               for (std::size_t i = 0; i < range_param_list_.size(); ++i)
                {
+                  const std::size_t  index = range_param_list_[i];
+                  range_data_type_t& rdt   = range_list_[index];
+
                   const range_t& rp = (*rdt.range);
                   std::size_t r0    = 0;
                   std::size_t r1    = 0;
 
-                  if (rp(r0, r1, rdt.size))
-                  {
-                     type_store_t& ts = typestore_list_[i];
+                  const std::size_t data_size =
+                  #ifndef exprtk_disable_string_capabilities
+                     rdt.str_node ? rdt.str_node->size() : rdt.size;
+                  #else
+                     rdt.size;
+                  #endif
 
-                     ts.size = rp.cache_size();
-                     #ifndef exprtk_disable_string_capabilities
-                     if (ts.type == type_store_t::e_string)
-                        ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
-                     else
-                     #endif
-                        ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
-                  }
-                  else
+                  if (!rp(r0, r1, data_size))
+                  {
                      return false;
+                  }
+
+                  type_store_t& ts = typestore_list_[index];
+
+                  ts.size = rp.cache_size();
+                  #ifndef exprtk_disable_string_capabilities
+                  if (ts.type == type_store_t::e_string)
+                     ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
+                  else
+                  #endif
+                     ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
                }
             }
 
@@ -12725,16 +15113,18 @@ namespace exprtk
       private:
 
          std::vector<expression_ptr> arg_list_;
-         std::vector<branch_t>         branch_;
-         mutable tmp_vs_t  expr_as_vec1_store_;
-         mutable range_list_t      range_list_;
+         std::vector<branch_t>       branch_;
+         std::vector<vecview_t>      vv_list_;
+         mutable tmp_vs_t            expr_as_vec1_store_;
+         mutable range_list_t        range_list_;
+         std::vector<std::size_t>    range_param_list_;
       };
 
       #ifndef exprtk_disable_string_capabilities
       template <typename T, typename StringFunction>
-      class string_function_node : public generic_function_node<T,StringFunction>,
-                                   public string_base_node<T>,
-                                   public range_interface <T>
+      class string_function_node : public generic_function_node<T,StringFunction>
+                                 , public string_base_node<T>
+                                 , public range_interface <T>
       {
       public:
 
@@ -12749,6 +15139,7 @@ namespace exprtk
             range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
             range_.cache.first  = range_.n0_c.second;
             range_.cache.second = range_.n1_c.second;
+            assert(valid());
          }
 
          inline bool operator <(const string_function_node<T,StringFunction>& fn) const
@@ -12758,23 +15149,21 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (gen_function_t::function_)
+            if (gen_function_t::populate_value_list())
             {
-               if (gen_function_t::populate_value_list())
-               {
-                  typedef typename StringFunction::parameter_list_t parameter_list_t;
+               typedef typename StringFunction::parameter_list_t parameter_list_t;
 
-                  const T result = (*gen_function_t::function_)
-                                      (
-                                        ret_string_,
-                                        parameter_list_t(gen_function_t::typestore_list_)
-                                      );
+               const T result =
+                  (*gen_function_t::function_)
+                  (
+                     ret_string_,
+                     parameter_list_t(gen_function_t::typestore_list_)
+                  );
 
-                  range_.n1_c.second  = ret_string_.size() - 1;
-                  range_.cache.second = range_.n1_c.second;
+               range_.n1_c.second  = ret_string_.size();
+               range_.cache.second = range_.n1_c.second;
 
-                  return result;
-               }
+               return result;
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -12785,6 +15174,11 @@ namespace exprtk
             return expression_node<T>::e_strfunction;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return gen_function_t::function_;
+         }
+
          std::string str() const exprtk_override
          {
             return ret_string_;
@@ -12834,18 +15228,18 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (gen_function_t::function_)
-            {
-               if (gen_function_t::populate_value_list())
-               {
-                  typedef typename GenericFunction::parameter_list_t parameter_list_t;
+            assert(gen_function_t::valid());
 
-                  return (*gen_function_t::function_)
-                            (
-                              param_seq_index_,
-                              parameter_list_t(gen_function_t::typestore_list_)
-                            );
-               }
+            if (gen_function_t::populate_value_list())
+            {
+               typedef typename GenericFunction::parameter_list_t parameter_list_t;
+
+               return
+                  (*gen_function_t::function_)
+                  (
+                     param_seq_index_,
+                     parameter_list_t(gen_function_t::typestore_list_)
+                  );
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -12879,24 +15273,22 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (str_function_t::function_)
+            if (str_function_t::populate_value_list())
             {
-               if (str_function_t::populate_value_list())
-               {
-                  typedef typename StringFunction::parameter_list_t parameter_list_t;
+               typedef typename StringFunction::parameter_list_t parameter_list_t;
 
-                  const T result = (*str_function_t::function_)
-                                      (
-                                        param_seq_index_,
-                                        str_function_t::ret_string_,
-                                        parameter_list_t(str_function_t::typestore_list_)
-                                      );
+               const T result =
+                  (*str_function_t::function_)
+                  (
+                     param_seq_index_,
+                     str_function_t::ret_string_,
+                     parameter_list_t(str_function_t::typestore_list_)
+                  );
 
-                  str_function_t::range_.n1_c.second  = str_function_t::ret_string_.size() - 1;
-                  str_function_t::range_.cache.second = str_function_t::range_.n1_c.second;
+               str_function_t::range_.n1_c.second  = str_function_t::ret_string_.size();
+               str_function_t::range_.cache.second = str_function_t::range_.n1_c.second;
 
-                  return result;
-               }
+               return result;
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -12913,15 +15305,15 @@ namespace exprtk
       };
       #endif
 
-      class return_exception
-      {};
+      class return_exception {};
 
       template <typename T>
       class null_igenfunc
       {
       public:
 
-         virtual ~null_igenfunc() {}
+         virtual ~null_igenfunc()
+         {}
 
          typedef type_store<T> generic_type;
          typedef typename generic_type::parameter_list parameter_list_t;
@@ -12947,14 +15339,13 @@ namespace exprtk
                      results_context_t& rc)
          : gen_function_t  (arg_list)
          , results_context_(&rc)
-         {}
+         {
+            assert(valid());
+         }
 
          inline T value() const exprtk_override
          {
-            if (
-                 (0 != results_context_) &&
-                 gen_function_t::populate_value_list()
-               )
+            if (gen_function_t::populate_value_list())
             {
                typedef typename type_store<T>::parameter_list parameter_list_t;
 
@@ -12972,6 +15363,11 @@ namespace exprtk
             return expression_node<T>::e_return;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return results_context_;
+         }
+
       private:
 
          results_context_t* results_context_;
@@ -12991,12 +15387,11 @@ namespace exprtk
          , return_invoked_ (false)
          {
             construct_branch_pair(body_, body);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(body_.first);
-
             try
             {
                return_invoked_ = false;
@@ -13007,6 +15402,7 @@ namespace exprtk
             catch(const return_exception&)
             {
                return_invoked_ = true;
+
                return std::numeric_limits<T>::quiet_NaN();
             }
          }
@@ -13016,6 +15412,11 @@ namespace exprtk
             return expression_node<T>::e_retenv;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return results_context_ && body_.first;
+         }
+
          inline bool* retinvk_ptr()
          {
             return &return_invoked_;
@@ -13400,7 +15801,7 @@ namespace exprtk
       }
 
       template <typename T>
-      struct vararg_add_op : public opr_base<T>
+      struct vararg_add_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13423,7 +15824,7 @@ namespace exprtk
 
                             for (std::size_t i = 0; i < arg_list.size(); ++i)
                             {
-                              result += value(arg_list[i]);
+                               result += value(arg_list[i]);
                             }
 
                             return result;
@@ -13467,7 +15868,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_mul_op : public opr_base<T>
+      struct vararg_mul_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13534,7 +15935,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_avg_op : public opr_base<T>
+      struct vararg_avg_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13590,7 +15991,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_min_op : public opr_base<T>
+      struct vararg_min_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13661,7 +16062,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_max_op : public opr_base<T>
+      struct vararg_max_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13732,7 +16133,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_mand_op : public opr_base<T>
+      struct vararg_mand_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13812,7 +16213,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_mor_op : public opr_base<T>
+      struct vararg_mor_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13892,7 +16293,7 @@ namespace exprtk
       };
 
       template <typename T>
-      struct vararg_multi_op : public opr_base<T>
+      struct vararg_multi_op exprtk_final : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
 
@@ -13913,14 +16314,13 @@ namespace exprtk
                case 7  : return process_7(arg_list);
                case 8  : return process_8(arg_list);
                default :
-                         {
-                            for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
-                            {
-                               value(arg_list[i]);
-                            }
-
-                            return value(arg_list.back());
-                         }
+                        {
+                           for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
+                           {
+                              value(arg_list[i]);
+                           }
+                           return value(arg_list.back());
+                        }
             }
          }
 
@@ -14009,7 +16409,7 @@ namespace exprtk
          static inline T process(const ivector_ptr v)
          {
             const T* vec = v->vec()->vds().data();
-            const std::size_t vec_size = v->vec()->vds().size();
+            const std::size_t vec_size = v->size();
 
             loop_unroll::details lud(vec_size);
 
@@ -14018,24 +16418,24 @@ namespace exprtk
                T result = T(0);
                int i    = 0;
 
-               exprtk_disable_fallthrough_begin
                switch (vec_size)
                {
-                  #define case_stmt(N)         \
-                  case N : result += vec[i++]; \
+                  #define case_stmt(N,fall_through) \
+                  case N : result += vec[i++];      \
+                  fall_through                      \
 
                   #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(16) case_stmt(15)
-                  case_stmt(14) case_stmt(13)
-                  case_stmt(12) case_stmt(11)
-                  case_stmt(10) case_stmt( 9)
-                  case_stmt( 8) case_stmt( 7)
-                  case_stmt( 6) case_stmt( 5)
+                  case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough)
+                  case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough)
+                  case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough)
+                  case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough)
+                  case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough)
+                  case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough)
+
                   #endif
-                  case_stmt( 4) case_stmt( 3)
-                  case_stmt( 2) case_stmt( 1)
+                  case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough)
+                  case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;)
                }
-               exprtk_disable_fallthrough_end
 
                #undef case_stmt
 
@@ -14070,24 +16470,23 @@ namespace exprtk
 
             int i = 0;
 
-            exprtk_disable_fallthrough_begin
             switch (lud.remainder)
             {
-               #define case_stmt(N)       \
-               case N : r[0] += vec[i++]; \
+               #define case_stmt(N,fall_through) \
+               case N : r[0] += vec[i++];        \
+               fall_through                      \
 
                #ifndef exprtk_disable_superscalar_unroll
-               case_stmt(15) case_stmt(14)
-               case_stmt(13) case_stmt(12)
-               case_stmt(11) case_stmt(10)
-               case_stmt( 9) case_stmt( 8)
-               case_stmt( 7) case_stmt( 6)
-               case_stmt( 5) case_stmt( 4)
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
                #endif
-               case_stmt( 3) case_stmt( 2)
-               case_stmt( 1)
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
             }
-            exprtk_disable_fallthrough_end
 
             #undef exprtk_loop
             #undef case_stmt
@@ -14110,7 +16509,7 @@ namespace exprtk
          static inline T process(const ivector_ptr v)
          {
             const T* vec = v->vec()->vds().data();
-            const std::size_t vec_size = v->vec()->vds().size();
+            const std::size_t vec_size = v->vec()->size();
 
             loop_unroll::details lud(vec_size);
 
@@ -14119,24 +16518,23 @@ namespace exprtk
                T result = T(1);
                int i    = 0;
 
-               exprtk_disable_fallthrough_begin
                switch (vec_size)
                {
-                  #define case_stmt(N)         \
-                  case N : result *= vec[i++]; \
+                  #define case_stmt(N,fall_through) \
+                  case N : result *= vec[i++];      \
+                  fall_through                      \
 
                   #ifndef exprtk_disable_superscalar_unroll
-                  case_stmt(16) case_stmt(15)
-                  case_stmt(14) case_stmt(13)
-                  case_stmt(12) case_stmt(11)
-                  case_stmt(10) case_stmt( 9)
-                  case_stmt( 8) case_stmt( 7)
-                  case_stmt( 6) case_stmt( 5)
+                  case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough)
+                  case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough)
+                  case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough)
+                  case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough)
+                  case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough)
+                  case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough)
                   #endif
-                  case_stmt( 4) case_stmt( 3)
-                  case_stmt( 2) case_stmt( 1)
+                  case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough)
+                  case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;)
                }
-               exprtk_disable_fallthrough_end
 
                #undef case_stmt
 
@@ -14171,33 +16569,32 @@ namespace exprtk
 
             int i = 0;
 
-            exprtk_disable_fallthrough_begin
             switch (lud.remainder)
             {
-               #define case_stmt(N)       \
-               case N : r[0] *= vec[i++]; \
+               #define case_stmt(N,fall_through) \
+               case N : r[0] *= vec[i++];        \
+               fall_through                      \
 
                #ifndef exprtk_disable_superscalar_unroll
-               case_stmt(15) case_stmt(14)
-               case_stmt(13) case_stmt(12)
-               case_stmt(11) case_stmt(10)
-               case_stmt( 9) case_stmt( 8)
-               case_stmt( 7) case_stmt( 6)
-               case_stmt( 5) case_stmt( 4)
+               case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough)
+               case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough)
+               case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough)
+               case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough)
+               case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough)
+               case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough)
                #endif
-               case_stmt( 3) case_stmt( 2)
-               case_stmt( 1)
+               case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough)
+               case_stmt( 1, (void)0;)
             }
-            exprtk_disable_fallthrough_end
 
             #undef exprtk_loop
             #undef case_stmt
 
             return (r[ 0] * r[ 1] * r[ 2] * r[ 3])
                    #ifndef exprtk_disable_superscalar_unroll
-                 + (r[ 4] * r[ 5] * r[ 6] * r[ 7])
-                 + (r[ 8] * r[ 9] * r[10] * r[11])
-                 + (r[12] * r[13] * r[14] * r[15])
+                 * (r[ 4] * r[ 5] * r[ 6] * r[ 7])
+                 * (r[ 8] * r[ 9] * r[10] * r[11])
+                 * (r[12] * r[13] * r[14] * r[15])
                    #endif
                    ;
          }
@@ -14210,7 +16607,7 @@ namespace exprtk
 
          static inline T process(const ivector_ptr v)
          {
-            const T vec_size = T(v->vec()->vds().size());
+            const T vec_size = T(v->vec()->size());
             return vec_add_op<T>::process(v) / vec_size;
          }
       };
@@ -14223,7 +16620,7 @@ namespace exprtk
          static inline T process(const ivector_ptr v)
          {
             const T* vec = v->vec()->vds().data();
-            const std::size_t vec_size = v->vec()->vds().size();
+            const std::size_t vec_size = v->vec()->size();
 
             T result = vec[0];
 
@@ -14247,7 +16644,7 @@ namespace exprtk
          static inline T process(const ivector_ptr v)
          {
             const T* vec = v->vec()->vds().data();
-            const std::size_t vec_size = v->vec()->vds().size();
+            const std::size_t vec_size = v->vec()->size();
 
             T result = vec[0];
 
@@ -14268,7 +16665,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~vov_base_node() {}
+         virtual ~vov_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14285,7 +16683,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~cov_base_node() {}
+         virtual ~cov_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14302,7 +16701,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~voc_base_node() {}
+         virtual ~voc_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14319,7 +16719,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~vob_base_node() {}
+         virtual ~vob_base_node()
+         {}
 
          virtual const T& v() const = 0;
       };
@@ -14329,7 +16730,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~bov_base_node() {}
+         virtual ~bov_base_node()
+         {}
 
          virtual const T& v() const = 0;
       };
@@ -14339,7 +16741,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~cob_base_node() {}
+         virtual ~cob_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14358,7 +16761,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~boc_base_node() {}
+         virtual ~boc_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14377,7 +16781,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~uv_base_node() {}
+         virtual ~uv_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14392,7 +16797,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~sos_base_node() {}
+         virtual ~sos_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14405,7 +16811,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~sosos_base_node() {}
+         virtual ~sosos_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14418,7 +16825,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~T0oT1oT2_base_node() {}
+         virtual ~T0oT1oT2_base_node()
+         {}
 
          virtual std::string type_id() const = 0;
       };
@@ -14428,7 +16836,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~T0oT1oT2oT3_base_node() {}
+         virtual ~T0oT1oT2oT3_base_node()
+         {}
 
          virtual std::string type_id() const = 0;
       };
@@ -14564,6 +16973,11 @@ namespace exprtk
             return Operation::type();
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline operator_type operation()
          {
             return Operation::operation();
@@ -15186,7 +17600,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~sf3ext_type_node() {}
+         virtual ~sf3ext_type_node()
+         {}
 
          virtual T0 t0() const = 0;
 
@@ -15644,16 +18059,16 @@ namespace exprtk
          typedef std::pair<expression_ptr,bool> branch_t;
          typedef Operation operation_t;
 
-         // variable op constant node
+         // variable op binary node
          explicit vob_node(const T& var, const expression_ptr branch)
          : v_(var)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
             return Operation::process(v_,branch_.first->value());
          }
 
@@ -15662,6 +18077,11 @@ namespace exprtk
             return v_;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline expression_node<T>* branch(const std::size_t&) const exprtk_override
          {
             return branch_.first;
@@ -15669,7 +18089,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -15695,16 +18115,16 @@ namespace exprtk
          typedef std::pair<expression_ptr,bool> branch_t;
          typedef Operation operation_t;
 
-         // variable op constant node
+         // binary node op variable node
          explicit bov_node(const expression_ptr branch, const T& var)
          : v_(var)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
             return Operation::process(branch_.first->value(),v_);
          }
 
@@ -15713,6 +18133,11 @@ namespace exprtk
             return v_;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline expression_node<T>* branch(const std::size_t&) const exprtk_override
          {
             return branch_.first;
@@ -15720,7 +18145,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -15746,16 +18171,16 @@ namespace exprtk
          typedef std::pair<expression_ptr,bool> branch_t;
          typedef Operation operation_t;
 
-         // variable op constant node
+         // constant op variable node
          explicit cob_node(const T const_var, const expression_ptr branch)
          : c_(const_var)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
             return Operation::process(c_,branch_.first->value());
          }
 
@@ -15774,6 +18199,11 @@ namespace exprtk
             (*const_cast<T*>(&c_)) = new_c;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline expression_node<T>* branch(const std::size_t&) const exprtk_override
          {
             return branch_.first;
@@ -15787,7 +18217,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -15813,16 +18243,16 @@ namespace exprtk
          typedef std::pair<expression_ptr,bool> branch_t;
          typedef Operation operation_t;
 
-         // variable op constant node
+         // binary node op constant node
          explicit boc_node(const expression_ptr branch, const T const_var)
          : c_(const_var)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
             return Operation::process(branch_.first->value(),c_);
          }
 
@@ -15841,6 +18271,11 @@ namespace exprtk
             (*const_cast<T*>(&c_)) = new_c;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline expression_node<T>* branch(const std::size_t&) const exprtk_override
          {
             return branch_.first;
@@ -15854,7 +18289,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -16013,7 +18448,13 @@ namespace exprtk
             std::size_t r1 = 0;
 
             if (rp1_(r0, r1, s1_.size()))
-               return Operation::process(s0_, s1_.substr(r0, (r1 - r0) + 1));
+            {
+               return Operation::process
+                      (
+                         s0_,
+                         s1_.substr(r0, (r1 - r0) + 1)
+                      );
+            }
             else
                return T(0);
          }
@@ -16085,10 +18526,11 @@ namespace exprtk
                  rp1_(r0_1, r1_1, s1_.size())
                )
             {
-               return Operation::process(
-                                          s0_.substr(r0_0, (r1_0 - r0_0) + 1),
-                                          s1_.substr(r0_1, (r1_1 - r0_1) + 1)
-                                        );
+               return Operation::process
+                      (
+                         s0_.substr(r0_0, (r1_0 - r0_0) + 1),
+                         s1_.substr(r0_1, (r1_1 - r0_1) + 1)
+                      );
             }
             else
                return T(0);
@@ -16149,6 +18591,7 @@ namespace exprtk
          , str1_base_ptr_ (0)
          , str0_range_ptr_(0)
          , str1_range_ptr_(0)
+         , initialised_   (false)
          {
             if (is_generally_string_node(branch(0)))
             {
@@ -16179,39 +18622,40 @@ namespace exprtk
 
                str1_range_ptr_ = &(range->range_ref());
             }
+
+            initialised_ =
+               str0_base_ptr_  &&
+               str1_base_ptr_  &&
+               str0_range_ptr_ &&
+               str1_range_ptr_;
+
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
+            branch(0)->value();
+            branch(1)->value();
+
+            std::size_t str0_r0 = 0;
+            std::size_t str0_r1 = 0;
+
+            std::size_t str1_r0 = 0;
+            std::size_t str1_r1 = 0;
+
+            const range_t& range0 = (*str0_range_ptr_);
+            const range_t& range1 = (*str1_range_ptr_);
+
             if (
-                 str0_base_ptr_  &&
-                 str1_base_ptr_  &&
-                 str0_range_ptr_ &&
-                 str1_range_ptr_
+                 range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
+                 range1(str1_r0, str1_r1, str1_base_ptr_->size())
                )
             {
-               branch(0)->value();
-               branch(1)->value();
-
-               std::size_t str0_r0 = 0;
-               std::size_t str0_r1 = 0;
-
-               std::size_t str1_r0 = 0;
-               std::size_t str1_r1 = 0;
-
-               const range_t& range0 = (*str0_range_ptr_);
-               const range_t& range1 = (*str1_range_ptr_);
-
-               if (
-                    range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
-                    range1(str1_r0, str1_r1, str1_base_ptr_->size())
-                  )
-               {
-                  return Operation::process(
-                                             str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0) + 1),
-                                             str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0) + 1)
-                                           );
-               }
+               return Operation::process
+                      (
+                         str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0)),
+                         str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0))
+                      );
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -16222,6 +18666,11 @@ namespace exprtk
             return Operation::type();
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_;
+         }
+
       private:
 
          str_sogens_node(const str_sogens_node<T,Operation>&) exprtk_delete;
@@ -16231,6 +18680,7 @@ namespace exprtk
          str_base_ptr str1_base_ptr_;
          range_ptr    str0_range_ptr_;
          range_ptr    str1_range_ptr_;
+         bool         initialised_;
       };
 
       template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
@@ -16242,7 +18692,7 @@ namespace exprtk
          typedef Operation operation_t;
          typedef sosos_node<T, SType0, SType1, SType2, Operation> node_type;
 
-         // variable op variable node
+         // string op string op string node
          explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
          : s0_(p0)
          , s1_(p1)
@@ -16334,11 +18784,11 @@ namespace exprtk
          explicit bipow_node(expression_ptr branch)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
             return PowOp::result(branch_.first->value());
          }
 
@@ -16347,6 +18797,11 @@ namespace exprtk
             return expression_node<T>::e_ipow;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
             expression_node<T>::ndb_t::collect(branch_, node_delete_list);
@@ -16396,7 +18851,7 @@ namespace exprtk
       };
 
       template <typename T, typename PowOp>
-      class bipowninv_node exprtk_final : public expression_node<T>
+      class bipowinv_node exprtk_final : public expression_node<T>
       {
       public:
 
@@ -16404,14 +18859,14 @@ namespace exprtk
          typedef std::pair<expression_ptr, bool> branch_t;
          typedef PowOp operation_t;
 
-         explicit bipowninv_node(expression_ptr branch)
+         explicit bipowinv_node(expression_ptr branch)
          {
             construct_branch_pair(branch_, branch);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            assert(branch_.first);
             return (T(1) / PowOp::result(branch_.first->value()));
          }
 
@@ -16420,9 +18875,14 @@ namespace exprtk
             return expression_node<T>::e_ipowinv;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const exprtk_override
@@ -16432,8 +18892,8 @@ namespace exprtk
 
       private:
 
-         bipowninv_node(const bipowninv_node<T,PowOp>&) exprtk_delete;
-         bipowninv_node<T,PowOp>& operator=(const bipowninv_node<T,PowOp>&) exprtk_delete;
+         bipowinv_node(const bipowinv_node<T,PowOp>&) exprtk_delete;
+         bipowinv_node<T,PowOp>& operator=(const bipowinv_node<T,PowOp>&) exprtk_delete;
 
          branch_t branch_;
       };
@@ -16577,6 +19037,46 @@ namespace exprtk
          return false;
       }
 
+      template <typename T>
+      inline bool is_loop_node(const expression_node<T>* node)
+      {
+         if (node)
+         {
+            switch (node->type())
+            {
+               case expression_node<T>::e_for    :
+               case expression_node<T>::e_repeat :
+               case expression_node<T>::e_while  : return true;
+               default                           : return false;
+            }
+         }
+
+         return false;
+      }
+
+      template <typename T>
+      inline bool is_block_node(const expression_node<T>* node)
+      {
+         if (node)
+         {
+            if (is_loop_node(node))
+            {
+               return true;
+            }
+
+            switch (node->type())
+            {
+               case expression_node<T>::e_conditional :
+               case expression_node<T>::e_mswitch     :
+               case expression_node<T>::e_switch      :
+               case expression_node<T>::e_vararg      : return true;
+               default                                : return false;
+            }
+         }
+
+         return false;
+      }
+
       class node_allocator
       {
       public:
@@ -17117,7 +19617,8 @@ namespace exprtk
       : param_count(pc)
       {}
 
-      virtual ~ifunction() {}
+      virtual ~ifunction()
+      {}
 
       #define empty_method_body(N)                   \
       {                                              \
@@ -17208,7 +19709,8 @@ namespace exprtk
    {
    public:
 
-      virtual ~ivararg_function() {}
+      virtual ~ivararg_function()
+      {}
 
       inline virtual T operator() (const std::vector<T>&)
       {
@@ -17233,12 +19735,13 @@ namespace exprtk
       typedef type_store<T> generic_type;
       typedef typename generic_type::parameter_list parameter_list_t;
 
-      igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar)
+      explicit igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar)
       : parameter_sequence(param_seq)
       , rtrn_type(rtr_type)
       {}
 
-      virtual ~igeneric_function() {}
+      virtual ~igeneric_function()
+      {}
 
       #define igeneric_function_empty_body(N)        \
       {                                              \
@@ -17262,6 +19765,8 @@ namespace exprtk
       inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t)
       igeneric_function_empty_body(4)
 
+      #undef igeneric_function_empty_body
+
       std::string parameter_sequence;
       return_type rtrn_type;
    };
@@ -17337,52 +19842,52 @@ namespace exprtk
 
    protected:
 
-       struct freefunc00 : public exprtk::ifunction<T>
+       struct freefunc00 exprtk_final : public exprtk::ifunction<T>
        {
           using exprtk::ifunction<T>::operator();
 
           explicit freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
-          inline T operator() ()
+          inline T operator() () exprtk_override
           { return f(); }
           ff00_functor f;
        };
 
-      struct freefunc01 : public exprtk::ifunction<T>
+      struct freefunc01 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
-         inline T operator() (const T& v0)
+         inline T operator() (const T& v0) exprtk_override
          { return f(v0); }
          ff01_functor f;
       };
 
-      struct freefunc02 : public exprtk::ifunction<T>
+      struct freefunc02 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
-         inline T operator() (const T& v0, const T& v1)
+         inline T operator() (const T& v0, const T& v1) exprtk_override
          { return f(v0, v1); }
          ff02_functor f;
       };
 
-      struct freefunc03 : public exprtk::ifunction<T>
+      struct freefunc03 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
-         inline T operator() (const T& v0, const T& v1, const T& v2)
+         inline T operator() (const T& v0, const T& v1, const T& v2) exprtk_override
          { return f(v0, v1, v2); }
          ff03_functor f;
       };
 
-      struct freefunc04 : public exprtk::ifunction<T>
+      struct freefunc04 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {}
-         inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3)
+         inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) exprtk_override
          { return f(v0, v1, v2, v3); }
          ff04_functor f;
       };
@@ -17392,120 +19897,120 @@ namespace exprtk
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {}
-         inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
+         inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) exprtk_override
          { return f(v0, v1, v2, v3, v4); }
          ff05_functor f;
       };
 
-      struct freefunc06 : public exprtk::ifunction<T>
+      struct freefunc06 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {}
-         inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
+         inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) exprtk_override
          { return f(v0, v1, v2, v3, v4, v5); }
          ff06_functor f;
       };
 
-      struct freefunc07 : public exprtk::ifunction<T>
+      struct freefunc07 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {}
          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
-                              const T& v5, const T& v6)
+                              const T& v5, const T& v6) exprtk_override
          { return f(v0, v1, v2, v3, v4, v5, v6); }
          ff07_functor f;
       };
 
-      struct freefunc08 : public exprtk::ifunction<T>
+      struct freefunc08 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {}
          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
-                              const T& v5, const T& v6, const T& v7)
+                              const T& v5, const T& v6, const T& v7) exprtk_override
          { return f(v0, v1, v2, v3, v4, v5, v6, v7); }
          ff08_functor f;
       };
 
-      struct freefunc09 : public exprtk::ifunction<T>
+      struct freefunc09 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {}
          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
-                              const T& v5, const T& v6, const T& v7, const T& v8)
+                              const T& v5, const T& v6, const T& v7, const T& v8) exprtk_override
          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); }
          ff09_functor f;
       };
 
-      struct freefunc10 : public exprtk::ifunction<T>
+      struct freefunc10 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {}
          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
-                              const T& v5, const T& v6, const T& v7, const T& v8, const T& v9)
+                              const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) exprtk_override
          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); }
          ff10_functor f;
       };
 
-      struct freefunc11 : public exprtk::ifunction<T>
+      struct freefunc11 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {}
          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
-                              const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10)
+                              const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) exprtk_override
          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); }
          ff11_functor f;
       };
 
-      struct freefunc12 : public exprtk::ifunction<T>
+      struct freefunc12 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {}
          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
-                              const T& v10, const T& v11)
+                              const T& v10, const T& v11) exprtk_override
          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); }
          ff12_functor f;
       };
 
-      struct freefunc13 : public exprtk::ifunction<T>
+      struct freefunc13 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {}
          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
-                              const T& v10, const T& v11, const T& v12)
+                              const T& v10, const T& v11, const T& v12) exprtk_override
          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); }
          ff13_functor f;
       };
 
-      struct freefunc14 : public exprtk::ifunction<T>
+      struct freefunc14 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {}
          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
-                              const T& v10, const T& v11, const T& v12, const T& v13)
+                              const T& v10, const T& v11, const T& v12, const T& v13) exprtk_override
          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); }
          ff14_functor f;
       };
 
-      struct freefunc15 : public exprtk::ifunction<T>
+      struct freefunc15 exprtk_final : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
 
          explicit freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {}
          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
-                              const T& v10, const T& v11, const T& v12, const T& v13, const T& v14)
+                              const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) exprtk_override
          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); }
          ff15_functor f;
       };
@@ -17765,7 +20270,7 @@ namespace exprtk
          {
             static inline bool test(const variable_node_t* p, const void* ptr)
             {
-               exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p->ref())),ptr));
+               exprtk_debug(("ptr_match::test() - %p <--> %p\n", reinterpret_cast<const void*>(&(p->ref())), ptr));
                return (&(p->ref()) == ptr);
             }
          };
@@ -18029,7 +20534,7 @@ namespace exprtk
 
    public:
 
-      symbol_table(const symtab_mutability_type mutability = e_mutable)
+      explicit symbol_table(const symtab_mutability_type mutability = e_mutable)
       : control_block_(control_block::create())
       {
          control_block_->set_mutability(mutability);
@@ -18508,6 +21013,34 @@ namespace exprtk
          return false;
       }
 
+      #define exprtk_define_reserved_function(NN)                                                    \
+      inline bool add_reserved_function(const std::string& function_name, ff##NN##_functor function) \
+      {                                                                                              \
+         if (!valid())                                                                               \
+         { return false; }                                                                           \
+         if (!valid_symbol(function_name,false))                                                     \
+         { return false; }                                                                           \
+         if (symbol_exists(function_name,false))                                                     \
+         { return false; }                                                                           \
+                                                                                                     \
+         exprtk::ifunction<T>* ifunc = new freefunc##NN(function);                                   \
+                                                                                                     \
+         local_data().free_function_list_.push_back(ifunc);                                          \
+                                                                                                     \
+         return add_reserved_function(function_name,(*local_data().free_function_list_.back()));     \
+      }                                                                                              \
+
+      exprtk_define_reserved_function(00) exprtk_define_reserved_function(01)
+      exprtk_define_reserved_function(02) exprtk_define_reserved_function(03)
+      exprtk_define_reserved_function(04) exprtk_define_reserved_function(05)
+      exprtk_define_reserved_function(06) exprtk_define_reserved_function(07)
+      exprtk_define_reserved_function(08) exprtk_define_reserved_function(09)
+      exprtk_define_reserved_function(10) exprtk_define_reserved_function(11)
+      exprtk_define_reserved_function(12) exprtk_define_reserved_function(13)
+      exprtk_define_reserved_function(14) exprtk_define_reserved_function(15)
+
+      #undef exprtk_define_reserved_function
+
       template <std::size_t N>
       inline bool add_vector(const std::string& vector_name, T (&v)[N])
       {
@@ -18682,12 +21215,48 @@ namespace exprtk
 
       template <typename Allocator,
                 template <typename, typename> class Sequence>
-      inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vlist) const
+      inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vec_list) const
       {
          if (!valid())
             return 0;
          else
-            return local_data().vector_store.get_list(vlist);
+            return local_data().vector_store.get_list(vec_list);
+      }
+
+      template <typename Allocator,
+                template <typename, typename> class Sequence>
+      inline std::size_t get_function_list(Sequence<std::string,Allocator>& function_list) const
+      {
+         if (!valid())
+            return 0;
+
+         std::vector<std::string> function_names;
+         std::size_t count = 0;
+
+         count += local_data().function_store         .get_list(function_names);
+         count += local_data().vararg_function_store  .get_list(function_names);
+         count += local_data().generic_function_store .get_list(function_names);
+         count += local_data().string_function_store  .get_list(function_names);
+         count += local_data().overload_function_store.get_list(function_names);
+
+         std::set<std::string> function_set;
+
+         for (std::size_t i = 0; i < function_names.size(); ++i)
+         {
+            function_set.insert(function_names[i]);
+         }
+
+         std::copy(function_set.begin(), function_set.end(),
+                   std::back_inserter(function_list));
+
+         return count;
+      }
+
+      inline std::vector<std::string> get_function_list() const
+      {
+         std::vector<std::string> result;
+         get_function_list(result);
+         return result;
       }
 
       inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const
@@ -18878,6 +21447,38 @@ namespace exprtk
          }
       }
 
+      inline void load_variables_from(const symbol_table<T>& st)
+      {
+         std::vector<std::string> name_list;
+
+         st.local_data().variable_store.get_list(name_list);
+
+         if (!name_list.empty())
+         {
+            for (std::size_t i = 0; i < name_list.size(); ++i)
+            {
+               T& variable = st.get_variable(name_list[i])->ref();
+               add_variable(name_list[i], variable);
+            }
+         }
+      }
+
+      inline void load_vectors_from(const symbol_table<T>& st)
+      {
+         std::vector<std::string> name_list;
+
+         st.local_data().vector_store.get_list(name_list);
+
+         if (!name_list.empty())
+         {
+            for (std::size_t i = 0; i < name_list.size(); ++i)
+            {
+               vector_holder_t& vecholder = *st.get_vector(name_list[i]);
+               add_vector(name_list[i], vecholder.data(), vecholder.size());
+            }
+         }
+      }
+
    private:
 
       inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const
@@ -18973,6 +21574,21 @@ namespace exprtk
             e_string
          };
 
+         static std::string to_str(data_type dt)
+         {
+            switch(dt)
+            {
+               case e_unknown   : return "e_unknown  ";
+               case e_expr      : return "e_expr"     ;
+               case e_vecholder : return "e_vecholder";
+               case e_data      : return "e_data"     ;
+               case e_vecdata   : return "e_vecdata"  ;
+               case e_string    : return "e_string"   ;
+            }
+
+            return "";
+         }
+
          struct data_pack
          {
             data_pack()
@@ -19178,17 +21794,18 @@ namespace exprtk
          return details::is_true(value());
       }
 
-      inline void register_symbol_table(symbol_table<T>& st)
+      inline bool 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])
+            if (st == symbol_table_list_[i])
             {
-               return;
+               return false;
             }
          }
 
          symbol_table_list_.push_back(st);
+         return true;
       }
 
       inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const
@@ -19201,6 +21818,11 @@ namespace exprtk
          return symbol_table_list_[index];
       }
 
+      std::size_t num_symbol_tables() const
+      {
+         return symbol_table_list_.size();
+      }
+
       typedef results_context<T> results_context_t;
 
       inline const results_context_t& results() const
@@ -19330,6 +21952,8 @@ namespace exprtk
       friend class parser<T>;
       friend class expression_helper<T>;
       friend class function_compositor<T>;
+      template <typename TT>
+      friend bool is_valid(const expression<TT>& expr);
    }; // class expression
 
    template <typename T>
@@ -19337,55 +21961,165 @@ namespace exprtk
    {
    public:
 
-      static inline bool is_constant(const expression<T>& expr)
+      enum node_types
       {
-         return details::is_constant_node(expr.control_block_->expr);
+         e_literal,
+         e_variable,
+         e_string,
+         e_unary,
+         e_binary,
+         e_function,
+         e_vararg,
+         e_null,
+         e_assert,
+         e_sf3ext,
+         e_sf4ext
+      };
+
+      static inline bool is_literal(const expression<T>& expr)
+      {
+         return expr.control_block_ && details::is_literal_node(expr.control_block_->expr);
       }
 
       static inline bool is_variable(const expression<T>& expr)
       {
-         return details::is_variable_node(expr.control_block_->expr);
+         return expr.control_block_ && details::is_variable_node(expr.control_block_->expr);
+      }
+
+      static inline bool is_string(const expression<T>& expr)
+      {
+         return expr.control_block_ && details::is_generally_string_node(expr.control_block_->expr);
       }
 
       static inline bool is_unary(const expression<T>& expr)
       {
-         return details::is_unary_node(expr.control_block_->expr);
+         return expr.control_block_ && details::is_unary_node(expr.control_block_->expr);
       }
 
       static inline bool is_binary(const expression<T>& expr)
       {
-         return details::is_binary_node(expr.control_block_->expr);
+         return expr.control_block_ && details::is_binary_node(expr.control_block_->expr);
       }
 
       static inline bool is_function(const expression<T>& expr)
       {
-         return details::is_function(expr.control_block_->expr);
+         return expr.control_block_ && details::is_function(expr.control_block_->expr);
+      }
+
+      static inline bool is_vararg(const expression<T>& expr)
+      {
+         return expr.control_block_ && details::is_vararg_node(expr.control_block_->expr);
       }
 
       static inline bool is_null(const expression<T>& expr)
       {
-         return details::is_null_node(expr.control_block_->expr);
+         return expr.control_block_ && details::is_null_node(expr.control_block_->expr);
+      }
+
+      static inline bool is_assert(const expression<T>& expr)
+      {
+         return expr.control_block_ && details::is_assert_node(expr.control_block_->expr);
+      }
+
+      static inline bool is_sf3ext(const expression<T>& expr)
+      {
+         return expr.control_block_ && details::is_sf3ext_node(expr.control_block_->expr);
+      }
+
+      static inline bool is_sf4ext(const expression<T>& expr)
+      {
+         return expr.control_block_ && details::is_sf4ext_node(expr.control_block_->expr);
+      }
+
+      static inline bool is_type(const expression<T>& expr, const node_types node_type)
+      {
+         if (0 == expr.control_block_)
+         {
+            return false;
+         }
+
+         switch (node_type)
+         {
+            case e_literal  : return is_literal_node(expr);
+            case e_variable : return is_variable    (expr);
+            case e_string   : return is_string      (expr);
+            case e_unary    : return is_unary       (expr);
+            case e_binary   : return is_binary      (expr);
+            case e_function : return is_function    (expr);
+            case e_null     : return is_null        (expr);
+            case e_assert   : return is_assert      (expr);
+            case e_sf3ext   : return is_sf3ext      (expr);
+            case e_sf4ext   : return is_sf4ext      (expr);
+         };
+
+         return false;
+      }
+
+      static inline bool match_type_sequence(const expression<T>& expr, const std::vector<node_types>& type_seq)
+      {
+         if ((0 == expr.control_block_) || !is_vararg(expr))
+         {
+            return false;
+         }
+
+         typedef details::vararg_node<T, exprtk::details::vararg_multi_op<T> > mo_vararg_t;
+
+         mo_vararg_t* vnode = dynamic_cast<mo_vararg_t*>(expr.control_block_->expr);
+
+         if (
+              (0 == vnode) ||
+              type_seq.empty() ||
+              (vnode->size() < type_seq.size())
+            )
+         {
+            return false;
+         }
+
+         for (std::size_t i = 0; i < type_seq.size(); ++i)
+         {
+            assert((*vnode)[i]);
+
+            switch(type_seq[i])
+            {
+               case e_literal  : { if (details::is_literal_node         ((*vnode)[i])) continue; } break;
+               case e_variable : { if (details::is_variable_node        ((*vnode)[i])) continue; } break;
+               case e_string   : { if (details::is_generally_string_node((*vnode)[i])) continue; } break;
+               case e_unary    : { if (details::is_unary_node           ((*vnode)[i])) continue; } break;
+               case e_binary   : { if (details::is_binary_node          ((*vnode)[i])) continue; } break;
+               case e_function : { if (details::is_function             ((*vnode)[i])) continue; } break;
+               case e_null     : { if (details::is_null_node            ((*vnode)[i])) continue; } break;
+               case e_assert   : { if (details::is_assert_node          ((*vnode)[i])) continue; } break;
+               case e_sf3ext   : { if (details::is_sf3ext_node          ((*vnode)[i])) continue; } break;
+               case e_sf4ext   : { if (details::is_sf4ext_node          ((*vnode)[i])) continue; } break;
+               case e_vararg   : break;
+            }
+
+            return false;
+         }
+
+         return true;
       }
    };
 
    template <typename T>
    inline bool is_valid(const expression<T>& expr)
    {
-      return !expression_helper<T>::is_null(expr);
+      return expr.control_block_ && !expression_helper<T>::is_null(expr);
    }
 
    namespace parser_error
    {
       enum error_mode
       {
-         e_unknown = 0,
-         e_syntax  = 1,
-         e_token   = 2,
-         e_numeric = 4,
-         e_symtab  = 5,
-         e_lexer   = 6,
-         e_helper  = 7,
-         e_parser  = 8
+         e_unknown   = 0,
+         e_syntax    = 1,
+         e_token     = 2,
+         e_numeric   = 4,
+         e_symtab    = 5,
+         e_lexer     = 6,
+         e_synthesis = 7,
+         e_helper    = 8,
+         e_parser    = 9
       };
 
       struct type
@@ -19414,7 +22148,7 @@ namespace exprtk
          t.token.type   = lexer::token::e_error;
          t.diagnostic   = diagnostic;
          t.src_location = src_location;
-         exprtk_debug(("%s\n",diagnostic .c_str()));
+         exprtk_debug(("%s\n", diagnostic .c_str()));
          return t;
       }
 
@@ -19428,7 +22162,7 @@ namespace exprtk
          t.token        = tk;
          t.diagnostic   = diagnostic;
          t.src_location = src_location;
-         exprtk_debug(("%s\n",diagnostic .c_str()));
+         exprtk_debug(("%s\n", diagnostic .c_str()));
          return t;
       }
 
@@ -19520,70 +22254,79 @@ namespace exprtk
          e_level10, e_level11, e_level12, e_level13, e_level14
       };
 
-      typedef const T&                                    cref_t;
-      typedef const T                                     const_t;
-      typedef ifunction<T>                                F;
-      typedef ivararg_function<T>                         VAF;
-      typedef igeneric_function<T>                        GF;
-      typedef ifunction<T>                                ifunction_t;
-      typedef ivararg_function<T>                         ivararg_function_t;
-      typedef igeneric_function<T>                        igeneric_function_t;
-      typedef details::expression_node<T>                 expression_node_t;
-      typedef details::literal_node<T>                    literal_node_t;
-      typedef details::unary_node<T>                      unary_node_t;
-      typedef details::binary_node<T>                     binary_node_t;
-      typedef details::trinary_node<T>                    trinary_node_t;
-      typedef details::quaternary_node<T>                 quaternary_node_t;
-      typedef details::conditional_node<T>                conditional_node_t;
-      typedef details::cons_conditional_node<T>           cons_conditional_node_t;
-      typedef details::while_loop_node<T>                 while_loop_node_t;
-      typedef details::repeat_until_loop_node<T>          repeat_until_loop_node_t;
-      typedef details::for_loop_node<T>                   for_loop_node_t;
-      typedef details::while_loop_rtc_node<T>             while_loop_rtc_node_t;
-      typedef details::repeat_until_loop_rtc_node<T>      repeat_until_loop_rtc_node_t;
-      typedef details::for_loop_rtc_node<T>               for_loop_rtc_node_t;
+      typedef const T&                                       cref_t;
+      typedef const T                                        const_t;
+      typedef ifunction<T>                                   F;
+      typedef ivararg_function<T>                            VAF;
+      typedef igeneric_function<T>                           GF;
+      typedef ifunction<T>                                   ifunction_t;
+      typedef ivararg_function<T>                            ivararg_function_t;
+      typedef igeneric_function<T>                           igeneric_function_t;
+      typedef details::expression_node<T>                    expression_node_t;
+      typedef details::literal_node<T>                       literal_node_t;
+      typedef details::unary_node<T>                         unary_node_t;
+      typedef details::binary_node<T>                        binary_node_t;
+      typedef details::trinary_node<T>                       trinary_node_t;
+      typedef details::quaternary_node<T>                    quaternary_node_t;
+      typedef details::conditional_node<T>                   conditional_node_t;
+      typedef details::cons_conditional_node<T>              cons_conditional_node_t;
+      typedef details::while_loop_node<T>                    while_loop_node_t;
+      typedef details::repeat_until_loop_node<T>             repeat_until_loop_node_t;
+      typedef details::for_loop_node<T>                      for_loop_node_t;
+      typedef details::while_loop_rtc_node<T>                while_loop_rtc_node_t;
+      typedef details::repeat_until_loop_rtc_node<T>         repeat_until_loop_rtc_node_t;
+      typedef details::for_loop_rtc_node<T>                  for_loop_rtc_node_t;
       #ifndef exprtk_disable_break_continue
-      typedef details::while_loop_bc_node<T>              while_loop_bc_node_t;
-      typedef details::repeat_until_loop_bc_node<T>       repeat_until_loop_bc_node_t;
-      typedef details::for_loop_bc_node<T>                for_loop_bc_node_t;
-      typedef details::while_loop_bc_rtc_node<T>          while_loop_bc_rtc_node_t;
-      typedef details::repeat_until_loop_bc_rtc_node<T>   repeat_until_loop_bc_rtc_node_t;
-      typedef details::for_loop_bc_rtc_node<T>            for_loop_bc_rtc_node_t;
+      typedef details::while_loop_bc_node<T>                 while_loop_bc_node_t;
+      typedef details::repeat_until_loop_bc_node<T>          repeat_until_loop_bc_node_t;
+      typedef details::for_loop_bc_node<T>                   for_loop_bc_node_t;
+      typedef details::while_loop_bc_rtc_node<T>             while_loop_bc_rtc_node_t;
+      typedef details::repeat_until_loop_bc_rtc_node<T>      repeat_until_loop_bc_rtc_node_t;
+      typedef details::for_loop_bc_rtc_node<T>               for_loop_bc_rtc_node_t;
       #endif
-      typedef details::switch_node<T>                     switch_node_t;
-      typedef details::variable_node<T>                   variable_node_t;
-      typedef details::vector_elem_node<T>                vector_elem_node_t;
-      typedef details::rebasevector_elem_node<T>          rebasevector_elem_node_t;
-      typedef details::rebasevector_celem_node<T>         rebasevector_celem_node_t;
-      typedef details::vector_node<T>                     vector_node_t;
-      typedef details::range_pack<T>                      range_t;
+      typedef details::switch_node<T>                        switch_node_t;
+      typedef details::variable_node<T>                      variable_node_t;
+      typedef details::vector_elem_node<T>                   vector_elem_node_t;
+      typedef details::vector_celem_node<T>                  vector_celem_node_t;
+      typedef details::vector_elem_rtc_node<T>               vector_elem_rtc_node_t;
+      typedef details::vector_celem_rtc_node<T>              vector_celem_rtc_node_t;
+      typedef details::rebasevector_elem_node<T>             rebasevector_elem_node_t;
+      typedef details::rebasevector_celem_node<T>            rebasevector_celem_node_t;
+      typedef details::rebasevector_elem_rtc_node<T>         rebasevector_elem_rtc_node_t;
+      typedef details::rebasevector_celem_rtc_node<T>        rebasevector_celem_rtc_node_t;
+      typedef details::vector_node<T>                        vector_node_t;
+      typedef details::vector_size_node<T>                   vector_size_node_t;
+      typedef details::range_pack<T>                         range_t;
       #ifndef exprtk_disable_string_capabilities
-      typedef details::stringvar_node<T>                  stringvar_node_t;
-      typedef details::string_literal_node<T>             string_literal_node_t;
-      typedef details::string_range_node<T>               string_range_node_t;
-      typedef details::const_string_range_node<T>         const_string_range_node_t;
-      typedef details::generic_string_range_node<T>       generic_string_range_node_t;
-      typedef details::string_concat_node<T>              string_concat_node_t;
-      typedef details::assignment_string_node<T>          assignment_string_node_t;
-      typedef details::assignment_string_range_node<T>    assignment_string_range_node_t;
-      typedef details::conditional_string_node<T>         conditional_string_node_t;
-      typedef details::cons_conditional_str_node<T>       cons_conditional_str_node_t;
+      typedef details::stringvar_node<T>                     stringvar_node_t;
+      typedef details::string_literal_node<T>                string_literal_node_t;
+      typedef details::string_range_node<T>                  string_range_node_t;
+      typedef details::const_string_range_node<T>            const_string_range_node_t;
+      typedef details::generic_string_range_node<T>          generic_string_range_node_t;
+      typedef details::string_concat_node<T>                 string_concat_node_t;
+      typedef details::assignment_string_node<T>             assignment_string_node_t;
+      typedef details::assignment_string_range_node<T>       assignment_string_range_node_t;
+      typedef details::conditional_string_node<T>            conditional_string_node_t;
+      typedef details::cons_conditional_str_node<T>          cons_conditional_str_node_t;
       #endif
-      typedef details::assignment_node<T>                 assignment_node_t;
-      typedef details::assignment_vec_elem_node<T>        assignment_vec_elem_node_t;
-      typedef details::assignment_rebasevec_elem_node<T>  assignment_rebasevec_elem_node_t;
-      typedef details::assignment_rebasevec_celem_node<T> assignment_rebasevec_celem_node_t;
-      typedef details::assignment_vec_node<T>             assignment_vec_node_t;
-      typedef details::assignment_vecvec_node<T>          assignment_vecvec_node_t;
-      typedef details::conditional_vector_node<T>         conditional_vector_node_t;
-      typedef details::scand_node<T>                      scand_node_t;
-      typedef details::scor_node<T>                       scor_node_t;
-      typedef lexer::token                                token_t;
-      typedef expression_node_t*                          expression_node_ptr;
-      typedef expression<T>                               expression_t;
-      typedef symbol_table<T>                             symbol_table_t;
-      typedef typename expression<T>::symtab_list_t       symbol_table_list_t;
-      typedef details::vector_holder<T>*                  vector_holder_ptr;
+      typedef details::assignment_node<T>                    assignment_node_t;
+      typedef details::assignment_vec_elem_node<T>           assignment_vec_elem_node_t;
+      typedef details::assignment_vec_elem_rtc_node<T>       assignment_vec_elem_rtc_node_t;
+      typedef details::assignment_rebasevec_elem_node<T>     assignment_rebasevec_elem_node_t;
+      typedef details::assignment_rebasevec_elem_rtc_node<T> assignment_rebasevec_elem_rtc_node_t;
+      typedef details::assignment_rebasevec_celem_node<T>    assignment_rebasevec_celem_node_t;
+      typedef details::assignment_vec_node<T>                assignment_vec_node_t;
+      typedef details::assignment_vecvec_node<T>             assignment_vecvec_node_t;
+      typedef details::conditional_vector_node<T>            conditional_vector_node_t;
+      typedef details::scand_node<T>                         scand_node_t;
+      typedef details::scor_node<T>                          scor_node_t;
+      typedef lexer::token                                   token_t;
+      typedef expression_node_t*                             expression_node_ptr;
+      typedef expression<T>                                  expression_t;
+      typedef symbol_table<T>                                symbol_table_t;
+      typedef typename expression<T>::symtab_list_t          symbol_table_list_t;
+      typedef details::vector_holder<T>                      vector_holder_t;
+      typedef vector_holder_t*                               vector_holder_ptr;
 
       typedef typename details::functor_t<T> functor_t;
       typedef typename functor_t::qfunc_t    quaternary_functor_t;
@@ -19636,6 +22379,7 @@ namespace exprtk
          enum element_type
          {
             e_none    ,
+            e_literal ,
             e_variable,
             e_vector  ,
             e_vecelem ,
@@ -19643,6 +22387,7 @@ namespace exprtk
          };
 
          typedef details::vector_holder<T> vector_holder_t;
+         typedef literal_node_t*           literal_node_ptr;
          typedef variable_node_t*          variable_node_ptr;
          typedef vector_holder_t*          vector_holder_ptr;
          typedef expression_node_t*        expression_node_ptr;
@@ -19657,8 +22402,8 @@ namespace exprtk
          , depth(std::numeric_limits<std::size_t>::max())
          , ref_count(0)
          , ip_index (0)
-         , type (e_none)
-         , active(false)
+         , type     (e_none)
+         , active   (false)
          , data     (0)
          , var_node (0)
          , vec_node (0)
@@ -19842,6 +22587,10 @@ namespace exprtk
 
             switch (se.type)
             {
+               case scope_element::e_literal    : delete reinterpret_cast<T*>(se.data);
+                                                  delete se.var_node;
+                                                  break;
+
                case scope_element::e_variable   : delete reinterpret_cast<T*>(se.data);
                                                   delete se.var_node;
                                                   break;
@@ -19906,6 +22655,25 @@ namespace exprtk
             return expression_node_ptr(0);
          }
 
+         inline std::string get_vector_name(const T* data)
+         {
+            for (std::size_t i = 0; i < element_.size(); ++i)
+            {
+               scope_element& se = element_[i];
+
+               if (
+                    se.active   &&
+                    se.vec_node &&
+                    (se.vec_node->data() == data)
+                  )
+               {
+                  return se.name;
+               }
+            }
+
+            return "neo-vector";
+         }
+
       private:
 
          scope_element_manager(const scope_element_manager&) exprtk_delete;
@@ -20092,16 +22860,17 @@ namespace exprtk
             if (++parser_.state_.stack_depth > parser_.settings_.max_stack_depth_)
             {
                limit_exceeded_ = true;
-               parser_.set_error(
-                  make_error(parser_error::e_parser,
-                     "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) +
-                     " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_),
-                     exprtk_error_location));
+               parser_.set_error(make_error(
+                  parser_error::e_parser,
+                  "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) +
+                  " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_),
+                  exprtk_error_location));
             }
          }
 
         ~stack_limit_handler()
          {
+            assert(parser_.state_.stack_depth > 0);
             parser_.state_.stack_depth--;
          }
 
@@ -20211,22 +22980,23 @@ namespace exprtk
          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 (valid_symbol(variable_name))
             {
-               if (!symtab_list_[i].valid())
+               for (std::size_t i = 0; i < symtab_list_.size(); ++i)
                {
-                  continue;
-               }
+                  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;
+                  result.variable = local_data(i)
+                                       .variable_store.get(variable_name);
+                  if (result.variable)
+                  {
+                     result.symbol_table = &symtab_list_[i];
+                     break;
+                  }
                }
             }
 
@@ -20461,12 +23231,16 @@ namespace exprtk
             for (std::size_t i = 0; i < symtab_list_.size(); ++i)
             {
                if (!symtab_list_[i].valid())
+               {
                   continue;
-               else
-                  result =
-                     local_data(i).vector_store.get(vector_name);
+               }
 
-               if (result) break;
+               result = local_data(i).vector_store.get(vector_name);
+
+               if (result)
+               {
+                  break;
+               }
             }
 
             return result;
@@ -20480,9 +23254,14 @@ namespace exprtk
             for (std::size_t i = 0; i < symtab_list_.size(); ++i)
             {
                if (!symtab_list_[i].valid())
+               {
                   continue;
-               else if (local_data(i).variable_store.is_constant(symbol_name))
+               }
+
+               if (local_data(i).variable_store.is_constant(symbol_name))
+               {
                   return true;
+               }
             }
 
             return false;
@@ -20513,9 +23292,14 @@ namespace exprtk
             for (std::size_t i = 0; i < symtab_list_.size(); ++i)
             {
                if (!symtab_list_[i].valid())
+               {
                   continue;
-               else if (symtab_list_[i].symbol_exists(symbol))
+               }
+
+               if (symtab_list_[i].symbol_exists(symbol))
+               {
                   return true;
+               }
             }
 
             return false;
@@ -20675,6 +23459,7 @@ namespace exprtk
          {
             parsing_return_stmt     = false;
             parsing_break_stmt      = false;
+            parsing_assert_stmt     = false;
             return_stmt_present     = false;
             side_effect_present     = false;
             scope_depth             = 0;
@@ -20692,12 +23477,13 @@ namespace exprtk
             {
                side_effect_present = true;
 
-               exprtk_debug(("activate_side_effect() - caller: %s\n",source.c_str()));
+               exprtk_debug(("activate_side_effect() - caller: %s\n", source.c_str()));
             }
          }
 
          bool parsing_return_stmt;
          bool parsing_break_stmt;
+         bool parsing_assert_stmt;
          bool return_stmt_present;
          bool side_effect_present;
          bool type_check_enabled;
@@ -20730,7 +23516,8 @@ namespace exprtk
          : mode(m)
          {}
 
-         virtual ~unknown_symbol_resolver() {}
+         virtual ~unknown_symbol_resolver()
+         {}
 
          virtual bool process(const std::string& /*unknown_symbol*/,
                               usr_symbol_type&   st,
@@ -20806,11 +23593,14 @@ namespace exprtk
                details::case_normalise(symbol_name_list_[i].first);
             }
 
-            std::sort(symbol_name_list_.begin(),symbol_name_list_.end());
+            std::sort(symbol_name_list_.begin(), symbol_name_list_.end());
 
-            std::unique_copy(symbol_name_list_.begin(),
-                             symbol_name_list_.end  (),
-                             std::back_inserter(symbols_list));
+            std::unique_copy
+            (
+               symbol_name_list_.begin(),
+               symbol_name_list_.end  (),
+               std::back_inserter(symbols_list)
+            );
 
             return symbols_list.size();
          }
@@ -20831,9 +23621,12 @@ namespace exprtk
 
             std::sort(assignment_name_list_.begin(),assignment_name_list_.end());
 
-            std::unique_copy(assignment_name_list_.begin(),
-                             assignment_name_list_.end  (),
-                             std::back_inserter(assignment_list));
+            std::unique_copy
+            (
+               assignment_name_list_.begin(),
+               assignment_name_list_.end  (),
+               std::back_inserter(assignment_list)
+            );
 
             return assignment_list.size();
          }
@@ -21020,7 +23813,7 @@ namespace exprtk
             e_ineq_gte  , e_ineq_gt
          };
 
-         static const std::size_t compile_all_opts =
+         static const std::size_t default_compile_all_opts =
                                      e_replacer          +
                                      e_joiner            +
                                      e_numeric_check     +
@@ -21029,9 +23822,10 @@ namespace exprtk
                                      e_commutative_check +
                                      e_strength_reduction;
 
-         settings_store(const std::size_t compile_options = compile_all_opts)
+         settings_store(const std::size_t compile_options = default_compile_all_opts)
          : max_stack_depth_(400)
          , max_node_depth_(10000)
+         , max_local_vector_size_(2000000000)
          {
            load_compile_options(compile_options);
          }
@@ -21078,12 +23872,24 @@ namespace exprtk
             return (*this);
          }
 
+         settings_store& enable_commutative_check()
+         {
+            enable_commutative_check_ = true;
+            return (*this);
+         }
+
+         settings_store& enable_strength_reduction()
+         {
+            enable_strength_reduction_ = true;
+            return (*this);
+         }
+
          settings_store& disable_all_base_functions()
          {
             std::copy(details::base_function_list,
                       details::base_function_list + details::base_function_list_size,
                       std::insert_iterator<disabled_entity_set_t>
-                        (disabled_func_set_, disabled_func_set_.begin()));
+                         (disabled_func_set_, disabled_func_set_.begin()));
             return (*this);
          }
 
@@ -21092,7 +23898,7 @@ namespace exprtk
             std::copy(details::cntrl_struct_list,
                       details::cntrl_struct_list + details::cntrl_struct_list_size,
                       std::insert_iterator<disabled_entity_set_t>
-                        (disabled_ctrl_set_, disabled_ctrl_set_.begin()));
+                         (disabled_ctrl_set_, disabled_ctrl_set_.begin()));
             return (*this);
          }
 
@@ -21110,7 +23916,7 @@ namespace exprtk
             std::copy(details::arithmetic_ops_list,
                       details::arithmetic_ops_list + details::arithmetic_ops_list_size,
                       std::insert_iterator<disabled_entity_set_t>
-                        (disabled_arithmetic_set_, disabled_arithmetic_set_.begin()));
+                         (disabled_arithmetic_set_, disabled_arithmetic_set_.begin()));
             return (*this);
          }
 
@@ -21119,7 +23925,7 @@ namespace exprtk
             std::copy(details::assignment_ops_list,
                       details::assignment_ops_list + details::assignment_ops_list_size,
                       std::insert_iterator<disabled_entity_set_t>
-                        (disabled_assignment_set_, disabled_assignment_set_.begin()));
+                         (disabled_assignment_set_, disabled_assignment_set_.begin()));
             return (*this);
          }
 
@@ -21128,7 +23934,7 @@ namespace exprtk
             std::copy(details::inequality_ops_list,
                       details::inequality_ops_list + details::inequality_ops_list_size,
                       std::insert_iterator<disabled_entity_set_t>
-                        (disabled_inequality_set_, disabled_inequality_set_.begin()));
+                         (disabled_inequality_set_, disabled_inequality_set_.begin()));
             return (*this);
          }
 
@@ -21138,6 +23944,18 @@ namespace exprtk
             return (*this);
          }
 
+         settings_store& disable_commutative_check()
+         {
+            enable_commutative_check_ = false;
+            return (*this);
+         }
+
+         settings_store& disable_strength_reduction()
+         {
+            enable_strength_reduction_ = false;
+            return (*this);
+         }
+
          bool replacer_enabled           () const { return enable_replacer_;           }
          bool commutative_check_enabled  () const { return enable_commutative_check_;  }
          bool joiner_enabled             () const { return enable_joiner_;             }
@@ -21263,7 +24081,7 @@ namespace exprtk
                                                            .find(inequality_opr_to_string(inequality));
          }
 
-         settings_store& disable_base_function(settings_base_funcs bf)
+         settings_store& disable_base_function(const settings_base_funcs bf)
          {
             if (
                  (e_bf_unknown != bf) &&
@@ -21276,7 +24094,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& disable_control_structure(settings_control_structs ctrl_struct)
+         settings_store& disable_control_structure(const settings_control_structs ctrl_struct)
          {
             if (
                  (e_ctrl_unknown != ctrl_struct) &&
@@ -21289,7 +24107,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& disable_logic_operation(settings_logic_opr logic)
+         settings_store& disable_logic_operation(const settings_logic_opr logic)
          {
             if (
                  (e_logic_unknown != logic) &&
@@ -21302,7 +24120,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& disable_arithmetic_operation(settings_arithmetic_opr arithmetic)
+         settings_store& disable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
          {
             if (
                  (e_arith_unknown != arithmetic) &&
@@ -21315,7 +24133,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& disable_assignment_operation(settings_assignment_opr assignment)
+         settings_store& disable_assignment_operation(const settings_assignment_opr assignment)
          {
             if (
                  (e_assign_unknown != assignment) &&
@@ -21328,7 +24146,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& disable_inequality_operation(settings_inequality_opr inequality)
+         settings_store& disable_inequality_operation(const settings_inequality_opr inequality)
          {
             if (
                  (e_ineq_unknown != inequality) &&
@@ -21341,7 +24159,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& enable_base_function(settings_base_funcs bf)
+         settings_store& enable_base_function(const settings_base_funcs bf)
          {
             if (
                  (e_bf_unknown != bf) &&
@@ -21359,7 +24177,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& enable_control_structure(settings_control_structs ctrl_struct)
+         settings_store& enable_control_structure(const settings_control_structs ctrl_struct)
          {
             if (
                  (e_ctrl_unknown != ctrl_struct) &&
@@ -21377,7 +24195,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& enable_logic_operation(settings_logic_opr logic)
+         settings_store& enable_logic_operation(const settings_logic_opr logic)
          {
             if (
                  (e_logic_unknown != logic) &&
@@ -21395,7 +24213,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& enable_arithmetic_operation(settings_arithmetic_opr arithmetic)
+         settings_store& enable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
          {
             if (
                  (e_arith_unknown != arithmetic) &&
@@ -21413,7 +24231,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& enable_assignment_operation(settings_assignment_opr assignment)
+         settings_store& enable_assignment_operation(const settings_assignment_opr assignment)
          {
             if (
                  (e_assign_unknown != assignment) &&
@@ -21431,7 +24249,7 @@ namespace exprtk
             return (*this);
          }
 
-         settings_store& enable_inequality_operation(settings_inequality_opr inequality)
+         settings_store& enable_inequality_operation(const settings_inequality_opr inequality)
          {
             if (
                  (e_ineq_unknown != inequality) &&
@@ -21459,6 +24277,26 @@ namespace exprtk
             max_node_depth_ = max_node_depth;
          }
 
+         void set_max_local_vector_size(const std::size_t max_local_vector_size)
+         {
+            max_local_vector_size_ = max_local_vector_size;
+         }
+
+         std::size_t max_stack_depth() const
+         {
+            return max_stack_depth_;
+         }
+
+         std::size_t max_node_depth() const
+         {
+            return max_node_depth_;
+         }
+
+         std::size_t max_local_vector_size() const
+         {
+            return max_local_vector_size_;
+         }
+
       private:
 
          void load_compile_options(const std::size_t compile_options)
@@ -21501,6 +24339,7 @@ namespace exprtk
                case details::e_mul : return "*";
                case details::e_div : return "/";
                case details::e_mod : return "%";
+               case details::e_pow : return "^";
                default             : return "" ;
             }
          }
@@ -21559,13 +24398,14 @@ namespace exprtk
 
          std::size_t max_stack_depth_;
          std::size_t max_node_depth_;
+         std::size_t max_local_vector_size_;
 
          friend class parser<T>;
       };
 
       typedef settings_store settings_t;
 
-      parser(const settings_t& settings = settings_t())
+      explicit parser(const settings_t& settings = settings_t())
       : settings_(settings)
       , resolve_unknown_symbol_(false)
       , results_context_(0)
@@ -21581,6 +24421,9 @@ namespace exprtk
       , operator_joiner_2_(2)
       , operator_joiner_3_(3)
       , loop_runtime_check_(0)
+      , vector_access_runtime_check_(0)
+      , compilation_check_ptr_(0)
+      , assert_check_(0)
       {
          init_precompilation();
 
@@ -21593,15 +24436,16 @@ namespace exprtk
 
          expression_generator_.init_synthesize_map();
          expression_generator_.set_parser(*this);
-         expression_generator_.set_uom(unary_op_map_);
-         expression_generator_.set_bom(binary_op_map_);
+         expression_generator_.set_uom (unary_op_map_     );
+         expression_generator_.set_bom (binary_op_map_    );
          expression_generator_.set_ibom(inv_binary_op_map_);
-         expression_generator_.set_sf3m(sf3_map_);
-         expression_generator_.set_sf4m(sf4_map_);
+         expression_generator_.set_sf3m(sf3_map_          );
+         expression_generator_.set_sf4m(sf4_map_          );
          expression_generator_.set_strength_reduction_state(settings_.strength_reduction_enabled());
       }
 
-     ~parser() {}
+     ~parser()
+      {}
 
       inline void init_precompilation()
       {
@@ -21669,11 +24513,15 @@ namespace exprtk
 
       inline bool compile(const std::string& expression_string, expression<T>& expr)
       {
-         state_          .reset();
-         error_list_     .clear();
-         brkcnt_list_    .clear();
-         synthesis_error_.clear();
-         sem_            .cleanup();
+         state_               .reset();
+         error_list_          .clear();
+         brkcnt_list_         .clear();
+         synthesis_error_     .clear();
+         immutable_memory_map_.reset();
+         immutable_symtok_map_.clear();
+         current_state_stack_ .clear();
+         assert_ids_          .clear();
+         sem_                 .cleanup();
 
          return_cleanup();
 
@@ -21681,10 +24529,10 @@ namespace exprtk
 
          if (expression_string.empty())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          "ERR001 - Empty expression!",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               "ERR001 - Empty expression!",
+               exprtk_error_location));
 
             return false;
          }
@@ -21697,19 +24545,31 @@ namespace exprtk
 
          if (lexer().empty())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          "ERR002 - Empty expression!",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               "ERR002 - Empty expression!",
+               exprtk_error_location));
 
             return false;
          }
 
+         if (halt_compilation_check())
+         {
+            exprtk_debug(("halt_compilation_check() - compile checkpoint 0\n"));
+            return false;
+         }
+
          if (!run_assemblies())
          {
             return false;
          }
 
+         if (halt_compilation_check())
+         {
+            exprtk_debug(("halt_compilation_check() - compile checkpoint 1\n"));
+            return false;
+         }
+
          symtab_store_.symtab_list_ = expr.get_symbol_table_list();
          dec_.clear();
 
@@ -21743,11 +24603,11 @@ namespace exprtk
          {
             if (error_list_.empty())
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR003 - Invalid expression encountered",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR003 - Invalid expression encountered",
+                  exprtk_error_location));
             }
 
             if ((0 != e) && branch_deletable(e))
@@ -21799,11 +24659,11 @@ namespace exprtk
                   default                         : diagnostic += "Unknown compiler error";
                }
 
-               set_error(
-                  make_error(parser_error::e_lexer,
-                             lexer()[i],
-                             diagnostic + ": " + lexer()[i].value,
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_lexer,
+                  lexer()[i],
+                  diagnostic + ": " + lexer()[i].value,
+                  exprtk_error_location));
             }
          }
       }
@@ -21842,11 +24702,11 @@ namespace exprtk
 
                   if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
                   {
-                     set_error(
-                        make_error(parser_error::e_token,
-                                   bracket_checker_ptr->error_token(),
-                                   "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'",
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_token,
+                        bracket_checker_ptr->error_token(),
+                        "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'",
+                        exprtk_error_location));
                   }
                   else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker<T>*>(helper_assembly_.error_token_scanner)))
                   {
@@ -21854,11 +24714,11 @@ namespace exprtk
                      {
                         lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)];
 
-                        set_error(
-                           make_error(parser_error::e_token,
-                                      error_token,
-                                      "ERR006 - Invalid numeric token: '" + error_token.value + "'",
-                                      exprtk_error_location));
+                        set_error(make_error(
+                           parser_error::e_token,
+                           error_token,
+                           "ERR006 - Invalid numeric token: '" + error_token.value + "'",
+                           exprtk_error_location));
                      }
 
                      if (numeric_checker_ptr->error_count())
@@ -21872,13 +24732,13 @@ namespace exprtk
                      {
                         std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i);
 
-                        set_error(
-                           make_error(parser_error::e_token,
-                                      error_token.first,
-                                      "ERR007 - Invalid token sequence: '" +
-                                      error_token.first.value  + "' and '" +
-                                      error_token.second.value + "'",
-                                      exprtk_error_location));
+                        set_error(make_error(
+                           parser_error::e_token,
+                           error_token.first,
+                           "ERR007 - Invalid token sequence: '" +
+                           error_token.first.value  + "' and '" +
+                           error_token.second.value + "'",
+                           exprtk_error_location));
                      }
 
                      if (sequence_validator_ptr->error_count())
@@ -21892,13 +24752,13 @@ namespace exprtk
                      {
                         std::pair<lexer::token,lexer::token> error_token = sequence_validator3_ptr->error(i);
 
-                        set_error(
-                           make_error(parser_error::e_token,
-                                      error_token.first,
-                                      "ERR008 - Invalid token sequence: '" +
-                                      error_token.first.value  + "' and '" +
-                                      error_token.second.value + "'",
-                                      exprtk_error_location));
+                        set_error(make_error(
+                           parser_error::e_token,
+                           error_token.first,
+                           "ERR008 - Invalid token sequence: '" +
+                           error_token.first.value  + "' and '" +
+                           error_token.second.value + "'",
+                           exprtk_error_location));
                      }
 
                      if (sequence_validator3_ptr->error_count())
@@ -21923,9 +24783,11 @@ namespace exprtk
       inline parser_error::type get_error(const std::size_t& index) const
       {
          if (index < error_list_.size())
+         {
             return error_list_[index];
-         else
-            throw std::invalid_argument("parser::get_error() - Invalid error index specificed");
+         }
+
+         throw std::invalid_argument("parser::get_error() - Invalid error index specified");
       }
 
       inline std::string error() const
@@ -21994,11 +24856,41 @@ namespace exprtk
          loop_runtime_check_ = &lrtchk;
       }
 
+      inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk)
+      {
+         vector_access_runtime_check_ = &vartchk;
+      }
+
+      inline void register_compilation_timeout_check(compilation_check& compchk)
+      {
+         compilation_check_ptr_ = &compchk;
+      }
+
+      inline void register_assert_check(assert_check& assrt_chck)
+      {
+         assert_check_ = &assrt_chck;
+      }
+
       inline void clear_loop_runtime_check()
       {
          loop_runtime_check_ = loop_runtime_check_ptr(0);
       }
 
+      inline void clear_vector_access_runtime_check()
+      {
+         vector_access_runtime_check_ = vector_access_runtime_check_ptr(0);
+      }
+
+      inline void clear_compilation_timeout_check()
+      {
+         compilation_check_ptr_ = compilation_check_ptr(0);
+      }
+
+      inline void clear_assert_check()
+      {
+         assert_check_ = assert_check_ptr(0);
+      }
+
    private:
 
       inline bool valid_base_operation(const std::string& symbol) const
@@ -22102,11 +24994,11 @@ namespace exprtk
             {
                if (error_list_.empty())
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR009 - Invalid expression encountered",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR009 - Invalid expression encountered",
+                     exprtk_error_location));
                }
 
                return error_node();
@@ -22132,15 +25024,31 @@ namespace exprtk
                exprtk_debug(("-------------------------------------------------\n"));
             }
 
-            if (lexer().finished())
-               break;
-            else if (token_is(token_t::e_eof,prsrhlpr_t::e_hold))
+            if (token_is(token_t::e_eof,prsrhlpr_t::e_hold))
             {
                if (lexer().finished())
                   break;
                else
                   next_token();
             }
+            else if (
+                      !settings_.commutative_check_enabled() &&
+                      (
+                        current_token().type == token_t::e_symbol ||
+                        current_token().type == token_t::e_number ||
+                        current_token().type == token_t::e_string ||
+                        token_is_bracket(prsrhlpr_t::e_hold)
+                      )
+                    )
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR010 - Invalid syntax '" + current_token().value  + "' possible missing operator or context",
+                  exprtk_error_location));
+
+               return error_node();
+            }
          }
 
          if (
@@ -22158,13 +25066,17 @@ namespace exprtk
          return result;
       }
 
-      std::string construct_subexpr(lexer::token& begin_token, lexer::token& end_token)
+      std::string construct_subexpr(lexer::token& begin_token,
+                                    lexer::token& end_token,
+                                    const bool cleanup_whitespace = true)
       {
          std::string result = lexer().substr(begin_token.position,end_token.position);
-
-         for (std::size_t i = 0; i < result.size(); ++i)
+         if (cleanup_whitespace)
          {
-            if (details::is_whitespace(result[i])) result[i] = ' ';
+            for (std::size_t i = 0; i < result.size(); ++i)
+            {
+               if (details::is_whitespace(result[i])) result[i] = ' ';
+            }
          }
 
          return result;
@@ -22176,11 +25088,13 @@ namespace exprtk
       {
          inline void set(const precedence_level& l,
                          const precedence_level& r,
-                         const details::operator_type& o)
+                         const details::operator_type& o,
+                         const token_t tkn = token_t())
          {
-            left  = l;
-            right = r;
+            left      = l;
+            right     = r;
             operation = o;
+            token     = tkn;
          }
 
          inline void reset()
@@ -22193,10 +25107,58 @@ namespace exprtk
          precedence_level left;
          precedence_level right;
          details::operator_type operation;
+         token_t token;
       };
 
+      inline void push_current_state(const state_t current_state)
+      {
+         current_state_stack_.push_back(current_state);
+      }
+
+      inline void pop_current_state()
+      {
+         if (!current_state_stack_.empty())
+         {
+            current_state_stack_.pop_back();
+         }
+      }
+
+      inline state_t current_state() const
+      {
+         return (!current_state_stack_.empty()) ?
+                current_state_stack_.back()     :
+                state_t();
+      }
+
+      inline bool halt_compilation_check()
+      {
+         compilation_check::compilation_context context;
+
+         if (compilation_check_ptr_ && !compilation_check_ptr_->continue_compilation(context))
+         {
+            const std::string error_message =
+               !context.error_message.empty() ? " Details: " + context.error_message : "";
+
+            set_error(make_error(
+               parser_error::e_parser,
+               token_t(),
+               "ERR011 - Internal compilation check failed." + error_message,
+               exprtk_error_location));
+
+            return true;
+         }
+
+         return false;
+      }
+
       inline expression_node_ptr parse_expression(precedence_level precedence = e_level00)
       {
+         if (halt_compilation_check())
+         {
+            exprtk_debug(("halt_compilation_check() - parse_expression checkpoint 2\n"));
+            return error_node();
+         }
+
          stack_limit_handler slh(*this);
 
          if (!slh)
@@ -22211,6 +25173,11 @@ namespace exprtk
             return error_node();
          }
 
+         if (token_is(token_t::e_eof,prsrhlpr_t::e_hold))
+         {
+            return expression;
+         }
+
          bool break_loop = false;
 
          state_t current_state;
@@ -22221,110 +25188,111 @@ namespace exprtk
 
             switch (current_token().type)
             {
-               case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign); break;
-               case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass); break;
-               case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass); break;
-               case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass); break;
-               case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass); break;
-               case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass); break;
-               case token_t::e_swap   : current_state.set(e_level00, e_level00, details::e_swap  ); break;
-               case token_t::e_lt     : current_state.set(e_level05, e_level06, details::e_lt    ); break;
-               case token_t::e_lte    : current_state.set(e_level05, e_level06, details::e_lte   ); break;
-               case token_t::e_eq     : current_state.set(e_level05, e_level06, details::e_eq    ); break;
-               case token_t::e_ne     : current_state.set(e_level05, e_level06, details::e_ne    ); break;
-               case token_t::e_gte    : current_state.set(e_level05, e_level06, details::e_gte   ); break;
-               case token_t::e_gt     : current_state.set(e_level05, e_level06, details::e_gt    ); break;
-               case token_t::e_add    : current_state.set(e_level07, e_level08, details::e_add   ); break;
-               case token_t::e_sub    : current_state.set(e_level07, e_level08, details::e_sub   ); break;
-               case token_t::e_div    : current_state.set(e_level10, e_level11, details::e_div   ); break;
-               case token_t::e_mul    : current_state.set(e_level10, e_level11, details::e_mul   ); break;
-               case token_t::e_mod    : current_state.set(e_level10, e_level11, details::e_mod   ); break;
-               case token_t::e_pow    : current_state.set(e_level12, e_level12, details::e_pow   ); break;
-               default                : if (token_t::e_symbol == current_token().type)
-                                        {
-                                           static const std::string s_and   = "and"  ;
-                                           static const std::string s_nand  = "nand" ;
-                                           static const std::string s_or    = "or"   ;
-                                           static const std::string s_nor   = "nor"  ;
-                                           static const std::string s_xor   = "xor"  ;
-                                           static const std::string s_xnor  = "xnor" ;
-                                           static const std::string s_in    = "in"   ;
-                                           static const std::string s_like  = "like" ;
-                                           static const std::string s_ilike = "ilike";
-                                           static const std::string s_and1  = "&"    ;
-                                           static const std::string s_or1   = "|"    ;
-                                           static const std::string s_not   = "not"  ;
+               case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign, current_token()); break;
+               case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass, current_token()); break;
+               case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass, current_token()); break;
+               case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass, current_token()); break;
+               case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass, current_token()); break;
+               case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass, current_token()); break;
+               case token_t::e_swap   : current_state.set(e_level00, e_level00, details::e_swap  , current_token()); break;
+               case token_t::e_lt     : current_state.set(e_level05, e_level06, details::e_lt    , current_token()); break;
+               case token_t::e_lte    : current_state.set(e_level05, e_level06, details::e_lte   , current_token()); break;
+               case token_t::e_eq     : current_state.set(e_level05, e_level06, details::e_eq    , current_token()); break;
+               case token_t::e_ne     : current_state.set(e_level05, e_level06, details::e_ne    , current_token()); break;
+               case token_t::e_gte    : current_state.set(e_level05, e_level06, details::e_gte   , current_token()); break;
+               case token_t::e_gt     : current_state.set(e_level05, e_level06, details::e_gt    , current_token()); break;
+               case token_t::e_add    : current_state.set(e_level07, e_level08, details::e_add   , current_token()); break;
+               case token_t::e_sub    : current_state.set(e_level07, e_level08, details::e_sub   , current_token()); break;
+               case token_t::e_div    : current_state.set(e_level10, e_level11, details::e_div   , current_token()); break;
+               case token_t::e_mul    : current_state.set(e_level10, e_level11, details::e_mul   , current_token()); break;
+               case token_t::e_mod    : current_state.set(e_level10, e_level11, details::e_mod   , current_token()); break;
+               case token_t::e_pow    : current_state.set(e_level12, e_level12, details::e_pow   , current_token()); break;
+               default                :
+                  if (token_t::e_symbol == current_token().type)
+                  {
+                     static const std::string s_and   = "and"  ;
+                     static const std::string s_nand  = "nand" ;
+                     static const std::string s_or    = "or"   ;
+                     static const std::string s_nor   = "nor"  ;
+                     static const std::string s_xor   = "xor"  ;
+                     static const std::string s_xnor  = "xnor" ;
+                     static const std::string s_in    = "in"   ;
+                     static const std::string s_like  = "like" ;
+                     static const std::string s_ilike = "ilike";
+                     static const std::string s_and1  = "&"    ;
+                     static const std::string s_or1   = "|"    ;
+                     static const std::string s_not   = "not"  ;
 
-                                           if (details::imatch(current_token().value,s_and))
-                                           {
-                                              current_state.set(e_level03, e_level04, details::e_and);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_and1))
-                                           {
-                                              #ifndef exprtk_disable_sc_andor
-                                              current_state.set(e_level03, e_level04, details::e_scand);
-                                              #else
-                                              current_state.set(e_level03, e_level04, details::e_and);
-                                              #endif
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_nand))
-                                           {
-                                              current_state.set(e_level03, e_level04, details::e_nand);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_or))
-                                           {
-                                              current_state.set(e_level01, e_level02, details::e_or);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_or1))
-                                           {
-                                              #ifndef exprtk_disable_sc_andor
-                                              current_state.set(e_level01, e_level02, details::e_scor);
-                                              #else
-                                              current_state.set(e_level01, e_level02, details::e_or);
-                                              #endif
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_nor))
-                                           {
-                                              current_state.set(e_level01, e_level02, details::e_nor);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_xor))
-                                           {
-                                              current_state.set(e_level01, e_level02, details::e_xor);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_xnor))
-                                           {
-                                              current_state.set(e_level01, e_level02, details::e_xnor);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_in))
-                                           {
-                                              current_state.set(e_level04, e_level04, details::e_in);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_like))
-                                           {
-                                              current_state.set(e_level04, e_level04, details::e_like);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_ilike))
-                                           {
-                                              current_state.set(e_level04, e_level04, details::e_ilike);
-                                              break;
-                                           }
-                                           else if (details::imatch(current_token().value,s_not))
-                                           {
-                                              break;
-                                           }
-                                        }
+                     if (details::imatch(current_token().value,s_and))
+                     {
+                        current_state.set(e_level03, e_level04, details::e_and, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_and1))
+                     {
+                        #ifndef exprtk_disable_sc_andor
+                        current_state.set(e_level03, e_level04, details::e_scand, current_token());
+                        #else
+                        current_state.set(e_level03, e_level04, details::e_and, current_token());
+                        #endif
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_nand))
+                     {
+                        current_state.set(e_level03, e_level04, details::e_nand, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_or))
+                     {
+                        current_state.set(e_level01, e_level02, details::e_or, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_or1))
+                     {
+                        #ifndef exprtk_disable_sc_andor
+                        current_state.set(e_level01, e_level02, details::e_scor, current_token());
+                        #else
+                        current_state.set(e_level01, e_level02, details::e_or, current_token());
+                        #endif
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_nor))
+                     {
+                        current_state.set(e_level01, e_level02, details::e_nor, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_xor))
+                     {
+                        current_state.set(e_level01, e_level02, details::e_xor, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_xnor))
+                     {
+                        current_state.set(e_level01, e_level02, details::e_xnor, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_in))
+                     {
+                        current_state.set(e_level04, e_level04, details::e_in, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_like))
+                     {
+                        current_state.set(e_level04, e_level04, details::e_like, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_ilike))
+                     {
+                        current_state.set(e_level04, e_level04, details::e_ilike, current_token());
+                        break;
+                     }
+                     else if (details::imatch(current_token().value,s_not))
+                     {
+                        break;
+                     }
+                  }
 
-                                        break_loop = true;
+                  break_loop = true;
             }
 
             if (break_loop)
@@ -22344,49 +25312,49 @@ namespace exprtk
 
             if (is_invalid_logic_operation(current_state.operation))
             {
-               free_node(node_allocator_,expression);
+               free_node(node_allocator_, expression);
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             prev_token,
-                             "ERR010 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  prev_token,
+                  "ERR012 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
             else if (is_invalid_arithmetic_operation(current_state.operation))
             {
-               free_node(node_allocator_,expression);
+               free_node(node_allocator_, expression);
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             prev_token,
-                             "ERR011 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  prev_token,
+                  "ERR013 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
             else if (is_invalid_inequality_operation(current_state.operation))
             {
-               free_node(node_allocator_,expression);
+               free_node(node_allocator_, expression);
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             prev_token,
-                             "ERR012 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  prev_token,
+                  "ERR014 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
             else if (is_invalid_assignment_operation(current_state.operation))
             {
-               free_node(node_allocator_,expression);
+               free_node(node_allocator_, expression);
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             prev_token,
-                             "ERR013 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  prev_token,
+                  "ERR015 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22401,34 +25369,38 @@ namespace exprtk
                   free_node(node_allocator_, expression  );
                   free_node(node_allocator_, right_branch);
 
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                prev_token,
-                                "ERR014 - Return statements cannot be part of sub-expressions",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     prev_token,
+                     "ERR016 - Return statements cannot be part of sub-expressions",
+                     exprtk_error_location));
 
                   return error_node();
                }
 
+               push_current_state(current_state);
+
                new_expression = expression_generator_
                                   (
                                     current_state.operation,
                                     expression,
                                     right_branch
                                   );
+
+               pop_current_state();
             }
 
             if (0 == new_expression)
             {
                if (error_list_.empty())
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                prev_token,
-                                !synthesis_error_.empty() ?
-                                synthesis_error_ :
-                                "ERR015 - General parsing error at token: '" + prev_token.value + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     prev_token,
+                     !synthesis_error_.empty() ?
+                     synthesis_error_ :
+                     "ERR017 - General parsing error at token: '" + prev_token.value + "'",
+                     exprtk_error_location));
                }
 
                free_node(node_allocator_, expression  );
@@ -22454,14 +25426,35 @@ namespace exprtk
 
          if ((0 != expression) && (expression->node_depth() > settings_.max_node_depth_))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                  current_token(),
-                  "ERR016 - Expression depth of " + details::to_str(static_cast<int>(expression->node_depth())) +
-                  " exceeds maximum allowed expression depth of " + details::to_str(static_cast<int>(settings_.max_node_depth_)),
-                  exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR018 - Expression depth of " + details::to_str(static_cast<int>(expression->node_depth())) +
+               " exceeds maximum allowed expression depth of " + details::to_str(static_cast<int>(settings_.max_node_depth_)),
+               exprtk_error_location));
 
-            free_node(node_allocator_,expression);
+            free_node(node_allocator_, expression);
+
+            return error_node();
+         }
+         else if (
+                   !settings_.commutative_check_enabled()          &&
+                   !details::is_logic_opr(current_token().value)   &&
+                   (current_state.operation == details::e_default) &&
+                   (
+                     current_token().type == token_t::e_symbol ||
+                     current_token().type == token_t::e_number ||
+                     current_token().type == token_t::e_string
+                   )
+                 )
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR019 - Invalid syntax '" + current_token().value  + "' possible missing operator or context",
+               exprtk_error_location));
+
+            free_node(node_allocator_, expression);
 
             return error_node();
          }
@@ -22479,7 +25472,7 @@ namespace exprtk
             {
                expression_node_ptr un_r = n->branch(0);
                n->release();
-               free_node(node_allocator_,node);
+               free_node(node_allocator_, node);
                node = un_r;
 
                return true;
@@ -22501,20 +25494,20 @@ namespace exprtk
                     (0 != (return_node = sem_         .get_variable(v)))
                   )
                {
-                  free_node(node_allocator_,node);
+                  free_node(node_allocator_, node);
                   node = return_node;
 
                   return true;
                }
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR017 - Failed to find variable node in symbol table",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR020 - Failed to find variable node in symbol table",
+                     exprtk_error_location));
 
-                  free_node(node_allocator_,node);
+                  free_node(node_allocator_, node);
 
                   return false;
                }
@@ -22610,6 +25603,7 @@ namespace exprtk
             {
                for (std::size_t i = 0; i < deq_.size(); ++i)
                {
+                  exprtk_debug(("~scoped_deq_delete() - deleting node: %p\n", reinterpret_cast<void*>(deq_[i])));
                   free_node(parser_.node_allocator_,deq_[i]);
                }
 
@@ -22644,6 +25638,7 @@ namespace exprtk
             {
                for (std::size_t i = 0; i < vec_.size(); ++i)
                {
+                  exprtk_debug(("~scoped_vec_delete() - deleting node: %p\n", reinterpret_cast<void*>(vec_[i])));
                   free_node(parser_.node_allocator_,vec_[i]);
                }
 
@@ -22651,6 +25646,11 @@ namespace exprtk
             }
          }
 
+         ptr_t operator[](const std::size_t index)
+         {
+            return vec_[index];
+         }
+
          bool delete_ptr;
          parser<T>& parser_;
          std::vector<ptr_t>& vec_;
@@ -22732,11 +25732,11 @@ namespace exprtk
             case 19 : func_node = parse_function_call<19>(function,function_name); break;
             case 20 : func_node = parse_function_call<20>(function,function_name); break;
             default : {
-                         set_error(
-                            make_error(parser_error::e_syntax,
-                                       current_token(),
-                                       "ERR018 - Invalid number of parameters for function: '" + function_name + "'",
-                                       exprtk_error_location));
+                         set_error(make_error(
+                           parser_error::e_syntax,
+                           current_token(),
+                           "ERR021 - Invalid number of parameters for function: '" + function_name + "'",
+                           exprtk_error_location));
 
                          return error_node();
                       }
@@ -22746,11 +25746,11 @@ namespace exprtk
             return func_node;
          else
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR019 - Failed to generate call to function: '" + function_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR022 - Failed to generate call to function: '" + function_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22765,11 +25765,11 @@ namespace exprtk
          #endif
          if (0 == NumberofParameters)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR020 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR023 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22788,11 +25788,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR021 - Expecting argument list for function: '" + function_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR024 - Expecting argument list for function: '" + function_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22803,11 +25803,11 @@ namespace exprtk
 
             if (0 == branch[i])
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR022 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR025 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22815,11 +25815,11 @@ namespace exprtk
             {
                if (!token_is(token_t::e_comma))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR023 - Invalid number of arguments for function: '" + function_name + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR026 - Invalid number of arguments for function: '" + function_name + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -22828,11 +25828,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_rbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR024 - Invalid number of arguments for function: '" + function_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR027 - Invalid number of arguments for function: '" + function_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22857,13 +25857,13 @@ namespace exprtk
               !token_is(token_t::e_rbracket)
             )
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR025 - Expecting '()' to proceed call to function: '" + function_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR028 - Expecting '()' to proceed call to function: '" + function_name + "'",
+               exprtk_error_location));
 
-            free_node(node_allocator_,result);
+            free_node(node_allocator_, result);
 
             return error_node();
          }
@@ -22882,23 +25882,23 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR026 - Expected a '(' at start of function call to '" + function_name  +
-                          "', instead got: '" + current_token().value + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR029 - Expected a '(' at start of function call to '" + function_name  +
+               "', instead got: '" + current_token().value + "'",
+               exprtk_error_location));
 
             return 0;
          }
 
          if (token_is(token_t::e_rbracket, e_hold))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR027 - Expected at least one input parameter for function call '" + function_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR030 - Expected at least one input parameter for function call '" + function_name + "'",
+               exprtk_error_location));
 
             return 0;
          }
@@ -22920,11 +25920,11 @@ namespace exprtk
                continue;
             else
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR028 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR031 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
+                  exprtk_error_location));
 
                return 0;
             }
@@ -22932,11 +25932,11 @@ namespace exprtk
 
          if (sd.delete_ptr)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR029 - Invalid number of input parameters passed to function '" + function_name  + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR032 - Invalid number of input parameters passed to function '" + function_name  + "'",
+               exprtk_error_location));
 
             return 0;
          }
@@ -22955,11 +25955,11 @@ namespace exprtk
 
          if (0 == std::distance(itr_range.first,itr_range.second))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          diagnostic_token,
-                          "ERR030 - No entry found for base operation: " + operation_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               diagnostic_token,
+               "ERR033 - No entry found for base operation: " + operation_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23002,11 +26002,11 @@ namespace exprtk
             free_node(node_allocator_, param_list[i]);
          }
 
-         set_error(
-            make_error(parser_error::e_syntax,
-                       diagnostic_token,
-                       "ERR031 - Invalid number of input parameters for call to function: '" + operation_name + "'",
-                       exprtk_error_location));
+         set_error(make_error(
+            parser_error::e_syntax,
+            diagnostic_token,
+            "ERR034 - Invalid number of input parameters for call to function: '" + operation_name + "'",
+            exprtk_error_location));
 
          return error_node();
       }
@@ -23022,47 +26022,52 @@ namespace exprtk
 
          if (!token_is(token_t::e_comma))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR032 - Expected ',' between if-statement condition and consequent",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR035 - Expected ',' between if-statement condition and consequent",
+               exprtk_error_location));
+
             result = false;
          }
          else if (0 == (consequent = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR033 - Failed to parse consequent for if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR036 - Failed to parse consequent for if-statement",
+               exprtk_error_location));
+
             result = false;
          }
          else if (!token_is(token_t::e_comma))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR034 - Expected ',' between if-statement consequent and alternative",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR037 - Expected ',' between if-statement consequent and alternative",
+               exprtk_error_location));
+
             result = false;
          }
          else if (0 == (alternative = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR035 - Failed to parse alternative for if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR038 - Failed to parse alternative for if-statement",
+               exprtk_error_location));
+
             result = false;
          }
          else if (!token_is(token_t::e_rbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR036 - Expected ')' at the end of if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR039 - Expected ')' at the end of if-statement",
+               exprtk_error_location));
+
             result = false;
          }
 
@@ -23076,15 +26081,30 @@ namespace exprtk
             {
                if (consq_is_str && alter_is_str)
                {
-                  return expression_generator_
-                           .conditional_string(condition, consequent, alternative);
+                  expression_node_ptr result_node =
+                     expression_generator_
+                        .conditional_string(condition, consequent, alternative);
+
+                  if (result_node && result_node->valid())
+                  {
+                     return result_node;
+                  }
+
+                  set_error(make_error(
+                     parser_error::e_synthesis,
+                     current_token(),
+                     "ERR040 - Failed to synthesize node: conditional_string",
+                     exprtk_error_location));
+
+                  free_node(node_allocator_, result_node);
+                  return error_node();
                }
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR037 - Return types of if-statement differ: string/non-string",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR041 - Return types of if-statement differ: string/non-string",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23104,11 +26124,11 @@ namespace exprtk
                            .conditional_vector(condition, consequent, alternative);
                }
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR038 - Return types of if-statement differ: vector/non-vector",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR042 - Return types of if-statement differ: vector/non-vector",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23138,11 +26158,31 @@ namespace exprtk
          {
             if (0 == (consequent = parse_multi_sequence("if-statement-01")))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR039 - Failed to parse body of consequent for if-statement",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR043 - Failed to parse body of consequent for if-statement",
+                  exprtk_error_location));
+
+               result = false;
+            }
+            else if
+            (
+              !settings_.commutative_check_enabled()           &&
+              !token_is("else",prsrhlpr_t::e_hold)             &&
+              !token_is_loop(prsrhlpr_t::e_hold)               &&
+              !token_is_arithmetic_opr(prsrhlpr_t::e_hold)     &&
+              !token_is_right_bracket (prsrhlpr_t::e_hold)     &&
+              !token_is_ineq_opr      (prsrhlpr_t::e_hold)     &&
+              !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
+              !token_is(token_t::e_eof    ,prsrhlpr_t::e_hold)
+            )
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR044 - Expected ';' at the end of the consequent for if-statement (1)",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23159,24 +26199,24 @@ namespace exprtk
 
             if (0 != (consequent = parse_expression()))
             {
-               if (!token_is(token_t::e_eof))
+               if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR040 - Expected ';' at the end of the consequent for if-statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR045 - Expected ';' at the end of the consequent for if-statement (2)",
+                     exprtk_error_location));
 
                   result = false;
                }
             }
             else
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR041 - Failed to parse body of consequent for if-statement",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR046 - Failed to parse body of consequent for if-statement",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23184,19 +26224,27 @@ namespace exprtk
 
          if (result)
          {
-            if (details::imatch(current_token().value,"else"))
+            if (
+                 details::imatch(current_token().value,"else") ||
+                 (token_is(token_t::e_eof, prsrhlpr_t::e_hold) && peek_token_is("else"))
+               )
             {
                next_token();
 
+               if (details::imatch(current_token().value,"else"))
+               {
+                  next_token();
+               }
+
                if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
                {
                   if (0 == (alternative = parse_multi_sequence("else-statement-01")))
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR042 - Failed to parse body of the 'else' for if-statement",
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR047 - Failed to parse body of the 'else' for if-statement",
+                        exprtk_error_location));
 
                      result = false;
                   }
@@ -23205,35 +26253,39 @@ namespace exprtk
                {
                   if (0 == (alternative = parse_conditional_statement()))
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR043 - Failed to parse body of if-else statement",
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR048 - Failed to parse body of if-else statement",
+                        exprtk_error_location));
 
                      result = false;
                   }
                }
                else if (0 != (alternative = parse_expression()))
                {
-                  if (!token_is(token_t::e_eof))
+                  if (
+                       !token_is(token_t::e_ternary    , prsrhlpr_t::e_hold) &&
+                       !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
+                       !token_is(token_t::e_eof)
+                     )
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR044 - Expected ';' at the end of the 'else-if' for the if-statement",
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR049 - Expected ';' at the end of the 'else-if' for the if-statement",
+                        exprtk_error_location));
 
                      result = false;
                   }
                }
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR045 - Failed to parse body of the 'else' for if-statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR050 - Failed to parse body of the 'else' for if-statement",
+                     exprtk_error_location));
 
                   result = false;
                }
@@ -23254,11 +26306,11 @@ namespace exprtk
                            .conditional_string(condition, consequent, alternative);
                }
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR046 - Return types of if-statement differ: string/non-string",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR051 - Return types of if-statement differ: string/non-string",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23278,11 +26330,11 @@ namespace exprtk
                            .conditional_vector(condition, consequent, alternative);
                }
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR047 - Return types of if-statement differ: vector/non-vector",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR052 - Return types of if-statement differ: vector/non-vector",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23309,21 +26361,21 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR048 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR053 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (0 == (condition = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR049 - Failed to parse condition for if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR054 - Failed to parse condition for if-statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23353,13 +26405,13 @@ namespace exprtk
             return parse_conditional_statement_02(condition);
          }
 
-         set_error(
-            make_error(parser_error::e_syntax,
-                       current_token(),
-                       "ERR050 - Invalid if-statement",
-                       exprtk_error_location));
+         set_error(make_error(
+            parser_error::e_syntax,
+            current_token(),
+            "ERR055 - Invalid if-statement",
+            exprtk_error_location));
 
-         free_node(node_allocator_,condition);
+         free_node(node_allocator_, condition);
 
          return error_node();
       }
@@ -23374,51 +26426,51 @@ namespace exprtk
 
          if (0 == condition)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR051 - Encountered invalid condition branch for ternary if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR056 - Encountered invalid condition branch for ternary if-statement",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (!token_is(token_t::e_ternary))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR052 - Expected '?' after condition of ternary if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR057 - Expected '?' after condition of ternary if-statement",
+               exprtk_error_location));
 
             result = false;
          }
          else if (0 == (consequent = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR053 - Failed to parse consequent for ternary if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR058 - Failed to parse consequent for ternary if-statement",
+               exprtk_error_location));
 
             result = false;
          }
          else if (!token_is(token_t::e_colon))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR054 - Expected ':' between ternary if-statement consequent and alternative",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR059 - Expected ':' between ternary if-statement consequent and alternative",
+               exprtk_error_location));
 
             result = false;
          }
          else if (0 == (alternative = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR055 - Failed to parse alternative for ternary if-statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR060 - Failed to parse alternative for ternary if-statement",
+               exprtk_error_location));
 
             result = false;
          }
@@ -23437,11 +26489,11 @@ namespace exprtk
                            .conditional_string(condition, consequent, alternative);
                }
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR056 - Return types of ternary differ: string/non-string",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR061 - Return types of ternary differ: string/non-string",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23461,11 +26513,11 @@ namespace exprtk
                            .conditional_vector(condition, consequent, alternative);
                }
 
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR057 - Return types of ternary differ: vector/non-vector",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR062 - Return types of ternary differ: vector/non-vector",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23488,11 +26540,11 @@ namespace exprtk
       {
          if (settings_.logic_disabled("not"))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR058 - Invalid or disabled logic operation 'not'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR063 - Invalid or disabled logic operation 'not'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23519,31 +26571,31 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR059 - Expected '(' at start of while-loop condition statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR064 - Expected '(' at start of while-loop condition statement",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (0 == (condition = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR060 - Failed to parse condition for while-loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR065 - Failed to parse condition for while-loop",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (!token_is(token_t::e_rbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR061 - Expected ')' at end of while-loop condition statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR066 - Expected ')' at end of while-loop condition statement",
+               exprtk_error_location));
 
             result = false;
          }
@@ -23556,21 +26608,21 @@ namespace exprtk
 
             if (0 == (branch = parse_multi_sequence("while-loop", true)))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR062 - Failed to parse body of while-loop"));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR067 - Failed to parse body of while-loop"));
                result = false;
             }
             else if (0 == (result_node = expression_generator_.while_loop(condition,
                                                                           branch,
                                                                           brkcnt_list_.front())))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR063 - Failed to synthesize while-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR068 - Failed to synthesize while-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23587,7 +26639,20 @@ namespace exprtk
             return error_node();
          }
 
-         return result_node;
+         if (result_node && result_node->valid())
+         {
+            return result_node;
+         }
+
+         set_error(make_error(
+            parser_error::e_synthesis,
+            current_token(),
+            "ERR069 - Failed to synthesize 'valid' while-loop",
+            exprtk_error_location));
+
+         free_node(node_allocator_, result_node);
+
+         return error_node();
       }
 
       inline expression_node_ptr parse_repeat_until_loop()
@@ -23611,7 +26676,7 @@ namespace exprtk
          }
          else
          {
-            const token_t::token_type seperator = token_t::e_eof;
+            const token_t::token_type separator = token_t::e_eof;
 
             scope_handler sh(*this);
 
@@ -23642,13 +26707,13 @@ namespace exprtk
                const bool is_next_until = peek_token_is(token_t::e_symbol) &&
                                           peek_token_is("until");
 
-               if (!token_is(seperator) && is_next_until)
+               if (!token_is(separator) && is_next_until)
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR064 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR070 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -23666,11 +26731,11 @@ namespace exprtk
 
             if (sdd.delete_ptr)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR065 - Failed to parse body of repeat until loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR071 - Failed to parse body of repeat until loop",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -23678,33 +26743,33 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR066 - Expected '(' before condition statement of repeat until loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR072 - Expected '(' before condition statement of repeat until loop",
+               exprtk_error_location));
 
-            free_node(node_allocator_,branch);
+            free_node(node_allocator_, branch);
             return error_node();
          }
          else if (0 == (condition = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR067 - Failed to parse condition for repeat until loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR073 - Failed to parse condition for repeat until loop",
+               exprtk_error_location));
 
-            free_node(node_allocator_,branch);
+            free_node(node_allocator_, branch);
             return error_node();
          }
          else if (!token_is(token_t::e_rbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR068 - Expected ')' after condition of repeat until loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR074 - Expected ')' after condition of repeat until loop",
+               exprtk_error_location));
 
             free_node(node_allocator_, branch   );
             free_node(node_allocator_, condition);
@@ -23712,27 +26777,42 @@ namespace exprtk
             return error_node();
          }
 
-         expression_node_ptr result;
+         expression_node_ptr result_node =
+            expression_generator_
+               .repeat_until_loop(
+                  condition,
+                  branch,
+                  brkcnt_list_.front());
 
-         result = expression_generator_
-                     .repeat_until_loop(condition, branch, brkcnt_list_.front());
-
-         if (0 == result)
+         if (0 == result_node)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR069 - Failed to synthesize repeat until loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR075 - Failed to synthesize repeat until loop",
+               exprtk_error_location));
 
-            free_node(node_allocator_,condition);
+            free_node(node_allocator_, condition);
 
             return error_node();
          }
 
          handle_brkcnt_scope_exit();
 
-         return result;
+         if (result_node && result_node->valid())
+         {
+            return result_node;
+         }
+
+         set_error(make_error(
+            parser_error::e_synthesis,
+            current_token(),
+            "ERR076 - Failed to synthesize 'valid' repeat until loop",
+            exprtk_error_location));
+
+         free_node(node_allocator_, result_node);
+
+         return error_node();
       }
 
       inline expression_node_ptr parse_for_loop()
@@ -23751,11 +26831,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR070 - Expected '(' at start of for-loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR077 - Expected '(' at start of for-loop",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23771,21 +26851,21 @@ namespace exprtk
 
                if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR071 - Expected a variable at the start of initialiser section of for-loop",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR078 - Expected a variable at the start of initialiser section of for-loop",
+                     exprtk_error_location));
 
                   return error_node();
                }
                else if (!peek_token_is(token_t::e_assign))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR072 - Expected variable assignment of initialiser section of for-loop",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR079 - Expected variable assignment of initialiser section of for-loop",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -23796,11 +26876,11 @@ namespace exprtk
 
                if ((se->name == loop_counter_symbol) && se->active)
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR073 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR080 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -23828,11 +26908,11 @@ namespace exprtk
 
                      if (!sem_.add_element(nse))
                      {
-                        set_error(
-                           make_error(parser_error::e_syntax,
-                                      current_token(),
-                                      "ERR074 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
-                                      exprtk_error_location));
+                        set_error(make_error(
+                           parser_error::e_syntax,
+                           current_token(),
+                           "ERR081 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
+                           exprtk_error_location));
 
                         sem_.free_element(nse);
 
@@ -23840,7 +26920,7 @@ namespace exprtk
                      }
                      else
                      {
-                        exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str()));
+                        exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n", nse.name.c_str()));
 
                         state_.activate_side_effect("parse_for_loop()");
                      }
@@ -23850,21 +26930,21 @@ namespace exprtk
 
             if (0 == (initialiser = parse_expression()))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR075 - Failed to parse initialiser of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR082 - Failed to parse initialiser of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
             else if (!token_is(token_t::e_eof))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR076 - Expected ';' after initialiser of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR083 - Expected ';' after initialiser of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23874,21 +26954,21 @@ namespace exprtk
          {
             if (0 == (condition = parse_expression()))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR077 - Failed to parse condition of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR084 - Failed to parse condition of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
             else if (!token_is(token_t::e_eof))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR078 - Expected ';' after condition section of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR085 - Expected ';' after condition section of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23898,21 +26978,21 @@ namespace exprtk
          {
             if (0 == (incrementor = parse_expression()))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR079 - Failed to parse incrementor of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR086 - Failed to parse incrementor of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
             else if (!token_is(token_t::e_rbracket))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR080 - Expected ')' after incrementor section of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR087 - Expected ')' after incrementor section of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23926,11 +27006,11 @@ namespace exprtk
 
             if (0 == (loop_body = parse_multi_sequence("for-loop", true)))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR081 - Failed to parse body of for-loop",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR088 - Failed to parse body of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23958,7 +27038,20 @@ namespace exprtk
                                            brkcnt_list_.front());
          handle_brkcnt_scope_exit();
 
-         return result_node;
+         if (result_node && result_node->valid())
+         {
+            return result_node;
+         }
+
+         set_error(make_error(
+            parser_error::e_synthesis,
+            current_token(),
+            "ERR089 - Failed to synthesize 'valid' for-loop",
+            exprtk_error_location));
+
+         free_node(node_allocator_, result_node);
+
+         return error_node();
       }
 
       inline expression_node_ptr parse_switch_statement()
@@ -23968,11 +27061,11 @@ namespace exprtk
 
          if (!details::imatch(current_token().value,"switch"))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR082 - Expected keyword 'switch'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR090 - Expected keyword 'switch'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23983,11 +27076,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_lcrlbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR083 - Expected '{' for call to switch statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR091 - Expected '{' for call to switch statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24008,18 +27101,21 @@ namespace exprtk
                   return error_node();
                else if (!token_is(token_t::e_colon))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR084 - Expected ':' for case of switch statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR092 - Expected ':' for case of switch statement",
+                     exprtk_error_location));
 
                   free_node(node_allocator_, condition);
 
                   return error_node();
                }
 
-               expression_node_ptr consequent = parse_expression();
+               expression_node_ptr consequent =
+                  (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
+                  parse_multi_sequence("switch-consequent") :
+                  parse_expression();
 
                if (0 == consequent)
                {
@@ -24029,11 +27125,11 @@ namespace exprtk
                }
                else if (!token_is(token_t::e_eof))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR085 - Expected ';' at end of case for switch statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR093 - Expected ';' at end of case for switch statement",
+                     exprtk_error_location));
 
                   free_node(node_allocator_, condition );
                   free_node(node_allocator_, consequent);
@@ -24058,11 +27154,11 @@ namespace exprtk
             {
                if (0 != default_statement)
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR086 - Multiple default cases for switch statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR094 - Multiple default cases for switch statement",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -24071,29 +27167,29 @@ namespace exprtk
 
                if (!token_is(token_t::e_colon))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR087 - Expected ':' for default of switch statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR095 - Expected ':' for default of switch statement",
+                     exprtk_error_location));
 
                   return error_node();
                }
 
-               if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
-                  default_statement = parse_multi_sequence("switch-default");
-               else
-                  default_statement = parse_expression();
+               default_statement =
+                  (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
+                  parse_multi_sequence("switch-default"):
+                  parse_expression();
 
                if (0 == default_statement)
                   return error_node();
                else if (!token_is(token_t::e_eof))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR088 - Expected ';' at end of default for switch statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR096 - Expected ';' at end of default for switch statement",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -24102,11 +27198,11 @@ namespace exprtk
                break;
             else
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR089 - Expected '}' at end of switch statement",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR097 - Expected '}' at end of switch statement",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24118,6 +27214,10 @@ namespace exprtk
          {
             arg_list.push_back(default_statement);
          }
+         else
+         {
+            arg_list.push_back(node_allocator_.allocate_c<literal_node_t>(std::numeric_limits<T>::quiet_NaN()));
+         }
 
          result = expression_generator_.switch_statement(arg_list, (0 != default_statement));
 
@@ -24133,11 +27233,11 @@ namespace exprtk
 
          if (!details::imatch(current_token().value,"[*]"))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR090 - Expected token '[*]'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR098 - Expected token '[*]'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24148,11 +27248,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_lcrlbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR091 - Expected '{' for call to [*] statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR099 - Expected '{' for call to [*] statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24161,11 +27261,11 @@ namespace exprtk
          {
             if (!details::imatch("case",current_token().value))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR092 - Expected a 'case' statement for multi-switch",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR100 - Expected a 'case' statement for multi-switch",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24179,27 +27279,30 @@ namespace exprtk
 
             if (!token_is(token_t::e_colon))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR093 - Expected ':' for case of [*] statement",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR101 - Expected ':' for case of [*] statement",
+                  exprtk_error_location));
 
                return error_node();
             }
 
-            expression_node_ptr consequent = parse_expression();
+            expression_node_ptr consequent =
+               (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
+               parse_multi_sequence("multi-switch-consequent") :
+               parse_expression();
 
             if (0 == consequent)
                return error_node();
 
             if (!token_is(token_t::e_eof))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR094 - Expected ';' at end of case for [*] statement",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR102 - Expected ';' at end of case for [*] statement",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24224,11 +27327,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_rcrlbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR095 - Expected '}' at end of [*] statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR103 - Expected '}' at end of [*] statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24250,11 +27353,11 @@ namespace exprtk
          if (details::imatch(symbol,"~"))
          {
             next_token();
-            return parse_multi_sequence();
+            return check_block_statement_closure(parse_multi_sequence());
          }
          else if (details::imatch(symbol,"[*]"))
          {
-            return parse_multi_switch_statement();
+            return check_block_statement_closure(parse_multi_switch_statement());
          }
          else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ;
          else if (details::imatch(symbol, "mand")) opt_type = details::e_mand;
@@ -24265,11 +27368,11 @@ namespace exprtk
          else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ;
          else
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR096 - Unsupported built-in vararg function: " + symbol,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR104 - Unsupported built-in vararg function: " + symbol,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24282,23 +27385,23 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR097 - Expected '(' for call to vararg function: " + symbol,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR105 - Expected '(' for call to vararg function: " + symbol,
+               exprtk_error_location));
 
             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));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR106 - vararg function: " + symbol +
+               " requires at least one input parameter",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24316,11 +27419,11 @@ namespace exprtk
                break;
             else if (!token_is(token_t::e_comma))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR099 - Expected ',' for call to vararg function: " + symbol,
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR107 - Expected ',' for call to vararg function: " + symbol,
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24337,13 +27440,13 @@ namespace exprtk
       {
          if (!token_is(token_t::e_lsqrbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR100 - Expected '[' as start of string range definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR108 - Expected '[' as start of string range definition",
+               exprtk_error_location));
 
-            free_node(node_allocator_,expression);
+            free_node(node_allocator_, expression);
 
             return error_node();
          }
@@ -24356,7 +27459,7 @@ namespace exprtk
 
          if (!parse_range(rp,true))
          {
-            free_node(node_allocator_,expression);
+            free_node(node_allocator_, expression);
 
             return error_node();
          }
@@ -24365,19 +27468,32 @@ namespace exprtk
 
          if (0 == result)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR101 - Failed to generate string range node",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR109 - Failed to generate string range node",
+               exprtk_error_location));
 
-            free_node(node_allocator_,expression);
+            free_node(node_allocator_, expression);
             rp.free();
          }
 
          rp.clear();
 
-         return result;
+         if (result && result->valid())
+         {
+            return result;
+         }
+
+         set_error(make_error(
+            parser_error::e_synthesis,
+            current_token(),
+            "ERR110 - Failed to synthesize node: string_range_node",
+            exprtk_error_location));
+
+         free_node(node_allocator_, result);
+         rp.free();
+         return error_node();
       }
       #else
       inline expression_node_ptr parse_string_range_statement(expression_node_ptr&)
@@ -24386,7 +27502,7 @@ namespace exprtk
       }
       #endif
 
-      inline void parse_pending_string_rangesize(expression_node_ptr& expression)
+      inline bool parse_pending_string_rangesize(expression_node_ptr& expression)
       {
          // Allow no more than 100 range calls, eg: s[][][]...[][]
          const std::size_t max_rangesize_parses = 100;
@@ -24404,6 +27520,61 @@ namespace exprtk
          {
             expression = parse_string_range_statement(expression);
          }
+
+         return (i > 1);
+      }
+
+      inline void parse_pending_vector_index_operator(expression_node_ptr& expression)
+      {
+         if
+            (
+              (0 != expression)           &&
+              error_list_.empty()         &&
+              is_ivector_node(expression)
+            )
+         {
+            if (
+                 settings_.commutative_check_enabled()       &&
+                 token_is(token_t::e_mul,prsrhlpr_t::e_hold) &&
+                 peek_token_is(token_t::e_lsqrbracket)
+               )
+            {
+               token_is(token_t::e_mul);
+               token_is(token_t::e_lsqrbracket);
+            }
+            else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold))
+            {
+               token_is(token_t::e_lsqrbracket);
+            }
+            else if (
+                      token_is(token_t::e_rbracket,prsrhlpr_t::e_hold) &&
+                      peek_token_is(token_t::e_lsqrbracket)
+                    )
+            {
+               token_is(token_t::e_rbracket   );
+               token_is(token_t::e_lsqrbracket);
+            }
+            else
+               return;
+
+            details::vector_interface<T>* vi = dynamic_cast<details::vector_interface<T>*>(expression);
+
+            if (vi)
+            {
+               details::vector_holder<T>& vec = vi->vec()->vec_holder();
+               const std::string vector_name  = sem_.get_vector_name(vec.data());
+               expression_node_ptr index      = parse_vector_index(vector_name);
+
+               if (index)
+               {
+                  expression = synthesize_vector_element(vector_name, &vec, expression, index);
+                  return;
+               }
+            }
+
+            free_node(node_allocator_, expression);
+            expression = error_node();
+         }
       }
 
       template <typename Allocator1,
@@ -24420,6 +27591,10 @@ namespace exprtk
 
          Sequence<expression_node_ptr,Allocator1> tmp_expression_list;
 
+         exprtk_debug(("simplify() - expression_list.size: %d  side_effect_list.size(): %d\n",
+                       static_cast<int>(expression_list .size()),
+                       static_cast<int>(side_effect_list.size())));
+
          bool return_node_present = false;
 
          for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
@@ -24439,7 +27614,7 @@ namespace exprtk
 
                for (std::size_t j = i + 1; j < expression_list.size(); ++j)
                {
-                  free_node(node_allocator_,expression_list[j]);
+                  free_node(node_allocator_, expression_list[j]);
                }
 
                return_node_present = true;
@@ -24452,7 +27627,7 @@ namespace exprtk
                       !side_effect_list[i]
                     )
             {
-               free_node(node_allocator_,expression_list[i]);
+               free_node(node_allocator_, expression_list[i]);
                continue;
             }
             else
@@ -24493,7 +27668,7 @@ namespace exprtk
       {
          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;
+         token_t::token_type separator     = token_t::e_eof;
 
          if (!token_is(open_bracket))
          {
@@ -24501,16 +27676,16 @@ namespace exprtk
             {
                open_bracket  = token_t::e_lbracket;
                close_bracket = token_t::e_rbracket;
-               seperator     = token_t::e_comma;
+               separator     = token_t::e_comma;
             }
             else
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR102 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" +
-                             ((!source.empty()) ? std::string(" section of " + source): ""),
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR111 - 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();
             }
@@ -24550,13 +27725,13 @@ namespace exprtk
 
             const bool is_next_close = peek_token_is(close_bracket);
 
-            if (!token_is(seperator) && is_next_close)
+            if (!token_is(separator) && is_next_close)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR103 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR112 - Expected '" + lexer::token::seperator_to_str(separator) + "' for call to multi-sequence section of " + source,
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24574,23 +27749,23 @@ namespace exprtk
       inline bool parse_range(range_t& rp, const bool skip_lsqr = false)
       {
          // Examples of valid ranges:
-         // 1. [1:5]     -> 1..5
-         // 2. [ :5]     -> 0..5
-         // 3. [1: ]     -> 1..end
-         // 4. [x:y]     -> x..y where x <= y
-         // 5. [x+1:y/2] -> x+1..y/2 where x+1 <= y/2
-         // 6. [ :y]     -> 0..y where 0 <= y
-         // 7. [x: ]     -> x..end where x <= end
+         // 1. [1:5]     -> [1,5)
+         // 2. [ :5]     -> [0,5)
+         // 3. [1: ]     -> [1,end)
+         // 4. [x:y]     -> [x,y) where x <= y
+         // 5. [x+1:y/2] -> [x+1,y/2) where x+1 <= y/2
+         // 6. [ :y]     -> [0,y) where 0 <= y
+         // 7. [x: ]     -> [x,end) where x <= end
 
          rp.clear();
 
          if (!skip_lsqr && !token_is(token_t::e_lsqrbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR104 - Expected '[' for start of range",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR113 - Expected '[' for start of range",
+               exprtk_error_location));
 
             return false;
          }
@@ -24607,11 +27782,11 @@ namespace exprtk
 
             if (0 == r0)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR105 - Failed parse begin section of range",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR114 - Failed parse begin section of range",
+                  exprtk_error_location));
 
                return false;
             }
@@ -24626,15 +27801,15 @@ namespace exprtk
                   rp.cache.first = rp.n0_c.second;
                }
 
-               free_node(node_allocator_,r0);
+               free_node(node_allocator_, r0);
 
                if (r0_value < T(0))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR106 - Range lower bound less than zero! Constraint: r0 >= 0",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR115 - Range lower bound less than zero! Constraint: r0 >= 0",
+                     exprtk_error_location));
 
                   return false;
                }
@@ -24647,11 +27822,11 @@ namespace exprtk
 
             if (!token_is(token_t::e_colon))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR107 - Expected ':' for break  in range",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR116 - Expected ':' for break  in range",
+                  exprtk_error_location));
 
                rp.free();
 
@@ -24670,11 +27845,11 @@ namespace exprtk
 
             if (0 == r1)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR108 - Failed parse end section of range",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR117 - Failed parse end section of range",
+                  exprtk_error_location));
 
                rp.free();
 
@@ -24691,15 +27866,15 @@ namespace exprtk
                   rp.cache.second = rp.n1_c.second;
                }
 
-               free_node(node_allocator_,r1);
+               free_node(node_allocator_, r1);
 
                if (r1_value < T(0))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR109 - Range upper bound less than zero! Constraint: r1 >= 0",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR118 - Range upper bound less than zero! Constraint: r1 >= 0",
+                     exprtk_error_location));
 
                   rp.free();
 
@@ -24714,11 +27889,11 @@ namespace exprtk
 
             if (!token_is(token_t::e_rsqrbracket))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR110 - Expected ']' for start of range",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR119 - Expected ']' for start of range",
+                  exprtk_error_location));
 
                rp.free();
 
@@ -24742,11 +27917,11 @@ namespace exprtk
 
             if (!rp_result || (r0 > r1))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR111 - Invalid range, Constraint: r0 <= r1",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR120 - Invalid range, Constraint: r0 <= r1",
+                  exprtk_error_location));
 
                return false;
             }
@@ -24786,11 +27961,11 @@ namespace exprtk
 
             if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR112 - Unknown string symbol",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR121 - Unknown string symbol",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24826,7 +28001,7 @@ namespace exprtk
 
                if (const_str_node)
                {
-                  free_node(node_allocator_,result);
+                  free_node(node_allocator_, result);
 
                   return expression_generator_(T(const_str_node->size()));
                }
@@ -24839,13 +28014,13 @@ namespace exprtk
 
             if (!parse_range(rp))
             {
-               free_node(node_allocator_,result);
+               free_node(node_allocator_, result);
 
                return error_node();
             }
             else if (const_str_node)
             {
-               free_node(node_allocator_,result);
+               free_node(node_allocator_, result);
                result = expression_generator_(const_str_node->ref(),rp);
             }
             else
@@ -24882,7 +28057,7 @@ namespace exprtk
                next_token();
                next_token();
 
-               free_node(node_allocator_,result);
+               free_node(node_allocator_, result);
 
                return expression_generator_(T(const_str.size()));
             }
@@ -24891,13 +28066,13 @@ namespace exprtk
 
             if (!parse_range(rp))
             {
-               free_node(node_allocator_,result);
+               free_node(node_allocator_, result);
                rp.free();
 
                return error_node();
             }
 
-            free_node(node_allocator_,result);
+            free_node(node_allocator_, result);
 
             if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max()))
             {
@@ -24910,13 +28085,13 @@ namespace exprtk
                  (rp.n1_c.first && (rp.n1_c.second >= const_str.size()))
                )
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "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));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR122 - 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));
 
                rp.free();
 
@@ -24940,30 +28115,60 @@ namespace exprtk
       }
       #endif
 
+      inline expression_node_ptr parse_vector_index(const std::string& vector_name = "")
+      {
+         expression_node_ptr index_expr = error_node();
+
+         if (0 == (index_expr = parse_expression()))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR123 - Failed to parse index for vector: '" + vector_name + "'",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (!token_is(token_t::e_rsqrbracket))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR124 - Expected ']' for index of vector: '" + vector_name + "'",
+               exprtk_error_location));
+
+            free_node(node_allocator_, index_expr);
+
+            return error_node();
+         }
+
+         return index_expr;
+      }
+
       inline expression_node_ptr parse_vector()
       {
-         const std::string symbol = current_token().value;
+         const std::string vector_name = current_token().value;
 
          vector_holder_ptr vec = vector_holder_ptr(0);
 
-         const scope_element& se = sem_.get_active_element(symbol);
+         const scope_element& se = sem_.get_active_element(vector_name);
 
          if (
-              !details::imatch(se.name, symbol) ||
+              !details::imatch(se.name, vector_name) ||
               (se.depth > state_.scope_depth)   ||
               (scope_element::e_vector != se.type)
             )
          {
             typedef typename symtab_store::vector_context vec_ctxt_t;
-            vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(symbol);
+            vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(vector_name);
 
             if (0 == vec_ctx.vector_holder)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR114 - Symbol '" + symbol+ " not a vector",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR125 - Symbol '" + vector_name + " not a vector",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24981,12 +28186,12 @@ namespace exprtk
             }
          }
          else
+         {
             vec = se.vec_node;
+         }
 
          assert(0 != vec);
 
-         expression_node_ptr index_expr = error_node();
-
          next_token();
 
          if (!token_is(token_t::e_lsqrbracket))
@@ -24995,31 +28200,28 @@ namespace exprtk
          }
          else if (token_is(token_t::e_rsqrbracket))
          {
-            return expression_generator_(T(vec->size()));
+            return (vec->rebaseable()) ?
+               node_allocator_.allocate<vector_size_node_t>(vec) :
+               expression_generator_(T(vec->size()));
          }
-         else if (0 == (index_expr = parse_expression()))
+
+         expression_node_ptr index_expr = parse_vector_index(vector_name);
+
+         if (index_expr)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR115 - Failed to parse index for vector: '" + symbol + "'",
-                          exprtk_error_location));
+            expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec);
 
-            return error_node();
-         }
-         else if (!token_is(token_t::e_rsqrbracket))
-         {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR116 - Expected ']' for index of vector: '" + symbol + "'",
-                          exprtk_error_location));
-
-            free_node(node_allocator_,index_expr);
-
-            return error_node();
+            return synthesize_vector_element(vector_name, vec, vec_node, index_expr);
          }
 
+         return error_node();
+      }
+
+      inline expression_node_ptr synthesize_vector_element(const std::string& vector_name,
+                                                           vector_holder_ptr vec,
+                                                           expression_node_ptr vec_node,
+                                                           expression_node_ptr index_expr)
+      {
          // Perform compile-time range check
          if (details::is_constant_node(index_expr))
          {
@@ -25028,20 +28230,21 @@ namespace exprtk
 
             if (index >= vec_size)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR117 - Index of " + details::to_str(index) + " out of range for "
-                             "vector '" + symbol + "' of size " + details::to_str(vec_size),
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR126 - Index of " + details::to_str(index) + " out of range for "
+                  "vector '" + vector_name + "' of size " + details::to_str(vec_size),
+                  exprtk_error_location));
 
-               free_node(node_allocator_,index_expr);
+               free_node(node_allocator_, vec_node  );
+               free_node(node_allocator_, index_expr);
 
                return error_node();
             }
          }
 
-         return expression_generator_.vector_element(symbol, vec, index_expr);
+         return expression_generator_.vector_element(vector_name, vec, vec_node, index_expr);
       }
 
       inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name)
@@ -25060,12 +28263,12 @@ namespace exprtk
             {
                if (!vararg_function->allow_zero_parameters())
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR118 - Zero parameter call to vararg function: "
-                                + vararg_function_name + " not allowed",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR127 - Zero parameter call to vararg function: "
+                     + vararg_function_name + " not allowed",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -25085,12 +28288,12 @@ namespace exprtk
                      break;
                   else if (!token_is(token_t::e_comma))
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR119 - Expected ',' for call to vararg function: "
-                                   + vararg_function_name,
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR128 - Expected ',' for call to vararg function: "
+                        + vararg_function_name,
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -25099,37 +28302,37 @@ namespace exprtk
          }
          else if (!vararg_function->allow_zero_parameters())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR120 - Zero parameter call to vararg function: "
-                          + vararg_function_name + " not allowed",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR129 - Zero parameter call to vararg function: "
+               + vararg_function_name + " not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
 
          if (arg_list.size() < vararg_function->min_num_args())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "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));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR130 - 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));
 
             return error_node();
          }
          else if (arg_list.size() > vararg_function->max_num_args())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "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));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR131 - 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));
 
             return error_node();
          }
@@ -25200,14 +28403,13 @@ namespace exprtk
 
             if (1 == error_list.size())
             {
-               parser_.
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                parser_.current_token(),
-                                "ERR123 - Failed parameter type check for function '" + function_name_ + "', "
-                                "Expected '" + function_definition_list_[0].param_seq +
-                                "' call set: '" + param_seq + "'",
-                                exprtk_error_location));
+               parser_.set_error(make_error(
+                  parser_error::e_syntax,
+                  parser_.current_token(),
+                  "ERR132 - Failed parameter type check for function '" + function_name_ + "', "
+                  "Expected '" + function_definition_list_[0].param_seq +
+                  "' call set: '" + param_seq + "'",
+                  exprtk_error_location));
             }
             else
             {
@@ -25222,14 +28424,13 @@ namespace exprtk
                   }
                }
 
-               parser_.
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                parser_.current_token(),
-                                "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));
+               parser_.set_error(make_error(
+                  parser_error::e_syntax,
+                  parser_.current_token(),
+                  "ERR133 - 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));
             }
 
             return false;
@@ -25364,13 +28565,12 @@ namespace exprtk
                {
                   invalid_state_ = false;
 
-                  parser_.
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   parser_.current_token(),
-                                   "ERR125 - Invalid parameter sequence of '" + param_seq_list[i] +
-                                   "' for function: " + function_name_,
-                                   exprtk_error_location));
+                  parser_.set_error(make_error(
+                     parser_error::e_syntax,
+                     parser_.current_token(),
+                     "ERR134 - Invalid parameter sequence of '" + param_seq_list[i] +
+                     "' for function: " + function_name_,
+                     exprtk_error_location));
                   return;
                }
 
@@ -25380,15 +28580,14 @@ namespace exprtk
                {
                   invalid_state_ = false;
 
-                  parser_.
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   parser_.current_token(),
-                                   "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],
-                                   exprtk_error_location));
+                  parser_.set_error(make_error(
+                     parser_error::e_syntax,
+                     parser_.current_token(),
+                     "ERR135 - 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],
+                     exprtk_error_location));
                   return;
                }
 
@@ -25424,11 +28623,11 @@ namespace exprtk
 
          if (tc.invalid())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR127 - Type checker instantiation failure for generic function: " + function_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR136 - Type checker instantiation failure for generic function: " + function_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25442,12 +28641,12 @@ namespace exprtk
                     !tc       .allow_zero_parameters()
                   )
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR128 - Zero parameter call to generic function: "
-                                + function_name + " not allowed",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR137 - Zero parameter call to generic function: "
+                     + function_name + " not allowed",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -25474,11 +28673,11 @@ namespace exprtk
                      break;
                   else if (!token_is(token_t::e_comma))
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR129 - Expected ',' for call to generic function: " + function_name,
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR138 - Expected ',' for call to generic function: " + function_name,
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -25491,12 +28690,12 @@ namespace exprtk
                    !tc      .allow_zero_parameters    ()
                  )
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR130 - Zero parameter call to generic function: "
-                          + function_name + " not allowed",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR139 - Zero parameter call to generic function: "
+               + function_name + " not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25508,22 +28707,21 @@ namespace exprtk
               !tc.verify(param_type_list, param_seq_index)
             )
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR131 - Invalid input parameter sequence for call to generic function: " + function_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR140 - Invalid input parameter sequence for call to generic function: " + function_name,
+               exprtk_error_location));
 
             return error_node();
          }
 
          expression_node_ptr result = error_node();
 
-         if (tc.paramseq_count() <= 1)
-            result = expression_generator_
-                       .generic_function_call(function, arg_list);
-         else
-            result = expression_generator_
+         result = (tc.paramseq_count() <= 1) ?
+                  expression_generator_
+                       .generic_function_call(function, arg_list) :
+                  expression_generator_
                        .generic_function_call(function, arg_list, param_seq_index);
 
          sdd.delete_ptr = (0 == result);
@@ -25546,12 +28744,12 @@ namespace exprtk
                     !tc       .allow_zero_parameters()
                   )
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR132 - Zero parameter call to generic function: "
-                                + function_name + " not allowed",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR141 - Zero parameter call to generic function: "
+                     + function_name + " not allowed",
+                     exprtk_error_location));
 
                   return false;
                }
@@ -25578,11 +28776,11 @@ namespace exprtk
                      break;
                   else if (!token_is(token_t::e_comma))
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR133 - Expected ',' for call to string function: " + function_name,
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR142 - Expected ',' for call to string function: " + function_name,
+                        exprtk_error_location));
 
                      return false;
                   }
@@ -25625,22 +28823,21 @@ namespace exprtk
 
          if (!tc.verify(param_type_list, param_seq_index))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR134 - Invalid input parameter sequence for call to string function: " + function_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR143 - Invalid input parameter sequence for call to string function: " + function_name,
+               exprtk_error_location));
 
             return error_node();
          }
 
          expression_node_ptr result = error_node();
 
-         if (tc.paramseq_count() <= 1)
-            result = expression_generator_
-                       .string_function_call(function, arg_list);
-         else
-            result = expression_generator_
+         result = (tc.paramseq_count() <= 1) ?
+                  expression_generator_
+                       .string_function_call(function, arg_list) :
+                  expression_generator_
                        .string_function_call(function, arg_list, param_seq_index);
 
          sdd.delete_ptr = (0 == result);
@@ -25677,11 +28874,11 @@ namespace exprtk
 
          if (!tc.verify(param_type_list, param_seq_index))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR135 - Invalid input parameter sequence for call to overloaded function: " + function_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR144 - Invalid input parameter sequence for call to overloaded function: " + function_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25708,11 +28905,11 @@ namespace exprtk
          }
          else
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR136 - Invalid return type for call to overloaded function: " + function_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR145 - Invalid return type for call to overloaded function: " + function_name,
+               exprtk_error_location));
          }
 
          sdd.delete_ptr = (0 == result);
@@ -25736,11 +28933,11 @@ namespace exprtk
 
             if (!p.token_is(token_t::e_lbracket))
             {
-               p.set_error(
-                    make_error(parser_error::e_syntax,
-                               p.current_token(),
-                               "ERR137 - Expected '(' for special function '" + sf_name + "'",
-                               exprtk_error_location));
+               p.set_error(make_error(
+                  parser_error::e_syntax,
+                  p.current_token(),
+                  "ERR146 - Expected '(' for special function '" + sf_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -25757,11 +28954,11 @@ namespace exprtk
                {
                   if (!p.token_is(token_t::e_comma))
                   {
-                     p.set_error(
-                          make_error(parser_error::e_syntax,
-                                     p.current_token(),
-                                     "ERR138 - Expected ',' before next parameter of special function '" + sf_name + "'",
-                                     exprtk_error_location));
+                     p.set_error(make_error(
+                        parser_error::e_syntax,
+                        p.current_token(),
+                        "ERR147 - Expected ',' before next parameter of special function '" + sf_name + "'",
+                        exprtk_error_location));
 
                      return p.error_node();
                   }
@@ -25770,11 +28967,11 @@ namespace exprtk
 
             if (!p.token_is(token_t::e_rbracket))
             {
-               p.set_error(
-                    make_error(parser_error::e_syntax,
-                               p.current_token(),
-                               "ERR139 - Invalid number of parameters for special function '" + sf_name + "'",
-                               exprtk_error_location));
+               p.set_error(make_error(
+                  parser_error::e_syntax,
+                  p.current_token(),
+                  "ERR148 - Invalid number of parameters for special function '" + sf_name + "'",
+                  exprtk_error_location));
 
                return p.error_node();
             }
@@ -25797,11 +28994,11 @@ namespace exprtk
               !details::is_digit(sf_name[3])
             )
          {
-            set_error(
-               make_error(parser_error::e_token,
-                          current_token(),
-                          "ERR140 - Invalid special function[1]: " + sf_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_token,
+               current_token(),
+               "ERR149 - Invalid special function[1]: " + sf_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25811,11 +29008,11 @@ namespace exprtk
 
          if (id >= details::e_sffinal)
          {
-            set_error(
-               make_error(parser_error::e_token,
-                          current_token(),
-                          "ERR141 - Invalid special function[2]: " + sf_name,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_token,
+               current_token(),
+               "ERR150 - Invalid special function[2]: " + sf_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25843,21 +29040,21 @@ namespace exprtk
       {
          if (state_.parsing_break_stmt)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR142 - Invoking 'break' within a break call is not allowed",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR151 - Invoking 'break' within a break call is not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (0 == state_.parsing_loop_stmt_count)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR143 - Invalid use of 'break', allowed only in the scope of a loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR152 - Invalid use of 'break', allowed only in the scope of a loop",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25876,23 +29073,23 @@ namespace exprtk
             {
                if (0 == (return_expr = parse_expression()))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR144 - Failed to parse return expression for 'break' statement",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR153 - Failed to parse return expression for 'break' statement",
+                     exprtk_error_location));
 
                   return error_node();
                }
                else if (!token_is(token_t::e_rsqrbracket))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR145 - Expected ']' at the completion of break's return expression",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR154 - Expected ']' at the completion of break's return expression",
+                     exprtk_error_location));
 
-                  free_node(node_allocator_,return_expr);
+                  free_node(node_allocator_, return_expr);
 
                   return error_node();
                }
@@ -25904,11 +29101,11 @@ namespace exprtk
          }
          else
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR146 - Invalid use of 'break', allowed only in the scope of a loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR155 - Invalid use of 'break', allowed only in the scope of a loop",
+               exprtk_error_location));
          }
 
          return error_node();
@@ -25918,11 +29115,11 @@ namespace exprtk
       {
          if (0 == state_.parsing_loop_stmt_count)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR147 - Invalid use of 'continue', allowed only in the scope of a loop",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR156 - Invalid use of 'continue', allowed only in the scope of a loop",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25940,242 +29137,72 @@ namespace exprtk
 
       inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name)
       {
-         expression_node_ptr size_expr = error_node();
+         expression_node_ptr size_expression_node = error_node();
 
          if (!token_is(token_t::e_lsqrbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR148 - Expected '[' as part of vector size definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR157 - Expected '[' as part of vector size definition",
+               exprtk_error_location));
 
             return error_node();
          }
-         else if (0 == (size_expr = parse_expression()))
+         else if (0 == (size_expression_node = parse_expression()))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR149 - Failed to determine size of vector '" + vec_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR158 - Failed to determine size of vector '" + vec_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
-         else if (!is_constant_node(size_expr))
+         else if (!is_constant_node(size_expression_node))
          {
-            free_node(node_allocator_,size_expr);
+            const bool is_rebaseble_vector =
+               (size_expression_node->type() == details::expression_node<T>::e_vecsize) &&
+               static_cast<details::vector_size_node<T>*>(size_expression_node)->vec_holder()->rebaseable();
 
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR150 - Expected a literal number as size of vector '" + vec_name + "'",
-                          exprtk_error_location));
+            free_node(node_allocator_, size_expression_node);
+
+            const std::string error_msg = (is_rebaseble_vector) ?
+                                          std::string("Rebasable/Resizable vector cannot be used to define the size of vector") :
+                                          std::string("Expected a constant literal number as size of vector");
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR159 - " + error_msg + " '" + vec_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
 
-         const T vector_size = size_expr->value();
+         const T vector_size = size_expression_node->value();
 
-         free_node(node_allocator_,size_expr);
+         free_node(node_allocator_, size_expression_node);
 
-         const T max_vector_size = T(2000000000.0);
+         const std::size_t max_vector_size = settings_.max_local_vector_size();
 
          if (
               (vector_size <= T(0)) ||
               std::not_equal_to<T>()
               (T(0),vector_size - details::numeric::trunc(vector_size)) ||
-              (vector_size > max_vector_size)
+              (static_cast<std::size_t>(vector_size) > max_vector_size)
             )
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "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));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR160 - Invalid vector size. Must be an integer in the "
+               "range [0," + details::to_str(static_cast<std::size_t>(max_vector_size)) + "], size: " +
+               details::to_str(details::numeric::to_int32(vector_size)),
+               exprtk_error_location));
 
             return error_node();
          }
 
-         std::vector<expression_node_ptr> vec_initilizer_list;
-
-         scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list);
-
-         bool single_value_initialiser = false;
-         bool vec_to_vec_initialiser   = false;
-         bool null_initialisation      = false;
-
-         if (!token_is(token_t::e_rsqrbracket))
-         {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR152 - Expected ']' as part of vector size definition",
-                          exprtk_error_location));
-
-            return error_node();
-         }
-         else if (!token_is(token_t::e_eof))
-         {
-            if (!token_is(token_t::e_assign))
-            {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR153 - Expected ':=' as part of vector definition",
-                             exprtk_error_location));
-
-               return error_node();
-            }
-            else if (token_is(token_t::e_lsqrbracket))
-            {
-               expression_node_ptr initialiser = parse_expression();
-
-               if (0 == initialiser)
-               {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR154 - Failed to parse single vector initialiser",
-                                exprtk_error_location));
-
-                  return error_node();
-               }
-
-               vec_initilizer_list.push_back(initialiser);
-
-               if (!token_is(token_t::e_rsqrbracket))
-               {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR155 - Expected ']' to close single value vector initialiser",
-                                exprtk_error_location));
-
-                  return error_node();
-               }
-
-               single_value_initialiser = true;
-            }
-            else if (!token_is(token_t::e_lcrlbracket))
-            {
-               expression_node_ptr initialiser = error_node();
-
-               // Is this a vector to vector assignment and initialisation?
-               if (token_t::e_symbol == current_token().type)
-               {
-                  // Is it a locally defined vector?
-                  const scope_element& se = sem_.get_active_element(current_token().value);
-
-                  if (scope_element::e_vector == se.type)
-                  {
-                     if (0 != (initialiser = parse_expression()))
-                        vec_initilizer_list.push_back(initialiser);
-                     else
-                        return error_node();
-                  }
-                  // Are we dealing with a user defined vector?
-                  else if (symtab_store_.is_vector(current_token().value))
-                  {
-                     lodge_symbol(current_token().value, e_st_vector);
-
-                     if (0 != (initialiser = parse_expression()))
-                        vec_initilizer_list.push_back(initialiser);
-                     else
-                        return error_node();
-                  }
-                  // Are we dealing with a null initialisation vector definition?
-                  else if (token_is(token_t::e_symbol,"null"))
-                     null_initialisation = true;
-               }
-
-               if (!null_initialisation)
-               {
-                  if (0 == initialiser)
-                  {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR156 - Expected '{' as part of vector initialiser list",
-                                   exprtk_error_location));
-
-                     return error_node();
-                  }
-                  else
-                     vec_to_vec_initialiser = true;
-               }
-            }
-            else if (!token_is(token_t::e_rcrlbracket))
-            {
-               for ( ; ; )
-               {
-                  expression_node_ptr initialiser = parse_expression();
-
-                  if (0 == initialiser)
-                  {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR157 - Expected '{' as part of vector initialiser list",
-                                   exprtk_error_location));
-
-                     return error_node();
-                  }
-                  else
-                     vec_initilizer_list.push_back(initialiser);
-
-                  if (token_is(token_t::e_rcrlbracket))
-                     break;
-
-                  const bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
-
-                  if (!token_is(token_t::e_comma) && is_next_close)
-                  {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR158 - Expected ',' between vector initialisers",
-                                   exprtk_error_location));
-
-                     return error_node();
-                  }
-
-                  if (token_is(token_t::e_rcrlbracket))
-                     break;
-               }
-            }
-
-            if (
-                 !token_is(token_t::e_rbracket   , prsrhlpr_t::e_hold) &&
-                 !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
-                 !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold)
-               )
-            {
-               if (!token_is(token_t::e_eof))
-               {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR159 - Expected ';' at end of vector definition",
-                                exprtk_error_location));
-
-                  return error_node();
-               }
-            }
-
-            if (T(vec_initilizer_list.size()) > vector_size)
-            {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR160 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
-                             exprtk_error_location));
-
-               return error_node();
-            }
-         }
-
          typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0);
 
          const std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size));
@@ -26186,11 +29213,11 @@ namespace exprtk
          {
             if (se.active)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26218,13 +29245,15 @@ namespace exprtk
             nse.data      = new T[vec_size];
             nse.vec_node  = new typename scope_element::vector_holder_t(reinterpret_cast<T*>(nse.data),nse.size);
 
+            details::set_zero_value(reinterpret_cast<T*>(nse.data),vec_size);
+
             if (!sem_.add_element(nse))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM",
+                  exprtk_error_location));
 
                sem_.free_element(nse);
 
@@ -26242,9 +29271,295 @@ namespace exprtk
 
          lodge_symbol(vec_name, e_st_local_vector);
 
+         std::vector<expression_node_ptr> vec_initilizer_list;
+
+         scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list);
+
+         bool single_value_initialiser = false;
+         bool range_value_initialiser  = false;
+         bool vec_to_vec_initialiser   = false;
+         bool null_initialisation      = false;
+
+         if (!token_is(token_t::e_rsqrbracket))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR163 - Expected ']' as part of vector size definition",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold))
+         {
+            if (!token_is(token_t::e_assign))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR164 - Expected ':=' as part of vector definition",
+                  exprtk_error_location));
+
+               return error_node();
+            }
+            else if (token_is(token_t::e_lsqrbracket))
+            {
+               expression_node_ptr initialiser_component = parse_expression();
+
+               if (0 == initialiser_component)
+               {
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR165 - Failed to parse first component of vector initialiser for vector: " + vec_name,
+                     exprtk_error_location));
+
+                  return error_node();
+               }
+
+               vec_initilizer_list.push_back(initialiser_component);
+
+               if (token_is(token_t::e_colon))
+               {
+                  initialiser_component = parse_expression();
+
+                  if (0 == initialiser_component)
+                  {
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR166 - Failed to parse second component of vector initialiser for vector: " + vec_name,
+                        exprtk_error_location));
+
+                     return error_node();
+                  }
+
+                  vec_initilizer_list.push_back(initialiser_component);
+               }
+
+               if (!token_is(token_t::e_rsqrbracket))
+               {
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR167 - Expected ']' to close single value vector initialiser",
+                     exprtk_error_location));
+
+                  return error_node();
+               }
+
+               switch (vec_initilizer_list.size())
+               {
+                  case 1 : single_value_initialiser = true; break;
+                  case 2 : range_value_initialiser  = true; break;
+               }
+            }
+            else if (!token_is(token_t::e_lcrlbracket))
+            {
+               expression_node_ptr initialiser = error_node();
+
+               // Is this a vector to vector assignment and initialisation?
+               if (token_t::e_symbol == current_token().type)
+               {
+                  // Is it a locally defined vector?
+                  const scope_element& lcl_se = sem_.get_active_element(current_token().value);
+
+                  if (scope_element::e_vector == lcl_se.type)
+                  {
+                     if (0 != (initialiser = parse_expression()))
+                        vec_initilizer_list.push_back(initialiser);
+                     else
+                        return error_node();
+                  }
+                  // Are we dealing with a user defined vector?
+                  else if (symtab_store_.is_vector(current_token().value))
+                  {
+                     lodge_symbol(current_token().value, e_st_vector);
+
+                     if (0 != (initialiser = parse_expression()))
+                        vec_initilizer_list.push_back(initialiser);
+                     else
+                        return error_node();
+                  }
+                  // Are we dealing with a null initialisation vector definition?
+                  else if (token_is(token_t::e_symbol,"null"))
+                     null_initialisation = true;
+               }
+
+               if (!null_initialisation)
+               {
+                  if (0 == initialiser)
+                  {
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR168 - Expected '{' as part of vector initialiser list",
+                        exprtk_error_location));
+
+                     return error_node();
+                  }
+                  else
+                     vec_to_vec_initialiser = true;
+               }
+            }
+            else if (!token_is(token_t::e_rcrlbracket))
+            {
+               for ( ; ; )
+               {
+                  expression_node_ptr initialiser = parse_expression();
+
+                  if (0 == initialiser)
+                  {
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR169 - Expected '{' as part of vector initialiser list",
+                        exprtk_error_location));
+
+                     return error_node();
+                  }
+                  else
+                     vec_initilizer_list.push_back(initialiser);
+
+                  if (token_is(token_t::e_rcrlbracket))
+                     break;
+
+                  const bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
+
+                  if (!token_is(token_t::e_comma) && is_next_close)
+                  {
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR170 - Expected ',' between vector initialisers",
+                        exprtk_error_location));
+
+                     return error_node();
+                  }
+
+                  if (token_is(token_t::e_rcrlbracket))
+                     break;
+               }
+            }
+
+            if (
+                 !token_is(token_t::e_rbracket   , prsrhlpr_t::e_hold) &&
+                 !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
+                 !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold)
+               )
+            {
+               if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
+               {
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR171 - Expected ';' at end of vector definition",
+                     exprtk_error_location));
+
+                  return error_node();
+               }
+            }
+
+            if (
+                 !single_value_initialiser &&
+                 !range_value_initialiser  &&
+                 (T(vec_initilizer_list.size()) > vector_size)
+               )
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR172 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
+                  exprtk_error_location));
+
+               return error_node();
+            }
+         }
+
          expression_node_ptr result = error_node();
 
-         if (null_initialisation)
+         if (
+              (vec_initilizer_list.size() == 1) &&
+              single_value_initialiser
+            )
+         {
+            if (details::is_constant_node(vec_initilizer_list[0]))
+            {
+              // vector_init_zero_value_node   var v[10] := [0]
+               if (T(0) == vec_initilizer_list[0]->value())
+               {
+                  result = node_allocator_
+                              .allocate<details::vector_init_zero_value_node<T> >(
+                                 (*vec_holder)[0],
+                                 vec_size,
+                                 vec_initilizer_list);
+               }
+               else
+               {
+                  // vector_init_single_constvalue_node   var v[10] := [123]
+                  result = node_allocator_
+                              .allocate<details::vector_init_single_constvalue_node<T> >(
+                                 (*vec_holder)[0],
+                                 vec_size,
+                                 vec_initilizer_list);
+               }
+            }
+            else
+            {
+               // vector_init_single_value_node   var v[10] := [123 + (x / y)]
+               result = node_allocator_
+                           .allocate<details::vector_init_single_value_node<T> >(
+                              (*vec_holder)[0],
+                              vec_size,
+                              vec_initilizer_list);
+            }
+         }
+         else if (
+                   (vec_initilizer_list.size() == 2) &&
+                   range_value_initialiser
+                 )
+         {
+            bool base_const = details::is_constant_node(vec_initilizer_list[0]);
+            bool inc_const  = details::is_constant_node(vec_initilizer_list[1]);
+
+            if (base_const && inc_const)
+            {
+               // vector_init_single_value_node   var v[10] := [1 : 3.5]
+               result = node_allocator_
+                           .allocate<details::vector_init_iota_constconst_node<T> >(
+                              (*vec_holder)[0],
+                              vec_size,
+                              vec_initilizer_list);
+            }
+            else if (base_const && !inc_const)
+            {
+               // vector_init_single_value_node   var v[10] := [1 : x + y]
+               result = node_allocator_
+                           .allocate<details::vector_init_iota_constnconst_node<T> >(
+                              (*vec_holder)[0],
+                              vec_size,
+                              vec_initilizer_list);
+            }
+            else if (!base_const && inc_const)
+            {
+               // vector_init_single_value_node   var v[10] := [x + y : 3]
+               result = node_allocator_
+                           .allocate<details::vector_init_iota_nconstconst_node<T> >(
+                              (*vec_holder)[0],
+                              vec_size,
+                              vec_initilizer_list);
+            }
+            else if (!base_const && !inc_const)
+            {
+               // vector_init_single_value_node   var v[10] := [x + y :  z / w]
+               result = node_allocator_
+                           .allocate<details::vector_init_iota_nconstnconst_node<T> >(
+                              (*vec_holder)[0],
+                              vec_size,
+                              vec_initilizer_list);
+            }
+         }
+         else if (null_initialisation)
             result = expression_generator_(T(0.0));
          else if (vec_to_vec_initialiser)
          {
@@ -26256,16 +29571,31 @@ namespace exprtk
                         vec_initilizer_list[0]);
          }
          else
+         {
             result = node_allocator_
-                        .allocate<details::vector_assignment_node<T> >(
+                        .allocate<details::vector_initialisation_node<T> >(
                            (*vec_holder)[0],
                            vec_size,
                            vec_initilizer_list,
                            single_value_initialiser);
+         }
 
-         svd.delete_ptr = (0 == result);
+         svd.delete_ptr = false;
 
-         return result;
+         if (result && result->valid())
+         {
+            return result;
+         }
+
+         details::free_node(node_allocator_, result);
+
+         set_error(make_error(
+            parser_error::e_synthesis,
+            current_token(),
+            "ERR173 - Failed to generate initialisation node for vector: " + vec_name,
+            exprtk_error_location));
+
+         return error_node();
       }
 
       #ifndef exprtk_disable_string_capabilities
@@ -26279,13 +29609,13 @@ namespace exprtk
          {
             if (se.active)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR163 - Illegal redefinition of local variable: '" + str_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR174 - Illegal redefinition of local variable: '" + str_name + "'",
+                  exprtk_error_location));
 
-               free_node(node_allocator_,initialisation_expression);
+               free_node(node_allocator_, initialisation_expression);
 
                return error_node();
             }
@@ -26311,13 +29641,13 @@ namespace exprtk
 
             if (!sem_.add_element(nse))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR164 - Failed to add new local string variable '" + str_name + "' to SEM",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR175 - Failed to add new local string variable '" + str_name + "' to SEM",
+                  exprtk_error_location));
 
-               free_node(node_allocator_,initialisation_expression);
+               free_node(node_allocator_, initialisation_expression);
 
                sem_.free_element(nse);
 
@@ -26326,7 +29656,7 @@ namespace exprtk
 
             str_node = nse.str_node;
 
-            exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n",nse.name.c_str()));
+            exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n", nse.name.c_str()));
          }
 
          lodge_symbol(str_name, e_st_local_string);
@@ -26357,11 +29687,11 @@ namespace exprtk
       {
          if (settings_.vardef_disabled())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR165 - Illegal variable definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR176 - Illegal variable definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26378,41 +29708,41 @@ namespace exprtk
 
          if (!token_is(token_t::e_symbol))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR166 - Expected a symbol for variable definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR177 - Expected a symbol for variable definition",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (details::is_reserved_symbol(var_name))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR167 - Illegal redefinition of reserved keyword: '" + var_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR178 - Illegal redefinition of reserved keyword: '" + var_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (symtab_store_.symbol_exists(var_name))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR168 - Illegal redefinition of variable '" + var_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR179 - Illegal redefinition of variable '" + var_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (local_variable_is_shadowed(var_name))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR169 - Illegal redefinition of local variable: '" + var_name + "'",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR180 - Illegal redefinition of local variable: '" + var_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26428,11 +29758,11 @@ namespace exprtk
          {
             if (0 == (initialisation_expression = parse_expression()))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR170 - Failed to parse initialisation expression",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR181 - Failed to parse initialisation expression for variable '" + var_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26446,13 +29776,13 @@ namespace exprtk
          {
             if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR171 - Expected ';' after variable definition",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR182 - Expected ';' after variable '" + var_name + "' definition",
+                  exprtk_error_location));
 
-               free_node(node_allocator_,initialisation_expression);
+               free_node(node_allocator_, initialisation_expression);
 
                return error_node();
             }
@@ -26474,11 +29804,11 @@ namespace exprtk
          {
             if (se.active)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR172 - Illegal redefinition of local variable: '" + var_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR183 - Illegal redefinition of local variable: '" + var_name + "'",
+                  exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
 
@@ -26506,11 +29836,11 @@ namespace exprtk
 
             if (!sem_.add_element(nse))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR173 - Failed to add new local variable '" + var_name + "' to SEM",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR184 - Failed to add new local variable '" + var_name + "' to SEM",
+                  exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
 
@@ -26521,7 +29851,7 @@ namespace exprtk
 
             var_node = nse.var_node;
 
-            exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str()));
+            exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n", nse.name.c_str()));
          }
 
          state_.activate_side_effect("parse_define_var_statement()");
@@ -26536,6 +29866,174 @@ namespace exprtk
          return expression_generator_(details::e_assign,branch);
       }
 
+      inline expression_node_ptr parse_define_constvar_statement()
+      {
+         if (settings_.vardef_disabled())
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR185 - Illegal const variable definition",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (!token_is("const"))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR186 - Expected 'const' keyword for const-variable definition",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (!token_is("var"))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR187 - Expected 'var' keyword for const-variable definition",
+               exprtk_error_location));
+
+            return error_node();
+         }
+
+         const std::string var_name = current_token().value;
+
+         expression_node_ptr initialisation_expression = error_node();
+
+         if (!token_is(token_t::e_symbol))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR188 - Expected a symbol for const-variable definition",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (details::is_reserved_symbol(var_name))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR189 - Illegal redefinition of reserved keyword: '" + var_name + "'",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (symtab_store_.symbol_exists(var_name))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR190 - Illegal redefinition of variable '" + var_name + "'",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (local_variable_is_shadowed(var_name))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR191 - Illegal redefinition of local variable: '" + var_name + "'",
+               exprtk_error_location));
+
+            return error_node();
+         }
+         else if (token_is(token_t::e_assign))
+         {
+            if (0 == (initialisation_expression = parse_expression()))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR192 - Failed to parse initialisation expression for const-variable: '" + var_name + "'",
+                  exprtk_error_location));
+
+               return error_node();
+            }
+            else if (!details::is_literal_node(initialisation_expression))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR193 - initialisation expression for const-variable: '" + var_name + "' must be a constant/literal",
+                  exprtk_error_location));
+
+               free_node(node_allocator_, initialisation_expression);
+
+               return error_node();
+            }
+         }
+
+         const T init_value = initialisation_expression->value();
+
+         free_node(node_allocator_, initialisation_expression);
+
+         expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
+
+         scope_element& se = sem_.get_element(var_name);
+
+         if (se.name == var_name)
+         {
+            if (se.active)
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR194 - Illegal redefinition of local variable: '" + var_name + "'",
+                  exprtk_error_location));
+
+               return error_node();
+            }
+            else if (scope_element::e_literal == se.type)
+            {
+               var_node  = se.var_node;
+               se.active = true;
+               se.depth  = state_.scope_depth;
+               se.ref_count++;
+            }
+         }
+
+         if (0 == var_node)
+         {
+            scope_element nse;
+            nse.name      = var_name;
+            nse.active    = true;
+            nse.ref_count = 1;
+            nse.type      = scope_element::e_literal;
+            nse.depth     = state_.scope_depth;
+            nse.data      = 0;
+            nse.var_node  = node_allocator_.allocate<literal_node_t>(init_value);
+
+            if (!sem_.add_element(nse))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR195 - Failed to add new local const-variable '" + var_name + "' to SEM",
+                  exprtk_error_location));
+
+               sem_.free_element(nse);
+
+               return error_node();
+            }
+
+            var_node = nse.var_node;
+
+            exprtk_debug(("parse_define_constvar_statement() - INFO - Added new local const-variable: %s\n", nse.name.c_str()));
+         }
+
+         state_.activate_side_effect("parse_define_constvar_statement()");
+
+         lodge_symbol(var_name, e_st_local_variable);
+
+         return expression_generator_(var_node->value());
+      }
+
       inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name)
       {
          if (
@@ -26543,21 +30041,21 @@ namespace exprtk
               !token_is(token_t::e_rcrlbracket)
             )
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR174 - Expected a '{}' for uninitialised var definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR196 - Expected a '{}' for uninitialised var definition",
+               exprtk_error_location));
 
             return error_node();
          }
          else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR175 - Expected ';' after uninitialised variable definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR197 - Expected ';' after uninitialised variable definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26570,11 +30068,11 @@ namespace exprtk
          {
             if (se.active)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR176 - Illegal redefinition of local variable: '" + var_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR198 - Illegal redefinition of local variable: '" + var_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26600,11 +30098,11 @@ namespace exprtk
 
             if (!sem_.add_element(nse))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR177 - Failed to add new local variable '" + var_name + "' to SEM",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR199 - Failed to add new local variable '" + var_name + "' to SEM",
+                  exprtk_error_location));
 
                sem_.free_element(nse);
 
@@ -26633,11 +30131,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_lbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR178 - Expected '(' at start of swap statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR200 - Expected '(' at start of swap statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26652,11 +30150,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR179 - Expected a symbol for variable or vector element definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR201 - Expected a symbol for variable or vector element definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26664,11 +30162,11 @@ namespace exprtk
          {
             if (0 == (variable0 = parse_vector()))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR180 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR202 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26697,11 +30195,11 @@ namespace exprtk
 
             if (0 == variable0)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR181 - First parameter to swap is an invalid variable: '" + var0_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR203 - First parameter to swap is an invalid variable: '" + var0_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26711,15 +30209,15 @@ namespace exprtk
 
          if (!token_is(token_t::e_comma))
          {
-            set_error(
-                make_error(parser_error::e_syntax,
-                           current_token(),
-                           "ERR182 - Expected ',' between parameters to swap",
-                           exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR204 - Expected ',' between parameters to swap",
+               exprtk_error_location));
 
             if (variable0_generated)
             {
-               free_node(node_allocator_,variable0);
+               free_node(node_allocator_, variable0);
             }
 
             return error_node();
@@ -26729,15 +30227,15 @@ namespace exprtk
 
          if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR183 - Expected a symbol for variable or vector element definition",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR205 - Expected a symbol for variable or vector element definition",
+               exprtk_error_location));
 
             if (variable0_generated)
             {
-               free_node(node_allocator_,variable0);
+               free_node(node_allocator_, variable0);
             }
 
             return error_node();
@@ -26746,15 +30244,15 @@ namespace exprtk
          {
             if (0 == (variable1 = parse_vector()))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR184 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR206 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
+                  exprtk_error_location));
 
                if (variable0_generated)
                {
-                  free_node(node_allocator_,variable0);
+                  free_node(node_allocator_, variable0);
                }
 
                return error_node();
@@ -26784,15 +30282,15 @@ namespace exprtk
 
             if (0 == variable1)
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR185 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR207 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
+                  exprtk_error_location));
 
                if (variable0_generated)
                {
-                  free_node(node_allocator_,variable0);
+                  free_node(node_allocator_, variable0);
                }
 
                return error_node();
@@ -26803,20 +30301,20 @@ namespace exprtk
 
          if (!token_is(token_t::e_rbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR186 - Expected ')' at end of swap statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR208 - Expected ')' at end of swap statement",
+               exprtk_error_location));
 
             if (variable0_generated)
             {
-               free_node(node_allocator_,variable0);
+               free_node(node_allocator_, variable0);
             }
 
             if (variable1_generated)
             {
-               free_node(node_allocator_,variable1);
+               free_node(node_allocator_, variable1);
             }
 
             return error_node();
@@ -26838,12 +30336,12 @@ namespace exprtk
 
             if (variable0_generated)
             {
-               free_node(node_allocator_,variable0);
+               free_node(node_allocator_, variable0);
             }
 
             if (variable1_generated)
             {
-               free_node(node_allocator_,variable1);
+               free_node(node_allocator_, variable1);
             }
          }
          else
@@ -26860,11 +30358,11 @@ namespace exprtk
       {
          if (state_.parsing_return_stmt)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR187 - Return call within a return call is not allowed",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR209 - Return call within a return call is not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26884,11 +30382,11 @@ namespace exprtk
 
          if (!token_is(token_t::e_lsqrbracket))
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR188 - Expected '[' at start of return statement",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR210 - Expected '[' at start of return statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26907,11 +30405,11 @@ namespace exprtk
                   break;
                else if (!token_is(token_t::e_comma))
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR189 - Expected ',' between values during call to return",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR211 - Expected ',' between values during call to return",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -26919,11 +30417,11 @@ namespace exprtk
          }
          else if (settings_.zero_return_disabled())
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR190 - Zero parameter return statement not allowed",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR212 - Zero parameter return statement not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26934,11 +30432,11 @@ namespace exprtk
          {
             if (!arg_list.empty())
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             prev_token,
-                             "ERR191 - Invalid ']' found during return call",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  prev_token,
+                  "ERR213 - Invalid ']' found during return call",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26977,6 +30475,194 @@ namespace exprtk
       }
       #endif
 
+      inline expression_node_ptr parse_assert_statement()
+      {
+         assert(details::imatch(current_token().value, "assert"));
+
+         if (state_.parsing_assert_stmt)
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR214 - Assert statement within an assert statement is not allowed",
+               exprtk_error_location));
+
+            return error_node();
+         }
+
+         scoped_bool_negator sbn(state_.parsing_assert_stmt);
+
+         next_token();
+
+         std::vector<expression_node_ptr> assert_arg_list(3, error_node());
+         scoped_vec_delete<expression_node_t> sdd((*this), assert_arg_list);
+
+         expression_node_ptr& assert_condition = assert_arg_list[0];
+         expression_node_ptr& assert_message   = assert_arg_list[1];
+         expression_node_ptr& assert_id        = assert_arg_list[2];
+
+         if (!token_is(token_t::e_lbracket))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR215 - Expected '(' at start of assert statement",
+               exprtk_error_location));
+
+            return error_node();
+         }
+
+         const token_t start_token = current_token();
+
+         // Parse the assert condition
+         if (0 == (assert_condition = parse_expression()))
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR216 - Failed to parse condition for assert statement",
+               exprtk_error_location));
+
+            return error_node();
+         }
+
+         const token_t end_token = current_token();
+
+         if (!token_is(token_t::e_rbracket))
+         {
+            if (!token_is(token_t::e_comma))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR217 - Expected ',' between condition and message for assert statement",
+                  exprtk_error_location));
+
+               return error_node();
+            }
+            // Parse the assert message
+            else if (
+                      (0 == (assert_message = parse_expression())) ||
+                      !details::is_generally_string_node(assert_message)
+                    )
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR218 - " +
+                  (assert_message ?
+                  std::string("Expected string for assert message") :
+                  std::string("Failed to parse message for assert statement")),
+                  exprtk_error_location));
+
+               return error_node();
+            }
+            else if (!token_is(token_t::e_rbracket))
+            {
+               if (!token_is(token_t::e_comma))
+               {
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR219 - Expected ',' between message and ID for assert statement",
+                     exprtk_error_location));
+
+                  return error_node();
+               }
+               // Parse assert ID
+               else if (
+                         (0 == (assert_id = parse_expression())) ||
+                         !details::is_const_string_node(assert_id)
+                       )
+               {
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR220 - " +
+                     (assert_id ?
+                     std::string("Expected literal string for assert ID") :
+                     std::string("Failed to parse string for assert ID")),
+                     exprtk_error_location));
+
+                  return error_node();
+               }
+               else if (!token_is(token_t::e_rbracket))
+               {
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR221 - Expected ')' at start of assert statement",
+                     exprtk_error_location));
+
+                  return error_node();
+               }
+            }
+         }
+
+         exprtk::assert_check::assert_context context;
+         context.condition = lexer().substr(start_token.position, end_token.position);
+         context.offet     = start_token.position;
+
+         if (0 == assert_check_)
+         {
+            exprtk_debug(("parse_assert_statement() - assert functionality is disabled. assert condition: %s\n",
+                          context.condition.c_str()));
+
+            return new details::null_node<T>();
+         }
+
+         #ifndef exprtk_disable_string_capabilities
+         if (assert_message && details::is_const_string_node(assert_message))
+         {
+            context.message = dynamic_cast<details::string_base_node<T>*>(assert_message)->str();
+         }
+
+         if (assert_id && details::is_const_string_node(assert_id))
+         {
+            context.id = dynamic_cast<details::string_base_node<T>*>(assert_id)->str();
+
+            if (assert_ids_.end() != assert_ids_.find(context.id))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR222 - Duplicate assert ID: " + context.id,
+                  exprtk_error_location));
+
+               return error_node();
+            }
+
+            assert_ids_.insert(context.id);
+            free_node(node_allocator_, assert_id);
+         }
+         #endif
+
+         expression_node_ptr result_node =
+            expression_generator_.assert_call(
+               assert_condition,
+               assert_message,
+               context);
+
+         exprtk_debug(("parse_assert_statement() - assert condition: [%s]\n", context.condition.c_str()      ));
+         exprtk_debug(("parse_assert_statement() - assert message:   [%s]\n", context.message  .c_str()      ));
+         exprtk_debug(("parse_assert_statement() - assert id:        [%s]\n", context.id       .c_str()      ));
+         exprtk_debug(("parse_assert_statement() - assert offset:    [%d]\n", static_cast<int>(context.offet)));
+
+         if (0 == result_node)
+         {
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR223 - Failed to synthesize assert",
+               exprtk_error_location));
+
+            return error_node();
+         }
+
+         sdd.delete_ptr = false;
+         return result_node;
+      }
+
       inline bool post_variable_process(const std::string& symbol)
       {
          if (
@@ -26987,11 +30673,11 @@ namespace exprtk
          {
             if (!settings_.commutative_check_enabled())
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR192 - Invalid sequence of variable '" + symbol + "' and bracket",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR224 - Invalid sequence of variable '" + symbol + "' and bracket",
+                  exprtk_error_location));
 
                return false;
             }
@@ -27009,23 +30695,26 @@ namespace exprtk
          if (details::is_generally_string_node(branch))
             return true;
 
+         if (details::is_ivector_node(branch))
+            return true;
+
          const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold;
 
          switch (token)
          {
-            case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket   ,hold) ||
-                                                        token_is(token_t::e_lcrlbracket,hold) ||
-                                                        token_is(token_t::e_lsqrbracket,hold) ;
+            case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket   , hold) ||
+                                                        token_is(token_t::e_lcrlbracket, hold) ||
+                                                        token_is(token_t::e_lsqrbracket, hold) ;
                                           break;
 
-            case token_t::e_lbracket    : implied_mul = token_is(token_t::e_lbracket   ,hold) ||
-                                                        token_is(token_t::e_lcrlbracket,hold) ||
-                                                        token_is(token_t::e_lsqrbracket,hold) ;
+            case token_t::e_lbracket    : implied_mul = token_is(token_t::e_lbracket   , hold) ||
+                                                        token_is(token_t::e_lcrlbracket, hold) ||
+                                                        token_is(token_t::e_lsqrbracket, hold) ;
                                           break;
 
-            case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket   ,hold) ||
-                                                        token_is(token_t::e_lcrlbracket,hold) ||
-                                                        token_is(token_t::e_lsqrbracket,hold) ;
+            case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket   , hold) ||
+                                                        token_is(token_t::e_lcrlbracket, hold) ||
+                                                        token_is(token_t::e_lsqrbracket, hold) ;
                                           break;
 
             default                     : return true;
@@ -27035,11 +30724,11 @@ namespace exprtk
          {
             if (!settings_.commutative_check_enabled())
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR193 - Invalid sequence of brackets",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR225 - Invalid sequence of brackets",
+                  exprtk_error_location));
 
                return false;
             }
@@ -27122,7 +30811,10 @@ namespace exprtk
 
             if (se.active && details::imatch(se.name, symbol))
             {
-               if (scope_element::e_variable == se.type)
+               if (
+                    (scope_element::e_variable == se.type) ||
+                    (scope_element::e_literal  == se.type)
+                  )
                {
                   se.active = true;
                   lodge_symbol(symbol, e_st_local_variable);
@@ -27132,7 +30824,9 @@ namespace exprtk
 
                   next_token();
 
-                  return se.var_node;
+                  return (scope_element::e_variable == se.type) ?
+                           se.var_node :
+                           expression_generator_(se.var_node->value());
                }
                else if (scope_element::e_vector == se.type)
                {
@@ -27170,11 +30864,11 @@ namespace exprtk
                   return func_node;
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR194 - Failed to generate node for function: '" + symbol + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR226 - Failed to generate node for function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27196,11 +30890,11 @@ namespace exprtk
                   return vararg_func_node;
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR195 - Failed to generate node for vararg function: '" + symbol + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR227 - Failed to generate node for vararg function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27222,11 +30916,11 @@ namespace exprtk
                   return genericfunc_node;
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR196 - Failed to generate node for generic function: '" + symbol + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR228 - Failed to generate node for generic function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27249,11 +30943,11 @@ namespace exprtk
                   return stringfunc_node;
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR197 - Failed to generate node for string function: '" + symbol + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR229 - Failed to generate node for string function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27275,11 +30969,11 @@ namespace exprtk
                   return overloadfunc_node;
                else
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR198 - Failed to generate node for overload function: '" + symbol + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR230 - Failed to generate node for overload function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27301,11 +30995,11 @@ namespace exprtk
                     !details::is_base_function(symbol)
                   )
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR199 - Invalid use of reserved symbol '" + symbol + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR231 - Invalid use of reserved symbol '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27332,11 +31026,13 @@ namespace exprtk
 
                      switch (usr_symbol_type)
                      {
-                        case unknown_symbol_resolver::e_usr_variable_type : create_result = symtab.create_variable(symbol, default_value);
-                                                                            break;
+                        case unknown_symbol_resolver::e_usr_variable_type :
+                           create_result = symtab.create_variable(symbol, default_value);
+                           break;
 
-                        case unknown_symbol_resolver::e_usr_constant_type : create_result = symtab.add_constant(symbol, default_value);
-                                                                            break;
+                        case unknown_symbol_resolver::e_usr_constant_type :
+                           create_result = symtab.add_constant(symbol, default_value);
+                           break;
 
                         default                                           : create_result = false;
                      }
@@ -27364,12 +31060,12 @@ namespace exprtk
                      }
                   }
 
-                  set_error(
-                     make_error(parser_error::e_symtab,
-                                current_token(),
-                                "ERR200 - Failed to create variable: '" + symbol + "'" +
-                                (error_message.empty() ? "" : " - " + error_message),
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_symtab,
+                     current_token(),
+                     "ERR232 - Failed to create variable: '" + symbol + "'" +
+                     (error_message.empty() ? "" : " - " + error_message),
+                     exprtk_error_location));
 
                }
                else if (unknown_symbol_resolver::e_usrmode_extended == unknown_symbol_resolver_->mode)
@@ -27384,27 +31080,51 @@ namespace exprtk
                      }
                   }
 
-                  set_error(
-                     make_error(parser_error::e_symtab,
-                                current_token(),
-                                "ERR201 - Failed to resolve symbol: '" + symbol + "'" +
-                                (error_message.empty() ? "" : " - " + error_message),
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_symtab,
+                     current_token(),
+                     "ERR233 - Failed to resolve symbol: '" + symbol + "'" +
+                     (error_message.empty() ? "" : " - " + error_message),
+                     exprtk_error_location));
                }
 
                return error_node();
             }
          }
 
-         set_error(
-            make_error(parser_error::e_syntax,
-                       current_token(),
-                       "ERR202 - Undefined symbol: '" + symbol + "'",
-                       exprtk_error_location));
+         set_error(make_error(
+            parser_error::e_syntax,
+            current_token(),
+            "ERR234 - Undefined symbol: '" + symbol + "'",
+            exprtk_error_location));
 
          return error_node();
       }
 
+      inline expression_node_ptr check_block_statement_closure(expression_node_ptr expression)
+      {
+         if (
+              expression &&
+              (
+                (current_token().type == token_t::e_symbol) ||
+                (current_token().type == token_t::e_number)
+              )
+            )
+         {
+            free_node(node_allocator_, expression);
+
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR235 - Invalid syntax '" + current_token().value  + "' possible missing operator or context",
+               exprtk_error_location));
+
+               return error_node();
+         }
+
+         return expression;
+      }
+
       inline expression_node_ptr parse_symbol()
       {
          static const std::string symbol_if       = "if"      ;
@@ -27416,9 +31136,11 @@ namespace exprtk
          static const std::string symbol_break    = "break"   ;
          static const std::string symbol_continue = "continue";
          static const std::string symbol_var      = "var"     ;
+         static const std::string symbol_const    = "const"   ;
          static const std::string symbol_swap     = "swap"    ;
          static const std::string symbol_return   = "return"  ;
          static const std::string symbol_not      = "not"     ;
+         static const std::string symbol_assert   = "assert"  ;
 
          const std::string symbol = current_token().value;
 
@@ -27446,28 +31168,28 @@ namespace exprtk
                    settings_.control_struct_enabled(symbol)
                  )
          {
-            return parse_while_loop();
+            return check_block_statement_closure(parse_while_loop());
          }
          else if (
                    details::imatch(symbol, symbol_repeat) &&
                    settings_.control_struct_enabled(symbol)
                  )
          {
-            return parse_repeat_until_loop();
+            return check_block_statement_closure(parse_repeat_until_loop());
          }
          else if (
                    details::imatch(symbol, symbol_for) &&
                    settings_.control_struct_enabled(symbol)
                  )
          {
-            return parse_for_loop();
+            return check_block_statement_closure(parse_for_loop());
          }
          else if (
                    details::imatch(symbol, symbol_switch) &&
                    settings_.control_struct_enabled(symbol)
                  )
          {
-            return parse_switch_statement();
+            return check_block_statement_closure(parse_switch_statement());
          }
          else if (details::is_valid_sf_symbol(symbol))
          {
@@ -27491,6 +31213,10 @@ namespace exprtk
          {
             return parse_define_var_statement();
          }
+         else if (details::imatch(symbol, symbol_const))
+         {
+            return parse_define_constvar_statement();
+         }
          else if (details::imatch(symbol, symbol_swap))
          {
             return parse_swap_statement();
@@ -27501,20 +31227,25 @@ namespace exprtk
                    settings_.control_struct_enabled(symbol)
                  )
          {
-            return parse_return_statement();
+            return check_block_statement_closure(parse_return_statement());
          }
          #endif
+         else if (details::imatch(symbol, symbol_assert))
+         {
+            return parse_assert_statement();
+         }
          else if (symtab_store_.valid() || !sem_.empty())
          {
             return parse_symtab_symbol();
          }
          else
          {
-            set_error(
-               make_error(parser_error::e_symtab,
-                          current_token(),
-                          "ERR203 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol,
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_symtab,
+               current_token(),
+               "ERR236 - Unknown variable or function encountered. Symbol table(s) "
+               "is either invalid or does not contain symbol: '" + symbol + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -27541,11 +31272,11 @@ namespace exprtk
 
                if (0 == literal_exp)
                {
-                  set_error(
-                     make_error(parser_error::e_numeric,
-                                current_token(),
-                                "ERR204 - Failed generate node for scalar: '" + current_token().value + "'",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_numeric,
+                     current_token(),
+                     "ERR237 - Failed generate node for scalar: '" + current_token().value + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27555,11 +31286,11 @@ namespace exprtk
             }
             else
             {
-               set_error(
-                  make_error(parser_error::e_numeric,
-                             current_token(),
-                             "ERR205 - Failed to convert '" + current_token().value + "' to a number",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_numeric,
+                  current_token(),
+                  "ERR238 - Failed to convert '" + current_token().value + "' to a number",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -27579,25 +31310,32 @@ namespace exprtk
             next_token();
 
             if (0 == (branch = parse_expression()))
-               return error_node();
-            else if (!token_is(token_t::e_rbracket))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR206 - Expected ')' instead of: '" + current_token().value + "'",
-                             exprtk_error_location));
+               return error_node();
+            }
 
-               details::free_node(node_allocator_,branch);
+            token_is(token_t::e_eof);
+
+            if (!token_is(token_t::e_rbracket))
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR239 - Expected ')' instead of: '" + current_token().value + "'",
+                  exprtk_error_location));
+
+               details::free_node(node_allocator_, branch);
 
                return error_node();
             }
             else if (!post_bracket_process(token_t::e_lbracket,branch))
             {
-               details::free_node(node_allocator_,branch);
+               details::free_node(node_allocator_, branch);
 
                return error_node();
             }
+
+            parse_pending_vector_index_operator(branch);
          }
          else if (token_t::e_lsqrbracket == current_token().type)
          {
@@ -27607,19 +31345,19 @@ namespace exprtk
                return error_node();
             else if (!token_is(token_t::e_rsqrbracket))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR207 - Expected ']' instead of: '" + current_token().value + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR240 - Expected ']' instead of: '" + current_token().value + "'",
+                  exprtk_error_location));
 
-               details::free_node(node_allocator_,branch);
+               details::free_node(node_allocator_, branch);
 
                return error_node();
             }
             else if (!post_bracket_process(token_t::e_lsqrbracket,branch))
             {
-               details::free_node(node_allocator_,branch);
+               details::free_node(node_allocator_, branch);
 
                return error_node();
             }
@@ -27632,19 +31370,19 @@ namespace exprtk
                return error_node();
             else if (!token_is(token_t::e_rcrlbracket))
             {
-               set_error(
-                  make_error(parser_error::e_syntax,
-                             current_token(),
-                             "ERR208 - Expected '}' instead of: '" + current_token().value + "'",
-                             exprtk_error_location));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR241 - Expected '}' instead of: '" + current_token().value + "'",
+                  exprtk_error_location));
 
-               details::free_node(node_allocator_,branch);
+               details::free_node(node_allocator_, branch);
 
                return error_node();
             }
             else if (!post_bracket_process(token_t::e_lcrlbracket,branch))
             {
-               details::free_node(node_allocator_,branch);
+               details::free_node(node_allocator_, branch);
 
                return error_node();
             }
@@ -27666,7 +31404,7 @@ namespace exprtk
 
                if (0 == result)
                {
-                  details::free_node(node_allocator_,branch);
+                  details::free_node(node_allocator_, branch);
 
                   return error_node();
                }
@@ -27681,21 +31419,21 @@ namespace exprtk
          }
          else if (token_t::e_eof == current_token().type)
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR209 - Premature end of expression[1]",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR242 - Premature end of expression[1]",
+               exprtk_error_location));
 
             return error_node();
          }
          else
          {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR210 - Premature end of expression[2]",
-                          exprtk_error_location));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR243 - Premature end of expression[2]",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -27796,6 +31534,8 @@ namespace exprtk
             register_synthezier(synthesize_covocov_expression4)
             register_synthezier(synthesize_vocovoc_expression4)
             register_synthezier(synthesize_covovoc_expression4)
+
+            #undef register_synthezier
             #endif
          }
 
@@ -27848,7 +31588,7 @@ namespace exprtk
          {
             typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation);
 
-            if ((*binary_op_map_).end() == bop_itr)
+            if (binary_op_map_->end() == bop_itr)
                return false;
 
             bop = bop_itr->second;
@@ -28260,13 +32000,20 @@ namespace exprtk
 
                if (details::is_string_node(branch[0]))
                   return !b1_is_genstring;
+               else if (details::is_literal_node(branch[0]))
+                  return true;
                else
                   return (
-                           !details::is_variable_node          (branch[0]) &&
-                           !details::is_vector_elem_node       (branch[0]) &&
-                           !details::is_rebasevector_elem_node (branch[0]) &&
-                           !details::is_rebasevector_celem_node(branch[0]) &&
-                           !details::is_vector_node            (branch[0])
+                           !details::is_variable_node              (branch[0]) &&
+                           !details::is_vector_elem_node           (branch[0]) &&
+                           !details::is_vector_celem_node          (branch[0]) &&
+                           !details::is_vector_elem_rtc_node       (branch[0]) &&
+                           !details::is_vector_celem_rtc_node      (branch[0]) &&
+                           !details::is_rebasevector_elem_node     (branch[0]) &&
+                           !details::is_rebasevector_celem_node    (branch[0]) &&
+                           !details::is_rebasevector_elem_rtc_node (branch[0]) &&
+                           !details::is_rebasevector_celem_rtc_node(branch[0]) &&
+                           !details::is_vector_node                (branch[0])
                          )
                          || b1_is_genstring;
             }
@@ -28421,18 +32168,42 @@ namespace exprtk
          {
             if ((0 == branch[0]) || (0 == branch[1]))
             {
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR244 - Invalid branches received for operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (is_invalid_string_op(operation,branch))
             {
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR245 - Invalid branch pair for string operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (is_invalid_assignment_op(operation,branch))
             {
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR246 - Invalid branch pair for assignment operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (is_invalid_break_continue_op(branch))
             {
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR247 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (details::e_assign == operation)
@@ -28551,10 +32322,22 @@ namespace exprtk
             {
                details::free_all_nodes(*node_allocator_,branch);
 
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR248 - Invalid branches operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (is_invalid_string_op(operation, branch))
             {
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR249 - Invalid branches for string operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (is_string_operation(operation, branch))
@@ -28601,6 +32384,16 @@ namespace exprtk
                details::free_node(*node_allocator_, consequent );
                details::free_node(*node_allocator_, alternative);
 
+               const std::string invalid_branches =
+                                 ((0 == condition ) ? std::string("condition ") : "") +
+                                 ((0 == consequent) ? std::string("consequent") : "") ;
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_parser,
+                  parser_->current_state().token,
+                  "ERR250 - Invalid " + invalid_branches + " for conditional statement",
+                  exprtk_error_location));
+
                return error_node();
             }
             // Can the condition be immediately evaluated? if so optimise.
@@ -28626,14 +32419,34 @@ namespace exprtk
                      return node_allocator_->allocate<details::null_node<T> >();
                }
             }
-            else if ((0 != consequent) && (0 != alternative))
+
+            expression_node_ptr result = error_node();
+            std::string node_name      = "Unknown!";
+
+            if ((0 != consequent) && (0 != alternative))
             {
-               return node_allocator_->
-                        allocate<conditional_node_t>(condition, consequent, alternative);
+               result = node_allocator_->allocate<conditional_node_t>(condition, consequent, alternative);
+               node_name = "conditional_node_t";
             }
             else
-               return node_allocator_->
-                        allocate<cons_conditional_node_t>(condition, consequent);
+            {
+               result = node_allocator_->allocate<cons_conditional_node_t>(condition, consequent);
+               node_name = "cons_conditional_node_t";
+            }
+
+            if (result && result->valid())
+            {
+               return result;
+            }
+
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_parser,
+               token_t(),
+               "ERR251 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
          #ifndef exprtk_disable_string_capabilities
@@ -28647,6 +32460,16 @@ namespace exprtk
                details::free_node(*node_allocator_, consequent );
                details::free_node(*node_allocator_, alternative);
 
+               const std::string invalid_branches =
+                                 ((0 == condition ) ? std::string("condition ") : "") +
+                                 ((0 == consequent) ? std::string("consequent") : "") ;
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_parser,
+                  parser_->current_state().token,
+                  "ERR252 - Invalid " + invalid_branches + " for string conditional statement",
+                  exprtk_error_location));
+
                return error_node();
             }
             // Can the condition be immediately evaluated? if so optimise.
@@ -28674,10 +32497,25 @@ namespace exprtk
                }
             }
             else if ((0 != consequent) && (0 != alternative))
-               return node_allocator_->
-                        allocate<conditional_string_node_t>(condition, consequent, alternative);
-            else
-               return error_node();
+            {
+               expression_node_ptr result =
+                  node_allocator_->allocate<conditional_string_node_t>(condition, consequent, alternative);
+
+               if (result && result->valid())
+               {
+                  return result;
+               }
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_parser,
+                  token_t(),
+                  "ERR253 - Failed to synthesize node: conditional_string_node_t",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+            }
+
+            return error_node();
          }
          #else
          inline expression_node_ptr conditional_string(expression_node_ptr,
@@ -28698,6 +32536,16 @@ namespace exprtk
                details::free_node(*node_allocator_, consequent );
                details::free_node(*node_allocator_, alternative);
 
+               const std::string invalid_branches =
+                                 ((0 == condition ) ? std::string("condition ") : "") +
+                                 ((0 == consequent) ? std::string("consequent") : "") ;
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_parser,
+                  parser_->current_state().token,
+                  "ERR254 - Invalid " + invalid_branches + " for vector conditional statement",
+                  exprtk_error_location));
+
                return error_node();
             }
             // Can the condition be immediately evaluated? if so optimise.
@@ -28746,16 +32594,34 @@ namespace exprtk
             return loop_runtime_check_ptr(0);
          }
 
+         inline vector_access_runtime_check_ptr get_vector_access_runtime_check() const
+         {
+            return parser_->vector_access_runtime_check_;
+         }
+
          inline expression_node_ptr while_loop(expression_node_ptr& condition,
                                                expression_node_ptr& branch,
                                                const bool break_continue_present = false) const
          {
-            if (!break_continue_present && details::is_constant_node(condition))
+            if (
+                 !break_continue_present              &&
+                 !parser_->state_.return_stmt_present &&
+                 details::is_constant_node(condition)
+               )
             {
                expression_node_ptr result = error_node();
                if (details::is_true(condition))
+               {
                   // Infinite loops are not allowed.
+
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_parser,
+                     parser_->current_state().token,
+                     "ERR255 - Infinite loop condition without 'break' or 'return' not allowed in while-loops",
+                     exprtk_error_location));
+
                   result = error_node();
+               }
                else
                   result = node_allocator_->allocate<details::null_node<Type> >();
 
@@ -28857,13 +32723,26 @@ namespace exprtk
                                              expression_node_ptr& loop_body,
                                              bool break_continue_present = false) const
          {
-            if (!break_continue_present && details::is_constant_node(condition))
+            if (
+                 !break_continue_present              &&
+                 !parser_->state_.return_stmt_present &&
+                 details::is_constant_node(condition)
+               )
             {
                expression_node_ptr result = error_node();
 
                if (details::is_true(condition))
+               {
                   // Infinite loops are not allowed.
+
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_parser,
+                     parser_->current_state().token,
+                     "ERR256 - Infinite loop condition without 'break' or 'return' not allowed in for-loop",
+                     exprtk_error_location));
+
                   result = error_node();
+               }
                else
                   result = node_allocator_->allocate<details::null_node<Type> >();
 
@@ -28890,19 +32769,19 @@ namespace exprtk
                if (rtc)
                   return node_allocator_->allocate<for_loop_rtc_node_t>
                                           (
-                                            initialiser,
-                                            condition,
-                                            incrementor,
-                                            loop_body,
-                                            rtc
+                                             initialiser,
+                                             condition,
+                                             incrementor,
+                                             loop_body,
+                                             rtc
                                           );
                else
                   return node_allocator_->allocate<for_loop_node_t>
                                           (
-                                            initialiser,
-                                            condition,
-                                            incrementor,
-                                            loop_body
+                                             initialiser,
+                                             condition,
+                                             incrementor,
+                                             loop_body
                                           );
             }
             #ifndef exprtk_disable_break_continue
@@ -28911,19 +32790,19 @@ namespace exprtk
                if (rtc)
                   return node_allocator_->allocate<for_loop_bc_rtc_node_t>
                                           (
-                                            initialiser,
-                                            condition,
-                                            incrementor,
-                                            loop_body,
-                                            rtc
+                                             initialiser,
+                                             condition,
+                                             incrementor,
+                                             loop_body,
+                                             rtc
                                           );
                else
                   return node_allocator_->allocate<for_loop_bc_node_t>
                                           (
-                                            initialiser,
-                                            condition,
-                                            incrementor,
-                                            loop_body
+                                             initialiser,
+                                             condition,
+                                             incrementor,
+                                             loop_body
                                           );
             }
             #else
@@ -28986,8 +32865,8 @@ namespace exprtk
 
             if (0 == result)
             {
-               T zero = T(0);
-               result = node_allocator_->allocate<literal_node_t>(zero);
+               const T zero = T(0);
+               result       = node_allocator_->allocate<literal_node_t>(zero);
             }
 
             for (std::size_t i = 0; i < arg_list.size(); ++i)
@@ -29161,6 +33040,28 @@ namespace exprtk
                return node_allocator_->allocate<details::multi_switch_node<Type> >(arg_list);
          }
 
+         inline expression_node_ptr assert_call(expression_node_ptr& assert_condition,
+                                                expression_node_ptr& assert_message,
+                                                const assert_check::assert_context& context)
+         {
+            typedef details::assert_node<Type> alloc_type;
+
+            expression_node_ptr result = node_allocator_->allocate_rrrr<alloc_type>
+               (assert_condition, assert_message, parser_->assert_check_, context);
+
+            if (result && result->valid())
+            {
+               parser_->state_.activate_side_effect("assert_call()");
+               return result;
+            }
+
+            details::free_node(*node_allocator_, result          );
+            details::free_node(*node_allocator_, assert_condition);
+            details::free_node(*node_allocator_, assert_message  );
+
+            return error_node();
+         }
+
          #define unary_opr_switch_statements             \
          case_stmt(details::e_abs   , details::abs_op  ) \
          case_stmt(details::e_acos  , details::acos_op ) \
@@ -29280,6 +33181,8 @@ namespace exprtk
                default : return error_node();
             }
 
+            assert(temp_node);
+
             const T v = temp_node->value();
 
             details::free_node(*node_allocator_,temp_node);
@@ -29383,6 +33286,8 @@ namespace exprtk
                default : return error_node();
             }
 
+            assert(temp_node);
+
             const T v = temp_node->value();
 
             details::free_node(*node_allocator_,temp_node);
@@ -29503,7 +33408,8 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
+         inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation,
+                                                                Sequence<expression_node_ptr,Allocator>& arg_list)
          {
             switch (operation)
             {
@@ -29526,7 +33432,8 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         inline expression_node_ptr vectorize_func(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
+         inline expression_node_ptr vectorize_func(const details::operator_type& operation,
+                                                   Sequence<expression_node_ptr,Allocator>& arg_list)
          {
             if (1 == arg_list.size())
             {
@@ -29551,7 +33458,8 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         inline expression_node_ptr vararg_function(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
+         inline expression_node_ptr vararg_function(const details::operator_type& operation,
+                                                    Sequence<expression_node_ptr,Allocator>& arg_list)
          {
             if (!all_nodes_valid(arg_list))
             {
@@ -29561,9 +33469,9 @@ namespace exprtk
             }
             else if (is_constant_foldable(arg_list))
                return const_optimise_varargfunc(operation,arg_list);
-            else if ((arg_list.size() == 1) && details::is_ivector_node(arg_list[0]))
+            else if ((1 == arg_list.size()) && details::is_ivector_node(arg_list[0]))
                return vectorize_func(operation,arg_list);
-            else if ((arg_list.size() == 1) && special_one_parameter_vararg(operation))
+            else if ((1 == arg_list.size()) && special_one_parameter_vararg(operation))
                return arg_list[0];
             else if (all_nodes_variables(arg_list))
                return varnode_optimise_varargfunc(operation,arg_list);
@@ -29571,17 +33479,32 @@ namespace exprtk
             #ifndef exprtk_disable_string_capabilities
             if (details::e_smulti == operation)
             {
-               return node_allocator_->
+               expression_node_ptr result = node_allocator_->
                  allocate<details::str_vararg_node<Type,details::vararg_multi_op<Type> > >(arg_list);
+               if (result && result->valid())
+               {
+                  return result;
+               }
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_synthesis,
+                  token_t(),
+                  "ERR257 - Failed to synthesize node: str_vararg_node<vararg_multi_op>",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
             }
             else
             #endif
             {
+               expression_node_ptr result = error_node();
+
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                               \
-                  case op0 : return node_allocator_->                                       \
+                  case op0 : result = node_allocator_->                                     \
                                 allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
+                             break;                                                         \
 
                   case_stmt(details::e_sum   , details::vararg_add_op  )
                   case_stmt(details::e_prod  , details::vararg_mul_op  )
@@ -29594,7 +33517,22 @@ namespace exprtk
                   #undef case_stmt
                   default : return error_node();
                }
+
+               if (result && result->valid())
+               {
+                  return result;
+               }
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_synthesis,
+                  token_t(),
+                  "ERR258 - Failed to synthesize node: vararg_node",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
             }
+
+            return error_node();
          }
 
          template <std::size_t N>
@@ -29635,7 +33573,19 @@ namespace exprtk
                   return error_node();
                }
 
-               return result;
+               if (result && result->valid())
+               {
+                  return result;
+               }
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_synthesis,
+                  token_t(),
+                  "ERR259 - Failed to synthesize node: function_N_node_t",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
          }
 
@@ -29672,7 +33622,19 @@ namespace exprtk
 
             parser_->state_.activate_side_effect("vararg_function_call()");
 
-            return result;
+            if (result && result->valid())
+            {
+               return result;
+            }
+
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_synthesis,
+               token_t(),
+               "ERR260 - Failed to synthesize node: vararg_function_node<ivararg_function_t>",
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
          inline expression_node_ptr generic_function_call(igeneric_function_t* gf,
@@ -29691,14 +33653,23 @@ namespace exprtk
             const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
 
             expression_node_ptr result = error_node();
+            std::string node_name = "Unknown";
 
             if (no_psi == param_seq_index)
+            {
                result = node_allocator_->allocate<alloc_type1>(arg_list,gf);
+               node_name = "generic_function_node<igeneric_function_t>";
+            }
             else
+            {
                result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
+               node_name = "multimode_genfunction_node<igeneric_function_t>";
+            }
 
             alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result);
 
+            assert(genfunc_node_ptr);
+
             if (
                  !arg_list.empty()                  &&
                  !gf->has_side_effects()            &&
@@ -29716,9 +33687,20 @@ namespace exprtk
             }
             else if (genfunc_node_ptr->init_branches())
             {
-               parser_->state_.activate_side_effect("generic_function_call()");
+               if (result && result->valid())
+               {
+                  parser_->state_.activate_side_effect("generic_function_call()");
+                  return result;
+               }
 
-               return result;
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_synthesis,
+                  token_t(),
+                  "ERR261 - Failed to synthesize node: " + node_name,
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
             else
             {
@@ -29746,14 +33728,23 @@ namespace exprtk
             const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
 
             expression_node_ptr result = error_node();
+            std::string node_name = "Unknown";
 
             if (no_psi == param_seq_index)
+            {
                result = node_allocator_->allocate<alloc_type1>(gf,arg_list);
+               node_name = "string_function_node<igeneric_function_t>";
+            }
             else
+            {
                result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
+               node_name = "multimode_strfunction_node<igeneric_function_t>";
+            }
 
             alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result);
 
+            assert(strfunc_node_ptr);
+
             if (
                  !arg_list.empty()       &&
                  !gf->has_side_effects() &&
@@ -29770,9 +33761,20 @@ namespace exprtk
             }
             else if (strfunc_node_ptr->init_branches())
             {
-               parser_->state_.activate_side_effect("string_function_call()");
+               if (result && result->valid())
+               {
+                  parser_->state_.activate_side_effect("string_function_call()");
+                  return result;
+               }
 
-               return result;
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_synthesis,
+                  token_t(),
+                  "ERR262 - Failed to synthesize node: " + node_name,
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
             else
             {
@@ -29800,11 +33802,24 @@ namespace exprtk
 
             alloc_type* return_node_ptr = static_cast<alloc_type*>(result);
 
+            assert(return_node_ptr);
+
             if (return_node_ptr->init_branches())
             {
-               parser_->state_.activate_side_effect("return_call()");
+               if (result && result->valid())
+               {
+                  parser_->state_.activate_side_effect("return_call()");
+                  return result;
+               }
 
-               return result;
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_synthesis,
+                  token_t(),
+                  "ERR263 - Failed to synthesize node: return_node",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
             else
             {
@@ -29842,28 +33857,93 @@ namespace exprtk
          }
          #endif
 
-         inline expression_node_ptr vector_element(const std::string& symbol,
-                                                   vector_holder_ptr vector_base,
+         inline expression_node_ptr vector_element(const std::string&  symbol,
+                                                   vector_holder_ptr   vector_base,
+                                                   expression_node_ptr vec_node,
                                                    expression_node_ptr index)
          {
             expression_node_ptr result = error_node();
+            std::string node_name = "Unknown";
 
             if (details::is_constant_node(index))
             {
-               std::size_t i = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
+               const std::size_t vec_index = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
 
                details::free_node(*node_allocator_,index);
 
-               if (vector_base->rebaseable())
+               if (vec_index >= vector_base->size())
                {
-                  return node_allocator_->allocate<rebasevector_celem_node_t>(i,vector_base);
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_parser,
+                     token_t(),
+                     "ERR264 - Index of " + details::to_str(vec_index) + " out of range for "
+                     "vector '" + symbol + "' of size " + details::to_str(vector_base->size()),
+                     exprtk_error_location));
+
+                  details::free_node(*node_allocator_,vec_node);
+
+                  return error_node();
                }
 
-               const scope_element& se = parser_->sem_.get_element(symbol,i);
+               if (vector_base->rebaseable())
+               {
+                  vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
 
-               if (se.index == i)
+                  result = (rtc) ?
+                     node_allocator_->allocate<rebasevector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) :
+                     node_allocator_->allocate<rebasevector_celem_node_t    >(vec_node, vec_index, vector_base     ) ;
+
+                  node_name = (rtc) ?
+                     "rebasevector_elem_rtc_node_t" :
+                     "rebasevector_elem_node_t"     ;
+
+                  if (result && result->valid())
+                  {
+                     return result;
+                  }
+
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_synthesis,
+                     token_t(),
+                     "ERR265 - Failed to synthesize node: " + node_name + " for vector: " + symbol,
+                     exprtk_error_location));
+
+                  details::free_node(*node_allocator_, result);
+                  return error_node();
+               }
+               else if (details::is_ivector_node(vec_node) && !details::is_vector_node(vec_node))
+               {
+                  vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
+
+                  result = (rtc) ?
+                     node_allocator_->allocate<vector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) :
+                     node_allocator_->allocate<vector_celem_node_t    >(vec_node, vec_index, vector_base     ) ;
+
+                  node_name = (rtc) ?
+                     "vector_elem_rtc_node_t" :
+                     "vector_elem_node_t"     ;
+
+                  if (result && result->valid())
+                  {
+                     return result;
+                  }
+
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_synthesis,
+                     token_t(),
+                     "ERR266 - Failed to synthesize node: " + node_name + " for vector: " + symbol,
+                     exprtk_error_location));
+
+                  details::free_node(*node_allocator_, result);
+                  return error_node();
+               }
+
+               const scope_element& se = parser_->sem_.get_element(symbol,vec_index);
+
+               if (se.index == vec_index)
                {
                   result = se.var_node;
+                  details::free_node(*node_allocator_,vec_node);
                }
                else
                {
@@ -29872,10 +33952,10 @@ namespace exprtk
                   nse.active    = true;
                   nse.ref_count = 1;
                   nse.type      = scope_element::e_vecelem;
-                  nse.index     = i;
+                  nse.index     = vec_index;
                   nse.depth     = parser_->state_.scope_depth;
                   nse.data      = 0;
-                  nse.var_node  = node_allocator_->allocate<variable_node_t>((*(*vector_base)[i]));
+                  nse.var_node  = node_allocator_->allocate<variable_node_t>((*(*vector_base)[vec_index]));
 
                   if (!parser_->sem_.add_element(nse))
                   {
@@ -29886,19 +33966,55 @@ namespace exprtk
                      result = error_node();
                   }
 
-                  exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse.name.c_str()));
+                  details::free_node(*node_allocator_,vec_node);
+
+                  exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n", nse.name.c_str()));
 
                   parser_->state_.activate_side_effect("vector_element()");
 
                   result = nse.var_node;
+                  node_name = "variable_node_t";
                }
             }
-            else if (vector_base->rebaseable())
-               result = node_allocator_->allocate<rebasevector_elem_node_t>(index,vector_base);
             else
-               result = node_allocator_->allocate<vector_elem_node_t>(index,vector_base);
+            {
+               vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
 
-            return result;
+               if (vector_base->rebaseable())
+               {
+                  result = (rtc) ?
+                     node_allocator_->allocate<rebasevector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) :
+                     node_allocator_->allocate<rebasevector_elem_node_t    >(vec_node, index, vector_base     ) ;
+
+                  node_name = (rtc) ?
+                     "rebasevector_elem_rtc_node_t" :
+                     "rebasevector_elem_node_t"     ;
+               }
+               else
+               {
+                  result = rtc ?
+                     node_allocator_->allocate<vector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) :
+                     node_allocator_->allocate<vector_elem_node_t    >(vec_node, index, vector_base     ) ;
+
+                  node_name = (rtc) ?
+                     "vector_elem_rtc_node_t" :
+                     "vector_elem_node_t"     ;
+               }
+            }
+
+            if (result && result->valid())
+            {
+               return result;
+            }
+
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_synthesis,
+               token_t(),
+               "ERR267 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
       private:
@@ -29995,12 +34111,27 @@ namespace exprtk
                   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_veccelem:
+                     return reinterpret_cast<const void*>(&static_cast<vector_celem_node_t*>(node)->ref());
+
+                  case details::expression_node<T>::e_vecelemrtc:
+                     return reinterpret_cast<const void*>(&static_cast<vector_elem_rtc_node_t*>(node)->ref());
+
+                  case details::expression_node<T>::e_veccelemrtc:
+                     return reinterpret_cast<const void*>(&static_cast<vector_celem_rtc_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_rbvecelemrtc:
+                     return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_rtc_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_rbveccelemrtc:
+                     return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_rtc_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());
 
@@ -30032,11 +34163,11 @@ namespace exprtk
                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));
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_parser,
+                     token,
+                     "ERR268 - 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.");
@@ -30058,16 +34189,26 @@ namespace exprtk
                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]))
+            else if (details::is_vector_elem_node(branch[0]) || details::is_vector_celem_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_vector_elem_rtc_node(branch[0]) || details::is_vector_celem_rtc_node(branch[0]))
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+               return synthesize_expression<assignment_vec_elem_rtc_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_elem_rtc_node(branch[0]))
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+               return synthesize_expression<assignment_rebasevec_elem_rtc_node_t, 2>(operation, branch);
+            }
             else if (details::is_rebasevector_celem_node(branch[0]))
             {
                lodge_assignment(e_st_vecelem,branch[0]);
@@ -30094,9 +34235,23 @@ namespace exprtk
                else
                   return synthesize_expression<assignment_vec_node_t,2>(operation, branch);
             }
+            else if (details::is_literal_node(branch[0]))
+            {
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR269 - Cannot assign value to const variable",
+                  exprtk_error_location));
+
+               return error_node();
+            }
             else
             {
-               parser_->set_synthesis_error("Invalid assignment operation.[1]");
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR270 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -30110,6 +34265,9 @@ namespace exprtk
                return error_node();
             }
 
+            expression_node_ptr result = error_node();
+            std::string node_name = "Unknown";
+
             if (details::is_variable_node(branch[0]))
             {
                lodge_assignment(e_st_variable,branch[0]);
@@ -30117,9 +34275,11 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                 \
-                  case op0 : return node_allocator_->                                                         \
+                  case op0 : result = node_allocator_->                                                       \
                                 template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                         \
+                             node_name = "assignment_op_node";                                                \
+                             break;                                                                           \
 
                   case_stmt(details::e_addass , details::add_op)
                   case_stmt(details::e_subass , details::sub_op)
@@ -30137,9 +34297,55 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                           \
-                  case op0 : return node_allocator_->                                                                   \
+                  case op0 : result = node_allocator_->                                                                 \
                                  template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
                                     (operation, branch[0], branch[1]);                                                  \
+                             node_name = "assignment_vec_elem_op_node";                                                 \
+                             break;                                                                                     \
+
+                  case_stmt(details::e_addass , details::add_op)
+                  case_stmt(details::e_subass , details::sub_op)
+                  case_stmt(details::e_mulass , details::mul_op)
+                  case_stmt(details::e_divass , details::div_op)
+                  case_stmt(details::e_modass , details::mod_op)
+                  #undef case_stmt
+                  default : return error_node();
+               }
+            }
+            else if (details::is_vector_elem_rtc_node(branch[0]))
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+
+               switch (operation)
+               {
+                  #define case_stmt(op0, op1)                                                                               \
+                  case op0 : result = node_allocator_->                                                                     \
+                                 template allocate_rrr<typename details::assignment_vec_elem_op_rtc_node<Type,op1<Type> > > \
+                                    (operation, branch[0], branch[1]);                                                      \
+                             node_name = "assignment_vec_elem_op_rtc_node";                                                 \
+                             break;                                                                                         \
+
+                  case_stmt(details::e_addass , details::add_op)
+                  case_stmt(details::e_subass , details::sub_op)
+                  case_stmt(details::e_mulass , details::mul_op)
+                  case_stmt(details::e_divass , details::div_op)
+                  case_stmt(details::e_modass , details::mod_op)
+                  #undef case_stmt
+                  default : return error_node();
+               }
+            }
+            else if (details::is_vector_celem_rtc_node(branch[0]))
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+
+               switch (operation)
+               {
+                  #define case_stmt(op0, op1)                                                                                \
+                  case op0 : result = node_allocator_->                                                                      \
+                                 template allocate_rrr<typename details::assignment_vec_celem_op_rtc_node<Type,op1<Type> > > \
+                                    (operation, branch[0], branch[1]);                                                       \
+                             node_name = "assignment_vec_celem_op_rtc_node";                                                 \
+                             break;                                                                                          \
 
                   case_stmt(details::e_addass , details::add_op)
                   case_stmt(details::e_subass , details::sub_op)
@@ -30157,9 +34363,11 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                                 \
-                  case op0 : return node_allocator_->                                                                         \
+                  case op0 : result = node_allocator_->                                                                       \
                                  template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \
                                     (operation, branch[0], branch[1]);                                                        \
+                             node_name = "assignment_rebasevec_elem_op_node";                                                 \
+                             break;                                                                                           \
 
                   case_stmt(details::e_addass , details::add_op)
                   case_stmt(details::e_subass , details::sub_op)
@@ -30177,9 +34385,55 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                                  \
-                  case op0 : return node_allocator_->                                                                          \
+                  case op0 : result = node_allocator_->                                                                        \
                                  template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \
                                     (operation, branch[0], branch[1]);                                                         \
+                             node_name = "assignment_rebasevec_celem_op_node";                                                 \
+                             break;                                                                                            \
+
+                  case_stmt(details::e_addass , details::add_op)
+                  case_stmt(details::e_subass , details::sub_op)
+                  case_stmt(details::e_mulass , details::mul_op)
+                  case_stmt(details::e_divass , details::div_op)
+                  case_stmt(details::e_modass , details::mod_op)
+                  #undef case_stmt
+                  default : return error_node();
+               }
+            }
+            else if (details::is_rebasevector_elem_rtc_node(branch[0]))
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+
+               switch (operation)
+               {
+                  #define case_stmt(op0, op1)                                                                                     \
+                  case op0 : result = node_allocator_->                                                                           \
+                                 template allocate_rrr<typename details::assignment_rebasevec_elem_op_rtc_node<Type,op1<Type> > > \
+                                    (operation, branch[0], branch[1]);                                                            \
+                             node_name = "assignment_rebasevec_elem_op_rtc_node";                                                 \
+                             break;                                                                                               \
+
+                  case_stmt(details::e_addass , details::add_op)
+                  case_stmt(details::e_subass , details::sub_op)
+                  case_stmt(details::e_mulass , details::mul_op)
+                  case_stmt(details::e_divass , details::div_op)
+                  case_stmt(details::e_modass , details::mod_op)
+                  #undef case_stmt
+                  default : return error_node();
+               }
+            }
+            else if (details::is_rebasevector_celem_rtc_node(branch[0]))
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+
+               switch (operation)
+               {
+                  #define case_stmt(op0, op1)                                                                                      \
+                  case op0 : result = node_allocator_->                                                                            \
+                                 template allocate_rrr<typename details::assignment_rebasevec_celem_op_rtc_node<Type,op1<Type> > > \
+                                    (operation, branch[0], branch[1]);                                                             \
+                             node_name = "assignment_rebasevec_celem_op_rtc_node";                                                 \
+                             break;                                                                                                \
 
                   case_stmt(details::e_addass , details::add_op)
                   case_stmt(details::e_subass , details::sub_op)
@@ -30199,9 +34453,11 @@ namespace exprtk
                   switch (operation)
                   {
                      #define case_stmt(op0, op1)                                                                        \
-                     case op0 : return node_allocator_->                                                                \
+                     case op0 : result = node_allocator_->                                                              \
                                    template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
                                       (operation, branch[0], branch[1]);                                                \
+                                node_name = "assignment_rebasevec_celem_op_node";                                       \
+                                break;                                                                                  \
 
                      case_stmt(details::e_addass , details::add_op)
                      case_stmt(details::e_subass , details::sub_op)
@@ -30217,9 +34473,11 @@ namespace exprtk
                   switch (operation)
                   {
                      #define case_stmt(op0, op1)                                                                     \
-                     case op0 : return node_allocator_->                                                             \
+                     case op0 : result = node_allocator_->                                                           \
                                    template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
                                       (operation, branch[0], branch[1]);                                             \
+                                node_name = "assignment_vec_op_node";                                                \
+                                break;                                                                               \
 
                      case_stmt(details::e_addass , details::add_op)
                      case_stmt(details::e_subass , details::sub_op)
@@ -30241,15 +34499,34 @@ namespace exprtk
 
                lodge_assignment(e_st_string,branch[0]);
 
-               return synthesize_expression<addass_t,2>(operation,branch);
+               result = synthesize_expression<addass_t,2>(operation,branch);
+               node_name = "assignment_string_node<T,details::asn_addassignment>";
             }
             #endif
             else
             {
-               parser_->set_synthesis_error("Invalid assignment operation[2]");
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR271 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
+
+            if (result && result->valid())
+            {
+               return result;
+            }
+
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_synthesis,
+               token_t(),
+               "ERR272 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
          inline expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type& operation,
@@ -30273,14 +34550,19 @@ namespace exprtk
             case_stmt(details::e_xor   , details::xor_op  ) \
             case_stmt(details::e_xnor  , details::xnor_op ) \
 
+            expression_node_ptr result = error_node();
+            std::string node_name = "Unknown";
+
             if (is_b0_ivec && is_b1_ivec)
             {
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                    \
-                  case op0 : return node_allocator_->                                                            \
+                  case op0 : result = node_allocator_->                                                          \
                                 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                            \
+                             node_name = "vec_binop_vecvec_node";                                                \
+                             break;                                                                              \
 
                   batch_eqineq_logic_case
                   #undef case_stmt
@@ -30292,9 +34574,11 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                    \
-                  case op0 : return node_allocator_->                                                            \
+                  case op0 : result = node_allocator_->                                                          \
                                 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                            \
+                             node_name = "vec_binop_vecval_node";                                                \
+                             break;                                                                              \
 
                   batch_eqineq_logic_case
                   #undef case_stmt
@@ -30306,9 +34590,11 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                    \
-                  case op0 : return node_allocator_->                                                            \
+                  case op0 : result = node_allocator_->                                                          \
                                 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                            \
+                             node_name = "vec_binop_valvec_node";                                                \
+                             break;                                                                              \
 
                   batch_eqineq_logic_case
                   #undef case_stmt
@@ -30318,6 +34604,20 @@ namespace exprtk
             else
                return error_node();
 
+            if (result && result->valid())
+            {
+               return result;
+            }
+
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_synthesis,
+               token_t(),
+               "ERR273 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
+
             #undef batch_eqineq_logic_case
          }
 
@@ -30334,14 +34634,19 @@ namespace exprtk
             case_stmt(details::e_div , details::div_op) \
             case_stmt(details::e_mod , details::mod_op) \
 
+            expression_node_ptr result = error_node();
+            std::string node_name = "Unknown";
+
             if (is_b0_ivec && is_b1_ivec)
             {
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                    \
-                  case op0 : return node_allocator_->                                                            \
+                  case op0 : result = node_allocator_->                                                          \
                                 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                            \
+                             node_name = "vec_binop_vecvec_node";                                                \
+                             break;                                                                              \
 
                   vector_ops
                   case_stmt(details::e_pow,details:: pow_op)
@@ -30354,9 +34659,11 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                    \
-                  case op0 : return node_allocator_->                                                            \
+                  case op0 : result = node_allocator_->                                                          \
                                 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                            \
+                             node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)";                                \
+                             break;                                                                              \
 
                   vector_ops
                   case_stmt(details::e_pow,details:: pow_op)
@@ -30369,9 +34676,11 @@ namespace exprtk
                switch (operation)
                {
                   #define case_stmt(op0, op1)                                                                    \
-                  case op0 : return node_allocator_->                                                            \
+                  case op0 : result = node_allocator_->                                                          \
                                 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
                                    (operation, branch[0], branch[1]);                                            \
+                             node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)";                                \
+                             break;                                                                              \
 
                   vector_ops
                   #undef case_stmt
@@ -30381,6 +34690,20 @@ namespace exprtk
             else
                return error_node();
 
+            if (result && result->valid())
+            {
+               return result;
+            }
+
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_synthesis,
+               token_t(),
+               "ERR274 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
+
             #undef vector_ops
          }
 
@@ -30398,6 +34721,7 @@ namespace exprtk
             #endif
 
             expression_node_ptr result = error_node();
+            std::string node_name      = "Unknown";
 
             if (v0_is_ivar && v1_is_ivar)
             {
@@ -30411,36 +34735,57 @@ namespace exprtk
                     (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1])))
                   )
                {
-                  result = node_allocator_->allocate<details::swap_node<T> >(v0,v1);
+                  result    = node_allocator_->allocate<details::swap_node<T> >(v0,v1);
+                  node_name = "swap_node";
                }
                else
-                  result = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
+               {
+                  result    = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
+                  node_name = "swap_generic_node";
+               }
             }
             else if (v0_is_ivec && v1_is_ivec)
             {
-               result = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
+               result    = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
+               node_name = "swap_vecvec_node";
             }
             #ifndef exprtk_disable_string_capabilities
             else if (v0_is_str && v1_is_str)
             {
                if (is_string_node(branch[0]) && is_string_node(branch[1]))
+               {
                   result = node_allocator_->allocate<details::swap_string_node<T> >
                                                (branch[0], branch[1]);
+                  node_name = "swap_string_node";
+               }
                else
+               {
                   result = node_allocator_->allocate<details::swap_genstrings_node<T> >
                                                (branch[0], branch[1]);
+                  node_name = "swap_genstrings_node";
+               }
             }
             #endif
             else
             {
                parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped");
-
                return error_node();
             }
 
-            parser_->state_.activate_side_effect("synthesize_swap_expression()");
+            if (result && result->valid())
+            {
+               parser_->state_.activate_side_effect("synthesize_swap_expression()");
+               return result;
+            }
 
-            return result;
+            parser_->set_error(parser_error::make_error(
+               parser_error::e_synthesis,
+               token_t(),
+               "ERR275 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
          #ifndef exprtk_disable_sc_andor
@@ -30596,7 +34941,7 @@ namespace exprtk
             else if (not_recipricol)
                return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
             else
-               return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowninv_node>(branch[0],p);
+               return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p);
          }
          #else
          inline expression_node_ptr cardinal_pow_optimisation(T&, const T&)
@@ -31969,9 +36314,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "t";
             }
          };
 
@@ -32034,9 +36379,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)";
             }
          };
 
@@ -32100,9 +36445,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "t";
             }
          };
 
@@ -32165,9 +36510,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)";
             }
          };
 
@@ -32230,9 +36575,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "t";
             }
          };
 
@@ -32295,9 +36640,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)";
             }
          };
 
@@ -32360,9 +36705,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "t";
             }
          };
 
@@ -32426,9 +36771,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)";
             }
          };
 
@@ -32545,9 +36890,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "t";
             }
          };
 
@@ -32664,9 +37009,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)";
             }
          };
 
@@ -32795,9 +37140,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)";
             }
          };
 
@@ -32922,9 +37267,9 @@ namespace exprtk
                                          const details::operator_type o1)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "t";
             }
          };
 
@@ -33057,10 +37402,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -33146,10 +37491,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -33235,10 +37580,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -33324,10 +37669,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -33413,10 +37758,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -33607,10 +37952,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -33851,10 +38196,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -34045,10 +38390,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -34238,10 +38583,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "t)" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t)";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "t)" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -34298,10 +38643,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34358,10 +38703,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34418,10 +38763,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34478,10 +38823,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34539,10 +38884,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34600,10 +38945,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34660,10 +39005,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34720,10 +39065,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34780,10 +39125,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"  << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "(t" << expr_gen.to_str(o2)
-                         << "t))";
+                  << "t"  << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "(t" << expr_gen.to_str(o2)
+                  << "t))";
             }
          };
 
@@ -34840,10 +39185,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -34900,10 +39245,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -34960,10 +39305,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -35020,10 +39365,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -35081,10 +39426,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
         };
 
@@ -35142,10 +39487,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -35202,10 +39547,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -35263,10 +39608,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "t"   << expr_gen.to_str(o0)
-                         << "((t" << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t)";
+                  << "t"   << expr_gen.to_str(o0)
+                  << "((t" << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t)";
             }
          };
 
@@ -35344,10 +39689,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35405,10 +39750,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35465,10 +39810,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35525,10 +39870,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35585,10 +39930,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35645,10 +39990,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35706,10 +40051,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35767,10 +40112,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35827,10 +40172,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "((t" << expr_gen.to_str(o0)
-                         << "t)"  << expr_gen.to_str(o1)
-                         << "t)"  << expr_gen.to_str(o2)
-                         << "t";
+                  << "((t" << expr_gen.to_str(o0)
+                  << "t)"  << expr_gen.to_str(o1)
+                  << "t)"  << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35887,10 +40232,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -35948,10 +40293,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36008,10 +40353,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36067,10 +40412,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36127,10 +40472,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36187,10 +40532,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36248,10 +40593,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36309,10 +40654,10 @@ namespace exprtk
                                          const details::operator_type o2)
             {
                return details::build_string()
-                         << "(t" << expr_gen.to_str(o0)
-                         << "(t" << expr_gen.to_str(o1)
-                         << "t)" << expr_gen.to_str(o2)
-                         << "t";
+                  << "(t" << expr_gen.to_str(o0)
+                  << "(t" << expr_gen.to_str(o1)
+                  << "t)" << expr_gen.to_str(o2)
+                  << "t";
             }
          };
 
@@ -36737,6 +41082,8 @@ namespace exprtk
                default : return error_node();
             }
          }
+
+         #undef string_opr_switch_statements
          #endif
 
          #ifndef exprtk_disable_string_capabilities
@@ -37070,11 +41417,22 @@ namespace exprtk
 
                   return node_allocator_->allocate<literal_node_t>(v);
                }
-               else
+
+               if (expression_point && expression_point->valid())
+               {
                   return expression_point;
+               }
+
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_parser,
+                  token_t(),
+                  "ERR276 - Failed to synthesize node: NodeType",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, expression_point);
             }
-            else
-               return error_node();
+
+            return error_node();
          }
 
          template <typename NodeType, std::size_t N>
@@ -37154,8 +41512,11 @@ namespace exprtk
          {
             scope_element& se = sem_.get_element(i);
 
+            exprtk_debug(("register_local_vars() - se[%s]\n", se.name.c_str()));
+
             if (
                  (scope_element::e_variable == se.type) ||
+                 (scope_element::e_literal  == se.type) ||
                  (scope_element::e_vecelem  == se.type)
                )
             {
@@ -37428,6 +41789,7 @@ namespace exprtk
       sf4_map_t sf4_map_;
       std::string synthesis_error_;
       scope_element_manager sem_;
+      std::vector<state_t> current_state_stack_;
 
       immutable_memory_map_t immutable_memory_map_;
       immutable_symtok_map_t immutable_symtok_map_;
@@ -37443,7 +41805,11 @@ namespace exprtk
       lexer::helper::sequence_validator         sequence_validator_;
       lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
 
-      loop_runtime_check_ptr loop_runtime_check_;
+      loop_runtime_check_ptr          loop_runtime_check_;
+      vector_access_runtime_check_ptr vector_access_runtime_check_;
+      compilation_check_ptr           compilation_check_ptr_;
+      assert_check_ptr                assert_check_;
+      std::set<std::string>           assert_ids_;
 
       template <typename ParserType>
       friend void details::disable_type_checking(ParserType& p);
@@ -37460,17 +41826,19 @@ namespace exprtk
          typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
          typedef typename parser_t::unknown_symbol_resolver usr_t;
 
-         struct resolve_as_vector : public parser_t::unknown_symbol_resolver
+         struct resolve_as_vector : public usr_t
          {
             typedef exprtk::parser<T> parser_t;
 
+            using usr_t::process;
+
             resolve_as_vector()
             : usr_t(usr_t::e_usrmode_extended)
             {}
 
             virtual bool process(const std::string& unknown_symbol,
                                  symbol_table_t& symbol_table,
-                                 std::string&)
+                                 std::string&) exprtk_override
             {
                static T v[1];
                symbol_table.add_vector(unknown_symbol,v);
@@ -37682,7 +42050,9 @@ namespace exprtk
       const symbol_table<T>& sym_table = e.get_symbol_table();
 
       if (!sym_table.valid())
+      {
          return std::numeric_limits<T>::quiet_NaN();
+      }
 
       details::variable_node<T>* var = sym_table.get_variable(variable_name);
 
@@ -37695,8 +42065,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    template <typename T>
@@ -37786,8 +42156,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    template <typename T>
@@ -37813,8 +42183,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    template <typename T>
@@ -37840,8 +42210,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    /*
@@ -38120,97 +42490,98 @@ namespace exprtk
          disable_has_side_effects(*this);
       }
 
-      virtual ~polynomial() {}
+      virtual ~polynomial()
+      {}
 
       #define poly_rtrn(NN) \
       return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
 
-      inline virtual T operator() (const T& x, const T& c1, const T& c0)
+      inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0));
       }
 
-      inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0)
+      inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0));
       }
 
-      inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0)
+      inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1,
-                                   const T& c0)
+                                   const T& c0) exprtk_override
       {
          poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2,
-                                   const T& c1, const T& c0)
+                                   const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3,
-                                   const T& c2, const T& c1, const T& c0)
+                                   const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4,
-                                   const T& c3, const T& c2, const T& c1, const T& c0)
+                                   const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5,
-                                   const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
+                                   const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6,
                                    const T& c5, const T& c4, const T& c3, const T& c2, const T& c1,
-                                   const T& c0)
+                                   const T& c0) exprtk_override
       {
          poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7,
                                    const T& c6, const T& c5, const T& c4, const T& c3, const T& c2,
-                                   const T& c1, const T& c0)
+                                   const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8,
                                    const T& c7, const T& c6, const T& c5, const T& c4, const T& c3,
-                                   const T& c2, const T& c1, const T& c0)
+                                   const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
       }
 
       inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9,
                                    const T& c8, const T& c7, const T& c6, const T& c5, const T& c4,
-                                   const T& c3, const T& c2, const T& c1, const T& c0)
+                                   const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
       {
          poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
       }
 
       #undef poly_rtrn
 
-      inline virtual T operator() ()
+      inline virtual T operator() () exprtk_override
       {
          return std::numeric_limits<T>::quiet_NaN();
       }
 
-      inline virtual T operator() (const T&)
+      inline virtual T operator() (const T&) exprtk_override
       {
          return std::numeric_limits<T>::quiet_NaN();
       }
 
-      inline virtual T operator() (const T&, const T&)
+      inline virtual T operator() (const T&, const T&) exprtk_override
       {
          return std::numeric_limits<T>::quiet_NaN();
       }
@@ -38312,6 +42683,50 @@ namespace exprtk
             return (*this);
          }
 
+         inline function& vars(const std::string& v0,
+                               const std::string& v1)
+         {
+            v_.push_back(v0);
+            v_.push_back(v1);
+            return (*this);
+         }
+
+         inline function& vars(const std::string& v0,
+                               const std::string& v1,
+                               const std::string& v2)
+         {
+            v_.push_back(v0);
+            v_.push_back(v1);
+            v_.push_back(v2);
+            return (*this);
+         }
+
+         inline function& vars(const std::string& v0,
+                               const std::string& v1,
+                               const std::string& v2,
+                               const std::string& v3)
+         {
+            v_.push_back(v0);
+            v_.push_back(v1);
+            v_.push_back(v2);
+            v_.push_back(v3);
+            return (*this);
+         }
+
+         inline function& vars(const std::string& v0,
+                               const std::string& v1,
+                               const std::string& v2,
+                               const std::string& v3,
+                               const std::string& v4)
+         {
+            v_.push_back(v0);
+            v_.push_back(v1);
+            v_.push_back(v2);
+            v_.push_back(v3);
+            v_.push_back(v4);
+            return (*this);
+         }
+
          std::string name_;
          std::string expression_;
          std::deque<std::string> v_;
@@ -38321,12 +42736,14 @@ namespace exprtk
 
       struct base_func : public exprtk::ifunction<T>
       {
-         typedef const T&                       type;
-         typedef exprtk::ifunction<T>     function_t;
-         typedef std::vector<T*>            varref_t;
-         typedef std::vector<T>                var_t;
+         typedef const T&                  type;
+         typedef exprtk::ifunction<T>      function_t;
+         typedef std::vector<T*>           varref_t;
+         typedef std::vector<T>            var_t;
+         typedef std::vector<std::string>  str_t;
          typedef std::pair<T*,std::size_t> lvarref_t;
          typedef std::vector<lvarref_t>    lvr_vec_t;
+         typedef std::vector<std::string*> lstr_vec_t;
 
          using exprtk::ifunction<T>::operator();
 
@@ -38338,10 +42755,11 @@ namespace exprtk
             v.resize(pc);
          }
 
-         virtual ~base_func() {}
+         virtual ~base_func()
+         {}
 
-         #define exprtk_assign(Index)   \
-         (*v[Index]) = v##Index; \
+         #define exprtk_assign(Index) \
+         (*v[Index]) = v##Index;      \
 
          inline void update(const T& v0)
          {
@@ -38387,17 +42805,33 @@ namespace exprtk
          {
             expression = expr;
 
-            typedef typename expression_t::control_block::local_data_list_t ldl_t;
+            typedef typename expression_t::control_block  ctrlblk_t;
+            typedef typename ctrlblk_t::local_data_list_t ldl_t;
+            typedef typename ctrlblk_t::data_type         data_t;
+            typedef typename ldl_t::value_type            ldl_value_type;
 
             const ldl_t ldl = expr.local_data_list();
 
-            std::vector<std::size_t> index_list;
+            std::vector<std::pair<std::size_t,data_t> > index_list;
 
             for (std::size_t i = 0; i < ldl.size(); ++i)
             {
+               exprtk_debug(("base_func::setup() - element[%02d] type: %s size: %d\n",
+                             static_cast<int>(i),
+                             expression_t::control_block::to_str(ldl[i].type).c_str(),
+                             static_cast<int>(ldl[i].size)));
+
+               switch (ldl[i].type)
+               {
+                  case ctrlblk_t::e_unknown   : continue;
+                  case ctrlblk_t::e_expr      : continue;
+                  case ctrlblk_t::e_vecholder : continue;
+                  default                     : break;
+               }
+
                if (ldl[i].size)
                {
-                  index_list.push_back(i);
+                  index_list.push_back(std::make_pair(i,ldl[i].type));
                }
             }
 
@@ -38405,19 +42839,34 @@ namespace exprtk
 
             for (std::size_t i = 0; i < index_list.size(); ++i)
             {
-               const std::size_t index = index_list[i];
+               const std::size_t index         = index_list[i].first;
+               const ldl_value_type& local_var = ldl[index];
+
+               assert(local_var.pointer);
 
                if (i < (index_list.size() - v.size()))
                {
-                  lv.push_back(
-                        std::make_pair(
-                           reinterpret_cast<T*>(ldl[index].pointer),
-                           ldl[index].size));
+                  if (local_var.type == ctrlblk_t::e_string)
+                  {
+                     local_str_vars.push_back(
+                        reinterpret_cast<std::string*>(local_var.pointer));
+                  }
+                  else if (
+                            (local_var.type == ctrlblk_t::e_data   ) ||
+                            (local_var.type == ctrlblk_t::e_vecdata)
+                          )
+                  {
+                     local_vars.push_back(std::make_pair(
+                        reinterpret_cast<T*>(local_var.pointer),
+                        local_var.size));
 
-                  local_var_stack_size += ldl[index].size;
+                     local_var_stack_size += local_var.size;
+                  }
                }
                else
-                  v[input_param_count++] = reinterpret_cast<T*>(ldl[index].pointer);
+               {
+                  v[input_param_count++] = reinterpret_cast<T*>(local_var.pointer);
+               }
             }
 
             clear_stack();
@@ -38433,14 +42882,21 @@ namespace exprtk
                {
                   var_t var_stack(v.size(),T(0));
                   copy(v,var_stack);
-                  param_stack.push_back(var_stack);
+                  input_params_stack.push_back(var_stack);
                }
 
-               if (!lv.empty())
+               if (!local_vars.empty())
                {
-                  var_t local_var_stack(local_var_stack_size,T(0));
-                  copy(lv,local_var_stack);
-                  local_stack.push_back(local_var_stack);
+                  var_t local_vec_frame(local_var_stack_size,T(0));
+                  copy(local_vars,local_vec_frame);
+                  local_var_stack.push_back(local_vec_frame);
+               }
+
+               if (!local_str_vars.empty())
+               {
+                  str_t local_str_frame(local_str_vars.size());
+                  copy(local_str_vars,local_str_frame);
+                  local_str_stack.push_back(local_str_frame);
                }
             }
          }
@@ -38451,14 +42907,20 @@ namespace exprtk
             {
                if (!v.empty())
                {
-                  copy(param_stack.back(),v);
-                  param_stack.pop_back();
+                  copy(input_params_stack.back(), v);
+                  input_params_stack.pop_back();
                }
 
-               if (!lv.empty())
+               if (!local_vars.empty())
                {
-                  copy(local_stack.back(),lv);
-                  local_stack.pop_back();
+                  copy(local_var_stack.back(), local_vars);
+                  local_var_stack.pop_back();
+               }
+
+               if (!local_str_vars.empty())
+               {
+                  copy(local_str_stack.back(), local_str_vars);
+                  local_str_stack.pop_back();
                }
             }
          }
@@ -38471,6 +42933,14 @@ namespace exprtk
             }
          }
 
+         void copy(const lstr_vec_t& src_v, str_t& dest_v)
+         {
+            for (std::size_t i = 0; i < src_v.size(); ++i)
+            {
+               dest_v[i] = (*src_v[i]);
+            }
+         }
+
          void copy(const var_t& src_v, varref_t& dest_v)
          {
             for (std::size_t i = 0; i < src_v.size(); ++i)
@@ -38503,9 +42973,12 @@ namespace exprtk
             typename var_t::const_iterator itr = src_v.begin();
             typedef  typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
 
-            for (std::size_t i = 0; i < src_v.size(); ++i)
+            for (std::size_t i = 0; i < dest_v.size(); ++i)
             {
-               lvarref_t vr = dest_v[i];
+               lvarref_t& vr = dest_v[i];
+
+               assert(vr.first != 0);
+               assert(vr.second > 0);
 
                if (1 == vr.second)
                   (*vr.first) = *itr++;
@@ -38517,6 +42990,16 @@ namespace exprtk
             }
          }
 
+         void copy(const str_t& src_str, lstr_vec_t& dest_str)
+         {
+            assert(src_str.size() == dest_str.size());
+
+            for (std::size_t i = 0; i < dest_str.size(); ++i)
+            {
+               *dest_str[i] = src_str[i];
+            }
+         }
+
          inline void clear_stack()
          {
             for (std::size_t i = 0; i < v.size(); ++i)
@@ -38530,29 +43013,19 @@ namespace exprtk
             return e.value();
          }
 
-         expression_t expression;
-         varref_t v;
-         lvr_vec_t lv;
-         std::size_t local_var_stack_size;
-         std::size_t stack_depth;
-         std::deque<var_t> param_stack;
-         std::deque<var_t> local_stack;
+         expression_t      expression;
+         varref_t          v;
+         lvr_vec_t         local_vars;
+         lstr_vec_t        local_str_vars;
+         std::size_t       local_var_stack_size;
+         std::size_t       stack_depth;
+         std::deque<var_t> input_params_stack;
+         std::deque<var_t> local_var_stack;
+         std::deque<str_t> local_str_stack;
       };
 
       typedef std::map<std::string,base_func*> funcparam_t;
 
-      struct func_0param : public base_func
-      {
-         using exprtk::ifunction<T>::operator();
-
-         func_0param() : base_func(0) {}
-
-         inline T operator() ()
-         {
-            return this->value(base_func::expression);
-         }
-      };
-
       typedef const T& type;
 
       template <typename BaseFuncType>
@@ -38577,13 +43050,26 @@ namespace exprtk
          scoped_bft& operator=(const scoped_bft&) exprtk_delete;
       };
 
+      struct func_0param : public base_func
+      {
+         using exprtk::ifunction<T>::operator();
+
+         func_0param() : base_func(0) {}
+
+         inline T operator() () exprtk_override
+         {
+            scoped_bft<func_0param> sb(*this);
+            return this->value(base_func::expression);
+         }
+      };
+
       struct func_1param : public base_func
       {
          using exprtk::ifunction<T>::operator();
 
          func_1param() : base_func(1) {}
 
-         inline T operator() (type v0)
+         inline T operator() (type v0) exprtk_override
          {
             scoped_bft<func_1param> sb(*this);
             base_func::update(v0);
@@ -38597,7 +43083,7 @@ namespace exprtk
 
          func_2param() : base_func(2) {}
 
-         inline T operator() (type v0, type v1)
+         inline T operator() (type v0, type v1) exprtk_override
          {
             scoped_bft<func_2param> sb(*this);
             base_func::update(v0, v1);
@@ -38611,7 +43097,7 @@ namespace exprtk
 
          func_3param() : base_func(3) {}
 
-         inline T operator() (type v0, type v1, type v2)
+         inline T operator() (type v0, type v1, type v2) exprtk_override
          {
             scoped_bft<func_3param> sb(*this);
             base_func::update(v0, v1, v2);
@@ -38625,7 +43111,7 @@ namespace exprtk
 
          func_4param() : base_func(4) {}
 
-         inline T operator() (type v0, type v1, type v2, type v3)
+         inline T operator() (type v0, type v1, type v2, type v3) exprtk_override
          {
             scoped_bft<func_4param> sb(*this);
             base_func::update(v0, v1, v2, v3);
@@ -38639,7 +43125,7 @@ namespace exprtk
 
          func_5param() : base_func(5) {}
 
-         inline T operator() (type v0, type v1, type v2, type v3, type v4)
+         inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override
          {
             scoped_bft<func_5param> sb(*this);
             base_func::update(v0, v1, v2, v3, v4);
@@ -38653,7 +43139,7 @@ namespace exprtk
 
          func_6param() : base_func(6) {}
 
-         inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5)
+         inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override
          {
             scoped_bft<func_6param> sb(*this);
             base_func::update(v0, v1, v2, v3, v4, v5);
@@ -38680,14 +43166,14 @@ namespace exprtk
          return result;
       }
 
-      #define def_fp_retval(N)                               \
-      struct func_##N##param_retval : public func_##N##param \
-      {                                                      \
-         inline T value(expression_t& e)                     \
-         {                                                   \
-            return return_value(e);                          \
-         }                                                   \
-      };                                                     \
+      #define def_fp_retval(N)                                            \
+      struct func_##N##param_retval exprtk_final : public func_##N##param \
+      {                                                                   \
+         inline T value(expression_t& e) exprtk_override                  \
+         {                                                                \
+            return return_value(e);                                       \
+         }                                                                \
+      };                                                                  \
 
       def_fp_retval(0)
       def_fp_retval(1)
@@ -38697,6 +43183,8 @@ namespace exprtk
       def_fp_retval(5)
       def_fp_retval(6)
 
+      #undef def_fp_retval
+
       template <typename Allocator,
                 template <typename, typename> class Sequence>
       inline bool add(const std::string& name,
@@ -38739,16 +43227,20 @@ namespace exprtk
    public:
 
       function_compositor()
-      : parser_(settings_t::compile_all_opts +
+      : parser_(settings_t::default_compile_all_opts +
                 settings_t::e_disable_zero_return)
       , fp_map_(7)
+      , load_variables_(false)
+      , load_vectors_(false)
       {}
 
-      function_compositor(const symbol_table_t& st)
+      explicit function_compositor(const symbol_table_t& st)
       : symbol_table_(st)
-      , parser_(settings_t::compile_all_opts +
+      , parser_(settings_t::default_compile_all_opts +
                 settings_t::e_disable_zero_return)
       , fp_map_(7)
+      , load_variables_(false)
+      , load_vectors_(false)
       {}
 
      ~function_compositor()
@@ -38771,6 +43263,46 @@ namespace exprtk
          auxiliary_symtab_list_.push_back(&symtab);
       }
 
+      void load_variables(const bool load = true)
+      {
+         load_variables_ = load;
+      }
+
+      void load_vectors(const bool load = true)
+      {
+         load_vectors_ = load;
+      }
+
+      inline void register_loop_runtime_check(loop_runtime_check& lrtchk)
+      {
+         parser_.register_loop_runtime_check(lrtchk);
+      }
+
+      inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk)
+      {
+         parser_.register_vector_access_runtime_check(vartchk);
+      }
+
+      inline void register_compilation_timeout_check(compilation_check& compchk)
+      {
+         parser_.register_compilation_timeout_check(compchk);
+      }
+
+      inline void clear_loop_runtime_check()
+      {
+         parser_.clear_loop_runtime_check();
+      }
+
+      inline void clear_vector_access_runtime_check()
+      {
+         parser_.clear_vector_access_runtime_check();
+      }
+
+      inline void clear_compilation_timeout_check()
+      {
+         parser_.clear_compilation_timeout_check();
+      }
+
       void clear()
       {
          symbol_table_.clear();
@@ -38789,6 +43321,10 @@ namespace exprtk
 
             fp_map_[i].clear();
          }
+
+         clear_loop_runtime_check         ();
+         clear_vector_access_runtime_check();
+         clear_compilation_timeout_check  ();
       }
 
       inline bool add(const function& f, const bool override = false)
@@ -38796,6 +43332,31 @@ namespace exprtk
          return add(f.name_, f.expression_, f.v_,override);
       }
 
+      inline std::string error() const
+      {
+         if (!error_list_.empty())
+         {
+            return error_list_[0].diagnostic;
+         }
+         else
+            return std::string("No Error");
+      }
+
+      inline std::size_t error_count() const
+      {
+         return error_list_.size();
+      }
+
+      inline parser_error::type get_error(const std::size_t& index) const
+      {
+         if (index < error_list_.size())
+         {
+            return error_list_[index];
+         }
+
+         throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
+      }
+
    private:
 
       template <typename Allocator,
@@ -38811,8 +43372,30 @@ namespace exprtk
          local_symbol_table.load_from(symbol_table_);
          local_symbol_table.add_constants();
 
+         if (load_variables_)
+         {
+            local_symbol_table.load_variables_from(symbol_table_);
+         }
+
+         if (load_vectors_)
+         {
+            local_symbol_table.load_vectors_from(symbol_table_);
+         }
+
+         error_list_.clear();
+
          if (!valid(name,input_var_list.size()))
+         {
+            parser_error::type error =
+               parser_error::make_error(
+                  parser_error::e_parser,
+                  lexer::token(),
+                  "ERR277 - Function '" + name + "' is an invalid overload",
+                  exprtk_error_location);
+
+            error_list_.push_back(error);
             return false;
+         }
 
          if (!forward(name,
                       input_var_list.size(),
@@ -38844,18 +43427,22 @@ namespace exprtk
 
          if (!parser_.compile(mod_expression,compiled_expression))
          {
-            exprtk_debug(("Compositor Error: %s\n",parser_.error().c_str()));
-            exprtk_debug(("Compositor modified expression: \n%s\n",mod_expression.c_str()));
+            exprtk_debug(("Compositor Error: %s\n", parser_.error().c_str()));
+            exprtk_debug(("Compositor modified expression: \n%s\n", mod_expression.c_str()));
 
             remove(name,input_var_list.size());
 
+            for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index)
+            {
+               error_list_.push_back(parser_.get_error(err_index));
+            }
+
             return false;
          }
 
          if (!return_present && parser_.dec().return_present())
          {
             remove(name,input_var_list.size());
-
             return compile_expression(name, expression, input_var_list, true);
          }
 
@@ -38976,11 +43563,14 @@ namespace exprtk
       std::map<std::string,expression_t> expr_map_;
       std::vector<funcparam_t> fp_map_;
       std::vector<symbol_table_t*> auxiliary_symtab_list_;
+      std::deque<parser_error::type> error_list_;
+      bool load_variables_;
+      bool load_vectors_;
    }; // class function_compositor
 
 } // namespace exprtk
 
-#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+#if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
 #   ifndef NOMINMAX
 #      define NOMINMAX
 #   endif
@@ -39001,9 +43591,11 @@ namespace exprtk
    {
    public:
 
-      #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+      #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
       timer()
       : in_use_(false)
+      , start_time_{ {0, 0} }
+      , stop_time_ { {0, 0} }
       {
          QueryPerformanceFrequency(&clock_frequency_);
       }
@@ -39081,7 +43673,7 @@ namespace exprtk
 
       bool in_use_;
 
-      #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+      #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
          LARGE_INTEGER start_time_;
          LARGE_INTEGER stop_time_;
          LARGE_INTEGER clock_frequency_;
@@ -39114,7 +43706,23 @@ namespace exprtk
                              const T v,
                              exprtk::details::numeric::details::real_type_tag)
       {
-         printf(fmt.c_str(),v);
+         #if defined(__clang__)
+            #pragma clang diagnostic push
+            #pragma clang diagnostic ignored "-Wformat-nonliteral"
+         #elif defined(__GNUC__) || defined(__GNUG__)
+            #pragma GCC diagnostic push
+            #pragma GCC diagnostic ignored "-Wformat-nonliteral"
+         #elif defined(_MSC_VER)
+         #endif
+
+         printf(fmt.c_str(), v);
+
+         #if defined(__clang__)
+            #pragma clang diagnostic pop
+         #elif defined(__GNUC__) || defined(__GNUG__)
+            #pragma GCC diagnostic pop
+         #elif defined(_MSC_VER)
+         #endif
       }
 
       template <typename T>
@@ -39174,19 +43782,19 @@ namespace exprtk
    } // namespace exprtk::rtl::io::details
 
    template <typename T>
-   struct print : public exprtk::igeneric_function<T>
+   struct print exprtk_final : public exprtk::igeneric_function<T>
    {
       typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
 
       using exprtk::igeneric_function<T>::operator();
 
-      print(const std::string& scalar_format = "%10.5f")
+      explicit print(const std::string& scalar_format = "%10.5f")
       : scalar_format_(scalar_format)
       {
          exprtk::enable_zero_parameters(*this);
       }
 
-      inline T operator() (parameter_list_t parameters)
+      inline T operator() (parameter_list_t parameters) exprtk_override
       {
          details::print_impl<T>::process(scalar_format_,parameters);
          return T(0);
@@ -39196,19 +43804,19 @@ namespace exprtk
    };
 
    template <typename T>
-   struct println : public exprtk::igeneric_function<T>
+   struct println exprtk_final : public exprtk::igeneric_function<T>
    {
       typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
 
       using exprtk::igeneric_function<T>::operator();
 
-      println(const std::string& scalar_format = "%10.5f")
+      explicit println(const std::string& scalar_format = "%10.5f")
       : scalar_format_(scalar_format)
       {
          exprtk::enable_zero_parameters(*this);
       }
 
-      inline T operator() (parameter_list_t parameters)
+      inline T operator() (parameter_list_t parameters) exprtk_override
       {
          details::print_impl<T>::process(scalar_format_,parameters);
          printf("\n");
@@ -39290,8 +43898,8 @@ namespace exprtk
 
                   return false;
                }
-               else
-                  stream_ptr = stream;
+
+               stream_ptr = stream;
 
                return true;
             }
@@ -39306,8 +43914,8 @@ namespace exprtk
 
                   return false;
                }
-               else
-                  stream_ptr = stream;
+
+               stream_ptr = stream;
 
                return true;
             }
@@ -39322,13 +43930,13 @@ namespace exprtk
 
                   return false;
                }
-               else
-                  stream_ptr = stream;
+
+               stream_ptr = stream;
 
                return true;
             }
-            else
-               return false;
+
+            return false;
          }
 
          template <typename Stream, typename Ptr>
@@ -39475,12 +44083,13 @@ namespace exprtk
          #ifdef _MSC_VER
          #pragma warning(pop)
          #endif
+         assert(sizeof(T) <= sizeof(void*));
       }
 
    } // namespace exprtk::rtl::io::file::details
 
    template <typename T>
-   class open : public exprtk::igeneric_function<T>
+   class open exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39489,18 +44098,20 @@ namespace exprtk
       typedef typename igfun_t::generic_type        generic_type;
       typedef typename generic_type::string_view    string_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       open()
       : exprtk::igeneric_function<T>("S|SS")
       { details::perform_check<T>(); }
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const std::string file_name = to_str(string_t(parameters[0]));
 
          if (file_name.empty())
+         {
             return T(0);
+         }
 
          if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
          {
@@ -39532,7 +44143,7 @@ namespace exprtk
    };
 
    template <typename T>
-   struct close : public exprtk::ifunction<T>
+   struct close exprtk_final : public exprtk::ifunction<T>
    {
       using exprtk::ifunction<T>::operator();
 
@@ -39540,7 +44151,7 @@ namespace exprtk
       : exprtk::ifunction<T>(1)
       { details::perform_check<T>(); }
 
-      inline T operator() (const T& v)
+      inline T operator() (const T& v) exprtk_override
       {
          details::file_descriptor* fd = details::make_handle(v);
 
@@ -39554,7 +44165,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class write : public exprtk::igeneric_function<T>
+   class write exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39565,13 +44176,13 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       write()
       : igfun_t("TS|TST|TV|TVT")
       { details::perform_check<T>(); }
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
 
@@ -39611,7 +44222,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class read : public exprtk::igeneric_function<T>
+   class read exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39622,13 +44233,13 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       read()
       : igfun_t("TS|TST|TV|TVT")
       { details::perform_check<T>(); }
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
 
@@ -39668,7 +44279,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class getline : public exprtk::igeneric_function<T>
+   class getline exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39678,14 +44289,13 @@ namespace exprtk
       typedef typename generic_type::string_view    string_t;
       typedef typename generic_type::scalar_view    scalar_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       getline()
       : igfun_t("T",igfun_t::e_rtrn_string)
       { details::perform_check<T>(); }
 
-      inline T operator() (std::string& result,
-                           parameter_list_t parameters)
+      inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override
       {
          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
          return T(fd->getline(result) ? 1 : 0);
@@ -39693,7 +44303,7 @@ namespace exprtk
    };
 
    template <typename T>
-   struct eof : public exprtk::ifunction<T>
+   struct eof exprtk_final : public exprtk::ifunction<T>
    {
       using exprtk::ifunction<T>::operator();
 
@@ -39701,10 +44311,9 @@ namespace exprtk
       : exprtk::ifunction<T>(1)
       { details::perform_check<T>(); }
 
-      inline T operator() (const T& v)
+      inline T operator() (const T& v) exprtk_override
       {
          details::file_descriptor* fd = details::make_handle(v);
-
          return (fd->eof() ? T(1) : T(0));
       }
    };
@@ -39814,236 +44423,7 @@ namespace exprtk
    } // namespace exprtk::rtl::details
 
    template <typename T>
-   class all_true : public exprtk::igeneric_function<T>
-   {
-   public:
-
-      typedef typename exprtk::igeneric_function<T> igfun_t;
-      typedef typename igfun_t::parameter_list_t    parameter_list_t;
-      typedef typename igfun_t::generic_type        generic_type;
-      typedef typename generic_type::vector_view    vector_t;
-
-      using exprtk::igeneric_function<T>::operator();
-
-      all_true()
-      : exprtk::igeneric_function<T>("V|VTT")
-        /*
-           Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
-        */
-      {}
-
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
-      {
-         const vector_t vec(parameters[0]);
-
-         std::size_t r0 = 0;
-         std::size_t r1 = vec.size() - 1;
-
-         if (
-              (1 == ps_index) &&
-              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
-            )
-            return std::numeric_limits<T>::quiet_NaN();
-
-         for (std::size_t i = r0; i <= r1; ++i)
-         {
-            if (vec[i] == T(0))
-            {
-               return T(0);
-            }
-         }
-
-         return T(1);
-      }
-   };
-
-   template <typename T>
-   class all_false : public exprtk::igeneric_function<T>
-   {
-   public:
-
-      typedef typename exprtk::igeneric_function<T> igfun_t;
-      typedef typename igfun_t::parameter_list_t    parameter_list_t;
-      typedef typename igfun_t::generic_type        generic_type;
-      typedef typename generic_type::vector_view    vector_t;
-
-      using exprtk::igeneric_function<T>::operator();
-
-      all_false()
-      : exprtk::igeneric_function<T>("V|VTT")
-        /*
-           Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
-        */
-      {}
-
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
-      {
-         const vector_t vec(parameters[0]);
-
-         std::size_t r0 = 0;
-         std::size_t r1 = vec.size() - 1;
-
-         if (
-              (1 == ps_index) &&
-              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
-            )
-            return std::numeric_limits<T>::quiet_NaN();
-
-         for (std::size_t i = r0; i <= r1; ++i)
-         {
-            if (vec[i] != T(0))
-            {
-               return T(0);
-            }
-         }
-
-         return T(1);
-      }
-   };
-
-   template <typename T>
-   class any_true : public exprtk::igeneric_function<T>
-   {
-   public:
-
-      typedef typename exprtk::igeneric_function<T> igfun_t;
-      typedef typename igfun_t::parameter_list_t    parameter_list_t;
-      typedef typename igfun_t::generic_type        generic_type;
-      typedef typename generic_type::vector_view    vector_t;
-
-      using exprtk::igeneric_function<T>::operator();
-
-      any_true()
-      : exprtk::igeneric_function<T>("V|VTT")
-        /*
-           Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
-        */
-      {}
-
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
-      {
-         const vector_t vec(parameters[0]);
-
-         std::size_t r0 = 0;
-         std::size_t r1 = vec.size() - 1;
-
-         if (
-              (1 == ps_index) &&
-              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
-            )
-            return std::numeric_limits<T>::quiet_NaN();
-
-         for (std::size_t i = r0; i <= r1; ++i)
-         {
-            if (vec[i] != T(0))
-            {
-               return T(1);
-            }
-         }
-
-         return T(0);
-      }
-   };
-
-   template <typename T>
-   class any_false : public exprtk::igeneric_function<T>
-   {
-   public:
-
-      typedef typename exprtk::igeneric_function<T> igfun_t;
-      typedef typename igfun_t::parameter_list_t    parameter_list_t;
-      typedef typename igfun_t::generic_type        generic_type;
-      typedef typename generic_type::vector_view    vector_t;
-
-      using exprtk::igeneric_function<T>::operator();
-
-      any_false()
-      : exprtk::igeneric_function<T>("V|VTT")
-        /*
-           Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
-        */
-      {}
-
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
-      {
-         const vector_t vec(parameters[0]);
-
-         std::size_t r0 = 0;
-         std::size_t r1 = vec.size() - 1;
-
-         if (
-              (1 == ps_index) &&
-              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
-            )
-            return std::numeric_limits<T>::quiet_NaN();
-
-         for (std::size_t i = r0; i <= r1; ++i)
-         {
-            if (vec[i] == T(0))
-            {
-               return T(1);
-            }
-         }
-
-         return T(0);
-      }
-   };
-
-   template <typename T>
-   class count : public exprtk::igeneric_function<T>
-   {
-   public:
-
-      typedef typename exprtk::igeneric_function<T> igfun_t;
-      typedef typename igfun_t::parameter_list_t    parameter_list_t;
-      typedef typename igfun_t::generic_type        generic_type;
-      typedef typename generic_type::vector_view    vector_t;
-
-      using exprtk::igeneric_function<T>::operator();
-
-      count()
-      : exprtk::igeneric_function<T>("V|VTT")
-        /*
-           Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
-        */
-      {}
-
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
-      {
-         const vector_t vec(parameters[0]);
-
-         std::size_t r0 = 0;
-         std::size_t r1 = vec.size() - 1;
-
-         if (
-              (1 == ps_index) &&
-              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
-            )
-            return std::numeric_limits<T>::quiet_NaN();
-
-         std::size_t cnt = 0;
-
-         for (std::size_t i = r0; i <= r1; ++i)
-         {
-            if (vec[i] != T(0)) ++cnt;
-         }
-
-         return T(cnt);
-      }
-   };
-
-   template <typename T>
-   class copy : public exprtk::igeneric_function<T>
+   class all_true exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40053,7 +44433,318 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
+
+      all_true()
+      : exprtk::igeneric_function<T>("V|VTT|T*")
+        /*
+           Overloads:
+           0. V   - vector
+           1. VTT - vector, r0, r1
+           2. T*  - T....T
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         if (2 == ps_index)
+         {
+            for (std::size_t i = 0; i < parameters.size(); ++i)
+            {
+               if (scalar_t(parameters[i])() == T(0))
+               {
+                  return T(0);
+               }
+            }
+         }
+         else
+         {
+            const vector_t vec(parameters[0]);
+
+            std::size_t r0 = 0;
+            std::size_t r1 = vec.size() - 1;
+
+            if (
+                 (1 == ps_index) &&
+                 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+               )
+            {
+               return std::numeric_limits<T>::quiet_NaN();
+            }
+
+            for (std::size_t i = r0; i <= r1; ++i)
+            {
+               if (vec[i] == T(0))
+               {
+                  return T(0);
+               }
+            }
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class all_false exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      all_false()
+      : exprtk::igeneric_function<T>("V|VTT|T*")
+        /*
+           Overloads:
+           0. V   - vector
+           1. VTT - vector, r0, r1
+           2. T*  - T....T
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         if (2 == ps_index)
+         {
+            for (std::size_t i = 0; i < parameters.size(); ++i)
+            {
+               if (scalar_t(parameters[i])() != T(0))
+               {
+                  return T(0);
+               }
+            }
+         }
+         else
+         {
+            const vector_t vec(parameters[0]);
+
+            std::size_t r0 = 0;
+            std::size_t r1 = vec.size() - 1;
+
+            if (
+                 (1 == ps_index) &&
+                 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+               )
+            {
+               return std::numeric_limits<T>::quiet_NaN();
+            }
+
+            for (std::size_t i = r0; i <= r1; ++i)
+            {
+               if (vec[i] != T(0))
+               {
+                  return T(0);
+               }
+            }
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class any_true exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      any_true()
+      : exprtk::igeneric_function<T>("V|VTT|T*")
+        /*
+           Overloads:
+           0. V   - vector
+           1. VTT - vector, r0, r1
+           2. T*  - T....T
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         if (2 == ps_index)
+         {
+            for (std::size_t i = 0; i < parameters.size(); ++i)
+            {
+               if (scalar_t(parameters[i])() != T(0))
+               {
+                  return T(1);
+               }
+            }
+         }
+         else
+         {
+            const vector_t vec(parameters[0]);
+
+            std::size_t r0 = 0;
+            std::size_t r1 = vec.size() - 1;
+
+            if (
+                 (1 == ps_index) &&
+                 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+               )
+            {
+               return std::numeric_limits<T>::quiet_NaN();
+            }
+
+            for (std::size_t i = r0; i <= r1; ++i)
+            {
+               if (vec[i] != T(0))
+               {
+                  return T(1);
+               }
+            }
+         }
+
+         return T(0);
+      }
+   };
+
+   template <typename T>
+   class any_false exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      any_false()
+      : exprtk::igeneric_function<T>("V|VTT|T*")
+        /*
+           Overloads:
+           0. V   - vector
+           1. VTT - vector, r0, r1
+           2. T*  - T....T
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         if (2 == ps_index)
+         {
+            for (std::size_t i = 0; i < parameters.size(); ++i)
+            {
+               if (scalar_t(parameters[i])() == T(0))
+               {
+                  return T(1);
+               }
+            }
+         }
+         else
+         {
+            const vector_t vec(parameters[0]);
+
+            std::size_t r0 = 0;
+            std::size_t r1 = vec.size() - 1;
+
+            if (
+                 (1 == ps_index) &&
+                 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+               )
+            {
+               return std::numeric_limits<T>::quiet_NaN();
+            }
+
+            for (std::size_t i = r0; i <= r1; ++i)
+            {
+               if (vec[i] == T(0))
+               {
+                  return T(1);
+               }
+            }
+         }
+
+         return T(0);
+      }
+   };
+
+   template <typename T>
+   class count exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      count()
+      : exprtk::igeneric_function<T>("V|VTT|T*")
+        /*
+           Overloads:
+           0. V   - vector
+           1. VTT - vector, r0, r1
+           2. T*  - T....T
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         std::size_t cnt = 0;
+
+         if (2 == ps_index)
+         {
+            for (std::size_t i = 0; i < parameters.size(); ++i)
+            {
+               if (scalar_t(parameters[i])() != T(0)) ++cnt;
+            }
+         }
+         else
+         {
+            const vector_t vec(parameters[0]);
+
+            std::size_t r0 = 0;
+            std::size_t r1 = vec.size() - 1;
+
+            if (
+                 (1 == ps_index) &&
+                 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+               )
+            {
+               return std::numeric_limits<T>::quiet_NaN();
+            }
+
+            for (std::size_t i = r0; i <= r1; ++i)
+            {
+               if (vec[i] != T(0)) ++cnt;
+            }
+         }
+
+         return T(cnt);
+      }
+   };
+
+   template <typename T>
+   class copy exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
 
       copy()
       : exprtk::igeneric_function<T>("VV|VTTVTT")
@@ -40064,7 +44755,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[0]);
                vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
@@ -40096,7 +44787,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class rol : public exprtk::igeneric_function<T>
+   class rol exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40106,7 +44797,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       rol()
       : exprtk::igeneric_function<T>("VT|VTTT")
@@ -40117,7 +44808,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
@@ -40147,7 +44838,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class ror : public exprtk::igeneric_function<T>
+   class ror exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40157,7 +44848,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       ror()
       : exprtk::igeneric_function<T>("VT|VTTT")
@@ -40168,7 +44859,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
@@ -40185,8 +44876,8 @@ namespace exprtk
             )
             return T(0);
 
-         std::size_t dist  = r1 - r0 + 1;
-         std::size_t shift = (dist - (n % dist)) % dist;
+         const std::size_t dist  = r1 - r0 + 1;
+         const std::size_t shift = (dist - (n % dist)) % dist;
 
          std::rotate(
             vec.begin() + r0,
@@ -40198,7 +44889,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class shift_left : public exprtk::igeneric_function<T>
+   class reverse exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40208,7 +44899,48 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
+
+      reverse()
+      : exprtk::igeneric_function<T>("V|VTT")
+        /*
+           Overloads:
+           0. V   - vector
+           1. VTT - vector, r0, r1
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         vector_t vec(parameters[0]);
+
+         std::size_t r0 = 0;
+         std::size_t r1 = vec.size() - 1;
+
+         if (
+              (1 == ps_index) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+            )
+            return T(0);
+
+         std::reverse(vec.begin() + r0, vec.begin() + r1 + 1);
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class shift_left exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
 
       shift_left()
       : exprtk::igeneric_function<T>("VT|VTTT")
@@ -40219,7 +44951,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
@@ -40246,7 +44978,7 @@ namespace exprtk
             vec.begin() + r0 + n,
             vec.begin() + r1 + 1);
 
-         for (std::size_t i = r1 - n + 1; i <= r1; ++i)
+         for (std::size_t i = r1 - n + 1ULL; i <= r1; ++i)
          {
             vec[i] = T(0);
          }
@@ -40256,7 +44988,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class shift_right : public exprtk::igeneric_function<T>
+   class shift_right exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40266,7 +44998,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       shift_right()
       : exprtk::igeneric_function<T>("VT|VTTT")
@@ -40277,7 +45009,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
@@ -40316,7 +45048,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class sort : public exprtk::igeneric_function<T>
+   class sort exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40326,7 +45058,7 @@ namespace exprtk
       typedef typename generic_type::string_view    string_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       sort()
       : exprtk::igeneric_function<T>("V|VTT|VS|VSTT")
@@ -40339,7 +45071,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
@@ -40379,7 +45111,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class nthelement : public exprtk::igeneric_function<T>
+   class nthelement exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40389,7 +45121,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       nthelement()
       : exprtk::igeneric_function<T>("VT|VTTT")
@@ -40400,7 +45132,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
@@ -40412,7 +45144,9 @@ namespace exprtk
             return T(0);
 
          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
+         {
             return std::numeric_limits<T>::quiet_NaN();
+         }
 
          std::nth_element(
             vec.begin() + r0,
@@ -40424,7 +45158,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class iota : public exprtk::igeneric_function<T>
+   class assign exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40434,41 +45168,41 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
-      iota()
-      : exprtk::igeneric_function<T>("VT|VTT|VTTT|VTTTT")
+      assign()
+      : exprtk::igeneric_function<T>("VT|VTTT|VTTTT")
         /*
            Overloads:
-           0. VT    - vector, increment
-           1. VTT   - vector, increment, base
-           2. VTTTT - vector, increment, r0, r1
-           3. VTTTT - vector, increment, base, r0, r1
+           0. VT    - vector, V
+           1. VTTT  - vector, V, r0, r1
+           2. VTTTT - vector, V, r0, r1, SS
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          vector_t vec(parameters[0]);
 
-         T increment = scalar_t(parameters[1])();
-         T base      = ((1 == ps_index) || (3 == ps_index)) ? scalar_t(parameters[2])() : T(0);
+         const T assign_value = scalar_t(parameters[1]);
+
+         const std::size_t step_size = (2 != ps_index) ? 1 :
+                                       static_cast<std::size_t>(scalar_t(parameters.back())());
 
          std::size_t r0 = 0;
          std::size_t r1 = vec.size() - 1;
 
-         if ((2 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
-            return std::numeric_limits<T>::quiet_NaN();
-         else if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 0))
-            return std::numeric_limits<T>::quiet_NaN();
-         else
+         if (
+              ((ps_index == 1) || (ps_index == 2)) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
+            )
          {
-            long long j = 0;
+            return T(0);
+         }
 
-            for (std::size_t i = r0; i <= r1; ++i, ++j)
-            {
-               vec[i] = base + (increment * j);
-            }
+         for (std::size_t i = r0; i <= r1; i += step_size)
+         {
+            vec[i] = assign_value;
          }
 
          return T(1);
@@ -40476,40 +45210,110 @@ namespace exprtk
    };
 
    template <typename T>
-   class sumk : public exprtk::igeneric_function<T>
+   class iota exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
       typedef typename exprtk::igeneric_function<T> igfun_t;
       typedef typename igfun_t::parameter_list_t    parameter_list_t;
       typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
-      sumk()
-      : exprtk::igeneric_function<T>("V|VTT")
+      iota()
+      : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT")
         /*
            Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
+           0. VTT  - vector, SV, SS
+           1. VT   - vector, SV, SS (+1)
+           2. VTTT - vector, r0, r1, SV, SS
+           3. VTT  - vector, r0, r1, SV, SS (+1)
+
+           Where:
+           1. SV - Start value
+           2. SS - Step size
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
-         const vector_t vec(parameters[0]);
+         vector_t vec(parameters[0]);
+
+         const T start_value = (ps_index <= 1) ?
+                               scalar_t(parameters[1]) :
+                               scalar_t(parameters[3]) ;
+
+         const T step_size = ((0 == ps_index) || (2 == ps_index)) ?
+                             scalar_t(parameters.back())() :
+                             T(1) ;
 
          std::size_t r0 = 0;
          std::size_t r1 = vec.size() - 1;
 
-         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
+         if (
+              ((ps_index == 2) || (ps_index == 3)) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+            )
+         {
+            return T(0);
+         }
+
+         for (std::size_t i = r0; i <= r1; ++i)
+         {
+            vec[i] = start_value + ((i - r0) * step_size);
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class sumk exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      sumk()
+      : exprtk::igeneric_function<T>("V|VTT|VTTT")
+        /*
+           Overloads:
+           0. V    - vector
+           1. VTT  - vector, r0, r1
+           2. VTTT - vector, r0, r1, stride
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         const vector_t vec(parameters[0]);
+
+         const std::size_t stride = (2 != ps_index) ? 1 :
+                                    static_cast<std::size_t>(scalar_t(parameters[3])());
+
+         std::size_t r0 = 0;
+         std::size_t r1 = vec.size() - 1;
+
+         if (
+              ((1 == ps_index) || (2 == ps_index)) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+            )
+         {
             return std::numeric_limits<T>::quiet_NaN();
+         }
 
          T result = T(0);
          T error  = T(0);
 
-         for (std::size_t i = r0; i <= r1; ++i)
+         for (std::size_t i = r0; i <= r1; i += stride)
          {
             details::kahan_sum(result, error, vec[i]);
          }
@@ -40519,7 +45323,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpy : public exprtk::igeneric_function<T>
+   class axpy exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40529,7 +45333,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       axpy()
       : exprtk::igeneric_function<T>("TVV|TVVTT")
@@ -40541,7 +45345,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[1]);
                vector_t y(parameters[2]);
@@ -40566,7 +45370,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpby : public exprtk::igeneric_function<T>
+   class axpby exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40576,7 +45380,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       axpby()
       : exprtk::igeneric_function<T>("TVTV|TVTVTT")
@@ -40588,7 +45392,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[1]);
                vector_t y(parameters[3]);
@@ -40614,7 +45418,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpyz : public exprtk::igeneric_function<T>
+   class axpyz exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40624,7 +45428,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       axpyz()
       : exprtk::igeneric_function<T>("TVVV|TVVVTT")
@@ -40636,7 +45440,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[1]);
          const vector_t y(parameters[2]);
@@ -40645,7 +45449,7 @@ namespace exprtk
          std::size_t r0 = 0;
          std::size_t r1 = std::min(x.size(),y.size()) - 1;
 
-         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
+         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
             return std::numeric_limits<T>::quiet_NaN();
          else if (helper::invalid_range(y, r0, r1))
             return std::numeric_limits<T>::quiet_NaN();
@@ -40664,7 +45468,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpbyz : public exprtk::igeneric_function<T>
+   class axpbyz exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40674,7 +45478,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       axpbyz()
       : exprtk::igeneric_function<T>("TVTVV|TVTVVTT")
@@ -40686,7 +45490,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[1]);
          const vector_t y(parameters[3]);
@@ -40695,7 +45499,7 @@ namespace exprtk
          std::size_t r0 = 0;
          std::size_t r1 = std::min(x.size(),y.size()) - 1;
 
-         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
+         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
             return std::numeric_limits<T>::quiet_NaN();
          else if (helper::invalid_range(y, r0, r1))
             return std::numeric_limits<T>::quiet_NaN();
@@ -40715,7 +45519,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpbz : public exprtk::igeneric_function<T>
+   class axpbsy exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40725,7 +45529,110 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
+
+      axpbsy()
+      : exprtk::igeneric_function<T>("TVTTV|TVTTVTT")
+        /*
+           y <- ax + by
+           Overloads:
+           0. TVTVV   - a, x(vector), b, shift, y(vector), z(vector)
+           1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         const vector_t x(parameters[1]);
+               vector_t y(parameters[4]);
+
+         std::size_t r0 = 0;
+         std::size_t r1 = std::min(x.size(),y.size()) - 1;
+
+         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
+            return std::numeric_limits<T>::quiet_NaN();
+         else if (helper::invalid_range(y, r0, r1))
+            return std::numeric_limits<T>::quiet_NaN();
+
+         const T a = scalar_t(parameters[0])();
+         const T b = scalar_t(parameters[2])();
+
+         const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
+
+         for (std::size_t i = r0; i <= r1; ++i)
+         {
+            y[i] = (a * x[i]) + (b * y[i + s]);
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class axpbsyz exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      axpbsyz()
+      : exprtk::igeneric_function<T>("TVTTVV|TVTTVVTT")
+        /*
+           z <- ax + by
+           Overloads:
+           0. TVTVV   - a, x(vector), b, shift, y(vector), z(vector)
+           1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         const vector_t x(parameters[1]);
+         const vector_t y(parameters[4]);
+               vector_t z(parameters[5]);
+
+         std::size_t r0 = 0;
+         std::size_t r1 = std::min(x.size(),y.size()) - 1;
+
+         if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1))
+            return std::numeric_limits<T>::quiet_NaN();
+         else if (helper::invalid_range(y, r0, r1))
+            return std::numeric_limits<T>::quiet_NaN();
+         else if (helper::invalid_range(z, r0, r1))
+            return std::numeric_limits<T>::quiet_NaN();
+
+         const T a = scalar_t(parameters[0])();
+         const T b = scalar_t(parameters[2])();
+
+         const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
+
+         for (std::size_t i = r0; i <= r1; ++i)
+         {
+            z[i] = (a * x[i]) + (b * y[i + s]);
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class axpbz exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
 
       axpbz()
       : exprtk::igeneric_function<T>("TVTV|TVTVTT")
@@ -40737,7 +45644,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[1]);
                vector_t z(parameters[3]);
@@ -40763,7 +45670,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class dot : public exprtk::igeneric_function<T>
+   class diff exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40773,7 +45680,55 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
+
+      diff()
+      : exprtk::igeneric_function<T>("VV|VVT")
+        /*
+           x_(i - stride) - x_i
+           Overloads:
+           0. VV  - x(vector), y(vector)
+           1. VVT - x(vector), y(vector), stride
+        */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         const vector_t x(parameters[0]);
+               vector_t y(parameters[1]);
+
+         const std::size_t r0 = 0;
+         const std::size_t r1 = std::min(x.size(),y.size()) - 1;
+
+         const std::size_t stride = (1 != ps_index) ? 1 :
+                                    std::min(r1,static_cast<std::size_t>(scalar_t(parameters[2])()));
+
+         for (std::size_t i = 0; i < stride; ++i)
+         {
+            y[i] = std::numeric_limits<T>::quiet_NaN();
+         }
+
+         for (std::size_t i = (r0 + stride); i <= r1; ++i)
+         {
+            y[i] = x[i] - x[i - stride];
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class dot exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
 
       dot()
       : exprtk::igeneric_function<T>("VV|VVTT")
@@ -40784,7 +45739,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[0]);
          const vector_t y(parameters[1]);
@@ -40809,7 +45764,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class dotk : public exprtk::igeneric_function<T>
+   class dotk exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40819,7 +45774,7 @@ namespace exprtk
       typedef typename generic_type::scalar_view    scalar_t;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       dotk()
       : exprtk::igeneric_function<T>("VV|VVTT")
@@ -40830,7 +45785,7 @@ namespace exprtk
         */
       {}
 
-      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
       {
          const vector_t x(parameters[0]);
          const vector_t y(parameters[1]);
@@ -40855,30 +45810,155 @@ namespace exprtk
       }
    };
 
+   template <typename T>
+   class threshold_below exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      threshold_below()
+      : exprtk::igeneric_function<T>("VTT|VTTTT")
+      /*
+         Overloads:
+         0. VTT   - vector, TV, SV
+         1. VTTTT - vector, r0, r1, TV, SV
+
+         Where:
+         TV - Threshold value
+         SV - Snap-to value
+      */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         vector_t vec(parameters[0]);
+
+         const T threshold_value = (0 == ps_index) ?
+                                   scalar_t(parameters[1]) :
+                                   scalar_t(parameters[3]) ;
+
+         const T snap_value = scalar_t(parameters.back());
+
+         std::size_t r0 = 0;
+         std::size_t r1 = vec.size() - 1;
+
+         if (
+              (1 == ps_index) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+            )
+         {
+            return T(0);
+         }
+
+         for (std::size_t i = r0; i <= r1; ++i)
+         {
+            if (vec[i] < threshold_value)
+            {
+               vec[i] = snap_value;
+            }
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename T>
+   class threshold_above exprtk_final : public exprtk::igeneric_function<T>
+   {
+   public:
+
+      typedef typename exprtk::igeneric_function<T> igfun_t;
+      typedef typename igfun_t::parameter_list_t    parameter_list_t;
+      typedef typename igfun_t::generic_type        generic_type;
+      typedef typename generic_type::scalar_view    scalar_t;
+      typedef typename generic_type::vector_view    vector_t;
+
+      using igfun_t::operator();
+
+      threshold_above()
+      : exprtk::igeneric_function<T>("VTT|VTTTT")
+      /*
+         Overloads:
+         0. VTT   - vector, TV, SV
+         1. VTTTT - vector, r0, r1, TV, SV
+
+         Where:
+         TV - Threshold value
+         SV - Snap-to value
+      */
+      {}
+
+      inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
+      {
+         vector_t vec(parameters[0]);
+
+         const T threshold_value = (0 == ps_index) ?
+                                   scalar_t(parameters[1]) :
+                                   scalar_t(parameters[3]) ;
+
+         const T snap_value = scalar_t(parameters.back());
+
+         std::size_t r0 = 0;
+         std::size_t r1 = vec.size() - 1;
+
+         if (
+              (1 == ps_index) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
+            )
+         {
+            return T(0);
+         }
+
+         for (std::size_t i = r0; i <= r1; ++i)
+         {
+            if (vec[i] > threshold_value)
+            {
+               vec[i] = snap_value;
+            }
+         }
+
+         return T(1);
+      }
+   };
+
    template <typename T>
    struct package
    {
-      all_true   <T> at;
-      all_false  <T> af;
-      any_true   <T> nt;
-      any_false  <T> nf;
-      count      <T>  c;
-      copy       <T> cp;
-      rol        <T> rl;
-      ror        <T> rr;
-      shift_left <T> sl;
-      shift_right<T> sr;
-      sort       <T> st;
-      nthelement <T> ne;
-      iota       <T> ia;
-      sumk       <T> sk;
-      axpy       <T> b1_axpy;
-      axpby      <T> b1_axpby;
-      axpyz      <T> b1_axpyz;
-      axpbyz     <T> b1_axpbyz;
-      axpbz      <T> b1_axpbz;
-      dot        <T> dt;
-      dotk       <T> dtk;
+      all_true       <T> at;
+      all_false      <T> af;
+      any_true       <T> nt;
+      any_false      <T> nf;
+      count          <T>  c;
+      copy           <T> cp;
+      rol            <T> rl;
+      ror            <T> rr;
+      reverse        <T> rev;
+      shift_left     <T> sl;
+      shift_right    <T> sr;
+      sort           <T> st;
+      nthelement     <T> ne;
+      assign         <T> an;
+      iota           <T> ia;
+      sumk           <T> sk;
+      axpy           <T> b1_axpy;
+      axpby          <T> b1_axpby;
+      axpyz          <T> b1_axpyz;
+      axpbyz         <T> b1_axpbyz;
+      axpbsy         <T> b1_axpbsy;
+      axpbsyz        <T> b1_axpbsyz;
+      axpbz          <T> b1_axpbz;
+      diff           <T> df;
+      dot            <T> dt;
+      dotk           <T> dtk;
+      threshold_above<T> ta;
+      threshold_below<T> tb;
 
       bool register_package(exprtk::symbol_table<T>& symtab)
       {
@@ -40891,29 +45971,36 @@ namespace exprtk
             return false;                                                             \
          }                                                                            \
 
-         exprtk_register_function("all_true"     , at       )
-         exprtk_register_function("all_false"    , af       )
-         exprtk_register_function("any_true"     , nt       )
-         exprtk_register_function("any_false"    , nf       )
-         exprtk_register_function("count"        , c        )
-         exprtk_register_function("copy"         , cp       )
-         exprtk_register_function("rotate_left"  , rl       )
-         exprtk_register_function("rol"          , rl       )
-         exprtk_register_function("rotate_right" , rr       )
-         exprtk_register_function("ror"          , rr       )
-         exprtk_register_function("shftl"        , sl       )
-         exprtk_register_function("shftr"        , sr       )
-         exprtk_register_function("sort"         , st       )
-         exprtk_register_function("nth_element"  , ne       )
-         exprtk_register_function("iota"         , ia       )
-         exprtk_register_function("sumk"         , sk       )
-         exprtk_register_function("axpy"         , b1_axpy  )
-         exprtk_register_function("axpby"        , b1_axpby )
-         exprtk_register_function("axpyz"        , b1_axpyz )
-         exprtk_register_function("axpbyz"       , b1_axpbyz)
-         exprtk_register_function("axpbz"        , b1_axpbz )
-         exprtk_register_function("dot"          , dt       )
-         exprtk_register_function("dotk"         , dtk      )
+         exprtk_register_function("all_true"        , at        )
+         exprtk_register_function("all_false"       , af        )
+         exprtk_register_function("any_true"        , nt        )
+         exprtk_register_function("any_false"       , nf        )
+         exprtk_register_function("count"           , c         )
+         exprtk_register_function("copy"            , cp        )
+         exprtk_register_function("rotate_left"     , rl        )
+         exprtk_register_function("rol"             , rl        )
+         exprtk_register_function("rotate_right"    , rr        )
+         exprtk_register_function("ror"             , rr        )
+         exprtk_register_function("reverse"         , rev       )
+         exprtk_register_function("shftl"           , sl        )
+         exprtk_register_function("shftr"           , sr        )
+         exprtk_register_function("sort"            , st        )
+         exprtk_register_function("nth_element"     , ne        )
+         exprtk_register_function("assign"          , an        )
+         exprtk_register_function("iota"            , ia        )
+         exprtk_register_function("sumk"            , sk        )
+         exprtk_register_function("axpy"            , b1_axpy   )
+         exprtk_register_function("axpby"           , b1_axpby  )
+         exprtk_register_function("axpyz"           , b1_axpyz  )
+         exprtk_register_function("axpbyz"          , b1_axpbyz )
+         exprtk_register_function("axpbsy"          , b1_axpbsy )
+         exprtk_register_function("axpbsyz"         , b1_axpbsyz)
+         exprtk_register_function("axpbz"           , b1_axpbz  )
+         exprtk_register_function("diff"            , df        )
+         exprtk_register_function("dot"             , dt        )
+         exprtk_register_function("dotk"            , dtk       )
+         exprtk_register_function("threshold_above" , ta        )
+         exprtk_register_function("threshold_below" , tb        )
          #undef exprtk_register_function
 
          return true;
@@ -40932,11 +46019,11 @@ namespace exprtk
       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 version = "2.718281828459045235360287471352662497757"
+                                 "24709369995957496696762772407663035354759"
+                                 "45713821785251664274274663919320030599218"
+                                 "17413596629043572900334295260595630738132";
+      static char_cptr date    = "20240101";
       static char_cptr min_cpp = "199711L";
 
       static inline std::string data()
@@ -40958,12 +46045,8 @@ namespace exprtk
    #undef exprtk_error_location
    #endif
 
-   #ifdef exprtk_disable_fallthrough_begin
-   #undef exprtk_disable_fallthrough_begin
-   #endif
-
-   #ifdef exprtk_disable_fallthrough_end
-   #undef exprtk_disable_fallthrough_end
+   #ifdef exprtk_fallthrough
+   #undef exprtk_fallthrough
    #endif
 
    #ifdef exprtk_override