From 18b160abba18fe72504fe2b98860e441b01846c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christoph=20Gr=C3=BCninger?= <foss@grueninger.de>
Date: Sat, 8 Jun 2024 14:24:12 +0200
Subject: [PATCH] Update exprtk.hpp to release from 2024

---
 dumux/io/expression/exprtk.hpp | 10455 ++++++++++++++++++++-----------
 1 file changed, 6891 insertions(+), 3564 deletions(-)

diff --git a/dumux/io/expression/exprtk.hpp b/dumux/io/expression/exprtk.hpp
index 21436d609d..9d6aa4909e 100644
--- a/dumux/io/expression/exprtk.hpp
+++ b/dumux/io/expression/exprtk.hpp
@@ -1,21 +1,19 @@
 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 // vi: set et ts=4 sw=4 sts=4:
 //
-// SPDX-FileCopyrightInfo: Copyright (c) 1999-2023 Arash Partow
+// SPDX-FileCopyrightInfo: Copyright (c) 1999-2024 Arash Partow
 // SPDX-License-Identifier: MIT
 //
 // The following code is a copy of the original code version that can be
-// accessed under the following Software Heritage permalink:
-// https://archive.softwareheritage.org/swh:1:cnt:b4530ba05521b7c40748fd88aae78d08b4632d7e
-//  ;origin=https://github.com/ArashPartow/exprtk;visit=swh:1:snp:6c6e3923490afd020f81599d510959c237767d13
-//  ;anchor=swh:1:rev:f46bffcd6966d38a09023fb37ba9335214c9b959;path=/exprtk.hpp
+// accessed under the following link:
+// https://www.partow.net/downloads/exprtk.zip
 //
 
 /*
  ******************************************************************
  *           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:                                              *
@@ -23,6 +21,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)                                 *
@@ -30,18 +29,19 @@
  * (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)]                  *
  *                                                                *
  ******************************************************************
 */
 
+
 #ifndef INCLUDE_EXPRTK_HPP
 #define INCLUDE_EXPRTK_HPP
 
@@ -54,7 +54,6 @@
 #include <cstdlib>
 #include <cstring>
 #include <deque>
-#include <exception>
 #include <functional>
 #include <iterator>
 #include <limits>
@@ -79,20 +78,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
@@ -103,6 +88,12 @@ namespace exprtk
       #define exprtk_delete
    #endif
 
+   #if __cplusplus >= 201603L
+      #define exprtk_fallthrough [[fallthrough]];
+   #else
+      #define exprtk_fallthrough
+   #endif
+
    namespace details
    {
       typedef char                   char_t;
@@ -235,10 +226,10 @@ namespace exprtk
                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();
@@ -376,9 +367,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; }
@@ -393,6 +384,7 @@ namespace exprtk
                   (*itr2++) = (*itr1++);
                   ++removal_count;
                }
+
                continue;
             }
             else
@@ -444,85 +436,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", "&", "|"
-                                  };
+      {
+         "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", "&", "|"
+      };
 
       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", "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", "&", "|"
+      };
 
       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);
 
@@ -658,7 +650,7 @@ namespace exprtk
                }
             }
             else if (data_end == d_itr)
-               return true;
+               break;
 
             if ((data_end == d_itr) || (null_itr == nd_itr))
                 return false;
@@ -673,23 +665,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,
@@ -762,13 +758,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);
 
@@ -801,17 +839,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           )
@@ -860,6 +898,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)
             {
@@ -994,8 +1038,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>
@@ -1005,8 +1049,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>
@@ -1205,9 +1249,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
 
@@ -1216,13 +1260,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()));
 
@@ -1301,12 +1346,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); }
@@ -1402,6 +1482,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)
          {
@@ -1641,38 +1728,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));
@@ -1722,7 +1809,6 @@ namespace exprtk
 
          if (length <= 4)
          {
-            exprtk_disable_fallthrough_begin
             switch (length)
             {
                #ifdef exprtk_use_lut
@@ -1735,17 +1821,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
 
@@ -1760,7 +1848,6 @@ namespace exprtk
 
                #undef exprtk_process_digit
             }
-            exprtk_disable_fallthrough_end
          }
          else
             return_result = false;
@@ -2079,14 +2166,54 @@ 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 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
@@ -2509,7 +2636,7 @@ namespace exprtk
                   }
                }
 
-                ++s_itr_;
+               ++s_itr_;
             }
 
             if (2 == mode)
@@ -2523,7 +2650,9 @@ namespace exprtk
 
          inline void scan_token()
          {
-            if (details::is_whitespace(*s_itr_))
+            const char_t c = *s_itr_;
+
+            if (details::is_whitespace(c))
             {
                skip_whitespace();
                return;
@@ -2533,34 +2662,34 @@ 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 (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_);
@@ -2670,7 +2799,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);
          }
 
@@ -2870,12 +2999,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);
@@ -2915,8 +3044,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);
@@ -2957,7 +3086,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~token_scanner() {}
+         virtual ~token_scanner()
+         {}
 
          explicit token_scanner(const std::size_t& stride)
          : stride_(stride)
@@ -3239,7 +3369,7 @@ namespace exprtk
 
                   ++changes;
 
-                  i+=2;
+                  i += 2;
 
                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1))
                      break;
@@ -3281,7 +3411,7 @@ namespace exprtk
 
                   ++changes;
 
-                  i+=3;
+                  i += 3;
 
                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2))
                      break;
@@ -3379,7 +3509,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:
 
@@ -3555,7 +3685,7 @@ namespace exprtk
             }
          };
 
-         class bracket_checker : public lexer::token_scanner
+         class bracket_checker exprtk_final : public lexer::token_scanner
          {
          public:
 
@@ -3566,7 +3696,7 @@ namespace exprtk
             , state_(true)
             {}
 
-            bool result()
+            bool result() exprtk_override
             {
                if (!stack_.empty())
                {
@@ -3587,7 +3717,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> >();
@@ -3595,7 +3725,7 @@ namespace exprtk
                error_token_.clear();
             }
 
-            bool operator() (const lexer::token& t)
+            bool operator() (const lexer::token& t) exprtk_override
             {
                if (
                     !t.value.empty()                       &&
@@ -3652,18 +3782,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)
                {
@@ -3704,7 +3834,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:
 
@@ -3747,7 +3877,7 @@ namespace exprtk
 
          private:
 
-            bool modify(lexer::token& t)
+            bool modify(lexer::token& t) exprtk_override
             {
                if (lexer::token::e_symbol == t.type)
                {
@@ -3810,12 +3940,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);
 
@@ -3977,12 +4107,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));
 
@@ -4239,6 +4369,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,
@@ -4282,6 +4417,92 @@ 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_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);
@@ -4308,16 +4529,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)
       {
@@ -4337,6 +4564,11 @@ namespace exprtk
          return data_;
       }
 
+      inline std::size_t base_size() const
+      {
+         return base_size_;
+      }
+
       inline std::size_t size() const
       {
          return size_;
@@ -4344,22 +4576,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(): %lu\n",
+                       reinterpret_cast<void*>(data_ref),
+                       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(): %lu\n",
+                       reinterpret_cast<void*>(data_ref),
+                       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_;
    };
@@ -4535,6 +4800,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
          {
@@ -4583,6 +4858,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)
@@ -4606,6 +4884,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()
@@ -4752,10 +5085,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
@@ -4782,11 +5116,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>
@@ -4909,7 +5260,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;
@@ -4959,7 +5310,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
@@ -5072,8 +5423,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);
@@ -5142,17 +5493,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:
 
@@ -5189,12 +5542,13 @@ 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_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
          };
 
          typedef T value_type;
@@ -5203,7 +5557,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
          {
@@ -5219,6 +5574,11 @@ namespace exprtk
          {
             return e_none;
          }
+
+         inline virtual bool valid() const
+         {
+            return true;
+         }
       }; // class expression_node
 
       template <typename T>
@@ -5263,6 +5623,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)
       {
@@ -5292,10 +5658,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()
                 );
       }
 
@@ -5305,12 +5676,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)
       {
@@ -5408,7 +5809,7 @@ namespace exprtk
       }
 
       template <typename T>
-      inline bool branch_deletable(expression_node<T>* node)
+      inline bool branch_deletable(const expression_node<T>* node)
       {
          return (0 != node)             &&
                 !is_variable_node(node) &&
@@ -5416,7 +5817,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)
          {
@@ -5440,7 +5841,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)
          {
@@ -5456,7 +5857,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)
          {
@@ -5490,7 +5891,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);
             }
@@ -5595,7 +5996,8 @@ namespace exprtk
          , depth(0)
          {}
 
-         virtual ~node_depth_base() {}
+         virtual ~node_depth_base()
+         {}
 
          virtual std::size_t node_depth() const { return 1; }
 
@@ -5627,6 +6029,7 @@ namespace exprtk
             if (!depth_set)
             {
                depth = 0;
+
                for (std::size_t i = 0; i < N; ++i)
                {
                   if (branch[i].first)
@@ -5634,6 +6037,7 @@ namespace exprtk
                      depth = std::max(depth,branch[i].first->node_depth());
                   }
                }
+
                depth += 1;
                depth_set = true;
             }
@@ -5641,12 +6045,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;
             }
 
@@ -5659,9 +6085,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;
             }
 
@@ -5674,9 +6098,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;
             }
 
@@ -5715,6 +6137,7 @@ namespace exprtk
                      depth = std::max(depth, compute_node_depth(branch_list[i].first));
                   }
                }
+
                depth_set = true;
             }
 
@@ -5807,12 +6230,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
             {
@@ -5824,6 +6249,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);
@@ -5834,15 +6264,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:
 
@@ -5853,19 +6293,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;
@@ -5877,28 +6320,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;
@@ -5907,7 +6356,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:
 
@@ -5915,30 +6364,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;
             }
 
+            vector_view<Type>* rebaseable_instance() exprtk_override
+            {
+               return &vec_view_;
+            }
+
          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 < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0);
+               assert(index < vec_view_.size());
+               return (&vec_view_[index]);
             }
 
-            std::size_t vector_size() const
+            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;
@@ -5947,6 +6414,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;
@@ -5968,6 +6491,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];
@@ -5978,6 +6505,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();
@@ -5985,7 +6517,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
@@ -5993,8 +6536,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];
       };
@@ -6072,12 +6623,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);
 
@@ -6097,6 +6647,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);
@@ -6158,7 +6713,8 @@ namespace exprtk
 
          typedef range_pack<T> range_t;
 
-         virtual ~range_interface() {}
+         virtual ~range_interface()
+         {}
 
          virtual range_t& range_ref() = 0;
 
@@ -6173,7 +6729,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;
 
@@ -6184,9 +6741,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:
 
@@ -6195,8 +6752,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;
          }
@@ -6263,13 +6820,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
@@ -6287,6 +6844,11 @@ namespace exprtk
             return branch_.first;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return branch_.first && branch_.first->valid();
+         }
+
          inline void release()
          {
             branch_.second = false;
@@ -6322,17 +6884,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
@@ -6347,12 +6909,15 @@ 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
@@ -6382,16 +6947,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);
          }
 
@@ -6407,12 +6969,15 @@ 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
@@ -6445,14 +7010,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();
@@ -6478,6 +7040,14 @@ 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);
@@ -6532,6 +7102,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_;
@@ -6553,14 +7132,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
@@ -6572,6 +7148,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);
@@ -6606,13 +7190,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
@@ -6624,6 +7206,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);
@@ -6665,7 +7254,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);
          }
@@ -6678,7 +7267,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
          }
@@ -6711,7 +7300,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
          }
@@ -6778,13 +7367,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_))
@@ -6800,6 +7387,13 @@ namespace exprtk
             return expression_node<T>::e_while;
          }
 
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            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);
@@ -6832,12 +7426,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(parent_t::valid());
+         }
 
          inline T value() const exprtk_override
          {
-            assert(parent_t::condition_.first);
-            assert(parent_t::loop_body_.first);
 
             T result = T(0);
 
@@ -6865,13 +7459,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
@@ -6888,6 +7480,13 @@ namespace exprtk
             return expression_node<T>::e_repeat;
          }
 
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            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);
@@ -6920,13 +7519,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(parent_t::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);
@@ -6958,13 +7556,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)
@@ -6994,6 +7590,11 @@ namespace exprtk
             return expression_node<T>::e_for;
          }
 
+         inline bool valid() const exprtk_override exprtk_final
+         {
+            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);
@@ -7033,13 +7634,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(parent_t::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();
@@ -7079,13 +7679,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_))
@@ -7121,13 +7720,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(parent_t::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();
@@ -7161,13 +7759,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
@@ -7191,8 +7788,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:
 
@@ -7204,13 +7801,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(parent_t::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();
@@ -7247,13 +7843,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)
@@ -7315,13 +7910,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(parent_t::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();
@@ -7388,7 +7982,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]);
                }
@@ -7398,29 +7992,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
@@ -7428,6 +8019,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);
@@ -7481,7 +8077,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]);
                }
@@ -7491,19 +8087,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;
@@ -7523,6 +8116,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);
@@ -7543,7 +8141,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~ivariable() {}
+         virtual ~ivariable()
+         {}
 
          virtual T& ref() = 0;
          virtual const T& ref() const = 0;
@@ -7551,8 +8150,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:
 
@@ -7689,7 +8288,7 @@ namespace exprtk
                  (std::numeric_limits<std::size_t>::max() == r1  )
                )
             {
-               r1 = size - 1;
+               r1 = size;
             }
 
             cache.first  = r0;
@@ -7704,12 +8303,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;
@@ -7723,16 +8322,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)");
+               #ifndef _MSC_VER
                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)");
+               #ifndef _MSC_VER
                return false;
+               #endif
             }
 
             return (r0 <= r1);
@@ -7774,19 +8377,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 std::size_t base_size() const = 0;
 
-         virtual vector_node_ptr vec() const = 0;
+         virtual vector_node_ptr vec  () const = 0;
 
-         virtual vector_node_ptr vec()       = 0;
+         virtual vector_node_ptr vec  ()       = 0;
 
-         virtual       vds_t& vds   ()       = 0;
+         virtual       vds_t& vds     ()       = 0;
 
-         virtual const vds_t& vds   () const = 0;
+         virtual const vds_t& vds     () const = 0;
 
-         virtual bool side_effect   () const { return false; }
+         virtual bool side_effect     () const { return false; }
       };
 
       template <typename T>
@@ -7813,6 +8419,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];
@@ -7833,9 +8445,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
@@ -7853,16 +8475,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:
 
@@ -7871,26 +8542,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
@@ -7898,32 +8573,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:
 
@@ -7933,27 +8914,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
@@ -7961,6 +8944,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_);
@@ -7968,54 +8961,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
@@ -8023,16 +9027,235 @@ 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 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>
@@ -8050,15 +9273,57 @@ namespace exprtk
          , 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_)
+               {
+                  details::set_zero_value(vector_base_, size_);
+               }
+               else if (const_nonzero_literal_value_initialse_)
                {
-                  *(vector_base_ + i) = initialiser_list_[0]->value();
+                  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
@@ -8072,10 +9337,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));
                }
             }
 
@@ -8087,6 +9351,11 @@ namespace exprtk
             return expression_node<T>::e_vecdefass;
          }
 
+         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);
@@ -8106,6 +9375,9 @@ namespace exprtk
          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>
@@ -8187,7 +9459,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)))
@@ -8213,37 +9484,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_)
-            {
-               assert(branch(0));
-               assert(branch(1));
-
-               binary_node<T>::branch(0)->value();
-               binary_node<T>::branch(1)->value();
+            binary_node<T>::branch(0)->value();
+            binary_node<T>::branch(1)->value();
 
-               T* vec0 = vec0_node_ptr_->vds().data();
-               T* vec1 = vec1_node_ptr_->vds().data();
+            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]);
-               }
+            assert(size() <= base_size());
+            const std::size_t n = size();
 
-               return vec1_node_ptr_->value();
+            for (std::size_t i = 0; i < n; ++i)
+            {
+               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
@@ -8261,9 +9524,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
@@ -8280,7 +9557,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_;
       };
@@ -8288,9 +9564,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:
 
@@ -8306,7 +9582,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;
          }
@@ -8318,7 +9594,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();
@@ -8384,9 +9660,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:
 
@@ -8470,9 +9746,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:
 
@@ -8539,9 +9815,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:
 
@@ -8581,8 +9857,7 @@ namespace exprtk
             }
 
             initialised_ = (str_base_ptr_ && str_range_ptr_);
-
-            assert(initialised_);
+            assert(valid());
          }
 
         ~generic_string_range_node()
@@ -8592,34 +9867,29 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
-            {
-               assert(branch_.first);
-
-               branch_.first->value();
+            branch_.first->value();
 
-               std::size_t str_r0 = 0;
-               std::size_t str_r1 = 0;
+            std::size_t str_r0 = 0;
+            std::size_t str_r1 = 0;
 
-               std::size_t r0 = 0;
-               std::size_t r1 = 0;
+            std::size_t r0 = 0;
+            std::size_t r1 = 0;
 
-               const range_t& range = str_range_ptr_->range_ref();
+            const range_t& range = str_range_ptr_->range_ref();
 
-               const std::size_t base_str_size = str_base_ptr_->size();
+            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;
+            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;
 
-                  range_.n1_c.second  = size - 1;
-                  range_.cache.second = range_.n1_c.second;
+               range_.n1_c.second  = size;
+               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();
@@ -8655,6 +9925,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);
@@ -8678,9 +9953,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:
 
@@ -8740,42 +10015,36 @@ namespace exprtk
                            str0_range_ptr_ &&
                            str1_range_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::size_t str0_r0 = 0;
-               std::size_t str0_r1 = 0;
+            std::size_t str0_r0 = 0;
+            std::size_t str0_r1 = 0;
 
-               std::size_t str1_r0 = 0;
-               std::size_t str1_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();
+            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;
+            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);
+               const std::size_t size1 = (str1_r1 - str1_r0);
 
-                  value_.assign(str0_base_ptr_->base() + str0_r0, size0);
-                  value_.append(str1_base_ptr_->base() + str1_r0, size1);
+               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();
@@ -8811,6 +10080,11 @@ namespace exprtk
             return expression_node<T>::e_strconcat;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool                initialised_;
@@ -8824,9 +10098,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:
 
@@ -8841,10 +10115,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)))
             {
@@ -8857,22 +10131,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();
          }
@@ -8907,6 +10174,11 @@ namespace exprtk
             return expression_node<T>::e_strswap;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool initialised_;
@@ -8972,87 +10244,81 @@ namespace exprtk
                            str0_range_ptr_ &&
                            str1_range_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::size_t str0_r0 = 0;
+            std::size_t str0_r1 = 0;
 
-               std::size_t str0_r0 = 0;
-               std::size_t str0_r1 = 0;
+            std::size_t str1_r0 = 0;
+            std::size_t str1_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_);
 
-               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())
+               )
+            {
+               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);
 
-               if (
-                    range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
-                    range1(str1_r0, str1_r1, str1_base_ptr_->size())
-                  )
-               {
-                  const std::size_t size0    = range0.cache_size();
-                  const std::size_t size1    = range1.cache_size();
-                  const std::size_t max_size = std::min(size0,size1);
+               char_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);
 
-                  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);
+               loop_unroll::details lud(max_size);
+               char_cptr upper_bound = s0 + lud.upper_bound;
 
-                  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]); \
 
-                  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;
-                  }
+                  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
 
-                  int i = 0;
+                  s0 += lud.batch_size;
+                  s1 += lud.batch_size;
+               }
 
-                  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
+               int i = 0;
 
-                  #undef exprtk_loop
-                  #undef case_stmt
+               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();
@@ -9063,6 +10329,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;
@@ -9080,7 +10351,7 @@ namespace exprtk
       {
       public:
 
-         static std::string null_value;
+         static const std::string null_value;
 
          explicit stringvar_size_node()
          : value_(&null_value)
@@ -9102,11 +10373,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>
@@ -9125,23 +10396,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
@@ -9149,6 +10412,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);
@@ -9161,7 +10429,7 @@ namespace exprtk
 
       private:
 
-         branch_t           branch_;
+         branch_t     branch_;
          str_base_ptr str_base_ptr_;
       };
 
@@ -9179,9 +10447,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:
 
@@ -9231,31 +10499,25 @@ namespace exprtk
                            str0_node_ptr_  &&
                            str1_range_ptr_ ;
 
-            assert(initialised_);
+            assert(valid());
          }
 
          inline T value() const exprtk_override
          {
-            if (initialised_)
-            {
-               assert(branch(0));
-               assert(branch(1));
+            branch(1)->value();
 
-               branch(1)->value();
-
-               std::size_t r0 = 0;
-               std::size_t r1 = 0;
+            std::size_t r0 = 0;
+            std::size_t r1 = 0;
 
-               const range_t& range = (*str1_range_ptr_);
+            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);
+            if (range(r0, r1, str1_base_ptr_->size()))
+            {
+               AssignmentProcess::execute(
+                  str0_node_ptr_->ref(),
+                  str1_base_ptr_->base() + r0, (r1 - r0));
 
-                  branch(0)->value();
-               }
+               branch(0)->value();
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -9291,6 +10553,11 @@ namespace exprtk
             return expression_node<T>::e_strass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool            initialised_;
@@ -9302,9 +10569,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:
 
@@ -9363,39 +10630,34 @@ namespace exprtk
                            str0_range_ptr_    &&
                            str1_range_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::size_t s0_r0 = 0;
-               std::size_t s0_r1 = 0;
+            std::size_t s0_r0 = 0;
+            std::size_t s0_r1 = 0;
 
-               std::size_t s1_r0 = 0;
-               std::size_t s1_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_);
+            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;
+            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));
 
-                  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();
@@ -9431,6 +10693,11 @@ namespace exprtk
             return expression_node<T>::e_strass;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return initialised_ && binary_node<T>::valid();
+         }
+
       private:
 
          bool             initialised_;
@@ -9443,9 +10710,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:
 
@@ -9506,55 +10773,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 range_t& range = str0_range_ptr_->range_ref();
-
-                  if (range(r0, r1, str0_base_ptr_->size()))
-                  {
-                     const std::size_t size = (r1 - r0) + 1;
+                  const std::size_t size = (r1 - r0);
 
-                     value_.assign(str0_base_ptr_->base() + r0, size);
+                  value_.assign(str0_base_ptr_->base() + r0, size);
 
-                     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 T(1);
-                  }
+                  return T(1);
                }
-               else
-               {
-                  alternative_->value();
+            }
+            else
+            {
+               alternative_->value();
 
-                  const range_t& range = str1_range_ptr_->range_ref();
+               const range_t& range = str1_range_ptr_->range_ref();
 
-                  if (range(r0, r1, str1_base_ptr_->size()))
-                  {
-                     const std::size_t size = (r1 - r0) + 1;
+               if (range(r0, r1, str1_base_ptr_->size()))
+               {
+                  const std::size_t size = (r1 - r0);
 
-                     value_.assign(str1_base_ptr_->base() + r0, size);
+                  value_.assign(str1_base_ptr_->base() + r0, size);
 
-                     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 T(0);
-                  }
+                  return T(0);
                }
             }
 
@@ -9591,6 +10851,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_;
@@ -9608,9 +10877,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:
 
@@ -9652,37 +10921,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_))
-               {
-                  consequent_->value();
-
-                  const range_t& range = str0_range_ptr_->range_ref();
+               const range_t& range = str0_range_ptr_->range_ref();
 
-                  std::size_t r0 = 0;
-                  std::size_t r1 = 0;
+               std::size_t r0 = 0;
+               std::size_t r1 = 0;
 
-                  if (range(r0, r1, str0_base_ptr_->size()))
-                  {
-                     const std::size_t size = (r1 - r0) + 1;
+               if (range(r0, r1, str0_base_ptr_->size()))
+               {
+                  const std::size_t size = (r1 - r0);
 
-                     value_.assign(str0_base_ptr_->base() + r0, size);
+                  value_.assign(str0_base_ptr_->base() + r0, size);
 
-                     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 T(1);
-                  }
+                  return T(1);
                }
             }
 
@@ -9719,6 +10981,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_;
@@ -9733,9 +11003,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:
 
@@ -9771,8 +11041,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;
@@ -9781,7 +11049,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]);
                   }
@@ -9791,7 +11059,12 @@ namespace exprtk
                      return;
                   }
                }
+
+               initialised_ = true;
             }
+
+            initialised_ &= str_base_ptr_ && str_range_ptr_;
+            assert(valid());
          }
 
          inline T value() const exprtk_override
@@ -9836,6 +11109,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);
@@ -10099,10 +11379,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();
@@ -10128,11 +11404,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();
@@ -10221,12 +11492,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]);
                }
@@ -10236,6 +11508,9 @@ namespace exprtk
                   return;
                }
             }
+
+            initialised_ = (arg_list_.size() == arg_list.size());
+            assert(valid());
          }
 
          inline T value() const exprtk_override
@@ -10248,6 +11523,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);
@@ -10261,6 +11541,7 @@ namespace exprtk
       private:
 
          std::vector<branch_t> arg_list_;
+         bool initialised_;
       };
 
       template <typename T, typename VarArgFunction>
@@ -10273,12 +11554,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());
@@ -10289,14 +11571,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
@@ -10304,9 +11586,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>
@@ -10326,22 +11614,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
@@ -10349,6 +11627,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);
@@ -10387,17 +11670,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:
@@ -10423,26 +11704,66 @@ 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_)
+            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_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)))
             {
-               assert(branch(1));
+               vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
+            }
 
-               T& result = vec_node_ptr_->ref();
+            assert(valid());
+         }
+
+         inline T value() const exprtk_override
+         {
+            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:
 
-         vector_elem_node<T>* vec_node_ptr_;
+         vector_elem_rtc_node<T>* vec_node_ptr_;
       };
 
       template <typename T>
@@ -10463,27 +11784,66 @@ 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_)
+            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_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)))
             {
-               assert(branch(1));
+               rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0));
+            }
 
-               T& result = rbvec_node_ptr_->ref();
+            assert(valid());
+         }
 
+         inline T value() const exprtk_override
+         {
+            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:
 
-         rebasevector_elem_node<T>* rbvec_node_ptr_;
+         rebasevector_elem_rtc_node<T>* rbvec_node_ptr_;
       };
 
       template <typename T>
@@ -10504,21 +11864,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:
@@ -10550,66 +11910,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_)
-            {
-               assert(branch(1));
-
-               const T v = branch(1)->value();
+            const T v = branch(1)->value();
 
-               T* vec = vds().data();
+            T* vec = vds().data();
 
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec + lud.upper_bound;
+            loop_unroll::details lud(size());
+            const T* upper_bound = vec + lud.upper_bound;
 
-               while (vec < upper_bound)
-               {
-                  #define exprtk_loop(N) \
-                  vec[N] = v;            \
+            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
+               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;
-               }
+               vec += lud.batch_size;
+            }
 
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N) \
-                  case N : *vec++ = v; \
+            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_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return vec_node_ptr_->value();
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return vec_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -10627,9 +11981,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
@@ -10699,74 +12066,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();
 
-               branch(1)->value();
-
-               if (src_is_ivec_)
-                  return vec0_node_ptr_->value();
+            if (src_is_ivec_)
+               return vec0_node_ptr_->value();
 
-               T* vec0 = vec0_node_ptr_->vds().data();
-               T* vec1 = vec1_node_ptr_->vds().data();
+            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;
+            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];     \
+            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
+               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;
-               }
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+            }
 
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)        \
-                  case N : *vec0++ = *vec1++; \
+            switch (lud.remainder)
+            {
+               #define case_stmt(N,fall_through) \
+               case N : *vec0++ = *vec1++;       \
+               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)
-                  #endif
-                  case_stmt( 3) case_stmt( 2)
-                  case_stmt( 1)
-               }
-               exprtk_disable_fallthrough_end
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return vec0_node_ptr_->value();
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return vec0_node_ptr_->value();
          }
 
          vector_node_ptr vec() exprtk_override
@@ -10784,9 +12148,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
@@ -10826,21 +12204,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:
@@ -10866,26 +12244,106 @@ 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_)
+            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_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)))
             {
-               assert(branch(1));
+               vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
+            }
 
-               T& v = vec_node_ptr_->ref();
-                  v = Operation::process(v,branch(1)->value());
+            assert(valid());
+         }
 
-               return v;
+         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));
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            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_node<T>* vec_node_ptr_;
+         vector_celem_rtc_node<T>* vec_node_ptr_;
       };
 
       template <typename T, typename Operation>
@@ -10906,21 +12364,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:
@@ -10946,26 +12404,106 @@ 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_)
+            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_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)))
             {
-               assert(branch(1));
+               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_;
+      };
 
-               T& v = rbvec_node_ptr_->ref();
-                  v = Operation::process(v,branch(1)->value());
+      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;
 
-               return v;
+         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));
             }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+
+            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_node<T>* rbvec_node_ptr_;
+         rebasevector_celem_rtc_node<T>* rbvec_node_ptr_;
       };
 
       template <typename T, typename Operation>
@@ -10992,66 +12530,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_)
-            {
-               assert(branch(1));
-
-               const T v = branch(1)->value();
+            const T v = branch(1)->value();
 
-               T* vec = vds().data();
+            T* vec = vds().data();
 
-               loop_unroll::details lud(size());
-               const T* upper_bound = vec + lud.upper_bound;
+            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); \
+            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
+               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;
-               }
+               vec += lud.batch_size;
+            }
 
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                  \
-                  case N : Operation::assign(*vec++,v); \
+            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) 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
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return vec_node_ptr_->value();
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return vec_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -11069,9 +12601,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
@@ -11134,81 +12679,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_)
-            {
-               assert(branch(0));
-               assert(branch(1));
-
-               branch(0)->value();
-               branch(1)->value();
+            branch(0)->value();
+            branch(1)->value();
 
-                     T* vec0 = vec0_node_ptr_->vds().data();
-               const T* vec1 = vec1_node_ptr_->vds().data();
+                  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;
+            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]); \
+            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
+               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;
-               }
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+            }
 
-               int i = 0;
+            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; } \
+            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) 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
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return vec0_node_ptr_->value();
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            return vec0_node_ptr_->value();
          }
 
          vector_node_ptr vec() const exprtk_override
@@ -11226,9 +12766,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
@@ -11254,6 +12808,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>
@@ -11263,8 +12875,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;
 
@@ -11274,8 +12888,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;
@@ -11316,104 +12928,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_)
-            {
-               assert(branch(0));
-               assert(branch(1));
+            branch(0)->value();
+            branch(1)->value();
 
-               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();
+            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;
+            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]); \
+            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
+               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;
-               }
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+               vec2 += lud.batch_size;
+            }
 
-               int i = 0;
+            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; } \
+            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)
-               }
-               exprtk_disable_fallthrough_end
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return (vds().data())[0];
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            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
@@ -11421,9 +13031,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
@@ -11438,12 +13062,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>
@@ -11455,8 +13078,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;
 
@@ -11465,8 +13090,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;
 
@@ -11490,93 +13113,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_)
-            {
-               assert(branch(0));
-               assert(branch(1));
+                        branch(0)->value();
+            const T v = branch(1)->value();
 
-                           branch(0)->value();
-               const T v = branch(1)->value();
+            const T* vec0 = vec0_node_ptr_->vds().data();
+                  T* vec1 = vds().data();
 
-               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;
 
-               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); \
+            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
+               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;
-               }
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+            }
 
-               int i = 0;
+            int i = 0;
 
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                        \
-                  case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
+            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) 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
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return (vds().data())[0];
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            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
@@ -11584,9 +13198,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
@@ -11602,9 +13229,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>
@@ -11616,8 +13242,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;
 
@@ -11626,8 +13254,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;
 
@@ -11651,93 +13277,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_)
-            {
-               assert(branch(0));
-               assert(branch(1));
+            const T v = branch(0)->value();
+                        branch(1)->value();
 
-               const T v = branch(0)->value();
-                           branch(1)->value();
+                  T* vec0 = vds().data();
+            const T* vec1 = vec1_node_ptr_->vds().data();
 
-                     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;
 
-               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]); \
+            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
+               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;
-               }
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+            }
 
-               int i = 0;
+            int i = 0;
 
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                        \
-                  case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
+            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) 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
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return (vds().data())[0];
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            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
@@ -11745,9 +13362,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
@@ -11763,9 +13394,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>
@@ -11777,28 +13407,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;
@@ -11810,91 +13440,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();
+            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;
+            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]); \
+            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
+               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;
-               }
+               vec0 += lud.batch_size;
+               vec1 += lud.batch_size;
+            }
 
-               int i = 0;
+            int i = 0;
 
-               exprtk_disable_fallthrough_begin
-               switch (lud.remainder)
-               {
-                  #define case_stmt(N)                                     \
-                  case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
+            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)
-               }
-               exprtk_disable_fallthrough_end
+               #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
+            #undef exprtk_loop
+            #undef case_stmt
 
-               return (vds().data())[0];
-            }
-            else
-               return std::numeric_limits<T>::quiet_NaN();
+            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
@@ -11902,9 +13525,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
@@ -11919,10 +13552,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>
@@ -11935,8 +13567,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,
@@ -11946,7 +13580,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  );
@@ -11975,67 +13609,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_)
-            {
-               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();
-               }
+            T result = T(0);
+            T* source_vector = 0;
+            T* result_vector = vds().data();
 
-               for (std::size_t i = 0; i < vec_size_; ++i)
-               {
-                  result_vector[i] = source_vector[i];
-               }
+            if (is_true(condition_))
+            {
+               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 result;
+            for (std::size_t i = 0; i < result_vec_size_; ++i)
+            {
+               result_vector[i] = source_vector[i];
             }
 
-            return std::numeric_limits<T>::quiet_NaN();
+            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
@@ -12043,9 +13672,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
@@ -12073,16 +13719,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>
@@ -12097,13 +13744,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()) &&
@@ -12125,13 +13771,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()) ||
@@ -12146,7 +13791,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;
@@ -12154,6 +13799,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>
@@ -12164,19 +13810,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)
             {
-               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;
+               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
@@ -12194,14 +13845,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
@@ -12212,6 +13860,11 @@ 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);
@@ -12234,6 +13887,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>
          {
@@ -12437,6 +14104,7 @@ namespace exprtk
          ifunction*  function_;
          std::size_t parameter_count_;
          branch_t    branch_[N];
+         bool        initialised_;
       };
 
       template <typename T, typename IFunction>
@@ -12449,7 +14117,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
          {
@@ -12458,10 +14128,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
@@ -12469,6 +14136,11 @@ namespace exprtk
             return expression_node<T>::e_function;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return function_;
+         }
+
       private:
 
          ifunction* function_;
@@ -12487,6 +14159,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
@@ -12496,13 +14169,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
@@ -12510,6 +14178,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)
@@ -12557,7 +14230,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;
@@ -12569,7 +14243,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
          {
@@ -12583,10 +14268,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)
             {
@@ -12604,7 +14290,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]))
@@ -12640,7 +14334,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]))
@@ -12674,14 +14371,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();
@@ -12692,6 +14386,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
@@ -12701,30 +14400,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);
+                  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
-                     return false;
+                  #endif
+                     ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
                }
             }
 
@@ -12737,16 +14446,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:
 
@@ -12761,6 +14472,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
@@ -12770,23 +14482,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();
@@ -12797,6 +14507,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_;
@@ -12846,18 +14561,18 @@ namespace exprtk
 
          inline T value() const exprtk_override
          {
-            if (gen_function_t::function_)
+            assert(gen_function_t::valid());
+
+            if (gen_function_t::populate_value_list())
             {
-               if (gen_function_t::populate_value_list())
-               {
-                  typedef typename GenericFunction::parameter_list_t parameter_list_t;
+               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
+                  (*gen_function_t::function_)
+                  (
+                     param_seq_index_,
+                     parameter_list_t(gen_function_t::typestore_list_)
+                  );
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -12891,24 +14606,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();
@@ -12925,15 +14638,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;
@@ -12984,6 +14697,11 @@ namespace exprtk
             return expression_node<T>::e_return;
          }
 
+         inline bool valid() const exprtk_override
+         {
+            return results_context_;
+         }
+
       private:
 
          results_context_t* results_context_;
@@ -13003,12 +14721,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;
@@ -13019,6 +14736,7 @@ namespace exprtk
             catch(const return_exception&)
             {
                return_invoked_ = true;
+
                return std::numeric_limits<T>::quiet_NaN();
             }
          }
@@ -13028,6 +14746,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_;
@@ -13412,7 +15135,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;
 
@@ -13435,7 +15158,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;
@@ -13479,7 +15202,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;
 
@@ -13546,7 +15269,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;
 
@@ -13602,7 +15325,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;
 
@@ -13673,7 +15396,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;
 
@@ -13744,7 +15467,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;
 
@@ -13824,7 +15547,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;
 
@@ -13904,7 +15627,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;
 
@@ -13925,14 +15648,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());
+                        }
             }
          }
 
@@ -14021,7 +15743,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);
 
@@ -14030,24 +15752,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
 
@@ -14082,24 +15804,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
@@ -14122,7 +15843,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);
 
@@ -14131,24 +15852,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
 
@@ -14183,33 +15903,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
                    ;
          }
@@ -14222,7 +15941,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;
          }
       };
@@ -14235,7 +15954,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];
 
@@ -14259,7 +15978,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];
 
@@ -14280,7 +15999,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~vov_base_node() {}
+         virtual ~vov_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14297,7 +16017,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~cov_base_node() {}
+         virtual ~cov_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14314,7 +16035,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~voc_base_node() {}
+         virtual ~voc_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14331,7 +16053,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~vob_base_node() {}
+         virtual ~vob_base_node()
+         {}
 
          virtual const T& v() const = 0;
       };
@@ -14341,7 +16064,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~bov_base_node() {}
+         virtual ~bov_base_node()
+         {}
 
          virtual const T& v() const = 0;
       };
@@ -14351,7 +16075,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~cob_base_node() {}
+         virtual ~cob_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14370,7 +16095,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~boc_base_node() {}
+         virtual ~boc_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14389,7 +16115,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~uv_base_node() {}
+         virtual ~uv_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14404,7 +16131,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~sos_base_node() {}
+         virtual ~sos_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14417,7 +16145,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~sosos_base_node() {}
+         virtual ~sosos_base_node()
+         {}
 
          inline virtual operator_type operation() const
          {
@@ -14430,7 +16159,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~T0oT1oT2_base_node() {}
+         virtual ~T0oT1oT2_base_node()
+         {}
 
          virtual std::string type_id() const = 0;
       };
@@ -14440,7 +16170,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~T0oT1oT2oT3_base_node() {}
+         virtual ~T0oT1oT2oT3_base_node()
+         {}
 
          virtual std::string type_id() const = 0;
       };
@@ -14576,6 +16307,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();
@@ -15198,7 +16934,8 @@ namespace exprtk
       {
       public:
 
-         virtual ~sf3ext_type_node() {}
+         virtual ~sf3ext_type_node()
+         {}
 
          virtual T0 t0() const = 0;
 
@@ -15656,16 +17393,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());
          }
 
@@ -15674,6 +17411,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;
@@ -15707,16 +17449,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_);
          }
 
@@ -15725,6 +17467,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;
@@ -15758,16 +17505,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());
          }
 
@@ -15786,6 +17533,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;
@@ -15825,16 +17577,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_);
          }
 
@@ -15853,6 +17605,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;
@@ -16025,7 +17782,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);
          }
@@ -16097,10 +17860,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);
@@ -16161,6 +17925,7 @@ namespace exprtk
          , str1_base_ptr_ (0)
          , str0_range_ptr_(0)
          , str1_range_ptr_(0)
+         , initialised_   (false)
          {
             if (is_generally_string_node(branch(0)))
             {
@@ -16191,39 +17956,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
          {
-            if (
-                 str0_base_ptr_  &&
-                 str1_base_ptr_  &&
-                 str0_range_ptr_ &&
-                 str1_range_ptr_
-               )
-            {
-               branch(0)->value();
-               branch(1)->value();
+            branch(0)->value();
+            branch(1)->value();
 
-               std::size_t str0_r0 = 0;
-               std::size_t str0_r1 = 0;
+            std::size_t str0_r0 = 0;
+            std::size_t str0_r1 = 0;
 
-               std::size_t str1_r0 = 0;
-               std::size_t str1_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_);
+            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)
-                                           );
-               }
+            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)),
+                         str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0))
+                      );
             }
 
             return std::numeric_limits<T>::quiet_NaN();
@@ -16234,6 +18000,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;
@@ -16243,6 +18014,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>
@@ -16254,7 +18026,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)
@@ -16346,11 +18118,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());
          }
 
@@ -16359,6 +18131,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);
@@ -16408,7 +18185,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:
 
@@ -16416,14 +18193,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()));
          }
 
@@ -16432,6 +18209,11 @@ 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);
@@ -16444,8 +18226,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_;
       };
@@ -17129,7 +18911,8 @@ namespace exprtk
       : param_count(pc)
       {}
 
-      virtual ~ifunction() {}
+      virtual ~ifunction()
+      {}
 
       #define empty_method_body(N)                   \
       {                                              \
@@ -17220,7 +19003,8 @@ namespace exprtk
    {
    public:
 
-      virtual ~ivararg_function() {}
+      virtual ~ivararg_function()
+      {}
 
       inline virtual T operator() (const std::vector<T>&)
       {
@@ -17245,12 +19029,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)        \
       {                                              \
@@ -17274,6 +19059,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;
    };
@@ -17349,52 +19136,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;
       };
@@ -17404,120 +19191,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;
       };
@@ -17777,7 +19564,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);
             }
          };
@@ -18041,7 +19828,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);
@@ -18694,12 +20481,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
@@ -18890,6 +20713,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
@@ -19190,17 +21045,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
@@ -19213,6 +21069,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
@@ -19342,6 +21203,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>
@@ -19351,53 +21214,54 @@ namespace exprtk
 
       static inline bool is_constant(const expression<T>& expr)
       {
-         return details::is_constant_node(expr.control_block_->expr);
+         return expr.control_block_ && details::is_constant_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_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_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);
       }
    };
 
    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
@@ -19426,7 +21290,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;
       }
 
@@ -19440,7 +21304,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;
       }
 
@@ -19532,70 +21396,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;
@@ -19669,8 +21542,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)
@@ -19918,6 +21791,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;
@@ -20104,16 +21996,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--;
          }
 
@@ -20473,12 +22366,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;
@@ -20492,9 +22389,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;
@@ -20525,9 +22427,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;
@@ -20704,7 +22611,7 @@ 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()));
             }
          }
 
@@ -20742,7 +22649,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,
@@ -20818,11 +22726,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();
          }
@@ -20843,9 +22754,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();
          }
@@ -21032,7 +22946,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     +
@@ -21041,9 +22955,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);
          }
@@ -21090,12 +23005,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);
          }
 
@@ -21104,7 +23031,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);
          }
 
@@ -21122,7 +23049,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);
          }
 
@@ -21131,7 +23058,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);
          }
 
@@ -21140,7 +23067,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);
          }
 
@@ -21150,6 +23077,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_;             }
@@ -21275,7 +23214,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) &&
@@ -21288,7 +23227,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) &&
@@ -21301,7 +23240,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) &&
@@ -21314,7 +23253,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) &&
@@ -21327,7 +23266,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) &&
@@ -21340,7 +23279,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) &&
@@ -21353,7 +23292,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) &&
@@ -21371,7 +23310,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) &&
@@ -21389,7 +23328,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) &&
@@ -21407,7 +23346,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) &&
@@ -21425,7 +23364,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) &&
@@ -21443,7 +23382,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) &&
@@ -21471,6 +23410,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)
@@ -21513,6 +23472,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 "" ;
             }
          }
@@ -21571,13 +23531,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)
@@ -21593,6 +23554,8 @@ namespace exprtk
       , operator_joiner_2_(2)
       , operator_joiner_3_(3)
       , loop_runtime_check_(0)
+      , vector_access_runtime_check_(0)
+      , compilation_check_ptr_(0)
       {
          init_precompilation();
 
@@ -21605,15 +23568,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()
       {
@@ -21681,11 +23645,14 @@ 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();
+         sem_                 .cleanup();
 
          return_cleanup();
 
@@ -21693,10 +23660,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;
          }
@@ -21709,11 +23676,16 @@ 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())
+         {
             return false;
          }
 
@@ -21722,6 +23694,11 @@ namespace exprtk
             return false;
          }
 
+         if (halt_compilation_check())
+         {
+            return false;
+         }
+
          symtab_store_.symtab_list_ = expr.get_symbol_table_list();
          dec_.clear();
 
@@ -21755,11 +23732,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))
@@ -21811,11 +23788,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));
             }
          }
       }
@@ -21854,11 +23831,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)))
                   {
@@ -21866,11 +23843,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())
@@ -21884,13 +23861,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())
@@ -21904,13 +23881,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())
@@ -21937,7 +23914,7 @@ namespace exprtk
          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
@@ -22006,11 +23983,31 @@ 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 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);
+      }
+
    private:
 
       inline bool valid_base_operation(const std::string& symbol) const
@@ -22114,11 +24111,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();
@@ -22144,9 +24141,7 @@ 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;
@@ -22188,11 +24183,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;
             operation = o;
+            token = tkn;
          }
 
          inline void reset()
@@ -22205,10 +24202,57 @@ 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(),
+               "ERR010 - 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())
+         {
+            return error_node();
+         }
+
          stack_limit_handler slh(*this);
 
          if (!slh)
@@ -22233,110 +24277,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"  ;
-
-                                           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;
-                                           }
-                                        }
-
-                                        break_loop = true;
+               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, 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;
             }
 
             if (break_loop)
@@ -22358,11 +24403,11 @@ namespace exprtk
             {
                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,
+                  "ERR011 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22370,11 +24415,11 @@ namespace exprtk
             {
                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,
+                  "ERR012 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22382,11 +24427,11 @@ namespace exprtk
             {
                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,
+                  "ERR013 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22394,11 +24439,11 @@ namespace exprtk
             {
                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,
+                  "ERR014 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22413,34 +24458,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,
+                     "ERR015 - 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_ :
+                     "ERR016 - General parsing error at token: '" + prev_token.value + "'",
+                     exprtk_error_location));
                }
 
                free_node(node_allocator_, expression  );
@@ -22466,12 +24515,12 @@ 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(),
+               "ERR017 - 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);
 
@@ -22520,11 +24569,11 @@ namespace exprtk
                }
                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(),
+                     "ERR018 - Failed to find variable node in symbol table",
+                     exprtk_error_location));
 
                   free_node(node_allocator_,node);
 
@@ -22744,11 +24793,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(),
+                           "ERR019 - Invalid number of parameters for function: '" + function_name + "'",
+                           exprtk_error_location));
 
                          return error_node();
                       }
@@ -22758,11 +24807,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(),
+               "ERR020 - Failed to generate call to function: '" + function_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22777,11 +24826,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(),
+               "ERR021 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22800,11 +24849,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(),
+               "ERR022 - Expecting argument list for function: '" + function_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22815,11 +24864,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(),
+                  "ERR023 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -22827,11 +24876,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(),
+                     "ERR024 - Invalid number of arguments for function: '" + function_name + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -22840,11 +24889,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(),
+               "ERR025 - Invalid number of arguments for function: '" + function_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -22869,11 +24918,11 @@ 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(),
+               "ERR026 - Expecting '()' to proceed call to function: '" + function_name + "'",
+               exprtk_error_location));
 
             free_node(node_allocator_,result);
 
@@ -22894,23 +24943,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(),
+               "ERR027 - 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(),
+               "ERR028 - Expected at least one input parameter for function call '" + function_name + "'",
+               exprtk_error_location));
 
             return 0;
          }
@@ -22932,11 +24981,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(),
+                  "ERR029 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
+                  exprtk_error_location));
 
                return 0;
             }
@@ -22944,11 +24993,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(),
+               "ERR030 - Invalid number of input parameters passed to function '" + function_name  + "'",
+               exprtk_error_location));
 
             return 0;
          }
@@ -22967,11 +25016,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,
+               "ERR031 - No entry found for base operation: " + operation_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23014,11 +25063,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,
+            "ERR032 - Invalid number of input parameters for call to function: '" + operation_name + "'",
+            exprtk_error_location));
 
          return error_node();
       }
@@ -23034,47 +25083,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(),
+               "ERR033 - 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(),
+               "ERR034 - 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(),
+               "ERR035 - 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(),
+               "ERR036 - 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(),
+               "ERR037 - Expected ')' at the end of if-statement",
+               exprtk_error_location));
+
             result = false;
          }
 
@@ -23088,15 +25142,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(),
+                     "ERR038 - 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(),
+                  "ERR039 - Return types of if-statement differ: string/non-string",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23116,11 +25185,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(),
+                  "ERR040 - Return types of if-statement differ: vector/non-vector",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23150,11 +25219,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(),
+                  "ERR041 - 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)
+            )
+            {
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR042 - Expected ';' at the end of the consequent for if-statement (1)",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23173,22 +25262,22 @@ namespace exprtk
             {
                if (!token_is(token_t::e_eof))
                {
-                  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(),
+                     "ERR043 - 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(),
+                  "ERR044 - Failed to parse body of consequent for if-statement",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23204,11 +25293,11 @@ namespace exprtk
                {
                   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(),
+                        "ERR045 - Failed to parse body of the 'else' for if-statement",
+                        exprtk_error_location));
 
                      result = false;
                   }
@@ -23217,35 +25306,38 @@ 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(),
+                        "ERR046 - 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_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(),
+                        "ERR047 - 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(),
+                     "ERR048 - Failed to parse body of the 'else' for if-statement",
+                     exprtk_error_location));
 
                   result = false;
                }
@@ -23266,11 +25358,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(),
+                  "ERR049 - Return types of if-statement differ: string/non-string",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23290,11 +25382,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(),
+                  "ERR050 - Return types of if-statement differ: vector/non-vector",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23321,21 +25413,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(),
+               "ERR051 - 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(),
+               "ERR052 - Failed to parse condition for if-statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23365,11 +25457,11 @@ 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(),
+            "ERR053 - Invalid if-statement",
+            exprtk_error_location));
 
          free_node(node_allocator_,condition);
 
@@ -23386,51 +25478,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(),
+               "ERR054 - 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(),
+               "ERR055 - 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(),
+               "ERR056 - 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(),
+               "ERR057 - 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(),
+               "ERR058 - Failed to parse alternative for ternary if-statement",
+               exprtk_error_location));
 
             result = false;
          }
@@ -23449,11 +25541,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(),
+                  "ERR059 - Return types of ternary differ: string/non-string",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23473,11 +25565,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(),
+                  "ERR060 - Return types of ternary differ: vector/non-vector",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23500,11 +25592,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(),
+               "ERR061 - Invalid or disabled logic operation 'not'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23531,31 +25623,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(),
+               "ERR062 - 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(),
+               "ERR063 - 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(),
+               "ERR064 - Expected ')' at end of while-loop condition statement",
+               exprtk_error_location));
 
             result = false;
          }
@@ -23568,21 +25660,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(),
+                  "ERR065 - 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(),
+                  "ERR066 - Failed to synthesize while-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23599,7 +25691,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(),
+            "ERR067 - 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()
@@ -23623,7 +25728,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);
 
@@ -23654,13 +25759,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(),
+                     "ERR068 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -23678,11 +25783,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(),
+                  "ERR069 - Failed to parse body of repeat until loop",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -23690,33 +25795,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(),
+               "ERR070 - Expected '(' before condition statement of repeat until loop",
+               exprtk_error_location));
 
             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(),
+               "ERR071 - Failed to parse condition for repeat until loop",
+               exprtk_error_location));
 
             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(),
+               "ERR072 - Expected ')' after condition of repeat until loop",
+               exprtk_error_location));
 
             free_node(node_allocator_, branch   );
             free_node(node_allocator_, condition);
@@ -23724,18 +25829,20 @@ namespace exprtk
             return error_node();
          }
 
-         expression_node_ptr result;
-
-         result = expression_generator_
-                     .repeat_until_loop(condition, branch, brkcnt_list_.front());
+         expression_node_ptr result_node =
+            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(),
+               "ERR073 - Failed to synthesize repeat until loop",
+               exprtk_error_location));
 
             free_node(node_allocator_,condition);
 
@@ -23744,7 +25851,20 @@ namespace exprtk
 
          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(),
+            "ERR074 - 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()
@@ -23763,11 +25883,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(),
+               "ERR075 - Expected '(' at start of for-loop",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23783,21 +25903,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(),
+                     "ERR076 - 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(),
+                     "ERR077 - Expected variable assignment of initialiser section of for-loop",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -23808,11 +25928,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(),
+                     "ERR078 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -23840,11 +25960,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(),
+                           "ERR079 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
+                           exprtk_error_location));
 
                         sem_.free_element(nse);
 
@@ -23852,7 +25972,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()");
                      }
@@ -23862,21 +25982,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(),
+                  "ERR080 - 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(),
+                  "ERR081 - Expected ';' after initialiser of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23886,21 +26006,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(),
+                  "ERR082 - 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(),
+                  "ERR083 - Expected ';' after condition section of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23910,21 +26030,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(),
+                  "ERR084 - 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(),
+                  "ERR085 - Expected ')' after incrementor section of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23938,11 +26058,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(),
+                  "ERR086 - Failed to parse body of for-loop",
+                  exprtk_error_location));
 
                result = false;
             }
@@ -23970,7 +26090,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(),
+            "ERR087 - 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()
@@ -23980,11 +26113,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(),
+               "ERR088 - Expected keyword 'switch'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -23995,11 +26128,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(),
+               "ERR089 - Expected '{' for call to switch statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24020,18 +26153,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(),
+                     "ERR090 - 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)
                {
@@ -24041,11 +26177,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(),
+                     "ERR091 - Expected ';' at end of case for switch statement",
+                     exprtk_error_location));
 
                   free_node(node_allocator_, condition );
                   free_node(node_allocator_, consequent);
@@ -24070,11 +26206,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(),
+                     "ERR092 - Multiple default cases for switch statement",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -24083,29 +26219,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(),
+                     "ERR093 - 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(),
+                     "ERR094 - Expected ';' at end of default for switch statement",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -24114,11 +26250,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(),
+                  "ERR095 - Expected '}' at end of switch statement",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24130,6 +26266,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));
 
@@ -24145,11 +26285,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(),
+               "ERR096 - Expected token '[*]'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24160,11 +26300,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(),
+               "ERR097 - Expected '{' for call to [*] statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24173,11 +26313,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(),
+                  "ERR098 - Expected a 'case' statement for multi-switch",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24191,27 +26331,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(),
+                  "ERR099 - 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(),
+                  "ERR100 - Expected ';' at end of case for [*] statement",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24236,11 +26379,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(),
+               "ERR101 - Expected '}' at end of [*] statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24277,11 +26420,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(),
+               "ERR102 - Unsupported built-in vararg function: " + symbol,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24294,23 +26437,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(),
+               "ERR103 - 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(),
+               "ERR104 - vararg function: " + symbol +
+               " requires at least one input parameter",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -24328,11 +26471,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(),
+                  "ERR105 - Expected ',' for call to vararg function: " + symbol,
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24349,11 +26492,11 @@ 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(),
+               "ERR106 - Expected '[' as start of string range definition",
+               exprtk_error_location));
 
             free_node(node_allocator_,expression);
 
@@ -24377,11 +26520,11 @@ 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(),
+               "ERR107 - Failed to generate string range node",
+               exprtk_error_location));
 
             free_node(node_allocator_,expression);
             rp.free();
@@ -24389,7 +26532,20 @@ namespace exprtk
 
          rp.clear();
 
-         return result;
+         if (result && result->valid())
+         {
+            return result;
+         }
+
+         set_error(make_error(
+            parser_error::e_synthesis,
+            current_token(),
+            "ERR108 - 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&)
@@ -24398,7 +26554,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;
@@ -24416,6 +26572,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,
@@ -24505,7 +26716,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))
          {
@@ -24513,16 +26724,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(),
+                  "ERR109 - 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();
             }
@@ -24562,13 +26773,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(),
+                  "ERR110 - Expected '" + details::to_str(separator) + "' for call to multi-sequence section of " + source,
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24586,23 +26797,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(),
+               "ERR111 - Expected '[' for start of range",
+               exprtk_error_location));
 
             return false;
          }
@@ -24619,11 +26830,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(),
+                  "ERR112 - Failed parse begin section of range",
+                  exprtk_error_location));
 
                return false;
             }
@@ -24642,11 +26853,11 @@ namespace exprtk
 
                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(),
+                     "ERR113 - Range lower bound less than zero! Constraint: r0 >= 0",
+                     exprtk_error_location));
 
                   return false;
                }
@@ -24659,11 +26870,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(),
+                  "ERR114 - Expected ':' for break  in range",
+                  exprtk_error_location));
 
                rp.free();
 
@@ -24682,11 +26893,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(),
+                  "ERR115 - Failed parse end section of range",
+                  exprtk_error_location));
 
                rp.free();
 
@@ -24707,11 +26918,11 @@ namespace exprtk
 
                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(),
+                     "ERR116 - Range upper bound less than zero! Constraint: r1 >= 0",
+                     exprtk_error_location));
 
                   rp.free();
 
@@ -24726,11 +26937,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(),
+                  "ERR117 - Expected ']' for start of range",
+                  exprtk_error_location));
 
                rp.free();
 
@@ -24754,11 +26965,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(),
+                  "ERR118 - Invalid range, Constraint: r0 <= r1",
+                  exprtk_error_location));
 
                return false;
             }
@@ -24798,11 +27009,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(),
+                  "ERR119 - Unknown string symbol",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24922,13 +27133,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(),
+                  "ERR120 - 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();
 
@@ -24952,30 +27163,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(),
+               "ERR121 - 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(),
+               "ERR122 - 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(),
+                  "ERR123 - Symbol '" + vector_name + " not a vector",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -24993,12 +27234,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))
@@ -25007,31 +27248,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()))
-         {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR115 - Failed to parse index for vector: '" + symbol + "'",
-                          exprtk_error_location));
 
-            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));
+         expression_node_ptr index_expr = parse_vector_index(vector_name);
 
-            free_node(node_allocator_,index_expr);
+         if (index_expr)
+         {
+            expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec);
 
-            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))
          {
@@ -25040,20 +27278,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(),
+                  "ERR124 - 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)
@@ -25072,12 +27311,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(),
+                     "ERR125 - Zero parameter call to vararg function: "
+                     + vararg_function_name + " not allowed",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -25097,12 +27336,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(),
+                        "ERR126 - Expected ',' for call to vararg function: "
+                        + vararg_function_name,
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -25111,37 +27350,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(),
+               "ERR127 - 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(),
+               "ERR128 - 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(),
+               "ERR129 - 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();
          }
@@ -25212,14 +27451,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(),
+                  "ERR130 - Failed parameter type check for function '" + function_name_ + "', "
+                  "Expected '" + function_definition_list_[0].param_seq +
+                  "' call set: '" + param_seq + "'",
+                  exprtk_error_location));
             }
             else
             {
@@ -25234,14 +27472,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(),
+                  "ERR131 - 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;
@@ -25376,13 +27613,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(),
+                     "ERR132 - Invalid parameter sequence of '" + param_seq_list[i] +
+                     "' for function: " + function_name_,
+                     exprtk_error_location));
                   return;
                }
 
@@ -25392,15 +27628,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(),
+                     "ERR133 - 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;
                }
 
@@ -25436,11 +27671,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(),
+               "ERR134 - Type checker instantiation failure for generic function: " + function_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25454,12 +27689,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(),
+                     "ERR135 - Zero parameter call to generic function: "
+                     + function_name + " not allowed",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -25486,11 +27721,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(),
+                        "ERR136 - Expected ',' for call to generic function: " + function_name,
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -25503,12 +27738,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(),
+               "ERR137 - Zero parameter call to generic function: "
+               + function_name + " not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25520,22 +27755,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(),
+               "ERR138 - 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);
@@ -25558,12 +27792,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(),
+                     "ERR139 - Zero parameter call to generic function: "
+                     + function_name + " not allowed",
+                     exprtk_error_location));
 
                   return false;
                }
@@ -25590,11 +27824,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(),
+                        "ERR140 - Expected ',' for call to string function: " + function_name,
+                        exprtk_error_location));
 
                      return false;
                   }
@@ -25637,22 +27871,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(),
+               "ERR141 - 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);
@@ -25689,11 +27922,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(),
+               "ERR142 - Invalid input parameter sequence for call to overloaded function: " + function_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25720,11 +27953,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(),
+               "ERR143 - Invalid return type for call to overloaded function: " + function_name,
+               exprtk_error_location));
          }
 
          sdd.delete_ptr = (0 == result);
@@ -25748,11 +27981,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(),
+                  "ERR144 - Expected '(' for special function '" + sf_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -25769,11 +28002,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(),
+                        "ERR145 - Expected ',' before next parameter of special function '" + sf_name + "'",
+                        exprtk_error_location));
 
                      return p.error_node();
                   }
@@ -25782,11 +28015,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(),
+                  "ERR146 - Invalid number of parameters for special function '" + sf_name + "'",
+                  exprtk_error_location));
 
                return p.error_node();
             }
@@ -25809,11 +28042,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(),
+               "ERR147 - Invalid special function[1]: " + sf_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25823,11 +28056,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(),
+               "ERR148 - Invalid special function[2]: " + sf_name,
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25855,21 +28088,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(),
+               "ERR149 - 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(),
+               "ERR150 - Invalid use of 'break', allowed only in the scope of a loop",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25888,21 +28121,21 @@ 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(),
+                     "ERR151 - 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(),
+                     "ERR152 - Expected ']' at the completion of break's return expression",
+                     exprtk_error_location));
 
                   free_node(node_allocator_,return_expr);
 
@@ -25916,11 +28149,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(),
+               "ERR153 - Invalid use of 'break', allowed only in the scope of a loop",
+               exprtk_error_location));
          }
 
          return error_node();
@@ -25930,11 +28163,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(),
+               "ERR154 - Invalid use of 'continue', allowed only in the scope of a loop",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -25952,60 +28185,68 @@ 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(),
+               "ERR155 - 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(),
+               "ERR156 - 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(),
+               "ERR157 - " + 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(),
+               "ERR158 - 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();
          }
@@ -26020,11 +28261,11 @@ namespace exprtk
 
          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));
+            set_error(make_error(
+               parser_error::e_syntax,
+               current_token(),
+               "ERR159 - Expected ']' as part of vector size definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26032,11 +28273,11 @@ namespace exprtk
          {
             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));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR160 - Expected ':=' as part of vector definition",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26046,11 +28287,11 @@ namespace exprtk
 
                if (0 == initialiser)
                {
-                  set_error(
-                     make_error(parser_error::e_syntax,
-                                current_token(),
-                                "ERR154 - Failed to parse single vector initialiser",
-                                exprtk_error_location));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR161 - Failed to parse single vector initialiser",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -26059,11 +28300,11 @@ namespace exprtk
 
                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));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR162 - Expected ']' to close single value vector initialiser",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -26106,11 +28347,11 @@ namespace exprtk
                {
                   if (0 == initialiser)
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR156 - Expected '{' as part of vector initialiser list",
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR163 - Expected '{' as part of vector initialiser list",
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -26126,11 +28367,11 @@ namespace exprtk
 
                   if (0 == initialiser)
                   {
-                     set_error(
-                        make_error(parser_error::e_syntax,
-                                   current_token(),
-                                   "ERR157 - Expected '{' as part of vector initialiser list",
-                                   exprtk_error_location));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR164 - Expected '{' as part of vector initialiser list",
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -26144,11 +28385,11 @@ namespace exprtk
 
                   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));
+                     set_error(make_error(
+                        parser_error::e_syntax,
+                        current_token(),
+                        "ERR165 - Expected ',' between vector initialisers",
+                        exprtk_error_location));
 
                      return error_node();
                   }
@@ -26166,11 +28407,11 @@ namespace exprtk
             {
                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));
+                  set_error(make_error(
+                     parser_error::e_syntax,
+                     current_token(),
+                     "ERR166 - Expected ';' at end of vector definition",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -26178,11 +28419,11 @@ namespace exprtk
 
             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));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR167 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26198,11 +28439,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(),
+                  "ERR168 - Illegal redefinition of local vector: '" + vec_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26230,13 +28471,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);
 
+            std::memset(nse.data, 0x00, vec_size * sizeof(T));
+
             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(),
+                  "ERR169 - Failed to add new local vector '" + vec_name + "' to SEM",
+                  exprtk_error_location));
 
                sem_.free_element(nse);
 
@@ -26256,6 +28499,12 @@ namespace exprtk
 
          expression_node_ptr result = error_node();
 
+         if (!single_value_initialiser && vec_initilizer_list.empty())
+         {
+            single_value_initialiser = true;
+            assert(vec_initilizer_list.size() <= 1);
+         }
+
          if (null_initialisation)
             result = expression_generator_(T(0.0));
          else if (vec_to_vec_initialiser)
@@ -26291,11 +28540,11 @@ 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(),
+                  "ERR170 - Illegal redefinition of local variable: '" + str_name + "'",
+                  exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -26323,11 +28572,11 @@ 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(),
+                  "ERR171 - Failed to add new local string variable '" + str_name + "' to SEM",
+                  exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -26338,7 +28587,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);
@@ -26369,11 +28618,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(),
+               "ERR172 - Illegal variable definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26390,41 +28639,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(),
+               "ERR173 - 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(),
+               "ERR174 - 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(),
+               "ERR175 - 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(),
+               "ERR176 - Illegal redefinition of local variable: '" + var_name + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26440,11 +28689,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(),
+                  "ERR177 - Failed to parse initialisation expression",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26458,11 +28707,11 @@ 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(),
+                  "ERR178 - Expected ';' after variable definition",
+                  exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -26486,11 +28735,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(),
+                  "ERR179 - Illegal redefinition of local variable: '" + var_name + "'",
+                  exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
 
@@ -26518,11 +28767,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(),
+                  "ERR180 - Failed to add new local variable '" + var_name + "' to SEM",
+                  exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
 
@@ -26533,7 +28782,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()");
@@ -26555,21 +28804,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(),
+               "ERR181 - 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(),
+               "ERR182 - Expected ';' after uninitialised variable definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26582,11 +28831,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(),
+                  "ERR183 - Illegal redefinition of local variable: '" + var_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26612,11 +28861,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(),
+                  "ERR184 - Failed to add new local variable '" + var_name + "' to SEM",
+                  exprtk_error_location));
 
                sem_.free_element(nse);
 
@@ -26645,11 +28894,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(),
+               "ERR185 - Expected '(' at start of swap statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26664,11 +28913,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(),
+               "ERR186 - Expected a symbol for variable or vector element definition",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26676,11 +28925,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(),
+                  "ERR187 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26709,11 +28958,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(),
+                  "ERR188 - First parameter to swap is an invalid variable: '" + var0_name + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26723,11 +28972,11 @@ 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(),
+               "ERR189 - Expected ',' between parameters to swap",
+               exprtk_error_location));
 
             if (variable0_generated)
             {
@@ -26741,11 +28990,11 @@ 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(),
+               "ERR190 - Expected a symbol for variable or vector element definition",
+               exprtk_error_location));
 
             if (variable0_generated)
             {
@@ -26758,11 +29007,11 @@ 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(),
+                  "ERR191 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
+                  exprtk_error_location));
 
                if (variable0_generated)
                {
@@ -26796,11 +29045,11 @@ 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(),
+                  "ERR192 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
+                  exprtk_error_location));
 
                if (variable0_generated)
                {
@@ -26815,11 +29064,11 @@ 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(),
+               "ERR193 - Expected ')' at end of swap statement",
+               exprtk_error_location));
 
             if (variable0_generated)
             {
@@ -26872,11 +29121,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(),
+               "ERR194 - Return call within a return call is not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26896,11 +29145,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(),
+               "ERR195 - Expected '[' at start of return statement",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26919,11 +29168,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(),
+                     "ERR196 - Expected ',' between values during call to return",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -26931,11 +29180,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(),
+               "ERR197 - Zero parameter return statement not allowed",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -26946,11 +29195,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,
+                  "ERR198 - Invalid ']' found during return call",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -26999,11 +29248,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(),
+                  "ERR199 - Invalid sequence of variable '" + symbol + "' and bracket",
+                  exprtk_error_location));
 
                return false;
             }
@@ -27047,11 +29296,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(),
+                  "ERR200 - Invalid sequence of brackets",
+                  exprtk_error_location));
 
                return false;
             }
@@ -27182,11 +29431,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(),
+                     "ERR201 - Failed to generate node for function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27208,11 +29457,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(),
+                     "ERR202 - Failed to generate node for vararg function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27234,11 +29483,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(),
+                     "ERR203 - Failed to generate node for generic function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27261,11 +29510,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(),
+                     "ERR204 - Failed to generate node for string function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27287,11 +29536,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(),
+                     "ERR205 - Failed to generate node for overload function: '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27313,11 +29562,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(),
+                     "ERR206 - Invalid use of reserved symbol '" + symbol + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27344,11 +29593,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;
                      }
@@ -27376,12 +29627,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(),
+                     "ERR207 - 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)
@@ -27396,23 +29647,23 @@ 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(),
+                     "ERR208 - 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(),
+            "ERR209 - Undefined symbol: '" + symbol + "'",
+            exprtk_error_location));
 
          return error_node();
       }
@@ -27522,11 +29773,12 @@ namespace exprtk
          }
          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(),
+               "ERR210 - Unknown variable or function encountered. Symbol table(s) "
+               "is either invalid or does not contain symbol: '" + symbol + "'",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -27553,11 +29805,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(),
+                     "ERR211 - Failed generate node for scalar: '" + current_token().value + "'",
+                     exprtk_error_location));
 
                   return error_node();
                }
@@ -27567,11 +29819,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(),
+                  "ERR212 - Failed to convert '" + current_token().value + "' to a number",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -27592,13 +29844,15 @@ namespace exprtk
 
             if (0 == (branch = parse_expression()))
                return error_node();
+            else if (token_is(token_t::e_eof))
+            {}
             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));
+               set_error(make_error(
+                  parser_error::e_syntax,
+                  current_token(),
+                  "ERR213 - Expected ')' instead of: '" + current_token().value + "'",
+                  exprtk_error_location));
 
                details::free_node(node_allocator_,branch);
 
@@ -27610,6 +29864,8 @@ namespace exprtk
 
                return error_node();
             }
+
+            parse_pending_vector_index_operator(branch);
          }
          else if (token_t::e_lsqrbracket == current_token().type)
          {
@@ -27619,11 +29875,11 @@ 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(),
+                  "ERR214 - Expected ']' instead of: '" + current_token().value + "'",
+                  exprtk_error_location));
 
                details::free_node(node_allocator_,branch);
 
@@ -27644,11 +29900,11 @@ 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(),
+                  "ERR215 - Expected '}' instead of: '" + current_token().value + "'",
+                  exprtk_error_location));
 
                details::free_node(node_allocator_,branch);
 
@@ -27693,21 +29949,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(),
+               "ERR216 - 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(),
+               "ERR217 - Premature end of expression[2]",
+               exprtk_error_location));
 
             return error_node();
          }
@@ -27808,6 +30064,8 @@ namespace exprtk
             register_synthezier(synthesize_covocov_expression4)
             register_synthezier(synthesize_vocovoc_expression4)
             register_synthezier(synthesize_covovoc_expression4)
+
+            #undef register_synthezier
             #endif
          }
 
@@ -27860,7 +30118,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;
@@ -28274,11 +30532,16 @@ namespace exprtk
                   return !b1_is_genstring;
                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;
             }
@@ -28433,18 +30696,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,
+                  "ERR218 - 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,
+                  "ERR219 - 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,
+                  "ERR220 - 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,
+                  "ERR221 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (details::e_assign == operation)
@@ -28563,10 +30850,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,
+                  "ERR222 - 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,
+                  "ERR223 - Invalid branches for string operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
+
                return error_node();
             }
             else if (is_string_operation(operation, branch))
@@ -28613,6 +30912,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,
+                  "ERR224 - Invalid " + invalid_branches + " for conditional statement",
+                  exprtk_error_location));
+
                return error_node();
             }
             // Can the condition be immediately evaluated? if so optimise.
@@ -28638,14 +30947,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(),
+               "ERR225 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
          #ifndef exprtk_disable_string_capabilities
@@ -28659,6 +30988,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,
+                  "ERR226 - Invalid " + invalid_branches + " for string conditional statement",
+                  exprtk_error_location));
+
                return error_node();
             }
             // Can the condition be immediately evaluated? if so optimise.
@@ -28686,10 +31025,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(),
+                  "ERR227 - 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,
@@ -28710,6 +31064,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,
+                  "ERR228 - Invalid " + invalid_branches + " for vector conditional statement",
+                  exprtk_error_location));
+
                return error_node();
             }
             // Can the condition be immediately evaluated? if so optimise.
@@ -28758,6 +31122,11 @@ 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
@@ -28766,8 +31135,17 @@ namespace exprtk
             {
                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,
+                     "ERR229 - Infinite loop condition with 'break' not allowed in while-loops",
+                     exprtk_error_location));
+
                   result = error_node();
+               }
                else
                   result = node_allocator_->allocate<details::null_node<Type> >();
 
@@ -28874,8 +31252,17 @@ namespace exprtk
                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,
+                     "ERR230 - Infinite loop condition without 'break' not allowed in for-loop",
+                     exprtk_error_location));
+
                   result = error_node();
+               }
                else
                   result = node_allocator_->allocate<details::null_node<Type> >();
 
@@ -28902,19 +31289,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
@@ -28923,19 +31310,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
@@ -28998,8 +31385,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)
@@ -29292,6 +31679,8 @@ namespace exprtk
                default : return error_node();
             }
 
+            assert(temp_node);
+
             const T v = temp_node->value();
 
             details::free_node(*node_allocator_,temp_node);
@@ -29395,6 +31784,8 @@ namespace exprtk
                default : return error_node();
             }
 
+            assert(temp_node);
+
             const T v = temp_node->value();
 
             details::free_node(*node_allocator_,temp_node);
@@ -29573,9 +31964,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);
@@ -29583,17 +31974,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(),
+                  "ERR231 - 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  )
@@ -29606,7 +32012,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(),
+                  "ERR232 - Failed to synthesize node: vararg_node",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
             }
+
+            return error_node();
          }
 
          template <std::size_t N>
@@ -29647,7 +32068,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(),
+                  "ERR233 - Failed to synthesize node: function_N_node_t",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
          }
 
@@ -29684,7 +32117,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(),
+               "ERR234 - 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,
@@ -29703,14 +32148,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()            &&
@@ -29728,9 +32182,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(),
+                  "ERR235 - Failed to synthesize node: " + node_name,
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
             else
             {
@@ -29758,14 +32223,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() &&
@@ -29782,9 +32256,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(),
+                  "ERR236 - Failed to synthesize node: " + node_name,
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
             else
             {
@@ -29812,11 +32297,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(),
+                  "ERR237 - Failed to synthesize node: return_node",
+                  exprtk_error_location));
+
+               details::free_node(*node_allocator_, result);
+               return error_node();
             }
             else
             {
@@ -29854,28 +32352,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 (vec_index >= vector_base->size())
+               {
+                  parser_->set_error(parser_error::make_error(
+                     parser_error::e_parser,
+                     token_t(),
+                     "ERR238 - 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();
+               }
+
                if (vector_base->rebaseable())
                {
-                  return node_allocator_->allocate<rebasevector_celem_node_t>(i,vector_base);
+                  vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
+
+                  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(),
+                     "ERR239 - 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(),
+                     "ERR240 - 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,i);
+               const scope_element& se = parser_->sem_.get_element(symbol,vec_index);
 
-               if (se.index == i)
+               if (se.index == vec_index)
                {
                   result = se.var_node;
+                  details::free_node(*node_allocator_,vec_node);
                }
                else
                {
@@ -29884,10 +32447,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))
                   {
@@ -29898,19 +32461,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(),
+               "ERR241 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
       private:
@@ -30007,12 +32606,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());
 
@@ -30044,11 +32658,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,
+                     "ERR242 - 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.");
@@ -30070,16 +32684,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]);
@@ -30108,7 +32732,11 @@ namespace exprtk
             }
             else
             {
-               parser_->set_synthesis_error("Invalid assignment operation.[1]");
+               parser_->set_error(parser_error::make_error(
+                  parser_error::e_syntax,
+                  parser_->current_state().token,
+                  "ERR243 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
+                  exprtk_error_location));
 
                return error_node();
             }
@@ -30122,6 +32750,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]);
@@ -30129,9 +32760,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)
@@ -30149,9 +32782,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)
@@ -30169,9 +32848,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)
@@ -30189,9 +32870,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)
@@ -30211,9 +32938,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)
@@ -30229,9 +32958,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)
@@ -30253,15 +32984,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,
+                  "ERR244 - 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(),
+               "ERR245 - 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,
@@ -30285,14 +33035,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
@@ -30304,9 +33059,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
@@ -30318,9 +33075,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
@@ -30330,6 +33089,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(),
+               "ERR246 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
+
             #undef batch_eqineq_logic_case
          }
 
@@ -30346,14 +33119,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)
@@ -30366,9 +33144,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)
@@ -30381,9 +33161,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
@@ -30393,6 +33175,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(),
+               "ERR247 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
+
             #undef vector_ops
          }
 
@@ -30410,6 +33206,7 @@ namespace exprtk
             #endif
 
             expression_node_ptr result = error_node();
+            std::string node_name      = "Unknown";
 
             if (v0_is_ivar && v1_is_ivar)
             {
@@ -30423,36 +33220,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(),
+               "ERR248 - Failed to synthesize node: " + node_name,
+               exprtk_error_location));
+
+            details::free_node(*node_allocator_, result);
+            return error_node();
          }
 
          #ifndef exprtk_disable_sc_andor
@@ -30608,7 +33426,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&)
@@ -31981,9 +34799,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";
             }
          };
 
@@ -32046,9 +34864,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)";
             }
          };
 
@@ -32112,9 +34930,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";
             }
          };
 
@@ -32177,9 +34995,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)";
             }
          };
 
@@ -32242,9 +35060,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";
             }
          };
 
@@ -32307,9 +35125,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)";
             }
          };
 
@@ -32372,9 +35190,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";
             }
          };
 
@@ -32438,9 +35256,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)";
             }
          };
 
@@ -32557,9 +35375,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";
             }
          };
 
@@ -32676,9 +35494,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)";
             }
          };
 
@@ -32807,9 +35625,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)";
             }
          };
 
@@ -32934,9 +35752,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";
             }
          };
 
@@ -33069,10 +35887,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)";
             }
          };
 
@@ -33158,10 +35976,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)";
             }
          };
 
@@ -33247,10 +36065,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)";
             }
          };
 
@@ -33336,10 +36154,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)";
             }
          };
 
@@ -33425,10 +36243,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)";
             }
          };
 
@@ -33619,10 +36437,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)";
             }
          };
 
@@ -33863,10 +36681,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)";
             }
          };
 
@@ -34057,10 +36875,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)";
             }
          };
 
@@ -34250,10 +37068,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)";
             }
          };
 
@@ -34310,10 +37128,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))";
             }
          };
 
@@ -34370,10 +37188,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))";
             }
          };
 
@@ -34430,10 +37248,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))";
             }
          };
 
@@ -34490,10 +37308,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))";
             }
          };
 
@@ -34551,10 +37369,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))";
             }
          };
 
@@ -34612,10 +37430,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))";
             }
          };
 
@@ -34672,10 +37490,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))";
             }
          };
 
@@ -34732,10 +37550,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))";
             }
          };
 
@@ -34792,10 +37610,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))";
             }
          };
 
@@ -34852,10 +37670,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)";
             }
          };
 
@@ -34912,10 +37730,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)";
             }
          };
 
@@ -34972,10 +37790,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)";
             }
          };
 
@@ -35032,10 +37850,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)";
             }
          };
 
@@ -35093,10 +37911,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)";
             }
         };
 
@@ -35154,10 +37972,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)";
             }
          };
 
@@ -35214,10 +38032,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)";
             }
          };
 
@@ -35275,10 +38093,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)";
             }
          };
 
@@ -35356,10 +38174,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";
             }
          };
 
@@ -35417,10 +38235,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";
             }
          };
 
@@ -35477,10 +38295,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";
             }
          };
 
@@ -35537,10 +38355,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";
             }
          };
 
@@ -35597,10 +38415,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";
             }
          };
 
@@ -35657,10 +38475,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";
             }
          };
 
@@ -35718,10 +38536,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";
             }
          };
 
@@ -35779,10 +38597,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";
             }
          };
 
@@ -35839,10 +38657,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";
             }
          };
 
@@ -35899,10 +38717,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";
             }
          };
 
@@ -35960,10 +38778,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";
             }
          };
 
@@ -36020,10 +38838,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";
             }
          };
 
@@ -36079,10 +38897,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";
             }
          };
 
@@ -36139,10 +38957,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";
             }
          };
 
@@ -36199,10 +39017,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";
             }
          };
 
@@ -36260,10 +39078,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";
             }
          };
 
@@ -36321,10 +39139,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";
             }
          };
 
@@ -36749,6 +39567,8 @@ namespace exprtk
                default : return error_node();
             }
          }
+
+         #undef string_opr_switch_statements
          #endif
 
          #ifndef exprtk_disable_string_capabilities
@@ -37082,11 +39902,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(),
+                  "ERR249 - 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>
@@ -37440,6 +40271,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_;
@@ -37455,7 +40287,9 @@ 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_;
 
       template <typename ParserType>
       friend void details::disable_type_checking(ParserType& p);
@@ -37482,7 +40316,7 @@ namespace exprtk
 
             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);
@@ -37694,7 +40528,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);
 
@@ -37707,8 +40543,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    template <typename T>
@@ -37798,8 +40634,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    template <typename T>
@@ -37825,8 +40661,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    template <typename T>
@@ -37852,8 +40688,8 @@ namespace exprtk
 
          return result;
       }
-      else
-         return std::numeric_limits<T>::quiet_NaN();
+
+      return std::numeric_limits<T>::quiet_NaN();
    }
 
    /*
@@ -38132,97 +40968,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();
       }
@@ -38324,6 +41161,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_;
@@ -38350,10 +41231,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)
          {
@@ -38559,7 +41441,7 @@ namespace exprtk
 
          func_0param() : base_func(0) {}
 
-         inline T operator() ()
+         inline T operator() () exprtk_override
          {
             return this->value(base_func::expression);
          }
@@ -38595,7 +41477,7 @@ namespace exprtk
 
          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);
@@ -38609,7 +41491,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);
@@ -38623,7 +41505,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);
@@ -38637,7 +41519,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);
@@ -38651,7 +41533,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);
@@ -38665,7 +41547,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);
@@ -38692,14 +41574,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)
@@ -38709,6 +41591,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,
@@ -38751,16 +41635,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()
@@ -38783,6 +41671,16 @@ 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;
+      }
+
       void clear()
       {
          symbol_table_.clear();
@@ -38808,6 +41706,29 @@ 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];
+         else
+            throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
+      }
+
    private:
 
       template <typename Allocator,
@@ -38823,8 +41744,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(),
+                  "ERR250 - Function '" + name + "' is an invalid overload",
+                  exprtk_error_location);
+
+            error_list_.push_back(error);
             return false;
+         }
 
          if (!forward(name,
                       input_var_list.size(),
@@ -38856,18 +41799,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);
          }
 
@@ -38988,11 +41935,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
@@ -39013,9 +41963,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 }
+      , stop_time_ { 0 }
       {
          QueryPerformanceFrequency(&clock_frequency_);
       }
@@ -39093,7 +42045,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_;
@@ -39126,7 +42078,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>
@@ -39186,19 +42154,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);
@@ -39208,19 +42176,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");
@@ -39302,8 +42270,8 @@ namespace exprtk
 
                   return false;
                }
-               else
-                  stream_ptr = stream;
+
+               stream_ptr = stream;
 
                return true;
             }
@@ -39318,8 +42286,8 @@ namespace exprtk
 
                   return false;
                }
-               else
-                  stream_ptr = stream;
+
+               stream_ptr = stream;
 
                return true;
             }
@@ -39334,13 +42302,13 @@ namespace exprtk
 
                   return false;
                }
-               else
-                  stream_ptr = stream;
+
+               stream_ptr = stream;
 
                return true;
             }
-            else
-               return false;
+
+            return false;
          }
 
          template <typename Stream, typename Ptr>
@@ -39487,12 +42455,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:
 
@@ -39501,13 +42470,13 @@ 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]));
 
@@ -39544,7 +42513,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();
 
@@ -39552,7 +42521,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);
 
@@ -39566,7 +42535,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class write : public exprtk::igeneric_function<T>
+   class write exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39577,13 +42546,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])());
 
@@ -39623,7 +42592,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class read : public exprtk::igeneric_function<T>
+   class read exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39634,13 +42603,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])());
 
@@ -39680,7 +42649,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class getline : public exprtk::igeneric_function<T>
+   class getline exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39690,14 +42659,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);
@@ -39705,7 +42673,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();
 
@@ -39713,7 +42681,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);
 
@@ -39826,7 +42794,7 @@ namespace exprtk
    } // namespace exprtk::rtl::details
 
    template <typename T>
-   class all_true : public exprtk::igeneric_function<T>
+   class all_true exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39835,7 +42803,7 @@ namespace exprtk
       typedef typename igfun_t::generic_type        generic_type;
       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")
@@ -39846,7 +42814,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 vec(parameters[0]);
 
@@ -39857,7 +42825,9 @@ namespace exprtk
               (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)
          {
@@ -39872,7 +42842,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class all_false : public exprtk::igeneric_function<T>
+   class all_false exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39881,7 +42851,7 @@ namespace exprtk
       typedef typename igfun_t::generic_type        generic_type;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       all_false()
       : exprtk::igeneric_function<T>("V|VTT")
@@ -39892,7 +42862,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 vec(parameters[0]);
 
@@ -39903,7 +42873,9 @@ namespace exprtk
               (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)
          {
@@ -39918,7 +42890,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class any_true : public exprtk::igeneric_function<T>
+   class any_true exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39927,7 +42899,7 @@ namespace exprtk
       typedef typename igfun_t::generic_type        generic_type;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       any_true()
       : exprtk::igeneric_function<T>("V|VTT")
@@ -39938,7 +42910,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 vec(parameters[0]);
 
@@ -39949,7 +42921,9 @@ namespace exprtk
               (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)
          {
@@ -39964,7 +42938,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class any_false : public exprtk::igeneric_function<T>
+   class any_false exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -39973,7 +42947,7 @@ namespace exprtk
       typedef typename igfun_t::generic_type        generic_type;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       any_false()
       : exprtk::igeneric_function<T>("V|VTT")
@@ -39984,7 +42958,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 vec(parameters[0]);
 
@@ -39995,7 +42969,9 @@ namespace exprtk
               (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)
          {
@@ -40010,7 +42986,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class count : public exprtk::igeneric_function<T>
+   class count exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40019,7 +42995,7 @@ namespace exprtk
       typedef typename igfun_t::generic_type        generic_type;
       typedef typename generic_type::vector_view    vector_t;
 
-      using exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       count()
       : exprtk::igeneric_function<T>("V|VTT")
@@ -40030,7 +43006,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 vec(parameters[0]);
 
@@ -40041,7 +43017,9 @@ namespace exprtk
               (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;
 
@@ -40055,7 +43033,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class copy : public exprtk::igeneric_function<T>
+   class copy exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40065,7 +43043,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();
 
       copy()
       : exprtk::igeneric_function<T>("VV|VTTVTT")
@@ -40076,7 +43054,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]);
@@ -40108,7 +43086,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class rol : public exprtk::igeneric_function<T>
+   class rol exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40118,7 +43096,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")
@@ -40129,7 +43107,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]);
 
@@ -40159,7 +43137,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class ror : public exprtk::igeneric_function<T>
+   class ror exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40169,7 +43147,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")
@@ -40180,7 +43158,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]);
 
@@ -40197,8 +43175,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,
@@ -40210,7 +43188,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class shift_left : public exprtk::igeneric_function<T>
+   class shift_left exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40220,7 +43198,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_left()
       : exprtk::igeneric_function<T>("VT|VTTT")
@@ -40231,7 +43209,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]);
 
@@ -40268,7 +43246,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:
 
@@ -40278,7 +43256,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")
@@ -40289,7 +43267,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]);
 
@@ -40328,7 +43306,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class sort : public exprtk::igeneric_function<T>
+   class sort exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40338,7 +43316,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")
@@ -40351,7 +43329,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]);
 
@@ -40391,7 +43369,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class nthelement : public exprtk::igeneric_function<T>
+   class nthelement exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40401,7 +43379,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")
@@ -40412,7 +43390,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]);
 
@@ -40424,7 +43402,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,
@@ -40436,7 +43416,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class iota : public exprtk::igeneric_function<T>
+   class assign exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40446,41 +43426,101 @@ 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();
+
+      assign()
+      : exprtk::igeneric_function<T>("VT|VTTT|VTTTT")
+        /*
+           Overloads:
+           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) exprtk_override
+      {
+         vector_t vec(parameters[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 (
+              ((ps_index == 1) || (ps_index == 2)) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
+            )
+         {
+            return T(0);
+         }
+
+         for (std::size_t i = r0; i <= r1; i += step_size)
+         {
+            vec[i] = assign_value;
+         }
+
+         return T(1);
+      }
+   };
+
+   template <typename 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 igfun_t::operator();
 
       iota()
-      : exprtk::igeneric_function<T>("VT|VTT|VTTT|VTTTT")
+      : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT")
         /*
            Overloads:
-           0. VT    - vector, increment
-           1. VTT   - vector, increment, base
-           2. VTTTT - vector, increment, r0, r1
-           3. VTTTT - vector, increment, base, 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
       {
          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 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 ((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 == 2) || (ps_index == 3)) &&
+              !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 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)
+         {
+            vec[i] = start_value + ((i - r0) * step_size);
          }
 
          return T(1);
@@ -40488,40 +43528,50 @@ namespace exprtk
    };
 
    template <typename T>
-   class sumk : public exprtk::igeneric_function<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 exprtk::igeneric_function<T>::operator();
+      using igfun_t::operator();
 
       sumk()
-      : exprtk::igeneric_function<T>("V|VTT")
+      : exprtk::igeneric_function<T>("V|VTT|VTTT")
         /*
            Overloads:
-           0. V   - vector
-           1. VTT - vector, r0, r1
+           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)
+      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) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
+         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]);
          }
@@ -40531,7 +43581,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpy : public exprtk::igeneric_function<T>
+   class axpy exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40541,7 +43591,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")
@@ -40553,7 +43603,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]);
@@ -40578,7 +43628,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpby : public exprtk::igeneric_function<T>
+   class axpby exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40588,7 +43638,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")
@@ -40600,7 +43650,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]);
@@ -40626,7 +43676,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpyz : public exprtk::igeneric_function<T>
+   class axpyz exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40636,7 +43686,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")
@@ -40648,7 +43698,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]);
@@ -40657,7 +43707,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();
@@ -40676,7 +43726,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpbyz : public exprtk::igeneric_function<T>
+   class axpbyz exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40686,7 +43736,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")
@@ -40698,7 +43748,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]);
@@ -40707,7 +43757,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();
@@ -40727,7 +43777,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class axpbz : public exprtk::igeneric_function<T>
+   class axpbsy exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40737,7 +43787,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")
@@ -40749,7 +43902,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]);
@@ -40775,7 +43928,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class dot : public exprtk::igeneric_function<T>
+   class diff exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40785,7 +43938,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")
@@ -40796,7 +43997,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]);
@@ -40821,7 +44022,7 @@ namespace exprtk
    };
 
    template <typename T>
-   class dotk : public exprtk::igeneric_function<T>
+   class dotk exprtk_final : public exprtk::igeneric_function<T>
    {
    public:
 
@@ -40831,7 +44032,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")
@@ -40842,7 +44043,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]);
@@ -40867,30 +44068,154 @@ 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;
+      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)
       {
@@ -40903,29 +44228,35 @@ 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("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;
@@ -40944,11 +44275,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.718281828459045235360287471352662"
+                                 "49775724709369995957496696762772407"
+                                 "66303535475945713821785251664274274"
+                                 "66391932003059921817413596629043572";
+      static char_cptr date    = "20240101";
       static char_cptr min_cpp = "199711L";
 
       static inline std::string data()
@@ -40970,12 +44301,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
-- 
GitLab