From 5d7e5f21c23506f8c0dcd894c038d06aa9153505 Mon Sep 17 00:00:00 2001
From: ArashPartow <partow@gmail.com>
Date: Wed, 1 Jan 2020 10:46:31 +1100
Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) 
 http://www.partow.net/programming/exprtk/index.html

---
 .travis.yml                  |    2 +-
 Makefile                     |    2 +-
 exprtk.hpp                   | 2434 ++++++++++++++++++++--------------
 exprtk_benchmark.cpp         |    2 +-
 exprtk_simple_example_01.cpp |    9 +-
 exprtk_simple_example_02.cpp |   23 +-
 exprtk_simple_example_03.cpp |    7 +-
 exprtk_simple_example_04.cpp |    4 +-
 exprtk_simple_example_05.cpp |    6 +-
 exprtk_simple_example_06.cpp |    4 +-
 exprtk_simple_example_07.cpp |    6 +-
 exprtk_simple_example_08.cpp |    6 +-
 exprtk_simple_example_09.cpp |    8 +-
 exprtk_simple_example_10.cpp |    6 +-
 exprtk_simple_example_11.cpp |    8 +-
 exprtk_simple_example_12.cpp |    4 +-
 exprtk_simple_example_13.cpp |    6 +-
 exprtk_simple_example_14.cpp |    6 +-
 exprtk_simple_example_15.cpp |    8 +-
 exprtk_simple_example_16.cpp |    4 +-
 exprtk_simple_example_17.cpp |    4 +-
 exprtk_simple_example_18.cpp |    4 +-
 exprtk_simple_example_19.cpp |    6 +-
 exprtk_test.cpp              |  524 +++++++-
 readme.txt                   |   98 +-
 25 files changed, 2108 insertions(+), 1083 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index adfae02..59c7873 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,4 @@
-dist: xenial
+dist: bionic
 
 language: cpp
 
diff --git a/Makefile b/Makefile
index 7bd2367..76d43a0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # **************************************************************
 # *         C++ Mathematical Expression Toolkit Library        *
 # *                                                            *
-# * Author: Arash Partow (1999-2019)                           *
+# * Author: Arash Partow (1999-2020)                           *
 # * URL: http://www.partow.net/programming/exprtk/index.html   *
 # *                                                            *
 # * Copyright notice:                                          *
diff --git a/exprtk.hpp b/exprtk.hpp
index 5f8cac1..ca38375 100644
--- a/exprtk.hpp
+++ b/exprtk.hpp
@@ -2,7 +2,7 @@
  ******************************************************************
  *           C++ Mathematical Expression Toolkit Library          *
  *                                                                *
- * Author: Arash Partow (1999-2019)                               *
+ * Author: Arash Partow (1999-2020)                               *
  * URL: http://www.partow.net/programming/exprtk/index.html       *
  *                                                                *
  * Copyright notice:                                              *
@@ -83,12 +83,14 @@ namespace exprtk
 
    namespace details
    {
-      typedef unsigned char     uchar_t;
-      typedef char               char_t;
-      typedef uchar_t*        uchar_ptr;
-      typedef char_t*          char_ptr;
-      typedef uchar_t const* uchar_cptr;
-      typedef char_t const*   char_cptr;
+      typedef unsigned char            uchar_t;
+      typedef char                      char_t;
+      typedef uchar_t*               uchar_ptr;
+      typedef char_t*                 char_ptr;
+      typedef uchar_t const*        uchar_cptr;
+      typedef char_t const*          char_cptr;
+      typedef unsigned long long int _uint64_t;
+      typedef long long int           _int64_t;
 
       inline bool is_whitespace(const char_t c)
       {
@@ -580,53 +582,64 @@ namespace exprtk
 
       template <typename Iterator, typename Compare>
       inline bool match_impl(const Iterator pattern_begin,
-                             const Iterator pattern_end,
-                             const Iterator data_begin,
-                             const Iterator data_end,
+                             const Iterator pattern_end  ,
+                             const Iterator data_begin   ,
+                             const Iterator data_end     ,
                              const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
-                             const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
+                             const typename std::iterator_traits<Iterator>::value_type& zero_or_one )
       {
-         Iterator d_itr = data_begin;
-         Iterator p_itr = pattern_begin;
+         const Iterator null_itr(0);
 
-         while ((p_itr != pattern_end) && (d_itr != data_end))
+         Iterator d_itr    = data_begin;
+         Iterator p_itr    = pattern_begin;
+         Iterator tb_p_itr = null_itr;
+         Iterator tb_d_itr = null_itr;
+
+         while (d_itr != data_end)
          {
             if (zero_or_more == *p_itr)
             {
-               while ((p_itr != pattern_end) && (*p_itr == zero_or_more || *p_itr == zero_or_one))
+               while ((pattern_end != p_itr) && ((zero_or_more == *p_itr) || (zero_or_one == *p_itr)))
                {
                   ++p_itr;
                }
 
-               if (p_itr == pattern_end)
+               if (pattern_end == p_itr)
                   return true;
 
-               const typename std::iterator_traits<Iterator>::value_type c = *(p_itr++);
+               const typename std::iterator_traits<Iterator>::value_type c = *(p_itr);
 
-               while ((d_itr != data_end) && !Compare::cmp(c,*d_itr))
+               while ((data_end != d_itr) && !Compare::cmp(c,*d_itr))
                {
                   ++d_itr;
                }
 
-               ++d_itr;
+               tb_p_itr = p_itr;
+               tb_d_itr = d_itr;
+
+               continue;
             }
-            else if ((*p_itr == zero_or_one) || Compare::cmp(*p_itr, *d_itr))
+            else if (!Compare::cmp(*p_itr, *d_itr) && (zero_or_one != *p_itr))
             {
-               ++d_itr;
-               ++p_itr;
+               if (null_itr == tb_d_itr)
+                  return false;
+
+               d_itr = tb_d_itr++;
+               p_itr = tb_p_itr;
+
+               continue;
             }
-            else
-               return false;
+
+            ++p_itr;
+            ++d_itr;
          }
 
-         if (d_itr != data_end)
-            return false;
-         else if (p_itr == pattern_end)
-            return true;
-         else if ((zero_or_more == *p_itr) || (zero_or_one == *p_itr))
+         while ((pattern_end != p_itr) && ((zero_or_more == *p_itr) || (zero_or_one == *p_itr)))
+         {
             ++p_itr;
+         }
 
-         return pattern_end == p_itr;
+         return (pattern_end == p_itr);
       }
 
       inline bool wc_match(const std::string& wild_card,
@@ -781,12 +794,12 @@ namespace exprtk
             exprtk_register_complex_type_tag(long double)
             exprtk_register_complex_type_tag(float      )
 
-            exprtk_register_int_type_tag(short                 )
-            exprtk_register_int_type_tag(int                   )
-            exprtk_register_int_type_tag(long long int         )
-            exprtk_register_int_type_tag(unsigned short        )
-            exprtk_register_int_type_tag(unsigned int          )
-            exprtk_register_int_type_tag(unsigned long long int)
+            exprtk_register_int_type_tag(short         )
+            exprtk_register_int_type_tag(int           )
+            exprtk_register_int_type_tag(_int64_t      )
+            exprtk_register_int_type_tag(unsigned short)
+            exprtk_register_int_type_tag(unsigned int  )
+            exprtk_register_int_type_tag(_uint64_t     )
 
             #undef exprtk_register_real_type_tag
             #undef exprtk_register_int_type_tag
@@ -834,9 +847,9 @@ namespace exprtk
             }
 
             template <typename T>
-            inline long long int to_int64_impl(const T v, real_type_tag)
+            inline _int64_t to_int64_impl(const T v, real_type_tag)
             {
-               return static_cast<long long int>(v);
+               return static_cast<_int64_t>(v);
             }
 
             template <typename T>
@@ -1374,7 +1387,7 @@ namespace exprtk
          }
 
          template <typename T>
-         inline long long int to_int64(const T v)
+         inline _int64_t to_int64(const T v)
          {
             const typename details::number_type<T>::type num_type;
             return to_int64_impl(v, num_type);
@@ -1835,7 +1848,7 @@ namespace exprtk
 
          bool instate = false;
 
-         static const char zero = static_cast<uchar_t>('0');
+         static const char_t zero = static_cast<uchar_t>('0');
 
          #define parse_digit_1(d)          \
          if ((digit = (*itr - zero)) < 10) \
@@ -2323,9 +2336,9 @@ namespace exprtk
             if (finished())
                return "";
             else if (token_list_.begin() != token_itr_)
-               return std::string(base_itr_ + (token_itr_ - 1)->position,s_end_);
+               return std::string(base_itr_ + (token_itr_ - 1)->position, s_end_);
             else
-               return std::string(base_itr_ + token_itr_->position,s_end_);
+               return std::string(base_itr_ + token_itr_->position, s_end_);
          }
 
       private:
@@ -3075,7 +3088,7 @@ namespace exprtk
       {
       public:
 
-         token_joiner(const std::size_t& stride)
+         explicit token_joiner(const std::size_t& stride)
          : stride_(stride)
          {}
 
@@ -3226,6 +3239,7 @@ namespace exprtk
                else if ((t0.type == lexer::token::e_rbracket   ) && (t1.type == lexer::token::e_symbol     )) match = true;
                else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol     )) match = true;
                else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol     )) match = true;
+               else if ((t0.type == lexer::token::e_symbol     ) && (t1.type == lexer::token::e_symbol     )) match = true;
 
                return (match) ? 1 : -1;
             }
@@ -3239,7 +3253,7 @@ namespace exprtk
          {
          public:
 
-            operator_joiner(const std::size_t& stride)
+            explicit operator_joiner(const std::size_t& stride)
             : token_joiner(stride)
             {}
 
@@ -3637,10 +3651,11 @@ namespace exprtk
             sequence_validator()
             : lexer::token_scanner(2)
             {
-               add_invalid(lexer::token::e_number ,lexer::token::e_number );
-               add_invalid(lexer::token::e_string ,lexer::token::e_string );
-               add_invalid(lexer::token::e_number ,lexer::token::e_string );
-               add_invalid(lexer::token::e_string ,lexer::token::e_number );
+               add_invalid(lexer::token::e_number, lexer::token::e_number);
+               add_invalid(lexer::token::e_string, lexer::token::e_string);
+               add_invalid(lexer::token::e_number, lexer::token::e_string);
+               add_invalid(lexer::token::e_string, lexer::token::e_number);
+
                add_invalid_set1(lexer::token::e_assign );
                add_invalid_set1(lexer::token::e_shr    );
                add_invalid_set1(lexer::token::e_shl    );
@@ -3714,21 +3729,21 @@ namespace exprtk
 
             void add_invalid_set1(lexer::token::token_type t)
             {
-               add_invalid(t,lexer::token::e_assign);
-               add_invalid(t,lexer::token::e_shr   );
-               add_invalid(t,lexer::token::e_shl   );
-               add_invalid(t,lexer::token::e_lte   );
-               add_invalid(t,lexer::token::e_ne    );
-               add_invalid(t,lexer::token::e_gte   );
-               add_invalid(t,lexer::token::e_lt    );
-               add_invalid(t,lexer::token::e_gt    );
-               add_invalid(t,lexer::token::e_eq    );
-               add_invalid(t,lexer::token::e_comma );
-               add_invalid(t,lexer::token::e_div   );
-               add_invalid(t,lexer::token::e_mul   );
-               add_invalid(t,lexer::token::e_mod   );
-               add_invalid(t,lexer::token::e_pow   );
-               add_invalid(t,lexer::token::e_colon );
+               add_invalid(t, lexer::token::e_assign);
+               add_invalid(t, lexer::token::e_shr   );
+               add_invalid(t, lexer::token::e_shl   );
+               add_invalid(t, lexer::token::e_lte   );
+               add_invalid(t, lexer::token::e_ne    );
+               add_invalid(t, lexer::token::e_gte   );
+               add_invalid(t, lexer::token::e_lt    );
+               add_invalid(t, lexer::token::e_gt    );
+               add_invalid(t, lexer::token::e_eq    );
+               add_invalid(t, lexer::token::e_comma );
+               add_invalid(t, lexer::token::e_div   );
+               add_invalid(t, lexer::token::e_mul   );
+               add_invalid(t, lexer::token::e_mod   );
+               add_invalid(t, lexer::token::e_pow   );
+               add_invalid(t, lexer::token::e_colon );
             }
 
             bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
@@ -3738,7 +3753,7 @@ namespace exprtk
                   switch (t)
                   {
                      case lexer::token::e_assign : return (']' != base);
-                     case lexer::token::e_string : return true;
+                     case lexer::token::e_string : return (')' != base);
                      default                     : return false;
                   }
                }
@@ -3809,23 +3824,23 @@ namespace exprtk
             sequence_validator_3tokens()
             : lexer::token_scanner(3)
             {
-               add_invalid(lexer::token::e_number , lexer::token::e_number , lexer::token::e_number);
-               add_invalid(lexer::token::e_string , lexer::token::e_string , lexer::token::e_string);
-               add_invalid(lexer::token::e_comma  , lexer::token::e_comma  , lexer::token::e_comma );
+               add_invalid(lexer::token::e_number, lexer::token::e_number, lexer::token::e_number);
+               add_invalid(lexer::token::e_string, lexer::token::e_string, lexer::token::e_string);
+               add_invalid(lexer::token::e_comma , lexer::token::e_comma , lexer::token::e_comma );
 
-               add_invalid(lexer::token::e_add ,lexer::token::e_add , lexer::token::e_add);
-               add_invalid(lexer::token::e_sub ,lexer::token::e_sub , lexer::token::e_sub);
-               add_invalid(lexer::token::e_div ,lexer::token::e_div , lexer::token::e_div);
-               add_invalid(lexer::token::e_mul ,lexer::token::e_mul , lexer::token::e_mul);
-               add_invalid(lexer::token::e_mod ,lexer::token::e_mod , lexer::token::e_mod);
-               add_invalid(lexer::token::e_pow ,lexer::token::e_pow , lexer::token::e_pow);
+               add_invalid(lexer::token::e_add   , lexer::token::e_add   , lexer::token::e_add   );
+               add_invalid(lexer::token::e_sub   , lexer::token::e_sub   , lexer::token::e_sub   );
+               add_invalid(lexer::token::e_div   , lexer::token::e_div   , lexer::token::e_div   );
+               add_invalid(lexer::token::e_mul   , lexer::token::e_mul   , lexer::token::e_mul   );
+               add_invalid(lexer::token::e_mod   , lexer::token::e_mod   , lexer::token::e_mod   );
+               add_invalid(lexer::token::e_pow   , lexer::token::e_pow   , lexer::token::e_pow   );
 
-               add_invalid(lexer::token::e_add ,lexer::token::e_sub , lexer::token::e_add);
-               add_invalid(lexer::token::e_sub ,lexer::token::e_add , lexer::token::e_sub);
-               add_invalid(lexer::token::e_div ,lexer::token::e_mul , lexer::token::e_div);
-               add_invalid(lexer::token::e_mul ,lexer::token::e_div , lexer::token::e_mul);
-               add_invalid(lexer::token::e_mod ,lexer::token::e_pow , lexer::token::e_mod);
-               add_invalid(lexer::token::e_pow ,lexer::token::e_mod , lexer::token::e_pow);
+               add_invalid(lexer::token::e_add   , lexer::token::e_sub   , lexer::token::e_add   );
+               add_invalid(lexer::token::e_sub   , lexer::token::e_add   , lexer::token::e_sub   );
+               add_invalid(lexer::token::e_div   , lexer::token::e_mul   , lexer::token::e_div   );
+               add_invalid(lexer::token::e_mul   , lexer::token::e_div   , lexer::token::e_mul   );
+               add_invalid(lexer::token::e_mod   , lexer::token::e_pow   , lexer::token::e_mod   );
+               add_invalid(lexer::token::e_pow   , lexer::token::e_mod   , lexer::token::e_pow   );
             }
 
             bool result()
@@ -4219,14 +4234,14 @@ namespace exprtk
    inline vector_view<T> make_vector_view(T* data,
                                           const std::size_t size, const std::size_t offset = 0)
    {
-      return vector_view<T>(data + offset,size);
+      return vector_view<T>(data + offset, size);
    }
 
    template <typename T>
    inline vector_view<T> make_vector_view(std::vector<T>& v,
                                           const std::size_t size, const std::size_t offset = 0)
    {
-      return vector_view<T>(v.data() + offset,size);
+      return vector_view<T>(v.data() + offset, size);
    }
 
    template <typename T> class results_context;
@@ -4243,13 +4258,18 @@ namespace exprtk
       };
 
       type_store()
-      : size(0),
-        data(0),
+      : data(0),
+        size(0),
         type(e_unknown)
       {}
 
+      union
+      {
+          void*  data;
+          T*     vec_data;
+      };
+
       std::size_t size;
-      void*       data;
       store_type  type;
 
       class parameter_list
@@ -4555,27 +4575,33 @@ namespace exprtk
       {
          switch (opr)
          {
-            case e_add    : return  "+";
-            case e_sub    : return  "-";
-            case e_mul    : return  "*";
-            case e_div    : return  "/";
-            case e_mod    : return  "%";
-            case e_pow    : return  "^";
-            case e_assign : return ":=";
-            case e_addass : return "+=";
-            case e_subass : return "-=";
-            case e_mulass : return "*=";
-            case e_divass : return "/=";
-            case e_modass : return "%=";
-            case e_lt     : return  "<";
-            case e_lte    : return "<=";
-            case e_eq     : return "==";
-            case e_equal  : return  "=";
-            case e_ne     : return "!=";
-            case e_nequal : return "<>";
-            case e_gte    : return ">=";
-            case e_gt     : return  ">";
-            default       : return"N/A";
+            case e_add    : return  "+"  ;
+            case e_sub    : return  "-"  ;
+            case e_mul    : return  "*"  ;
+            case e_div    : return  "/"  ;
+            case e_mod    : return  "%"  ;
+            case e_pow    : return  "^"  ;
+            case e_assign : return ":="  ;
+            case e_addass : return "+="  ;
+            case e_subass : return "-="  ;
+            case e_mulass : return "*="  ;
+            case e_divass : return "/="  ;
+            case e_modass : return "%="  ;
+            case e_lt     : return  "<"  ;
+            case e_lte    : return "<="  ;
+            case e_eq     : return "=="  ;
+            case e_equal  : return  "="  ;
+            case e_ne     : return "!="  ;
+            case e_nequal : return "<>"  ;
+            case e_gte    : return ">="  ;
+            case e_gt     : return  ">"  ;
+            case e_and    : return "and" ;
+            case e_or     : return "or"  ;
+            case e_xor    : return "xor" ;
+            case e_nand   : return "nand";
+            case e_nor    : return "nor" ;
+            case e_xnor   : return "xnor";
+            default       : return "N/A" ;
          }
       }
 
@@ -4976,7 +5002,7 @@ namespace exprtk
          template <typename T>
          inline T process(const operator_type operation, const T arg0, const T arg1)
          {
-            return exprtk::details::numeric::details::process_impl(operation,arg0,arg1);
+            return exprtk::details::numeric::details::process_impl(operation, arg0, arg1);
          }
       }
 
@@ -4987,42 +5013,42 @@ namespace exprtk
 
          enum node_type
          {
-            e_none         , e_null         , e_constant     , e_unary        ,
-            e_binary       , e_binary_ext   , e_trinary      , e_quaternary   ,
-            e_vararg       , e_conditional  , e_while        , e_repeat       ,
-            e_for          , e_switch       , e_mswitch      , e_return       ,
-            e_retenv       , e_variable     , e_stringvar    , e_stringconst  ,
-            e_stringvarrng , e_cstringvarrng, e_strgenrange  , e_strconcat    ,
-            e_stringvarsize, e_strswap      , e_stringsize   , e_stringvararg ,
-            e_function     , e_vafunction   , e_genfunction  , e_strfunction  ,
-            e_strcondition , e_strccondition, e_add          , e_sub          ,
-            e_mul          , e_div          , e_mod          , e_pow          ,
-            e_lt           , e_lte          , e_gt           , e_gte          ,
-            e_eq           , e_ne           , e_and          , e_nand         ,
-            e_or           , e_nor          , e_xor          , e_xnor         ,
-            e_in           , e_like         , e_ilike        , e_inranges     ,
-            e_ipow         , e_ipowinv      , e_abs          , e_acos         ,
-            e_acosh        , e_asin         , e_asinh        , e_atan         ,
-            e_atanh        , e_ceil         , e_cos          , e_cosh         ,
-            e_exp          , e_expm1        , e_floor        , e_log          ,
-            e_log10        , e_log2         , e_log1p        , e_neg          ,
-            e_pos          , e_round        , e_sin          , e_sinc         ,
-            e_sinh         , e_sqrt         , e_tan          , e_tanh         ,
-            e_cot          , e_sec          , e_csc          , e_r2d          ,
-            e_d2r          , e_d2g          , e_g2d          , e_notl         ,
-            e_sgn          , e_erf          , e_erfc         , e_ncdf         ,
-            e_frac         , e_trunc        , e_uvouv        , e_vov          ,
-            e_cov          , e_voc          , e_vob          , e_bov          ,
-            e_cob          , e_boc          , e_vovov        , e_vovoc        ,
-            e_vocov        , e_covov        , e_covoc        , e_vovovov      ,
-            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_break        , e_continue     ,
+            e_none          , e_null          , e_constant    , e_unary        ,
+            e_binary        , e_binary_ext    , e_trinary     , e_quaternary   ,
+            e_vararg        , e_conditional   , e_while       , e_repeat       ,
+            e_for           , e_switch        , e_mswitch     , e_return       ,
+            e_retenv        , e_variable      , e_stringvar   , e_stringconst  ,
+            e_stringvarrng  , e_cstringvarrng , e_strgenrange , e_strconcat    ,
+            e_stringvarsize , e_strswap       , e_stringsize  , e_stringvararg ,
+            e_function      , e_vafunction    , e_genfunction , e_strfunction  ,
+            e_strcondition  , e_strccondition , e_add         , e_sub          ,
+            e_mul           , e_div           , e_mod         , e_pow          ,
+            e_lt            , e_lte           , e_gt          , e_gte          ,
+            e_eq            , e_ne            , e_and         , e_nand         ,
+            e_or            , e_nor           , e_xor         , e_xnor         ,
+            e_in            , e_like          , e_ilike       , e_inranges     ,
+            e_ipow          , e_ipowinv       , e_abs         , e_acos         ,
+            e_acosh         , e_asin          , e_asinh       , e_atan         ,
+            e_atanh         , e_ceil          , e_cos         , e_cosh         ,
+            e_exp           , e_expm1         , e_floor       , e_log          ,
+            e_log10         , e_log2          , e_log1p       , e_neg          ,
+            e_pos           , e_round         , e_sin         , e_sinc         ,
+            e_sinh          , e_sqrt          , e_tan         , e_tanh         ,
+            e_cot           , e_sec           , e_csc         , e_r2d          ,
+            e_d2r           , e_d2g           , e_g2d         , e_notl         ,
+            e_sgn           , e_erf           , e_erfc        , e_ncdf         ,
+            e_frac          , e_trunc         , e_uvouv       , e_vov          ,
+            e_cov           , e_voc           , e_vob         , e_bov          ,
+            e_cob           , e_boc           , e_vovov       , e_vovoc        ,
+            e_vocov         , e_covov         , e_covoc       , e_vovovov      ,
+            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_break       , e_continue     ,
             e_swap
          };
 
@@ -6683,7 +6709,7 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
+         explicit switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
          {
             if (1 != (arg_list.size() & 1))
                return;
@@ -6761,7 +6787,7 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
+         explicit switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
          : switch_node<T>(arg_list)
          {}
 
@@ -6780,7 +6806,7 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
+         explicit multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
          {
             if (0 != (arg_list.size() & 1))
                return;
@@ -6875,7 +6901,7 @@ namespace exprtk
          : value_(&null_value)
          {}
 
-         variable_node(T& v)
+         explicit variable_node(T& v)
          : value_(&v)
          {}
 
@@ -6976,13 +7002,14 @@ namespace exprtk
                   (!n0_c.first && !n1_c.first);
          }
 
-         bool operator() (std::size_t& r0, std::size_t& r1, const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
+         bool operator() (std::size_t& r0, std::size_t& r1,
+                          const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
          {
             if (n0_c.first)
                r0 = n0_c.second;
             else if (n0_e.first)
             {
-               T r0_value = n0_e.second->value();
+               const T r0_value = n0_e.second->value();
 
                if (r0_value < 0)
                   return false;
@@ -6996,7 +7023,7 @@ namespace exprtk
                r1 = n1_c.second;
             else if (n1_e.first)
             {
-               T r1_value = n1_e.second->value();
+               const T r1_value = n1_e.second->value();
 
                if (r1_value < 0)
                   return false;
@@ -7098,7 +7125,7 @@ namespace exprtk
          typedef vector_node<T>*     vector_node_ptr;
          typedef vec_data_store<T>             vds_t;
 
-         vector_node(vector_holder_t* vh)
+         explicit vector_node(vector_holder_t* vh)
          : vector_holder_(vh),
            vds_((*vector_holder_).size(),(*vector_holder_)[0])
          {
@@ -7878,8 +7905,8 @@ namespace exprtk
                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)
+                    range      (str_r0, str_r1, base_str_size) &&
+                    base_range_(    r0,     r1, base_str_size)
                   )
                {
                   const std::size_t size = (r1 - r0) + 1;
@@ -8015,8 +8042,8 @@ namespace exprtk
                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())
+                    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;
@@ -8115,7 +8142,7 @@ namespace exprtk
                binary_node<T>::branch_[0].first->value();
                binary_node<T>::branch_[1].first->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();
@@ -8232,8 +8259,8 @@ namespace exprtk
                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())
+                    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();
@@ -8271,8 +8298,8 @@ namespace exprtk
                   exprtk_disable_fallthrough_begin
                   switch (lud.remainder)
                   {
-                     #define case_stmt(N)                      \
-                     case N : { std::swap(s0[i],s1[i]); ++i; } \
+                     #define case_stmt(N)                       \
+                     case N : { std::swap(s0[i], s1[i]); ++i; } \
 
                      #ifndef exprtk_disable_superscalar_unroll
                      case_stmt(15) case_stmt(14)
@@ -8353,7 +8380,7 @@ namespace exprtk
          typedef expression_node <T>* expression_ptr;
          typedef string_base_node<T>*   str_base_ptr;
 
-         string_size_node(expression_ptr brnch)
+         explicit string_size_node(expression_ptr brnch)
          : branch_(brnch),
            branch_deletable_(branch_deletable(branch_)),
            str_base_ptr_(0)
@@ -8611,7 +8638,7 @@ namespace exprtk
                     range1(s1_r0, s1_r1, str1_base_ptr_->size())
                   )
                {
-                  std::size_t size = std::min((s0_r1 - s0_r0),(s1_r1 - s1_r0)) + 1;
+                  std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0)) + 1;
 
                   std::copy(str1_base_ptr_->base() + s1_r0,
                             str1_base_ptr_->base() + s1_r0 + size,
@@ -8954,7 +8981,7 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
+         explicit str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
          : final_node_(arg_list.back()),
            final_deletable_(branch_deletable(final_node_)),
            initialised_(false),
@@ -9101,7 +9128,7 @@ namespace exprtk
       template <typename T>                              \
       struct sf##NN##_op : public sf_base<T>             \
       {                                                  \
-         typedef typename sf_base<T>::Type Type;         \
+         typedef typename sf_base<T>::Type const Type;   \
          static inline T process(Type x, Type y, Type z) \
          {                                               \
             return (OP0);                                \
@@ -9165,7 +9192,7 @@ namespace exprtk
       template <typename T>                                      \
       struct sf##NN##_op : public sf_base<T>                     \
       {                                                          \
-         typedef typename sf_base<T>::Type Type;                 \
+         typedef typename sf_base<T>::Type const Type;           \
          static inline T process(Type x, Type y, Type z, Type w) \
          {                                                       \
             return (OP0);                                        \
@@ -9420,7 +9447,7 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
+         explicit vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
          {
             arg_list_     .resize(arg_list.size());
             delete_branch_.resize(arg_list.size());
@@ -9454,10 +9481,7 @@ namespace exprtk
 
          inline T value() const
          {
-            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
@@ -9480,7 +9504,7 @@ namespace exprtk
 
          template <typename Allocator,
                    template <typename, typename> class Sequence>
-         vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
+         explicit vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
          {
             arg_list_.resize(arg_list.size());
 
@@ -9524,7 +9548,7 @@ namespace exprtk
 
          typedef expression_node<T>* expression_ptr;
 
-         vectorize_node(const expression_ptr v)
+         explicit vectorize_node(const expression_ptr v)
          : ivec_ptr_(0),
            v_(v),
            v_deletable_(branch_deletable(v_))
@@ -9756,8 +9780,8 @@ namespace exprtk
 
                while (vec < upper_bound)
                {
-                 #define exprtk_loop(N) \
-                  vec[N] = v;           \
+                  #define exprtk_loop(N) \
+                  vec[N] = v;            \
 
                   exprtk_loop( 0) exprtk_loop( 1)
                   exprtk_loop( 2) exprtk_loop( 3)
@@ -10313,16 +10337,16 @@ namespace exprtk
                binary_node<T>::branch_[0].first->value();
                binary_node<T>::branch_[1].first->value();
 
-               T* vec0 = vec0_node_ptr_->vds().data();
-               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;
 
                while (vec0 < upper_bound)
                {
-                  #define exprtk_loop(N)                         \
-                  vec0[N] = Operation::process(vec0[N],vec1[N]); \
+                  #define exprtk_loop(N)                          \
+                  vec0[N] = Operation::process(vec0[N], vec1[N]); \
 
                   exprtk_loop( 0) exprtk_loop( 1)
                   exprtk_loop( 2) exprtk_loop( 3)
@@ -10344,8 +10368,8 @@ namespace exprtk
                exprtk_disable_fallthrough_begin
                switch (lud.remainder)
                {
-                  #define case_stmt(N)                                             \
-                  case N : { vec0[i] = Operation::process(vec0[i],vec1[i]); ++i; } \
+                  #define case_stmt(N)                                              \
+                  case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
 
                   #ifndef exprtk_disable_superscalar_unroll
                   case_stmt(15) case_stmt(14)
@@ -10498,17 +10522,17 @@ namespace exprtk
                binary_node<T>::branch_[0].first->value();
                binary_node<T>::branch_[1].first->value();
 
-               T* vec0 = vec0_node_ptr_->vds().data();
-               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;
 
                while (vec2 < upper_bound)
                {
-                  #define exprtk_loop(N)                         \
-                  vec2[N] = Operation::process(vec0[N],vec1[N]); \
+                  #define exprtk_loop(N)                          \
+                  vec2[N] = Operation::process(vec0[N], vec1[N]); \
 
                   exprtk_loop( 0) exprtk_loop( 1)
                   exprtk_loop( 2) exprtk_loop( 3)
@@ -10531,8 +10555,8 @@ namespace exprtk
                exprtk_disable_fallthrough_begin
                switch (lud.remainder)
                {
-                  #define case_stmt(N)                                             \
-                  case N : { vec2[i] = Operation::process(vec0[i],vec1[i]); ++i; } \
+                  #define case_stmt(N)                                              \
+                  case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
 
                   #ifndef exprtk_disable_superscalar_unroll
                   case_stmt(15) case_stmt(14)
@@ -10657,16 +10681,16 @@ namespace exprtk
                            binary_node<T>::branch_[0].first->value();
                const T v = binary_node<T>::branch_[1].first->value();
 
-               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;
 
                while (vec0 < upper_bound)
                {
-                  #define exprtk_loop(N)                   \
-                  vec1[N] = Operation::process(vec0[N],v); \
+                  #define exprtk_loop(N)                    \
+                  vec1[N] = Operation::process(vec0[N], v); \
 
                   exprtk_loop( 0) exprtk_loop( 1)
                   exprtk_loop( 2) exprtk_loop( 3)
@@ -10688,8 +10712,8 @@ namespace exprtk
                exprtk_disable_fallthrough_begin
                switch (lud.remainder)
                {
-                  #define case_stmt(N)                                       \
-                  case N : { vec1[i] = Operation::process(vec0[i],v); ++i; } \
+                  #define case_stmt(N)                                        \
+                  case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
 
                   #ifndef exprtk_disable_superscalar_unroll
                   case_stmt(15) case_stmt(14)
@@ -10812,16 +10836,16 @@ namespace exprtk
                const T v = binary_node<T>::branch_[0].first->value();
                            binary_node<T>::branch_[1].first->value();
 
-               T* vec0 = vds().data();
-               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;
 
                while (vec0 < upper_bound)
                {
-                  #define exprtk_loop(N)                   \
-                  vec0[N] = Operation::process(v,vec1[N]); \
+                  #define exprtk_loop(N)                    \
+                  vec0[N] = Operation::process(v, vec1[N]); \
 
                   exprtk_loop( 0) exprtk_loop( 1)
                   exprtk_loop( 2) exprtk_loop( 3)
@@ -10843,8 +10867,8 @@ namespace exprtk
                exprtk_disable_fallthrough_begin
                switch (lud.remainder)
                {
-                  #define case_stmt(N)                                       \
-                  case N : { vec0[i] = Operation::process(v,vec1[i]); ++i; } \
+                  #define case_stmt(N)                                        \
+                  case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
 
                   #ifndef exprtk_disable_superscalar_unroll
                   case_stmt(15) case_stmt(14)
@@ -10964,8 +10988,8 @@ namespace exprtk
 
             if (vec0_node_ptr_)
             {
-               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;
@@ -11116,7 +11140,7 @@ namespace exprtk
          typedef std::pair<expression_ptr,bool> branch_t;
          typedef IFunction ifunction;
 
-         function_N_node(ifunction* func)
+         explicit function_N_node(ifunction* func)
          : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
            parameter_count_(func->param_count)
          {}
@@ -11407,7 +11431,7 @@ namespace exprtk
          typedef expression_node<T>* expression_ptr;
          typedef IFunction ifunction;
 
-         function_N_node(ifunction* func)
+         explicit function_N_node(ifunction* func)
          : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
          {}
 
@@ -11550,6 +11574,7 @@ 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);
                }
                #ifndef exprtk_disable_string_capabilities
                else if (is_generally_string_node(arg_list_[i]))
@@ -11715,16 +11740,17 @@ namespace exprtk
 
          inline T value() const
          {
-            T result = std::numeric_limits<T>::quiet_NaN();
-
             if (gen_function_t::function_)
             {
                if (gen_function_t::populate_value_list())
                {
                   typedef typename StringFunction::parameter_list_t parameter_list_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;
@@ -11733,7 +11759,7 @@ namespace exprtk
                }
             }
 
-            return result;
+            return std::numeric_limits<T>::quiet_NaN();
          }
 
          inline typename expression_node<T>::node_type type() const
@@ -11790,20 +11816,21 @@ namespace exprtk
 
          inline T value() const
          {
-            T result = std::numeric_limits<T>::quiet_NaN();
-
             if (gen_function_t::function_)
             {
                if (gen_function_t::populate_value_list())
                {
                   typedef typename GenericFunction::parameter_list_t parameter_list_t;
 
-                  return (*gen_function_t::function_)(param_seq_index_,
-                                                      parameter_list_t(gen_function_t::typestore_list_));
+                  return (*gen_function_t::function_)
+                            (
+                              param_seq_index_,
+                              parameter_list_t(gen_function_t::typestore_list_)
+                            );
                }
             }
 
-            return result;
+            return std::numeric_limits<T>::quiet_NaN();
          }
 
          inline typename expression_node<T>::node_type type() const
@@ -11834,17 +11861,18 @@ namespace exprtk
 
          inline T value() const
          {
-            T result = std::numeric_limits<T>::quiet_NaN();
-
             if (str_function_t::function_)
             {
                if (str_function_t::populate_value_list())
                {
                   typedef typename StringFunction::parameter_list_t parameter_list_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;
@@ -11853,7 +11881,7 @@ namespace exprtk
                }
             }
 
-            return result;
+            return std::numeric_limits<T>::quiet_NaN();
          }
 
          inline typename expression_node<T>::node_type type() const
@@ -12058,20 +12086,21 @@ namespace exprtk
       template <typename T>
       struct opr_base
       {
-         typedef typename details::functor_t<T>::Type Type;
+         typedef typename details::functor_t<T>::Type    Type;
          typedef typename details::functor_t<T>::RefType RefType;
-         typedef typename details::functor_t<T> functor_t;
-         typedef typename functor_t::qfunc_t quaternary_functor_t;
-         typedef typename functor_t::tfunc_t    trinary_functor_t;
-         typedef typename functor_t::bfunc_t     binary_functor_t;
-         typedef typename functor_t::ufunc_t      unary_functor_t;
+         typedef typename details::functor_t<T>          functor_t;
+         typedef typename functor_t::qfunc_t  quaternary_functor_t;
+         typedef typename functor_t::tfunc_t     trinary_functor_t;
+         typedef typename functor_t::bfunc_t      binary_functor_t;
+         typedef typename functor_t::ufunc_t       unary_functor_t;
       };
 
       template <typename T>
       struct add_op : public opr_base<T>
       {
-         typedef typename opr_base<T>::Type Type;
+         typedef typename opr_base<T>::Type    Type;
          typedef typename opr_base<T>::RefType RefType;
+
          static inline T process(Type t1, Type t2) { return t1 + t2; }
          static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
          static inline void assign(RefType t1, Type t2) { t1 += t2; }
@@ -12082,8 +12111,9 @@ namespace exprtk
       template <typename T>
       struct mul_op : public opr_base<T>
       {
-         typedef typename opr_base<T>::Type Type;
+         typedef typename opr_base<T>::Type    Type;
          typedef typename opr_base<T>::RefType RefType;
+
          static inline T process(Type t1, Type t2) { return t1 * t2; }
          static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
          static inline void assign(RefType t1, Type t2) { t1 *= t2; }
@@ -12094,8 +12124,9 @@ namespace exprtk
       template <typename T>
       struct sub_op : public opr_base<T>
       {
-         typedef typename opr_base<T>::Type Type;
+         typedef typename opr_base<T>::Type    Type;
          typedef typename opr_base<T>::RefType RefType;
+
          static inline T process(Type t1, Type t2) { return t1 - t2; }
          static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
          static inline void assign(RefType t1, Type t2) { t1 -= t2; }
@@ -12106,8 +12137,9 @@ namespace exprtk
       template <typename T>
       struct div_op : public opr_base<T>
       {
-         typedef typename opr_base<T>::Type Type;
+         typedef typename opr_base<T>::Type    Type;
          typedef typename opr_base<T>::RefType RefType;
+
          static inline T process(Type t1, Type t2) { return t1 / t2; }
          static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
          static inline void assign(RefType t1, Type t2) { t1 /= t2; }
@@ -12118,8 +12150,9 @@ namespace exprtk
       template <typename T>
       struct mod_op : public opr_base<T>
       {
-         typedef typename opr_base<T>::Type Type;
+         typedef typename opr_base<T>::Type    Type;
          typedef typename opr_base<T>::RefType RefType;
+
          static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
          static inline void assign(RefType t1, Type t2) { t1 = numeric::modulus<T>(t1,t2); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
@@ -12129,8 +12162,9 @@ namespace exprtk
       template <typename T>
       struct pow_op : public opr_base<T>
       {
-         typedef typename opr_base<T>::Type Type;
+         typedef typename opr_base<T>::Type    Type;
          typedef typename opr_base<T>::RefType RefType;
+
          static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
          static inline void assign(RefType t1, Type t2) { t1 = numeric::pow<T>(t1,t2); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
@@ -12141,6 +12175,7 @@ namespace exprtk
       struct lt_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
@@ -12151,6 +12186,7 @@ namespace exprtk
       struct lte_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
@@ -12161,6 +12197,7 @@ namespace exprtk
       struct gt_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
@@ -12171,6 +12208,7 @@ namespace exprtk
       struct gte_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
@@ -12191,6 +12229,7 @@ namespace exprtk
       struct equal_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
@@ -12201,6 +12240,7 @@ namespace exprtk
       struct ne_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
@@ -12211,6 +12251,7 @@ namespace exprtk
       struct and_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
          static inline details::operator_type operation() { return details::e_and; }
@@ -12220,6 +12261,7 @@ namespace exprtk
       struct nand_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; }
          static inline details::operator_type operation() { return details::e_nand; }
@@ -12229,6 +12271,7 @@ namespace exprtk
       struct or_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
          static inline details::operator_type operation() { return details::e_or; }
@@ -12238,6 +12281,7 @@ namespace exprtk
       struct nor_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
          static inline details::operator_type operation() { return details::e_nor; }
@@ -12247,6 +12291,7 @@ namespace exprtk
       struct xor_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
          static inline details::operator_type operation() { return details::e_xor; }
@@ -12256,6 +12301,7 @@ namespace exprtk
       struct xnor_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
          static inline details::operator_type operation() { return details::e_xnor; }
@@ -12265,6 +12311,7 @@ namespace exprtk
       struct in_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
          static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
@@ -12275,6 +12322,7 @@ namespace exprtk
       struct like_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
          static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; }
@@ -12285,6 +12333,7 @@ namespace exprtk
       struct ilike_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
          static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; }
@@ -12295,6 +12344,7 @@ namespace exprtk
       struct inrange_op : public opr_base<T>
       {
          typedef typename opr_base<T>::Type Type;
+
          static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
          static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
          {
@@ -12563,16 +12613,16 @@ namespace exprtk
          static inline T process_4(const Sequence& arg_list)
          {
             return std::min<T>(
-                        std::min<T>(value(arg_list[0]),value(arg_list[1])),
-                        std::min<T>(value(arg_list[2]),value(arg_list[3])));
+                        std::min<T>(value(arg_list[0]), value(arg_list[1])),
+                        std::min<T>(value(arg_list[2]), value(arg_list[3])));
          }
 
          template <typename Sequence>
          static inline T process_5(const Sequence& arg_list)
          {
             return std::min<T>(
-                   std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),
-                               std::min<T>(value(arg_list[2]),value(arg_list[3]))),
+                   std::min<T>(std::min<T>(value(arg_list[0]), value(arg_list[1])),
+                               std::min<T>(value(arg_list[2]), value(arg_list[3]))),
                                value(arg_list[4]));
          }
       };
@@ -12634,16 +12684,16 @@ namespace exprtk
          static inline T process_4(const Sequence& arg_list)
          {
             return std::max<T>(
-                        std::max<T>(value(arg_list[0]),value(arg_list[1])),
-                        std::max<T>(value(arg_list[2]),value(arg_list[3])));
+                        std::max<T>(value(arg_list[0]), value(arg_list[1])),
+                        std::max<T>(value(arg_list[2]), value(arg_list[3])));
          }
 
          template <typename Sequence>
          static inline T process_5(const Sequence& arg_list)
          {
             return std::max<T>(
-                   std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),
-                               std::max<T>(value(arg_list[2]),value(arg_list[3]))),
+                   std::max<T>(std::max<T>(value(arg_list[0]), value(arg_list[1])),
+                               std::max<T>(value(arg_list[2]), value(arg_list[3]))),
                                value(arg_list[4]));
          }
       };
@@ -12669,7 +12719,7 @@ namespace exprtk
                          {
                             for (std::size_t i = 0; i < arg_list.size(); ++i)
                             {
-                               if (std::equal_to<T>()(T(0),value(arg_list[i])))
+                               if (std::equal_to<T>()(T(0), value(arg_list[i])))
                                   return T(0);
                             }
 
@@ -12682,15 +12732,15 @@ namespace exprtk
          static inline T process_1(const Sequence& arg_list)
          {
             return std::not_equal_to<T>()
-                      (T(0),value(arg_list[0])) ? T(1) : T(0);
+                      (T(0), value(arg_list[0])) ? T(1) : T(0);
          }
 
          template <typename Sequence>
          static inline T process_2(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[1]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[1]))
                    ) ? T(1) : T(0);
          }
 
@@ -12698,9 +12748,9 @@ namespace exprtk
          static inline T process_3(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[2]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[2]))
                    ) ? T(1) : T(0);
          }
 
@@ -12708,10 +12758,10 @@ namespace exprtk
          static inline T process_4(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[3]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[2])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[3]))
                    ) ? T(1) : T(0);
          }
 
@@ -12719,11 +12769,11 @@ namespace exprtk
          static inline T process_5(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[3])) &&
-                     std::not_equal_to<T>()(T(0),value(arg_list[4]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[2])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[3])) &&
+                     std::not_equal_to<T>()(T(0), value(arg_list[4]))
                    ) ? T(1) : T(0);
          }
       };
@@ -12749,7 +12799,7 @@ namespace exprtk
                          {
                             for (std::size_t i = 0; i < arg_list.size(); ++i)
                             {
-                               if (std::not_equal_to<T>()(T(0),value(arg_list[i])))
+                               if (std::not_equal_to<T>()(T(0), value(arg_list[i])))
                                   return T(1);
                             }
 
@@ -12762,15 +12812,15 @@ namespace exprtk
          static inline T process_1(const Sequence& arg_list)
          {
             return std::not_equal_to<T>()
-                      (T(0),value(arg_list[0])) ? T(1) : T(0);
+                      (T(0), value(arg_list[0])) ? T(1) : T(0);
          }
 
          template <typename Sequence>
          static inline T process_2(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[1]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[1]))
                    ) ? T(1) : T(0);
          }
 
@@ -12778,9 +12828,9 @@ namespace exprtk
          static inline T process_3(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[2]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[2]))
                    ) ? T(1) : T(0);
          }
 
@@ -12788,10 +12838,10 @@ namespace exprtk
          static inline T process_4(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[3]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[2])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[3]))
                    ) ? T(1) : T(0);
          }
 
@@ -12799,11 +12849,11 @@ namespace exprtk
          static inline T process_5(const Sequence& arg_list)
          {
             return (
-                     std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[3])) ||
-                     std::not_equal_to<T>()(T(0),value(arg_list[4]))
+                     std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[2])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[3])) ||
+                     std::not_equal_to<T>()(T(0), value(arg_list[4]))
                    ) ? T(1) : T(0);
          }
       };
@@ -13715,15 +13765,15 @@ namespace exprtk
       template <typename T, typename T0, typename T1>                                                           \
       const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
 
-      synthesis_node_type_define(const T0&,const T1&, e_vov)
-      synthesis_node_type_define(const T0&,const T1 , e_voc)
-      synthesis_node_type_define(const T0 ,const T1&, e_cov)
-      synthesis_node_type_define(      T0&,      T1&,e_none)
-      synthesis_node_type_define(const T0 ,const T1 ,e_none)
-      synthesis_node_type_define(      T0&,const T1 ,e_none)
-      synthesis_node_type_define(const T0 ,      T1&,e_none)
-      synthesis_node_type_define(const T0&,      T1&,e_none)
-      synthesis_node_type_define(      T0&,const T1&,e_none)
+      synthesis_node_type_define(const T0&, const T1&,  e_vov)
+      synthesis_node_type_define(const T0&, const T1 ,  e_voc)
+      synthesis_node_type_define(const T0 , const T1&,  e_cov)
+      synthesis_node_type_define(      T0&,       T1&, e_none)
+      synthesis_node_type_define(const T0 , const T1 , e_none)
+      synthesis_node_type_define(      T0&, const T1 , e_none)
+      synthesis_node_type_define(const T0 ,       T1&, e_none)
+      synthesis_node_type_define(const T0&,       T1&, e_none)
+      synthesis_node_type_define(      T0&, const T1&, e_none)
       #undef synthesis_node_type_define
 
       template <typename T, typename T0, typename T1, typename T2>
@@ -13737,15 +13787,15 @@ namespace exprtk
       template <typename T, typename T0, typename T1, typename T2>                                                     \
       const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
 
-      synthesis_node_type_define(const T0&,const T1&,const T2&, e_vovov)
-      synthesis_node_type_define(const T0&,const T1&,const T2 , e_vovoc)
-      synthesis_node_type_define(const T0&,const T1 ,const T2&, e_vocov)
-      synthesis_node_type_define(const T0 ,const T1&,const T2&, e_covov)
-      synthesis_node_type_define(const T0 ,const T1&,const T2 , e_covoc)
-      synthesis_node_type_define(const T0 ,const T1 ,const T2 , e_none )
-      synthesis_node_type_define(const T0 ,const T1 ,const T2&, e_none )
-      synthesis_node_type_define(const T0&,const T1 ,const T2 , e_none )
-      synthesis_node_type_define(      T0&,      T1&,      T2&, e_none )
+      synthesis_node_type_define(const T0&, const T1&, const T2&, e_vovov)
+      synthesis_node_type_define(const T0&, const T1&, const T2 , e_vovoc)
+      synthesis_node_type_define(const T0&, const T1 , const T2&, e_vocov)
+      synthesis_node_type_define(const T0 , const T1&, const T2&, e_covov)
+      synthesis_node_type_define(const T0 , const T1&, const T2 , e_covoc)
+      synthesis_node_type_define(const T0 , const T1 , const T2 , e_none )
+      synthesis_node_type_define(const T0 , const T1 , const T2&, e_none )
+      synthesis_node_type_define(const T0&, const T1 , const T2 , e_none )
+      synthesis_node_type_define(      T0&,       T1&,       T2&, e_none )
       #undef synthesis_node_type_define
 
       template <typename T, typename T0, typename T1, typename T2, typename T3>
@@ -13759,22 +13809,22 @@ namespace exprtk
       template <typename T, typename T0, typename T1, typename T2, typename T3>                                               \
       const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
 
-      synthesis_node_type_define(const T0&,const T1&,const T2&, const T3&,e_vovovov)
-      synthesis_node_type_define(const T0&,const T1&,const T2&, const T3 ,e_vovovoc)
-      synthesis_node_type_define(const T0&,const T1&,const T2 , const T3&,e_vovocov)
-      synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3&,e_vocovov)
-      synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3&,e_covovov)
-      synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3&,e_covocov)
-      synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc)
-      synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3 ,e_covovoc)
-      synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3&,e_vococov)
-      synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3 ,e_none   )
-      synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3&,e_none   )
-      synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3 ,e_none   )
-      synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3 ,e_none   )
-      synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3 ,e_none   )
-      synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3&,e_none   )
-      synthesis_node_type_define(const T0&,const T1&,const T2 , const T3 ,e_none   )
+      synthesis_node_type_define(const T0&, const T1&, const T2&, const T3&, e_vovovov)
+      synthesis_node_type_define(const T0&, const T1&, const T2&, const T3 , e_vovovoc)
+      synthesis_node_type_define(const T0&, const T1&, const T2 , const T3&, e_vovocov)
+      synthesis_node_type_define(const T0&, const T1 , const T2&, const T3&, e_vocovov)
+      synthesis_node_type_define(const T0 , const T1&, const T2&, const T3&, e_covovov)
+      synthesis_node_type_define(const T0 , const T1&, const T2 , const T3&, e_covocov)
+      synthesis_node_type_define(const T0&, const T1 , const T2&, const T3 , e_vocovoc)
+      synthesis_node_type_define(const T0 , const T1&, const T2&, const T3 , e_covovoc)
+      synthesis_node_type_define(const T0&, const T1 , const T2 , const T3&, e_vococov)
+      synthesis_node_type_define(const T0 , const T1 , const T2 , const T3 , e_none   )
+      synthesis_node_type_define(const T0 , const T1 , const T2 , const T3&, e_none   )
+      synthesis_node_type_define(const T0 , const T1 , const T2&, const T3 , e_none   )
+      synthesis_node_type_define(const T0 , const T1&, const T2 , const T3 , e_none   )
+      synthesis_node_type_define(const T0&, const T1 , const T2 , const T3 , e_none   )
+      synthesis_node_type_define(const T0 , const T1 , const T2&, const T3&, e_none   )
+      synthesis_node_type_define(const T0&, const T1&, const T2 , const T3 , e_none   )
       #undef synthesis_node_type_define
 
       template <typename T, typename T0, typename T1>
@@ -13876,7 +13926,7 @@ namespace exprtk
 
          inline T value() const
          {
-            return ProcessMode::process(t0_,t1_,t2_,f0_,f1_);
+            return ProcessMode::process(t0_, t1_, t2_, f0_, f1_);
          }
 
          inline T0 t0() const
@@ -14006,7 +14056,7 @@ namespace exprtk
 
          static inline std::string id()
          {
-            return process_mode_t::template id<T0,T1,T2,T3>();
+            return process_mode_t::template id<T0, T1, T2, T3>();
          }
 
          template <typename Allocator>
@@ -14358,7 +14408,7 @@ namespace exprtk
 
          inline T3 t3() const
          {
-            return t2_;
+            return t3_;
          }
 
          std::string type_id() const
@@ -14411,27 +14461,27 @@ namespace exprtk
       template <typename T, typename T0, typename T1>
       struct T0oT1_define
       {
-         typedef details::T0oT1<T,T0,T1> type0;
+         typedef details::T0oT1<T, T0, T1> type0;
       };
 
       template <typename T, typename T0, typename T1, typename T2>
       struct T0oT1oT2_define
       {
-         typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode0> type0;
-         typedef details::T0oT1oT2<T,T0,T1,T2,typename T0oT1oT2process<T>::mode1> type1;
-         typedef details::T0oT1oT2_sf3<T,T0,T1,T2> sf3_type;
-         typedef details::sf3ext_type_node<T,T0,T1,T2> sf3_type_node;
+         typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode0> type0;
+         typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode1> type1;
+         typedef details::T0oT1oT2_sf3<T, T0, T1, T2> sf3_type;
+         typedef details::sf3ext_type_node<T, T0, T1, T2> sf3_type_node;
       };
 
       template <typename T, typename T0, typename T1, typename T2, typename T3>
       struct T0oT1oT2oT3_define
       {
-         typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode0> type0;
-         typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode1> type1;
-         typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode2> type2;
-         typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode3> type3;
-         typedef details::T0oT1oT2oT3<T,T0,T1,T2,T3,typename T0oT1oT20T3process<T>::mode4> type4;
-         typedef details::T0oT1oT2oT3_sf4<T,T0,T1,T2,T3> sf4_type;
+         typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode0> type0;
+         typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode1> type1;
+         typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode2> type2;
+         typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode3> type3;
+         typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode4> type4;
+         typedef details::T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> sf4_type;
       };
 
       template <typename T, typename Operation>
@@ -16042,8 +16092,9 @@ namespace exprtk
 
       enum return_type
       {
-         e_rtrn_scalar = 0,
-         e_rtrn_string = 1
+         e_rtrn_scalar   = 0,
+         e_rtrn_string   = 1,
+         e_rtrn_overload = 2
       };
 
       typedef T type;
@@ -16115,7 +16166,7 @@ namespace exprtk
        {
           using exprtk::ifunction<T>::operator();
 
-          freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
+          explicit freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
           inline T operator() ()
           { return f(); }
           ff00_functor f;
@@ -16125,7 +16176,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
+         explicit freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
          inline T operator() (const T& v0)
          { return f(v0); }
          ff01_functor f;
@@ -16135,7 +16186,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
+         explicit freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
          inline T operator() (const T& v0, const T& v1)
          { return f(v0, v1); }
          ff02_functor f;
@@ -16145,7 +16196,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
+         explicit freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
          inline T operator() (const T& v0, const T& v1, const T& v2)
          { return f(v0, v1, v2); }
          ff03_functor f;
@@ -16155,7 +16206,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3); }
          ff04_functor f;
@@ -16165,7 +16216,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4); }
          ff05_functor f;
@@ -16175,7 +16226,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4, v5); }
          ff06_functor f;
@@ -16185,7 +16236,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4, v5, v6); }
@@ -16196,7 +16247,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4, v5, v6, v7); }
@@ -16207,7 +16258,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); }
@@ -16218,7 +16269,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); }
@@ -16229,7 +16280,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {}
+         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)
          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); }
@@ -16240,7 +16291,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {}
+         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)
@@ -16252,7 +16303,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {}
+         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)
@@ -16264,7 +16315,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {}
+         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)
@@ -16276,7 +16327,7 @@ namespace exprtk
       {
          using exprtk::ifunction<T>::operator();
 
-         freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {}
+         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)
@@ -16699,6 +16750,7 @@ namespace exprtk
             type_store<ivararg_function <T>,ivararg_function <T> > vararg_function_store;
             type_store<igeneric_function<T>,igeneric_function<T> > generic_function_store;
             type_store<igeneric_function<T>,igeneric_function<T> > string_function_store;
+            type_store<igeneric_function<T>,igeneric_function<T> > overload_function_store;
             type_store<vector_holder_t,vector_holder_t>            vector_store;
 
             st_data()
@@ -16749,7 +16801,7 @@ namespace exprtk
            data_(st_data::create())
          {}
 
-         control_block(st_data* data)
+         explicit control_block(st_data* data)
          : ref_count(1),
            data_(data)
          {}
@@ -16970,6 +17022,16 @@ namespace exprtk
             return local_data().string_function_store.get(function_name);
       }
 
+      inline generic_function_ptr get_overload_function(const std::string& function_name) const
+      {
+         if (!valid())
+            return reinterpret_cast<generic_function_ptr>(0);
+         else if (!valid_symbol(function_name))
+            return reinterpret_cast<generic_function_ptr>(0);
+         else
+            return local_data().overload_function_store.get(function_name);
+      }
+
       typedef vector_holder_t* vector_holder_ptr;
 
       inline vector_holder_ptr get_vector(const std::string& vector_name) const
@@ -17071,7 +17133,7 @@ namespace exprtk
          else if (symbol_exists(variable_name))
             return false;
          else
-            return local_data().variable_store.add(variable_name,t,is_constant);
+            return local_data().variable_store.add(variable_name, t, is_constant);
       }
 
       inline bool add_constant(const std::string& constant_name, const T& value)
@@ -17086,7 +17148,7 @@ namespace exprtk
          local_data().local_symbol_list_.push_back(value);
          T& t = local_data().local_symbol_list_.back();
 
-         return add_variable(constant_name,t,true);
+         return add_variable(constant_name, t, true);
       }
 
       #ifndef exprtk_disable_string_capabilities
@@ -17099,7 +17161,7 @@ namespace exprtk
          else if (symbol_exists(stringvar_name))
             return false;
          else
-            return local_data().stringvar_store.add(stringvar_name,s,is_constant);
+            return local_data().stringvar_store.add(stringvar_name, s, is_constant);
       }
       #endif
 
@@ -17135,14 +17197,33 @@ namespace exprtk
             return false;
          else if (symbol_exists(function_name))
             return false;
-         else if (std::string::npos != function.parameter_sequence.find_first_not_of("STVZ*?|"))
+         else if (
+                   (
+                     (generic_function_t::e_rtrn_scalar == function.rtrn_type) ||
+                     (generic_function_t::e_rtrn_string == function.rtrn_type)
+                   ) &&
+                   std::string::npos != function.parameter_sequence.find_first_not_of("STVZ*?|")
+                 )
             return false;
-         else if (generic_function_t::e_rtrn_scalar == function.rtrn_type)
-            return local_data().generic_function_store.add(function_name,function);
-         else if (generic_function_t::e_rtrn_string == function.rtrn_type)
-            return local_data().string_function_store.add(function_name, function);
-         else
+         else if (
+                   (generic_function_t::e_rtrn_overload  == function.rtrn_type) &&
+                   std::string::npos != function.parameter_sequence.find_first_not_of("STVZ*?|:")
+                 )
             return false;
+
+         switch (function.rtrn_type)
+         {
+            case generic_function_t::e_rtrn_scalar :
+               return local_data().generic_function_store.add(function_name,function);
+
+            case generic_function_t::e_rtrn_string :
+               return local_data().string_function_store.add(function_name,function);
+
+            case generic_function_t::e_rtrn_overload :
+               return local_data().overload_function_store.add(function_name,function);
+         }
+
+         return false;
       }
 
       #define exprtk_define_freefunction(NN)                                                \
@@ -17205,14 +17286,33 @@ namespace exprtk
             return false;
          else if (symbol_exists(function_name,false))
             return false;
-         else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
+         else if (
+                   (
+                     (generic_function_t::e_rtrn_scalar == function.rtrn_type) ||
+                     (generic_function_t::e_rtrn_string == function.rtrn_type)
+                   ) &&
+                   std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|")
+                 )
             return false;
-         else if (generic_function_t::e_rtrn_scalar == function.rtrn_type)
-            return local_data().generic_function_store.add(function_name,function);
-         else if (generic_function_t::e_rtrn_string == function.rtrn_type)
-            return local_data().string_function_store.add(function_name, function);
-         else
+         else if (
+                   generic_function_t::e_rtrn_overload &&
+                   std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|:")
+                 )
             return false;
+
+         switch (function.rtrn_type)
+         {
+            case generic_function_t::e_rtrn_scalar :
+               return local_data().generic_function_store.add(function_name,function);
+
+            case generic_function_t::e_rtrn_string :
+               return local_data().string_function_store.add(function_name,function);
+
+            case generic_function_t::e_rtrn_overload :
+               return local_data().overload_function_store.add(function_name,function);
+         }
+
+         return false;
       }
 
       template <std::size_t N>
@@ -17239,7 +17339,7 @@ namespace exprtk
          else if (0 == v_size)
             return false;
          else
-            return local_data().vector_store.add(vector_name,v,v_size);
+            return local_data().vector_store.add(vector_name, v, v_size);
       }
 
       template <typename Allocator>
@@ -17568,6 +17668,21 @@ namespace exprtk
                }
             }
          }
+
+         {
+            std::vector<std::string> name_list;
+
+            st.local_data().overload_function_store.get_list(name_list);
+
+            if (!name_list.empty())
+            {
+               for (std::size_t i = 0; i < name_list.size(); ++i)
+               {
+                  exprtk::igeneric_function<T>& ifunc = *st.get_overload_function(name_list[i]);
+                  add_function(name_list[i],ifunc);
+               }
+            }
+         }
       }
 
    private:
@@ -17695,7 +17810,7 @@ namespace exprtk
            return_invoked(&retinv_null)
          {}
 
-         control_block(expression_ptr e)
+         explicit control_block(expression_ptr e)
          : ref_count(1),
            expr     (e),
            results  (0),
@@ -17788,7 +17903,7 @@ namespace exprtk
          control_block_->ref_count++;
       }
 
-      expression(const symbol_table<T>& symbol_table)
+      explicit expression(const symbol_table<T>& symbol_table)
       : control_block_(0)
       {
          set_expression(new details::null_node<T>());
@@ -18004,7 +18119,7 @@ namespace exprtk
       }
 
       control_block* control_block_;
-      symtab_list_t      symbol_table_list_;
+      symtab_list_t  symbol_table_list_;
 
       friend class parser<T>;
       friend class expression_helper<T>;
@@ -18409,7 +18524,7 @@ namespace exprtk
          typedef variable_node_t*     variable_node_ptr;
          typedef parser<T>                     parser_t;
 
-         scope_element_manager(parser<T>& p)
+         explicit scope_element_manager(parser<T>& p)
          : parser_(p),
            input_param_cnt_(0)
          {}
@@ -18520,6 +18635,10 @@ namespace exprtk
 
          inline void free_element(scope_element& se)
          {
+            #ifdef exprtk_enable_debugging
+            exprtk_debug(("free_element() - se[%s]\n", se.name.c_str()));
+            #endif
+
             switch (se.type)
             {
                case scope_element::e_variable   : if (se.data    ) delete (T*) se.data;
@@ -18602,7 +18721,7 @@ namespace exprtk
 
          typedef parser<T> parser_t;
 
-         scope_handler(parser<T>& p)
+         explicit scope_handler(parser<T>& p)
          : parser_(p)
          {
             parser_.state_.scope_depth++;
@@ -18833,6 +18952,27 @@ namespace exprtk
             return result;
          }
 
+         inline generic_function_ptr get_overload_function(const std::string& function_name) const
+         {
+            if (!valid_function_name(function_name))
+               return reinterpret_cast<generic_function_ptr>(0);
+
+            generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
+
+            for (std::size_t i = 0; i < symtab_list_.size(); ++i)
+            {
+               if (!symtab_list_[i].valid())
+                  continue;
+               else
+                  result =
+                     local_data(i).overload_function_store.get(function_name);
+
+               if (result) break;
+            }
+
+            return result;
+         }
+
          inline vector_holder_ptr get_vector(const std::string& vector_name) const
          {
             if (!valid_symbol(vector_name))
@@ -19528,7 +19668,7 @@ namespace exprtk
          bool rsrvd_sym_usr_disabled     () const { return disable_rsrvd_sym_usr_;     }
          bool zero_return_disabled       () const { return disable_zero_return_;       }
 
-         bool function_enabled(const std::string& function_name)
+         bool function_enabled(const std::string& function_name) const
          {
             if (disabled_func_set_.empty())
                return true;
@@ -19536,7 +19676,7 @@ namespace exprtk
                return (disabled_func_set_.end() == disabled_func_set_.find(function_name));
          }
 
-         bool control_struct_enabled(const std::string& control_struct)
+         bool control_struct_enabled(const std::string& control_struct) const
          {
             if (disabled_ctrl_set_.empty())
                return true;
@@ -19544,7 +19684,7 @@ namespace exprtk
                return (disabled_ctrl_set_.end() == disabled_ctrl_set_.find(control_struct));
          }
 
-         bool logic_enabled(const std::string& logic_operation)
+         bool logic_enabled(const std::string& logic_operation) const
          {
             if (disabled_logic_set_.empty())
                return true;
@@ -19552,7 +19692,7 @@ namespace exprtk
                return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation));
          }
 
-         bool arithmetic_enabled(const details::operator_type& arithmetic_operation)
+         bool arithmetic_enabled(const details::operator_type& arithmetic_operation) const
          {
             if (disabled_logic_set_.empty())
                return true;
@@ -19561,7 +19701,7 @@ namespace exprtk
                                                             .find(arith_opr_to_string(arithmetic_operation));
          }
 
-         bool assignment_enabled(const details::operator_type& assignment)
+         bool assignment_enabled(const details::operator_type& assignment) const
          {
             if (disabled_assignment_set_.empty())
                return true;
@@ -19570,7 +19710,7 @@ namespace exprtk
                                                            .find(assign_opr_to_string(assignment));
          }
 
-         bool inequality_enabled(const details::operator_type& inequality)
+         bool inequality_enabled(const details::operator_type& inequality) const
          {
             if (disabled_inequality_set_.empty())
                return true;
@@ -19579,7 +19719,7 @@ namespace exprtk
                                                            .find(inequality_opr_to_string(inequality));
          }
 
-         bool function_disabled(const std::string& function_name)
+         bool function_disabled(const std::string& function_name) const
          {
             if (disabled_func_set_.empty())
                return false;
@@ -19587,7 +19727,7 @@ namespace exprtk
                return (disabled_func_set_.end() != disabled_func_set_.find(function_name));
          }
 
-         bool control_struct_disabled(const std::string& control_struct)
+         bool control_struct_disabled(const std::string& control_struct) const
          {
             if (disabled_ctrl_set_.empty())
                return false;
@@ -19595,7 +19735,7 @@ namespace exprtk
                return (disabled_ctrl_set_.end() != disabled_ctrl_set_.find(control_struct));
          }
 
-         bool logic_disabled(const std::string& logic_operation)
+         bool logic_disabled(const std::string& logic_operation) const
          {
             if (disabled_logic_set_.empty())
                return false;
@@ -19603,7 +19743,7 @@ namespace exprtk
                return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation));
          }
 
-         bool assignment_disabled(const details::operator_type assignment_operation)
+         bool assignment_disabled(const details::operator_type assignment_operation) const
          {
             if (disabled_assignment_set_.empty())
                return false;
@@ -19612,7 +19752,16 @@ namespace exprtk
                                                            .find(assign_opr_to_string(assignment_operation));
          }
 
-         bool arithmetic_disabled(const details::operator_type arithmetic_operation)
+         bool logic_disabled(const details::operator_type logic_operation) const
+         {
+            if (disabled_logic_set_.empty())
+               return false;
+            else
+               return disabled_logic_set_.end() != disabled_logic_set_
+                                                           .find(logic_opr_to_string(logic_operation));
+         }
+
+         bool arithmetic_disabled(const details::operator_type arithmetic_operation) const
          {
             if (disabled_arithmetic_set_.empty())
                return false;
@@ -19621,7 +19770,7 @@ namespace exprtk
                                                            .find(arith_opr_to_string(arithmetic_operation));
          }
 
-         bool inequality_disabled(const details::operator_type& inequality)
+         bool inequality_disabled(const details::operator_type& inequality) const
          {
             if (disabled_inequality_set_.empty())
                return false;
@@ -19835,7 +19984,7 @@ namespace exprtk
             disable_zero_return_       = (compile_options & e_disable_zero_return ) == e_disable_zero_return;
          }
 
-         std::string assign_opr_to_string(details::operator_type opr)
+         std::string assign_opr_to_string(details::operator_type opr) const
          {
             switch (opr)
             {
@@ -19849,7 +19998,7 @@ namespace exprtk
             }
          }
 
-         std::string arith_opr_to_string(details::operator_type opr)
+         std::string arith_opr_to_string(details::operator_type opr) const
          {
             switch (opr)
             {
@@ -19862,7 +20011,7 @@ namespace exprtk
             }
          }
 
-         std::string inequality_opr_to_string(details::operator_type opr)
+         std::string inequality_opr_to_string(details::operator_type opr) const
          {
             switch (opr)
             {
@@ -19878,6 +20027,21 @@ namespace exprtk
             }
          }
 
+         std::string logic_opr_to_string(details::operator_type opr) const
+         {
+            switch (opr)
+            {
+               case details::e_and  : return "and" ;
+               case details::e_or   : return "or"  ;
+               case details::e_xor  : return "xor" ;
+               case details::e_nand : return "nand";
+               case details::e_nor  : return "nor" ;
+               case details::e_xnor : return "xnor";
+               case details::e_notl : return "not" ;
+               default              : return ""    ;
+            }
+         }
+
          bool enable_replacer_;
          bool enable_joiner_;
          bool enable_numeric_check_;
@@ -19956,8 +20120,8 @@ namespace exprtk
          if (settings_.replacer_enabled())
          {
             symbol_replacer_.clear();
-            symbol_replacer_.add_replace("true" ,"1",lexer::token::e_number);
-            symbol_replacer_.add_replace("false","0",lexer::token::e_number);
+            symbol_replacer_.add_replace("true" , "1", lexer::token::e_number);
+            symbol_replacer_.add_replace("false", "0", lexer::token::e_number);
             helper_assembly_.token_modifier_list.clear();
             helper_assembly_.register_modifier(&symbol_replacer_);
          }
@@ -20067,7 +20231,7 @@ namespace exprtk
                dec_.return_present_ = true;
 
                e = expression_generator_
-                     .return_envelope(e,results_context_,retinvk_ptr);
+                     .return_envelope(e, results_context_, retinvk_ptr);
             }
 
             expr.set_expression(e);
@@ -20089,15 +20253,15 @@ namespace exprtk
                              exprtk_error_location));
             }
 
-            dec_.clear    ();
-            sem_.cleanup  ();
-            return_cleanup();
-
             if ((0 != e) && branch_deletable(e))
             {
                destroy_node(e);
             }
 
+            dec_.clear    ();
+            sem_.cleanup  ();
+            return_cleanup();
+
             return false;
          }
       }
@@ -20262,7 +20426,7 @@ namespace exprtk
          return settings_;
       }
 
-      inline parser_error::type get_error(const std::size_t& index)
+      inline parser_error::type get_error(const std::size_t& index) const
       {
          if (index < error_list_.size())
             return error_list_[index];
@@ -20333,7 +20497,7 @@ namespace exprtk
 
    private:
 
-      inline bool valid_base_operation(const std::string& symbol)
+      inline bool valid_base_operation(const std::string& symbol) const
       {
          const std::size_t length = symbol.size();
 
@@ -20347,7 +20511,7 @@ namespace exprtk
                    (base_ops_map_.end() != base_ops_map_.find(symbol));
       }
 
-      inline bool valid_vararg_operation(const std::string& symbol)
+      inline bool valid_vararg_operation(const std::string& symbol) const
       {
          static const std::string s_sum     = "sum" ;
          static const std::string s_mul     = "mul" ;
@@ -20374,17 +20538,22 @@ namespace exprtk
                settings_.function_enabled(symbol);
       }
 
-      bool is_invalid_arithmetic_operation(const details::operator_type operation)
+      bool is_invalid_logic_operation(const details::operator_type operation) const
+      {
+         return settings_.logic_disabled(operation);
+      }
+
+      bool is_invalid_arithmetic_operation(const details::operator_type operation) const
       {
          return settings_.arithmetic_disabled(operation);
       }
 
-      bool is_invalid_assignment_operation(const details::operator_type operation)
+      bool is_invalid_assignment_operation(const details::operator_type operation) const
       {
          return settings_.assignment_disabled(operation);
       }
 
-      bool is_invalid_inequality_operation(const details::operator_type operation)
+      bool is_invalid_inequality_operation(const details::operator_type operation) const
       {
          return settings_.inequality_disabled(operation);
       }
@@ -20408,8 +20577,6 @@ namespace exprtk
          std::vector<expression_node_ptr> arg_list;
          std::vector<bool> side_effect_list;
 
-         expression_node_ptr result = error_node();
-
          scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
 
          lexer::token begin_token;
@@ -20476,7 +20643,7 @@ namespace exprtk
             dec_.final_stmt_return_ = true;
          }
 
-         result = simplify(arg_list,side_effect_list);
+         const expression_node_ptr result = simplify(arg_list,side_effect_list);
 
          sdd.delete_ptr = (0 == result);
 
@@ -20539,25 +20706,25 @@ 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;
+               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";
@@ -20660,14 +20827,26 @@ namespace exprtk
             expression_node_ptr right_branch   = error_node();
             expression_node_ptr new_expression = error_node();
 
-            if (is_invalid_arithmetic_operation(current_state.operation))
+            if (is_invalid_logic_operation(current_state.operation))
             {
                free_node(node_allocator_,expression);
 
                set_error(
                   make_error(parser_error::e_syntax,
                              prev_token,
-                             "ERR009 - Invalid arithmetic operation '" + details::to_str(current_state.operation) + "'",
+                             "ERR009 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'",
+                             exprtk_error_location));
+
+               return error_node();
+            }
+            else if (is_invalid_arithmetic_operation(current_state.operation))
+            {
+               free_node(node_allocator_,expression);
+
+               set_error(
+                  make_error(parser_error::e_syntax,
+                             prev_token,
+                             "ERR010 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -20679,7 +20858,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              prev_token,
-                             "ERR010 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
+                             "ERR011 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -20691,7 +20870,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              prev_token,
-                             "ERR011 - Invalid assignment operation '" + details::to_str(current_state.operation) + "'",
+                             "ERR012 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -20710,7 +20889,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 prev_token,
-                                "ERR012 - Return statements cannot be part of sub-expressions",
+                                "ERR013 - Return statements cannot be part of sub-expressions",
                                 exprtk_error_location));
 
                   return error_node();
@@ -20733,7 +20912,7 @@ namespace exprtk
                                 prev_token,
                                 !synthesis_error_.empty() ?
                                 synthesis_error_ :
-                                "ERR013 - General parsing error at token: '" + prev_token.value + "'",
+                                "ERR014 - General parsing error at token: '" + prev_token.value + "'",
                                 exprtk_error_location));
                }
 
@@ -20803,7 +20982,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR014 - Failed to find variable node in symbol table",
+                                "ERR015 - Failed to find variable node in symbol table",
                                 exprtk_error_location));
 
                   free_node(node_allocator_,node);
@@ -20926,7 +21105,7 @@ namespace exprtk
 
       struct scoped_bool_negator
       {
-         scoped_bool_negator(bool& bb)
+         explicit scoped_bool_negator(bool& bb)
          : b(bb)
          { b = !b; }
 
@@ -20938,7 +21117,7 @@ namespace exprtk
 
       struct scoped_bool_or_restorer
       {
-         scoped_bool_or_restorer(bool& bb)
+         explicit scoped_bool_or_restorer(bool& bb)
          : b(bb),
            original_value_(bb)
          {}
@@ -20983,7 +21162,7 @@ namespace exprtk
                          set_error(
                             make_error(parser_error::e_syntax,
                                        current_token(),
-                                       "ERR015 - Invalid number of parameters for function: '" + function_name + "'",
+                                       "ERR016 - Invalid number of parameters for function: '" + function_name + "'",
                                        exprtk_error_location));
 
                          return error_node();
@@ -20997,7 +21176,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR016 - Failed to generate call to function: '" + function_name + "'",
+                          "ERR017 - Failed to generate call to function: '" + function_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -21016,7 +21195,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR017 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
+                          "ERR018 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
                           exprtk_error_location));
 
             return error_node();
@@ -21039,7 +21218,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR018 - Expecting argument list for function: '" + function_name + "'",
+                          "ERR019 - Expecting argument list for function: '" + function_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -21054,7 +21233,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR019 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
+                             "ERR020 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -21066,7 +21245,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR020 - Invalid number of arguments for function: '" + function_name + "'",
+                                "ERR021 - Invalid number of arguments for function: '" + function_name + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21079,7 +21258,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR021 - Invalid number of arguments for function: '" + function_name + "'",
+                          "ERR022 - Invalid number of arguments for function: '" + function_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -21108,7 +21287,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR022 - Expecting '()' to proceed call to function: '" + function_name + "'",
+                          "ERR023 - Expecting '()' to proceed call to function: '" + function_name + "'",
                           exprtk_error_location));
 
             free_node(node_allocator_,result);
@@ -21133,7 +21312,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR023 - Expected a '(' at start of function call to '" + function_name  +
+                          "ERR024 - Expected a '(' at start of function call to '" + function_name  +
                           "', instead got: '" + current_token().value + "'",
                           exprtk_error_location));
 
@@ -21145,7 +21324,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR024 - Expected at least one input parameter for function call '" + function_name + "'",
+                          "ERR025 - Expected at least one input parameter for function call '" + function_name + "'",
                           exprtk_error_location));
 
             return 0;
@@ -21171,7 +21350,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR025 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
+                             "ERR026 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
                              exprtk_error_location));
 
                return 0;
@@ -21183,7 +21362,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR026 - Invalid number of input parameters passed to function '" + function_name  + "'",
+                          "ERR027 - Invalid number of input parameters passed to function '" + function_name  + "'",
                           exprtk_error_location));
 
             return 0;
@@ -21206,7 +21385,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           diagnostic_token,
-                          "ERR027 - No entry found for base operation: " + operation_name,
+                          "ERR028 - No entry found for base operation: " + operation_name,
                           exprtk_error_location));
 
             return error_node();
@@ -21221,7 +21400,7 @@ namespace exprtk
          {
             for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
             {
-               details::base_operation_t& operation = itr->second;
+               const details::base_operation_t& operation = itr->second;
 
                if (operation.num_params == parameter_count)
                {
@@ -21253,7 +21432,7 @@ namespace exprtk
          set_error(
             make_error(parser_error::e_syntax,
                        diagnostic_token,
-                       "ERR028 - Invalid number of input parameters for call to function: '" + operation_name + "'",
+                       "ERR029 - Invalid number of input parameters for call to function: '" + operation_name + "'",
                        exprtk_error_location));
 
          return error_node();
@@ -21273,7 +21452,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR029 - Expected ',' between if-statement condition and consequent",
+                          "ERR030 - Expected ',' between if-statement condition and consequent",
                           exprtk_error_location));
             result = false;
          }
@@ -21282,7 +21461,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR030 - Failed to parse consequent for if-statement",
+                          "ERR031 - Failed to parse consequent for if-statement",
                           exprtk_error_location));
             result = false;
          }
@@ -21291,7 +21470,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR031 - Expected ',' between if-statement consequent and alternative",
+                          "ERR032 - Expected ',' between if-statement consequent and alternative",
                           exprtk_error_location));
             result = false;
          }
@@ -21300,7 +21479,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR032 - Failed to parse alternative for if-statement",
+                          "ERR033 - Failed to parse alternative for if-statement",
                           exprtk_error_location));
             result = false;
          }
@@ -21309,7 +21488,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR033 - Expected ')' at the end of if-statement",
+                          "ERR034 - Expected ')' at the end of if-statement",
                           exprtk_error_location));
             result = false;
          }
@@ -21325,13 +21504,13 @@ namespace exprtk
                if (consq_is_str && alter_is_str)
                {
                   return expression_generator_
-                           .conditional_string(condition,consequent,alternative);
+                           .conditional_string(condition, consequent, alternative);
                }
 
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR034 - Return types of ternary if-statement differ",
+                             "ERR035 - Return types of ternary if-statement differ",
                              exprtk_error_location));
 
                result = false;
@@ -21349,7 +21528,7 @@ namespace exprtk
          }
          else
             return expression_generator_
-                      .conditional(condition,consequent,alternative);
+                      .conditional(condition, consequent, alternative);
       }
 
       inline expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition)
@@ -21366,7 +21545,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR035 - Failed to parse body of consequent for if-statement",
+                             "ERR036 - Failed to parse body of consequent for if-statement",
                              exprtk_error_location));
 
                result = false;
@@ -21389,7 +21568,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR036 - Expected ';' at the end of the consequent for if-statement",
+                                "ERR037 - Expected ';' at the end of the consequent for if-statement",
                                 exprtk_error_location));
 
                   result = false;
@@ -21400,7 +21579,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR037 - Failed to parse body of consequent for if-statement",
+                             "ERR038 - Failed to parse body of consequent for if-statement",
                              exprtk_error_location));
 
                result = false;
@@ -21420,7 +21599,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR038 - Failed to parse body of the 'else' for if-statement",
+                                   "ERR039 - Failed to parse body of the 'else' for if-statement",
                                    exprtk_error_location));
 
                      result = false;
@@ -21433,7 +21612,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR039 - Failed to parse body of if-else statement",
+                                   "ERR040 - Failed to parse body of if-else statement",
                                    exprtk_error_location));
 
                      result = false;
@@ -21446,7 +21625,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR040 - Expected ';' at the end of the 'else-if' for the if-statement",
+                                   "ERR041 - Expected ';' at the end of the 'else-if' for the if-statement",
                                    exprtk_error_location));
 
                      result = false;
@@ -21457,7 +21636,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR041 - Failed to parse body of the 'else' for if-statement",
+                                "ERR042 - Failed to parse body of the 'else' for if-statement",
                                 exprtk_error_location));
 
                   result = false;
@@ -21482,7 +21661,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR042 - Return types of ternary if-statement differ",
+                             "ERR043 - Return types of ternary if-statement differ",
                              exprtk_error_location));
 
                result = false;
@@ -21514,7 +21693,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR043 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
+                          "ERR044 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -21524,7 +21703,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR044 - Failed to parse condition for if-statement",
+                          "ERR045 - Failed to parse condition for if-statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21556,7 +21735,7 @@ namespace exprtk
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR045 - Invalid if-statement",
+                       "ERR046 - Invalid if-statement",
                        exprtk_error_location));
 
          free_node(node_allocator_,condition);
@@ -21577,7 +21756,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR046 - Encountered invalid condition branch for ternary if-statement",
+                          "ERR047 - Encountered invalid condition branch for ternary if-statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21587,7 +21766,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR047 - Expected '?' after condition of ternary if-statement",
+                          "ERR048 - Expected '?' after condition of ternary if-statement",
                           exprtk_error_location));
 
             result = false;
@@ -21597,7 +21776,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR048 - Failed to parse consequent for ternary if-statement",
+                          "ERR049 - Failed to parse consequent for ternary if-statement",
                           exprtk_error_location));
 
             result = false;
@@ -21607,7 +21786,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR049 - Expected ':' between ternary if-statement consequent and alternative",
+                          "ERR050 - Expected ':' between ternary if-statement consequent and alternative",
                           exprtk_error_location));
 
             result = false;
@@ -21617,7 +21796,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR050 - Failed to parse alternative for ternary if-statement",
+                          "ERR051 - Failed to parse alternative for ternary if-statement",
                           exprtk_error_location));
 
             result = false;
@@ -21640,7 +21819,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR051 - Return types of ternary if-statement differ",
+                             "ERR052 - Return types of ternary if-statement differ",
                              exprtk_error_location));
 
                result = false;
@@ -21661,6 +21840,22 @@ namespace exprtk
                       .conditional(condition, consequent, alternative);
       }
 
+      inline expression_node_ptr parse_not_statement()
+      {
+         if (settings_.logic_disabled("not"))
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR053 - Invalid or disabled logic operation 'not'",
+                          exprtk_error_location));
+
+            return error_node();
+         }
+
+         return parse_base_operation();
+      }
+
       inline expression_node_ptr parse_while_loop()
       {
          // Parse: [while][(][test expr][)][{][expression][}]
@@ -21677,7 +21872,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR052 - Expected '(' at start of while-loop condition statement",
+                          "ERR054 - Expected '(' at start of while-loop condition statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21687,7 +21882,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR053 - Failed to parse condition for while-loop",
+                          "ERR055 - Failed to parse condition for while-loop",
                           exprtk_error_location));
 
             return error_node();
@@ -21697,7 +21892,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR054 - Expected ')' at end of while-loop condition statement",
+                          "ERR056 - Expected ')' at end of while-loop condition statement",
                           exprtk_error_location));
 
             result = false;
@@ -21712,7 +21907,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR055 - Failed to parse body of while-loop"));
+                             "ERR057 - Failed to parse body of while-loop"));
                result = false;
             }
             else if (0 == (result_node = expression_generator_.while_loop(condition,
@@ -21722,7 +21917,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR056 - Failed to synthesize while-loop",
+                             "ERR058 - Failed to synthesize while-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21764,7 +21959,7 @@ namespace exprtk
          }
          else
          {
-            token_t::token_type seperator = token_t::e_eof;
+            const token_t::token_type seperator = token_t::e_eof;
 
             scope_handler sh(*this);
 
@@ -21790,15 +21985,15 @@ namespace exprtk
                   break;
                }
 
-               bool is_next_until = peek_token_is(token_t::e_symbol) &&
-                                    peek_token_is("until");
+               const bool is_next_until = peek_token_is(token_t::e_symbol) &&
+                                          peek_token_is("until");
 
                if (!token_is(seperator) && is_next_until)
                {
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR057 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop",
+                                "ERR059 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21822,7 +22017,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR058 - Failed to parse body of repeat until loop",
+                             "ERR060 - Failed to parse body of repeat until loop",
                              exprtk_error_location));
 
                return error_node();
@@ -21836,7 +22031,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR059 - Expected '(' before condition statement of repeat until loop",
+                          "ERR061 - Expected '(' before condition statement of repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,branch);
@@ -21850,7 +22045,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR060 - Failed to parse condition for repeat until loop",
+                          "ERR062 - Failed to parse condition for repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,branch);
@@ -21862,7 +22057,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR061 - Expected ')' after condition of repeat until loop",
+                          "ERR063 - Expected ')' after condition of repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,    branch);
@@ -21883,7 +22078,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR062 - Failed to synthesize repeat until loop",
+                          "ERR064 - Failed to synthesize repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,condition);
@@ -21908,7 +22103,6 @@ namespace exprtk
 
          scope_element* se = 0;
          bool result       = true;
-         std::string loop_counter_symbol;
 
          next_token();
 
@@ -21919,7 +22113,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR063 - Expected '(' at start of for-loop",
+                          "ERR065 - Expected '(' at start of for-loop",
                           exprtk_error_location));
 
             return error_node();
@@ -21939,7 +22133,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR064 - Expected a variable at the start of initialiser section of for-loop",
+                                "ERR066 - Expected a variable at the start of initialiser section of for-loop",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21949,13 +22143,13 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR065 - Expected variable assignment of initialiser section of for-loop",
+                                "ERR067 - Expected variable assignment of initialiser section of for-loop",
                                 exprtk_error_location));
 
                   return error_node();
                }
 
-               loop_counter_symbol = current_token().value;
+               const std::string loop_counter_symbol = current_token().value;
 
                se = &sem_.get_element(loop_counter_symbol);
 
@@ -21964,7 +22158,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR066 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
+                                "ERR068 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21996,7 +22190,7 @@ namespace exprtk
                         set_error(
                            make_error(parser_error::e_syntax,
                                       current_token(),
-                                      "ERR067 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
+                                      "ERR069 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
                                       exprtk_error_location));
 
                         sem_.free_element(nse);
@@ -22018,7 +22212,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR068 - Failed to parse initialiser of for-loop",
+                             "ERR070 - Failed to parse initialiser of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22028,7 +22222,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR069 - Expected ';' after initialiser of for-loop",
+                             "ERR071 - Expected ';' after initialiser of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22042,7 +22236,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR070 - Failed to parse condition of for-loop",
+                             "ERR072 - Failed to parse condition of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22052,7 +22246,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR071 - Expected ';' after condition section of for-loop",
+                             "ERR073 - Expected ';' after condition section of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22066,7 +22260,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR072 - Failed to parse incrementor of for-loop",
+                             "ERR074 - Failed to parse incrementor of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22076,7 +22270,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR073 - Expected ')' after incrementor section of for-loop",
+                             "ERR075 - Expected ')' after incrementor section of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22092,7 +22286,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR074 - Failed to parse body of for-loop",
+                             "ERR076 - Failed to parse body of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -22106,8 +22300,6 @@ namespace exprtk
                se->ref_count--;
             }
 
-            sem_.cleanup();
-
             free_node(node_allocator_, initialiser);
             free_node(node_allocator_,   condition);
             free_node(node_allocator_, incrementor);
@@ -22144,7 +22336,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR075 - Expected keyword 'switch'",
+                          "ERR077 - Expected keyword 'switch'",
                           exprtk_error_location));
 
             return error_node();
@@ -22159,7 +22351,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR076 - Expected '{' for call to switch statement",
+                          "ERR078 - Expected '{' for call to switch statement",
                           exprtk_error_location));
 
             return error_node();
@@ -22172,7 +22364,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR077 - Expected either a 'case' or 'default' statement",
+                             "ERR079 - Expected either a 'case' or 'default' statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22189,7 +22381,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR078 - Expected ':' for case of switch statement",
+                             "ERR080 - Expected ':' for case of switch statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22204,7 +22396,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR079 - Expected ';' at end of case for switch statement",
+                             "ERR081 - Expected ';' at end of case for switch statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22230,7 +22422,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR080 - Expected ':' for default of switch statement",
+                                "ERR082 - Expected ':' for default of switch statement",
                                 exprtk_error_location));
 
                   return error_node();
@@ -22252,7 +22444,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR081 - Expected ';' at end of default for switch statement",
+                                "ERR083 - Expected ';' at end of default for switch statement",
                                 exprtk_error_location));
 
                   return error_node();
@@ -22268,7 +22460,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR082 - Expected '}' at end of switch statement",
+                          "ERR084 - Expected '}' at end of switch statement",
                           exprtk_error_location));
 
             return error_node();
@@ -22284,14 +22476,13 @@ namespace exprtk
       inline expression_node_ptr parse_multi_switch_statement()
       {
          std::vector<expression_node_ptr> arg_list;
-         expression_node_ptr result = error_node();
 
          if (!details::imatch(current_token().value,"[*]"))
          {
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR083 - Expected token '[*]'",
+                          "ERR085 - Expected token '[*]'",
                           exprtk_error_location));
 
             return error_node();
@@ -22306,7 +22497,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR084 - Expected '{' for call to [*] statement",
+                          "ERR086 - Expected '{' for call to [*] statement",
                           exprtk_error_location));
 
             return error_node();
@@ -22319,7 +22510,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR085 - Expected a 'case' statement for multi-switch",
+                             "ERR087 - Expected a 'case' statement for multi-switch",
                              exprtk_error_location));
 
                return error_node();
@@ -22337,7 +22528,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR086 - Expected ':' for case of [*] statement",
+                             "ERR088 - Expected ':' for case of [*] statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22353,7 +22544,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR087 - Expected ';' at end of case for [*] statement",
+                             "ERR089 - Expected ';' at end of case for [*] statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22367,7 +22558,7 @@ namespace exprtk
             }
             else
             {
-               arg_list.push_back(condition);
+               arg_list.push_back( condition);
                arg_list.push_back(consequent);
             }
 
@@ -22382,13 +22573,13 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR088 - Expected '}' at end of [*] statement",
+                          "ERR090 - Expected '}' at end of [*] statement",
                           exprtk_error_location));
 
             return error_node();
          }
 
-         result = expression_generator_.multi_switch_statement(arg_list);
+         const expression_node_ptr result = expression_generator_.multi_switch_statement(arg_list);
 
          svd.delete_ptr = (0 == result);
 
@@ -22398,7 +22589,6 @@ namespace exprtk
       inline expression_node_ptr parse_vararg_function()
       {
          std::vector<expression_node_ptr> arg_list;
-         expression_node_ptr result = error_node();
 
          details::operator_type opt_type = details::e_default;
          const std::string symbol = current_token().value;
@@ -22424,7 +22614,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR089 - Unsupported vararg function: " + symbol,
+                          "ERR091 - Unsupported vararg function: " + symbol,
                           exprtk_error_location));
 
             return error_node();
@@ -22432,7 +22622,7 @@ namespace exprtk
 
          scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
 
-         lodge_symbol(symbol,e_st_function);
+         lodge_symbol(symbol, e_st_function);
 
          next_token();
 
@@ -22441,7 +22631,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR090 - Expected '(' for call to vararg function: " + symbol,
+                          "ERR092 - Expected '(' for call to vararg function: " + symbol,
                           exprtk_error_location));
 
             return error_node();
@@ -22463,14 +22653,14 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR091 - Expected ',' for call to vararg function: " + symbol,
+                             "ERR093 - Expected ',' for call to vararg function: " + symbol,
                              exprtk_error_location));
 
                return error_node();
             }
          }
 
-         result = expression_generator_.vararg_function(opt_type,arg_list);
+         const expression_node_ptr result = expression_generator_.vararg_function(opt_type,arg_list);
 
          sdd.delete_ptr = (0 == result);
          return result;
@@ -22484,7 +22674,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR092 - Expected '[' as start of string range definition",
+                          "ERR094 - Expected '[' as start of string range definition",
                           exprtk_error_location));
 
             free_node(node_allocator_,expression);
@@ -22512,7 +22702,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR093 - Failed to generate string range node",
+                          "ERR095 - Failed to generate string range node",
                           exprtk_error_location));
 
             free_node(node_allocator_,expression);
@@ -22648,7 +22838,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR094 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
+                             "ERR096 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
                              ((!source.empty()) ? std::string(" section of " + source): ""),
                              exprtk_error_location));
 
@@ -22688,14 +22878,14 @@ namespace exprtk
             if (token_is(close_bracket))
                break;
 
-            bool is_next_close = peek_token_is(close_bracket);
+            const bool is_next_close = peek_token_is(close_bracket);
 
             if (!token_is(seperator) && is_next_close)
             {
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR095 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
+                             "ERR097 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
                              exprtk_error_location));
 
                return error_node();
@@ -22729,7 +22919,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR096 - Expected '[' for start of range",
+                          "ERR098 - Expected '[' for start of range",
                           exprtk_error_location));
 
             return false;
@@ -22750,7 +22940,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR097 - Failed parse begin section of range",
+                             "ERR099 - Failed parse begin section of range",
                              exprtk_error_location));
 
                return false;
@@ -22773,7 +22963,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR098 - Range lower bound less than zero! Constraint: r0 >= 0",
+                                "ERR100 - Range lower bound less than zero! Constraint: r0 >= 0",
                                 exprtk_error_location));
 
                   return false;
@@ -22790,7 +22980,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR099 - Expected ':' for break  in range",
+                             "ERR101 - Expected ':' for break  in range",
                              exprtk_error_location));
 
                rp.free();
@@ -22813,7 +23003,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR100 - Failed parse end section of range",
+                             "ERR102 - Failed parse end section of range",
                              exprtk_error_location));
 
                rp.free();
@@ -22838,7 +23028,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR101 - Range upper bound less than zero! Constraint: r1 >= 0",
+                                "ERR103 - Range upper bound less than zero! Constraint: r1 >= 0",
                                 exprtk_error_location));
 
                   return false;
@@ -22855,7 +23045,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR102 - Expected ']' for start of range",
+                             "ERR104 - Expected ']' for start of range",
                              exprtk_error_location));
 
                rp.free();
@@ -22876,7 +23066,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR103 - Invalid range, Constraint: r0 <= r1",
+                             "ERR105 - Invalid range, Constraint: r0 <= r1",
                              exprtk_error_location));
 
                return false;
@@ -22908,7 +23098,7 @@ namespace exprtk
          {
             se.active = true;
             result    = se.str_node;
-            lodge_symbol(symbol,e_st_local_string);
+            lodge_symbol(symbol, e_st_local_string);
          }
          else
          {
@@ -22917,7 +23107,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR104 - Unknown string symbol",
+                             "ERR106 - Unknown string symbol",
                              exprtk_error_location));
 
                return error_node();
@@ -22931,7 +23121,7 @@ namespace exprtk
                result = expression_generator_(const_str_node->str());
             }
 
-            lodge_symbol(symbol,e_st_string);
+            lodge_symbol(symbol, e_st_string);
          }
 
          if (peek_token_is(token_t::e_lsqrbracket))
@@ -23031,7 +23221,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR105 - Overflow in range for string: '" + const_str + "'[" +
+                             "ERR107 - 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));
@@ -23075,7 +23265,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR106 - Symbol '" + symbol+ " not a vector",
+                             "ERR108 - Symbol '" + symbol+ " not a vector",
                              exprtk_error_location));
 
                return error_node();
@@ -23101,7 +23291,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR107 - Failed to parse index for vector: '" + symbol + "'",
+                          "ERR109 - Failed to parse index for vector: '" + symbol + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -23111,7 +23301,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR108 - Expected ']' for index of vector: '" + symbol + "'",
+                          "ERR110 - Expected ']' for index of vector: '" + symbol + "'",
                           exprtk_error_location));
 
             free_node(node_allocator_,index_expr);
@@ -23130,7 +23320,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR109 - Index of " + details::to_str(index) + " out of range for "
+                             "ERR111 - Index of " + details::to_str(index) + " out of range for "
                              "vector '" + symbol + "' of size " + details::to_str(vec_size),
                              exprtk_error_location));
 
@@ -23140,7 +23330,7 @@ namespace exprtk
             }
          }
 
-         return expression_generator_.vector_element(symbol,vec,index_expr);
+         return expression_generator_.vector_element(symbol, vec, index_expr);
       }
 
       inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name)
@@ -23162,7 +23352,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR110 - Zero parameter call to vararg function: "
+                                "ERR112 - Zero parameter call to vararg function: "
                                 + vararg_function_name + " not allowed",
                                 exprtk_error_location));
 
@@ -23187,7 +23377,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR111 - Expected ',' for call to vararg function: "
+                                   "ERR113 - Expected ',' for call to vararg function: "
                                    + vararg_function_name,
                                    exprtk_error_location));
 
@@ -23201,7 +23391,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR112 - Zero parameter call to vararg function: "
+                          "ERR114 - Zero parameter call to vararg function: "
                           + vararg_function_name + " not allowed",
                           exprtk_error_location));
 
@@ -23213,7 +23403,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR113 - Invalid number of parameters to call to vararg function: "
+                          "ERR115 - 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));
@@ -23225,7 +23415,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR114 - Invalid number of parameters to call to vararg function: "
+                          "ERR116 - 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));
@@ -23244,34 +23434,54 @@ namespace exprtk
       {
       public:
 
+         enum return_type_t
+         {
+            e_overload = ' ',
+            e_numeric  = 'T',
+            e_string   = 'S'
+         };
+
+         struct function_prototype_t
+         {
+             return_type_t return_type;
+             std::string   param_seq;
+         };
+
          typedef parser<T> parser_t;
-         typedef std::vector<std::string> param_seq_list_t;
+         typedef std::vector<function_prototype_t> function_definition_list_t;
 
          type_checker(parser_t& p,
                       const std::string& func_name,
-                      const std::string& param_seq)
+                      const std::string& func_prototypes,
+                      const return_type_t default_return_type)
          : invalid_state_(true),
            parser_(p),
-           function_name_(func_name)
+           function_name_(func_name),
+           default_return_type_(default_return_type)
          {
-            split(param_seq);
+            parse_function_prototypes(func_prototypes);
+         }
+
+         void set_default_return_type(const std::string& return_type)
+         {
+            default_return_type_ = return_type;
          }
 
          bool verify(const std::string& param_seq, std::size_t& pseq_index)
          {
-            if (param_seq_list_.empty())
+            if (function_definition_list_.empty())
                return true;
 
             std::vector<std::pair<std::size_t,char> > error_list;
 
-            for (std::size_t i = 0; i < param_seq_list_.size(); ++i)
+            for (std::size_t i = 0; i < function_definition_list_.size(); ++i)
             {
                details::char_t diff_value = 0;
                std::size_t     diff_index = 0;
 
-               bool result = details::sequence_match(param_seq_list_[i],
-                                                     param_seq,
-                                                     diff_index,diff_value);
+               const bool result = details::sequence_match(function_definition_list_[i].param_seq,
+                                                           param_seq,
+                                                           diff_index, diff_value);
 
               if (result)
               {
@@ -23279,7 +23489,7 @@ namespace exprtk
                  return true;
               }
               else
-                 error_list.push_back(std::make_pair(diff_index,diff_value));
+                 error_list.push_back(std::make_pair(diff_index, diff_value));
             }
 
             if (1 == error_list.size())
@@ -23288,8 +23498,9 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 parser_.current_token(),
-                                "ERR115 - Failed parameter type check for function '" + function_name_ + "', "
-                                "Expected '" + param_seq_list_[0] + "'  call set: '" + param_seq +"'",
+                                "ERR117 - Failed parameter type check for function '" + function_name_ + "', "
+                                "Expected '" + function_definition_list_[0].param_seq +
+                                "'  call set: '" + param_seq + "'",
                                 exprtk_error_location));
             }
             else
@@ -23309,8 +23520,9 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 parser_.current_token(),
-                                "ERR116 - Failed parameter type check for function '" + function_name_ + "', "
-                                "Best match: '" + param_seq_list_[max_diff_index] + "'  call set: '" + param_seq +"'",
+                                "ERR118 - 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));
             }
 
@@ -23319,12 +23531,17 @@ namespace exprtk
 
          std::size_t paramseq_count() const
          {
-            return param_seq_list_.size();
+            return function_definition_list_.size();
          }
 
          std::string paramseq(const std::size_t& index) const
          {
-            return param_seq_list_[index];
+            return function_definition_list_[index].param_seq;
+         }
+
+         return_type_t return_type(const std::size_t& index) const
+         {
+            return function_definition_list_[index].return_type;
          }
 
          bool invalid() const
@@ -23334,93 +23551,142 @@ namespace exprtk
 
          bool allow_zero_parameters() const
          {
-            return
-               param_seq_list_.end() != std::find(param_seq_list_.begin(),
-                                                  param_seq_list_.end(),
-                                                  "Z");
+
+            for (std::size_t i = 0; i < function_definition_list_.size(); ++i)
+            {
+               if (std::string::npos != function_definition_list_[i].param_seq.find("Z"))
+               {
+                  return true;
+               }
+            }
+
+            return false;
          }
 
       private:
 
-         void split(const std::string& s)
+         std::vector<std::string> split_param_seq(const std::string& param_seq, const details::char_t delimiter = '|') const
          {
-            if (s.empty())
-               return;
+             std::string::const_iterator current_begin = param_seq.begin();
+             std::string::const_iterator iter          = param_seq.begin();
 
-            std::size_t start = 0;
-            std::size_t end   = 0;
+             std::vector<std::string> result;
 
-            param_seq_list_t param_seq_list;
+             while (iter != param_seq.end())
+             {
+                 if (*iter == delimiter)
+                 {
+                     result.push_back(std::string(current_begin, iter));
+                     current_begin = ++iter;
+                 }
+                 else
+                     ++iter;
+             }
 
-            struct token_validator
+             if (current_begin != iter)
+             {
+                 result.push_back(std::string(current_begin, iter));
+             }
+
+             return result;
+         }
+
+         inline bool is_valid_token(std::string param_seq,
+                                    function_prototype_t& funcproto) const
+         {
+            // Determine return type
+            funcproto.return_type = default_return_type_;
+
+            if (param_seq.size() > 2)
             {
-               static inline bool process(const std::string& str,
-                                          std::size_t s, std::size_t e,
-                                          param_seq_list_t& psl)
+               if (':' == param_seq[1])
                {
-                  if (
-                       (e - s) &&
-                       (std::string::npos == str.find("?*")) &&
-                       (std::string::npos == str.find("**"))
-                     )
-                  {
-                     const std::string curr_str = str.substr(s, e - s);
+                  // Note: Only overloaded igeneric functions can have return
+                  // type definitions.
+                  if (type_checker::e_overload != default_return_type_)
+                     return false;
 
-                     if ("Z" == curr_str)
-                     {
-                        psl.push_back(curr_str);
-                        return true;
-                     }
-                     else if (std::string::npos == curr_str.find_first_not_of("STV*?|"))
-                     {
-                        psl.push_back(curr_str);
-                        return true;
-                     }
+                  switch (param_seq[0])
+                  {
+                     case 'T' : funcproto.return_type = type_checker::e_numeric;
+                                break;
+
+                     case 'S' : funcproto.return_type = type_checker::e_string;
+                                break;
+
+                     default  : return false;
                   }
 
-                  return false;
+                  param_seq.erase(0,2);
                }
-            };
+            }
 
-            while (std::string::npos != (end = s.find('|',start)))
+            if (
+                 (std::string::npos != param_seq.find("?*")) ||
+                 (std::string::npos != param_seq.find("**"))
+               )
             {
-               if (!token_validator::process(s, start, end, param_seq_list))
+               return false;
+            }
+            else if (
+                      (std::string::npos == param_seq.find_first_not_of("STV*?|")) ||
+                      ("Z" == param_seq)
+                    )
+            {
+               funcproto.param_seq = param_seq;
+               return true;
+            }
+
+            return false;
+         }
+
+         void parse_function_prototypes(const std::string& func_prototypes)
+         {
+            if (func_prototypes.empty())
+               return;
+
+            std::vector<std::string> param_seq_list = split_param_seq(func_prototypes);
+
+            typedef std::map<std::string,std::size_t> param_seq_map_t;
+            param_seq_map_t param_seq_map;
+
+            for (std::size_t i = 0; i < param_seq_list.size(); ++i)
+            {
+               function_prototype_t func_proto;
+
+               if (!is_valid_token(param_seq_list[i], func_proto))
                {
                   invalid_state_ = false;
 
-                  const std::string err_param_seq = s.substr(start, end - start);
-
                   parser_.
                      set_error(
                         make_error(parser_error::e_syntax,
                                    parser_.current_token(),
-                                   "ERR117 - Invalid parameter sequence of '" + err_param_seq +
-                                   "'  for function: " + function_name_,
+                                   "ERR119 - Invalid parameter sequence of '" + param_seq_list[i] +
+                                   "' for function: " + function_name_,
                                    exprtk_error_location));
-
                   return;
                }
-               else
-                  start = end + 1;
-            }
 
-            if (start < s.size())
-            {
-               if (token_validator::process(s, start, s.size(), param_seq_list))
-                  param_seq_list_ = param_seq_list;
-               else
+               param_seq_map_t::const_iterator seq_itr = param_seq_map.find(param_seq_list[i]);
+
+               if (param_seq_map.end() != seq_itr)
                {
-                  const std::string err_param_seq = s.substr(start, s.size() - start);
+                  invalid_state_ = false;
 
                   parser_.
                      set_error(
                         make_error(parser_error::e_syntax,
                                    parser_.current_token(),
-                                   "ERR118 - Invalid parameter sequence of '" + err_param_seq +
-                                   "'  for function: " + function_name_,
+                                   "ERR120 - 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;
                }
+
+               function_definition_list_.push_back(func_proto);
             }
          }
 
@@ -23430,7 +23696,8 @@ namespace exprtk
          bool invalid_state_;
          parser_t& parser_;
          std::string function_name_;
-         param_seq_list_t param_seq_list_;
+         const return_type_t default_return_type_;
+         function_definition_list_t function_definition_list_;
       };
 
       inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name)
@@ -23443,30 +23710,14 @@ namespace exprtk
 
          std::string param_type_list;
 
-         type_checker tc((*this), function_name, function->parameter_sequence);
+         type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string);
 
          if (tc.invalid())
          {
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR119 - Type checker instantiation failure for generic function: " + function_name,
-                          exprtk_error_location));
-
-            return error_node();
-         }
-
-         if (
-              !function->parameter_sequence.empty() &&
-              function->allow_zero_parameters    () &&
-              !tc      .allow_zero_parameters    ()
-            )
-         {
-            set_error(
-               make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR120 - Mismatch in zero parameter condition for generic function: "
-                          + function_name,
+                          "ERR121 - Type checker instantiation failure for generic function: " + function_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23484,7 +23735,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR121 - Zero parameter call to generic function: "
+                                "ERR122 - Zero parameter call to generic function: "
                                 + function_name + " not allowed",
                                 exprtk_error_location));
 
@@ -23516,7 +23767,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR122 - Expected ',' for call to generic function: " + function_name,
+                                   "ERR123 - Expected ',' for call to generic function: " + function_name,
                                    exprtk_error_location));
 
                      return error_node();
@@ -23533,7 +23784,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR123 - Zero parameter call to generic function: "
+                          "ERR124 - Zero parameter call to generic function: "
                           + function_name + " not allowed",
                           exprtk_error_location));
 
@@ -23550,7 +23801,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR124 - Expected ',' for call to generic function: " + function_name,
+                          "ERR125 - Invalid input parameter sequence for call to generic function: " + function_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23570,37 +23821,39 @@ namespace exprtk
          return result;
       }
 
-      #ifndef exprtk_disable_string_capabilities
-      inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name)
+      inline bool parse_igeneric_function_params(std::string& param_type_list,
+                                                 std::vector<expression_node_ptr>& arg_list,
+                                                 const std::string& function_name,
+                                                 igeneric_function<T>* function,
+                                                 const type_checker& tc)
       {
-         std::vector<expression_node_ptr> arg_list;
-
-         scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
-
-         next_token();
-
-         std::string param_type_list;
-
-         type_checker tc((*this), function_name, function->parameter_sequence);
-
-         if (
-              (!function->parameter_sequence.empty()) &&
-              (0 == tc.paramseq_count())
-            )
-         {
-            return error_node();
-         }
-
          if (token_is(token_t::e_lbracket))
          {
-            if (!token_is(token_t::e_rbracket))
+            if (token_is(token_t::e_rbracket))
+            {
+               if (
+                    !function->allow_zero_parameters() &&
+                    !tc       .allow_zero_parameters()
+                  )
+               {
+                  set_error(
+                     make_error(parser_error::e_syntax,
+                                current_token(),
+                                "ERR126 - Zero parameter call to generic function: "
+                                + function_name + " not allowed",
+                                exprtk_error_location));
+
+                  return false;
+               }
+            }
+            else
             {
                for ( ; ; )
                {
                   expression_node_ptr arg = parse_expression();
 
                   if (0 == arg)
-                     return error_node();
+                     return false;
 
                   if (is_ivector_node(arg))
                      param_type_list += 'V';
@@ -23618,13 +23871,44 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR125 - Expected ',' for call to string function: " + function_name,
+                                   "ERR127 - Expected ',' for call to string function: " + function_name,
                                    exprtk_error_location));
 
-                     return error_node();
+                     return false;
                   }
                }
             }
+
+            return true;
+         }
+         else
+            return false;
+      }
+
+      #ifndef exprtk_disable_string_capabilities
+      inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name)
+      {
+         // Move pass the function name
+         next_token();
+
+         std::string param_type_list;
+
+         type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string);
+
+         if (
+              (!function->parameter_sequence.empty()) &&
+              (0 == tc.paramseq_count())
+            )
+         {
+            return error_node();
+         }
+
+         std::vector<expression_node_ptr> arg_list;
+         scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
+
+         if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc))
+         {
+            return error_node();
          }
 
          std::size_t param_seq_index = 0;
@@ -23634,7 +23918,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR126 - Expected ',' for call to string function: " + function_name,
+                          "ERR128 - Invalid input parameter sequence for call to string function: " + function_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23653,15 +23937,86 @@ namespace exprtk
 
          return result;
       }
+
+      inline expression_node_ptr parse_overload_function_call(igeneric_function<T>* function, const std::string& function_name)
+      {
+         // Move pass the function name
+         next_token();
+
+         std::string param_type_list;
+
+         type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_overload);
+
+         if (
+              (!function->parameter_sequence.empty()) &&
+              (0 == tc.paramseq_count())
+            )
+         {
+            return error_node();
+         }
+
+         std::vector<expression_node_ptr> arg_list;
+         scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
+
+         if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc))
+         {
+            return error_node();
+         }
+
+         std::size_t param_seq_index = 0;
+
+         if (!tc.verify(param_type_list, param_seq_index))
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR129 - Invalid input parameter sequence for call to overloaded function: " + function_name,
+                          exprtk_error_location));
+
+            return error_node();
+         }
+
+         expression_node_ptr result = error_node();
+
+         if (type_checker::e_numeric == tc.return_type(param_seq_index))
+         {
+            if (tc.paramseq_count() <= 1)
+               result = expression_generator_
+                          .generic_function_call(function, arg_list);
+            else
+               result = expression_generator_
+                          .generic_function_call(function, arg_list, param_seq_index);
+         }
+         else if (type_checker::e_string == tc.return_type(param_seq_index))
+         {
+            if (tc.paramseq_count() <= 1)
+               result = expression_generator_
+                          .string_function_call(function, arg_list);
+            else
+               result = expression_generator_
+                          .string_function_call(function, arg_list, param_seq_index);
+         }
+         else
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR130 - Invalid return type for call to overloaded function: " + function_name,
+                          exprtk_error_location));
+         }
+
+         sdd.delete_ptr = (0 == result);
+         return result;
+      }
       #endif
 
       template <typename Type, std::size_t NumberOfParameters>
       struct parse_special_function_impl
       {
-         static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type, const std::string& sf_name)
+         static inline expression_node_ptr process(parser<Type>& p, const details::operator_type opt_type, const std::string& sf_name)
          {
             expression_node_ptr branch[NumberOfParameters];
-            expression_node_ptr result  = error_node();
+            expression_node_ptr result = error_node();
 
             std::fill_n(branch,NumberOfParameters,reinterpret_cast<expression_node_ptr>(0));
 
@@ -23674,7 +24029,7 @@ namespace exprtk
                p.set_error(
                     make_error(parser_error::e_syntax,
                                p.current_token(),
-                               "ERR127 - Expected '(' for special function '" + sf_name + "'",
+                               "ERR131 - Expected '(' for special function '" + sf_name + "'",
                                exprtk_error_location));
 
                return error_node();
@@ -23695,7 +24050,7 @@ namespace exprtk
                      p.set_error(
                           make_error(parser_error::e_syntax,
                                      p.current_token(),
-                                     "ERR128 - Expected ',' before next parameter of special function '" + sf_name + "'",
+                                     "ERR132 - Expected ',' before next parameter of special function '" + sf_name + "'",
                                      exprtk_error_location));
 
                      return p.error_node();
@@ -23708,7 +24063,7 @@ namespace exprtk
                p.set_error(
                     make_error(parser_error::e_syntax,
                                p.current_token(),
-                               "ERR129 - Invalid number of parameters for special function '" + sf_name + "'",
+                               "ERR133 - Invalid number of parameters for special function '" + sf_name + "'",
                                exprtk_error_location));
 
                return p.error_node();
@@ -23735,7 +24090,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_token,
                           current_token(),
-                          "ERR130 - Invalid special function[1]: " + sf_name,
+                          "ERR134 - Invalid special function[1]: " + sf_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23749,7 +24104,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_token,
                           current_token(),
-                          "ERR131 - Invalid special function[2]: " + sf_name,
+                          "ERR135 - Invalid special function[2]: " + sf_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23781,7 +24136,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR132 - Break call within a break call is not allowed",
+                          "ERR136 - Break call within a break call is not allowed",
                           exprtk_error_location));
 
             return error_node();
@@ -23804,7 +24159,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR133 - Failed to parse return expression for 'break' statement",
+                                "ERR137 - Failed to parse return expression for 'break' statement",
                                 exprtk_error_location));
 
                   return error_node();
@@ -23814,7 +24169,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR134 - Expected ']' at the completion of break's return expression",
+                                "ERR138 - Expected ']' at the completion of break's return expression",
                                 exprtk_error_location));
 
                   free_node(node_allocator_,return_expr);
@@ -23832,7 +24187,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR135 - Invalid use of 'break', allowed only in the scope of a loop",
+                          "ERR139 - Invalid use of 'break', allowed only in the scope of a loop",
                           exprtk_error_location));
          }
 
@@ -23855,7 +24210,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR136 - Invalid use of 'continue', allowed only in the scope of a loop",
+                          "ERR140 - Invalid use of 'continue', allowed only in the scope of a loop",
                           exprtk_error_location));
 
             return error_node();
@@ -23872,7 +24227,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR137 - Expected '[' as part of vector size definition",
+                          "ERR141 - Expected '[' as part of vector size definition",
                           exprtk_error_location));
 
             return error_node();
@@ -23882,7 +24237,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR138 - Failed to determine size of vector '" + vec_name + "'",
+                          "ERR142 - Failed to determine size of vector '" + vec_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -23894,26 +24249,29 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR139 - Expected a literal number as size of vector '" + vec_name + "'",
+                          "ERR143 - Expected a literal number as size of vector '" + vec_name + "'",
                           exprtk_error_location));
 
             return error_node();
          }
 
-         T vector_size = size_expr->value();
+         const T vector_size = size_expr->value();
 
          free_node(node_allocator_,size_expr);
 
+         const T max_vector_size = T(2000000000.0);
+
          if (
               (vector_size <= T(0)) ||
               std::not_equal_to<T>()
-              (T(0),vector_size - details::numeric::trunc(vector_size))
+              (T(0),vector_size - details::numeric::trunc(vector_size)) ||
+              (vector_size > max_vector_size)
             )
          {
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR140 - Invalid vector size. Must be an integer greater than zero, size: " +
+                          "ERR144 - 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));
 
@@ -23933,7 +24291,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR141 - Expected ']' as part of vector size definition",
+                          "ERR145 - Expected ']' as part of vector size definition",
                           exprtk_error_location));
 
             return error_node();
@@ -23945,7 +24303,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR142 - Expected ':=' as part of vector definition",
+                             "ERR146 - Expected ':=' as part of vector definition",
                              exprtk_error_location));
 
                return error_node();
@@ -23959,7 +24317,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR143 - Failed to parse single vector initialiser",
+                                "ERR147 - Failed to parse single vector initialiser",
                                 exprtk_error_location));
 
                   return error_node();
@@ -23972,7 +24330,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR144 - Expected ']' to close single value vector initialiser",
+                                "ERR148 - Expected ']' to close single value vector initialiser",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24000,7 +24358,7 @@ namespace exprtk
                   // Are we dealing with a user defined vector?
                   else if (symtab_store_.is_vector(current_token().value))
                   {
-                     lodge_symbol(current_token().value,e_st_vector);
+                     lodge_symbol(current_token().value, e_st_vector);
 
                      if (0 != (initialiser = parse_expression()))
                         vec_initilizer_list.push_back(initialiser);
@@ -24019,7 +24377,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR145 - Expected '{' as part of vector initialiser list",
+                                   "ERR149 - Expected '{' as part of vector initialiser list",
                                    exprtk_error_location));
 
                      return error_node();
@@ -24039,7 +24397,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR146 - Expected '{' as part of vector initialiser list",
+                                   "ERR150 - Expected '{' as part of vector initialiser list",
                                    exprtk_error_location));
 
                      return error_node();
@@ -24050,14 +24408,14 @@ namespace exprtk
                   if (token_is(token_t::e_rcrlbracket))
                      break;
 
-                  bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
+                  const bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
 
                   if (!token_is(token_t::e_comma) && is_next_close)
                   {
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR147 - Expected ',' between vector initialisers",
+                                   "ERR151 - Expected ',' between vector initialisers",
                                    exprtk_error_location));
 
                      return error_node();
@@ -24079,7 +24437,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR148 - Expected ';' at end of vector definition",
+                                "ERR152 - Expected ';' at end of vector definition",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24091,7 +24449,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR149 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
+                             "ERR153 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24111,7 +24469,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR150 - Illegal redefinition of local vector: '" + vec_name + "'",
+                             "ERR154 - Illegal redefinition of local vector: '" + vec_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24145,7 +24503,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR151 - Failed to add new local vector '" + vec_name + "' to SEM",
+                             "ERR155 - Failed to add new local vector '" + vec_name + "' to SEM",
                              exprtk_error_location));
 
                sem_.free_element(nse);
@@ -24162,7 +24520,7 @@ namespace exprtk
 
          state_.activate_side_effect("parse_define_vector_statement()");
 
-         lodge_symbol(vec_name,e_st_local_vector);
+         lodge_symbol(vec_name, e_st_local_vector);
 
          expression_node_ptr result = error_node();
 
@@ -24204,7 +24562,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR152 - Illegal redefinition of local variable: '" + str_name + "'",
+                             "ERR156 - Illegal redefinition of local variable: '" + str_name + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
@@ -24236,7 +24594,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR153 - Failed to add new local string variable '" + str_name + "' to SEM",
+                             "ERR157 - Failed to add new local string variable '" + str_name + "' to SEM",
                              exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
@@ -24251,7 +24609,7 @@ namespace exprtk
             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);
+         lodge_symbol(str_name, e_st_local_string);
 
          state_.activate_side_effect("parse_define_string_statement()");
 
@@ -24282,7 +24640,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR154 - Illegal variable definition",
+                          "ERR158 - Illegal variable definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24303,7 +24661,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR155 - Expected a symbol for variable definition",
+                          "ERR159 - Expected a symbol for variable definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24313,7 +24671,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR156 - Illegal redefinition of reserved keyword: '" + var_name + "'",
+                          "ERR160 - Illegal redefinition of reserved keyword: '" + var_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -24323,7 +24681,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR157 - Illegal redefinition of variable '" + var_name + "'",
+                          "ERR161 - Illegal redefinition of variable '" + var_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -24333,7 +24691,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR158 - Illegal redefinition of local variable: '" + var_name + "'",
+                          "ERR162 - Illegal redefinition of local variable: '" + var_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -24353,7 +24711,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR159 - Failed to parse initialisation expression",
+                             "ERR163 - Failed to parse initialisation expression",
                              exprtk_error_location));
 
                return error_node();
@@ -24371,7 +24729,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR160 - Expected ';' after variable definition",
+                             "ERR164 - Expected ';' after variable definition",
                              exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
@@ -24399,7 +24757,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR161 - Illegal redefinition of local variable: '" + var_name + "'",
+                             "ERR165 - Illegal redefinition of local variable: '" + var_name + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
@@ -24431,7 +24789,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR162 - Failed to add new local variable '" + var_name + "' to SEM",
+                             "ERR166 - Failed to add new local variable '" + var_name + "' to SEM",
                              exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
@@ -24448,7 +24806,7 @@ namespace exprtk
 
          state_.activate_side_effect("parse_define_var_statement()");
 
-         lodge_symbol(var_name,e_st_local_variable);
+         lodge_symbol(var_name, e_st_local_variable);
 
          expression_node_ptr branch[2] = {0};
 
@@ -24468,7 +24826,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR163 - Expected a '{}' for uninitialised var definition",
+                          "ERR167 - Expected a '{}' for uninitialised var definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24478,7 +24836,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR164 - Expected ';' after uninitialised variable definition",
+                          "ERR168 - Expected ';' after uninitialised variable definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24495,7 +24853,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR165 - Illegal redefinition of local variable: '" + var_name + "'",
+                             "ERR169 - Illegal redefinition of local variable: '" + var_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24525,7 +24883,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR166 - Failed to add new local variable '" + var_name + "' to SEM",
+                             "ERR170 - Failed to add new local variable '" + var_name + "' to SEM",
                              exprtk_error_location));
 
                sem_.free_element(nse);
@@ -24537,7 +24895,7 @@ namespace exprtk
                           nse.name.c_str()));
          }
 
-         lodge_symbol(var_name,e_st_local_variable);
+         lodge_symbol(var_name, e_st_local_variable);
 
          state_.activate_side_effect("parse_uninitialised_var_statement()");
 
@@ -24558,7 +24916,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR167 - Expected '(' at start of swap statement",
+                          "ERR171 - Expected '(' at start of swap statement",
                           exprtk_error_location));
 
             return error_node();
@@ -24577,7 +24935,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR168 - Expected a symbol for variable or vector element definition",
+                          "ERR172 - Expected a symbol for variable or vector element definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24589,7 +24947,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR169 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
+                             "ERR173 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24615,14 +24973,14 @@ namespace exprtk
                variable0 = se.var_node;
             }
 
-            lodge_symbol(var0_name,e_st_variable);
+            lodge_symbol(var0_name, e_st_variable);
 
             if (0 == variable0)
             {
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR170 - First parameter to swap is an invalid variable: '" + var0_name + "'",
+                             "ERR174 - First parameter to swap is an invalid variable: '" + var0_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24636,7 +24994,7 @@ namespace exprtk
             set_error(
                 make_error(parser_error::e_syntax,
                            current_token(),
-                           "ERR171 - Expected ',' between parameters to swap",
+                           "ERR175 - Expected ',' between parameters to swap",
                            exprtk_error_location));
 
             if (variable0_generated)
@@ -24654,7 +25012,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR172 - Expected a symbol for variable or vector element definition",
+                          "ERR176 - Expected a symbol for variable or vector element definition",
                           exprtk_error_location));
 
             if (variable0_generated)
@@ -24671,7 +25029,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR173 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
+                             "ERR177 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
                              exprtk_error_location));
 
                if (variable0_generated)
@@ -24702,14 +25060,14 @@ namespace exprtk
                variable1 = se.var_node;
             }
 
-            lodge_symbol(var1_name,e_st_variable);
+            lodge_symbol(var1_name, e_st_variable);
 
             if (0 == variable1)
             {
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR174 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
+                             "ERR178 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
                              exprtk_error_location));
 
                if (variable0_generated)
@@ -24728,7 +25086,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR175 - Expected ')' at end of swap statement",
+                          "ERR179 - Expected ')' at end of swap statement",
                           exprtk_error_location));
 
             if (variable0_generated)
@@ -24785,7 +25143,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR176 - Return call within a return call is not allowed",
+                          "ERR180 - Return call within a return call is not allowed",
                           exprtk_error_location));
 
             return error_node();
@@ -24809,7 +25167,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR177 - Expected '[' at start of return statement",
+                          "ERR181 - Expected '[' at start of return statement",
                           exprtk_error_location));
 
             return error_node();
@@ -24832,7 +25190,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR178 - Expected ',' between values during call to return",
+                                "ERR182 - Expected ',' between values during call to return",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24844,7 +25202,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR179 - Zero parameter return statement not allowed",
+                          "ERR183 - Zero parameter return statement not allowed",
                           exprtk_error_location));
 
             return error_node();
@@ -24859,7 +25217,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              prev_token,
-                             "ERR180 - Invalid ']' found during return call",
+                             "ERR184 - Invalid ']' found during return call",
                              exprtk_error_location));
 
                return error_node();
@@ -24912,7 +25270,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR181 - Invalid sequence of variable '"+ symbol + "' and bracket",
+                             "ERR185 - Invalid sequence of variable '"+ symbol + "' and bracket",
                              exprtk_error_location));
 
                return false;
@@ -24960,7 +25318,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR182 - Invalid sequence of brackets",
+                             "ERR186 - Invalid sequence of brackets",
                              exprtk_error_location));
 
                return false;
@@ -24993,7 +25351,7 @@ namespace exprtk
             if (!post_variable_process(symbol))
                return error_node();
 
-            lodge_symbol(symbol,e_st_variable);
+            lodge_symbol(symbol, e_st_variable);
             next_token();
 
             return variable;
@@ -25009,7 +25367,7 @@ namespace exprtk
                if (scope_element::e_variable == se.type)
                {
                   se.active = true;
-                  lodge_symbol(symbol,e_st_local_variable);
+                  lodge_symbol(symbol, e_st_local_variable);
 
                   if (!post_variable_process(symbol))
                      return error_node();
@@ -25045,7 +25403,7 @@ namespace exprtk
 
             if (function)
             {
-               lodge_symbol(symbol,e_st_function);
+               lodge_symbol(symbol, e_st_function);
 
                expression_node_ptr func_node =
                                       parse_function_invocation(function,symbol);
@@ -25057,7 +25415,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR183 - Failed to generate node for function: '" + symbol + "'",
+                                "ERR187 - Failed to generate node for function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25071,7 +25429,7 @@ namespace exprtk
 
             if (vararg_function)
             {
-               lodge_symbol(symbol,e_st_function);
+               lodge_symbol(symbol, e_st_function);
 
                expression_node_ptr vararg_func_node =
                                       parse_vararg_function_call(vararg_function, symbol);
@@ -25083,7 +25441,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR184 - Failed to generate node for vararg function: '" + symbol + "'",
+                                "ERR188 - Failed to generate node for vararg function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25097,7 +25455,7 @@ namespace exprtk
 
             if (generic_function)
             {
-               lodge_symbol(symbol,e_st_function);
+               lodge_symbol(symbol, e_st_function);
 
                expression_node_ptr genericfunc_node =
                                       parse_generic_function_call(generic_function, symbol);
@@ -25109,7 +25467,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR185 - Failed to generate node for generic function: '" + symbol + "'",
+                                "ERR189 - Failed to generate node for generic function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25124,7 +25482,7 @@ namespace exprtk
 
             if (string_function)
             {
-               lodge_symbol(symbol,e_st_function);
+               lodge_symbol(symbol, e_st_function);
 
                expression_node_ptr stringfunc_node =
                                       parse_string_function_call(string_function, symbol);
@@ -25136,7 +25494,33 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR186 - Failed to generate node for string function: '" + symbol + "'",
+                                "ERR190 - Failed to generate node for string function: '" + symbol + "'",
+                                exprtk_error_location));
+
+                  return error_node();
+               }
+            }
+         }
+
+         {
+            // Are we dealing with a vararg overloaded scalar/string returning function?
+            igeneric_function<T>* overload_function = symtab_store_.get_overload_function(symbol);
+
+            if (overload_function)
+            {
+               lodge_symbol(symbol, e_st_function);
+
+               expression_node_ptr overloadfunc_node =
+                                      parse_overload_function_call(overload_function, symbol);
+
+               if (overloadfunc_node)
+                  return overloadfunc_node;
+               else
+               {
+                  set_error(
+                     make_error(parser_error::e_syntax,
+                                current_token(),
+                                "ERR191 - Failed to generate node for overload function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25148,7 +25532,7 @@ namespace exprtk
          // Are we dealing with a vector?
          if (symtab_store_.is_vector(symbol))
          {
-            lodge_symbol(symbol,e_st_vector);
+            lodge_symbol(symbol, e_st_vector);
             return parse_vector();
          }
 
@@ -25162,7 +25546,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR187 - Invalid use of reserved symbol '" + symbol + "'",
+                                "ERR192 - Invalid use of reserved symbol '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25210,7 +25594,7 @@ namespace exprtk
                               var = expression_generator_(var->value());
                            }
 
-                           lodge_symbol(symbol,e_st_variable);
+                           lodge_symbol(symbol, e_st_variable);
 
                            if (!post_variable_process(symbol))
                               return error_node();
@@ -25225,7 +25609,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_symtab,
                                 current_token(),
-                                "ERR188 - Failed to create variable: '" + symbol + "'" +
+                                "ERR193 - Failed to create variable: '" + symbol + "'" +
                                 (error_message.empty() ? "" : " - " + error_message),
                                 exprtk_error_location));
 
@@ -25245,7 +25629,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_symtab,
                                 current_token(),
-                                "ERR189 - Failed to resolve symbol: '" + symbol + "'" +
+                                "ERR194 - Failed to resolve symbol: '" + symbol + "'" +
                                 (error_message.empty() ? "" : " - " + error_message),
                                 exprtk_error_location));
                }
@@ -25257,7 +25641,7 @@ namespace exprtk
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR190 - Undefined symbol: '" + symbol + "'",
+                       "ERR195 - Undefined symbol: '" + symbol + "'",
                        exprtk_error_location));
 
          return error_node();
@@ -25276,11 +25660,16 @@ namespace exprtk
          static const std::string symbol_var      = "var"     ;
          static const std::string symbol_swap     = "swap"    ;
          static const std::string symbol_return   = "return"  ;
+         static const std::string symbol_not      = "not"     ;
 
          if (valid_vararg_operation(current_token().value))
          {
             return parse_vararg_function();
          }
+         else if (details::imatch(current_token().value, symbol_not))
+         {
+            return parse_not_statement();
+         }
          else if (valid_base_operation(current_token().value))
          {
             return parse_base_operation();
@@ -25364,7 +25753,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_symtab,
                           current_token(),
-                          "ERR191 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value,
+                          "ERR196 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value,
                           exprtk_error_location));
 
             return error_node();
@@ -25388,7 +25777,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_numeric,
                                 current_token(),
-                                "ERR192 - Failed generate node for scalar: '" + current_token().value + "'",
+                                "ERR197 - Failed generate node for scalar: '" + current_token().value + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25402,7 +25791,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_numeric,
                              current_token(),
-                             "ERR193 - Failed to convert '" + current_token().value + "' to a number",
+                             "ERR198 - Failed to convert '" + current_token().value + "' to a number",
                              exprtk_error_location));
 
                return error_node();
@@ -25429,7 +25818,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR194 - Expected ')' instead of: '" + current_token().value + "'",
+                             "ERR199 - Expected ')' instead of: '" + current_token().value + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,branch);
@@ -25454,7 +25843,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR195 - Expected ']' instead of: '" + current_token().value + "'",
+                             "ERR200 - Expected ']' instead of: '" + current_token().value + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,branch);
@@ -25479,7 +25868,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR196 - Expected '}' instead of: '" + current_token().value + "'",
+                             "ERR201 - Expected '}' instead of: '" + current_token().value + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,branch);
@@ -25519,7 +25908,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR197 - Premature end of expression[1]",
+                          "ERR202 - Premature end of expression[1]",
                           exprtk_error_location));
 
             return error_node();
@@ -25529,7 +25918,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR198 - Premature end of expression[2]",
+                          "ERR203 - Premature end of expression[2]",
                           exprtk_error_location));
 
             return error_node();
@@ -25703,7 +26092,7 @@ namespace exprtk
             return true;
          }
 
-         inline details::operator_type get_operator(const binary_functor_t& bop)
+         inline details::operator_type get_operator(const binary_functor_t& bop) const
          {
             return (*inv_binary_op_map_).find(bop)->second;
          }
@@ -25762,9 +26151,9 @@ namespace exprtk
                    (details::e_frac  == operation) || (details::e_trunc == operation) ;
          }
 
-         inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc)
+         inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc) const
          {
-            typename sf3_map_t::iterator itr = sf3_map_->find(sf3id);
+            typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id);
 
             if (sf3_map_->end() == itr)
                return false;
@@ -25774,9 +26163,9 @@ namespace exprtk
             return true;
          }
 
-         inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc)
+         inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc) const
          {
-            typename sf4_map_t::iterator itr = sf4_map_->find(sf4id);
+            typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id);
 
             if (sf4_map_->end() == itr)
                return false;
@@ -25786,9 +26175,9 @@ namespace exprtk
             return true;
          }
 
-         inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation)
+         inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation) const
          {
-            typename sf3_map_t::iterator itr = sf3_map_->find(sf3id);
+            typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id);
 
             if (sf3_map_->end() == itr)
                return false;
@@ -25798,9 +26187,9 @@ namespace exprtk
             return true;
          }
 
-         inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation)
+         inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation) const
          {
-            typename sf4_map_t::iterator itr = sf4_map_->find(sf4id);
+            typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id);
 
             if (sf4_map_->end() == itr)
                return false;
@@ -25928,7 +26317,7 @@ namespace exprtk
                    (details::e_xnor == operation) ;
          }
 
-         inline std::string branch_to_id(expression_node_ptr branch)
+         inline std::string branch_to_id(expression_node_ptr branch) const
          {
             static const std::string null_str   ("(null)" );
             static const std::string const_str  ("(c)"    );
@@ -25969,7 +26358,7 @@ namespace exprtk
                return "ERROR";
          }
 
-         inline std::string branch_to_id(expression_node_ptr (&branch)[2])
+         inline std::string branch_to_id(expression_node_ptr (&branch)[2]) const
          {
             return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]);
          }
@@ -26087,7 +26476,7 @@ namespace exprtk
                       !details::is_constant_node(branch[1]) ;
          }
 
-         inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
+         inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
          {
             if (is_assignment_operation(operation))
             {
@@ -26109,7 +26498,7 @@ namespace exprtk
                return false;
          }
 
-         inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2])
+         inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2]) const
          {
             if (
                  !details::is_constant_node(branch[1]) ||
@@ -26125,7 +26514,7 @@ namespace exprtk
             return cardinal_pow_optimisable(operation, c);
          }
 
-         inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2])
+         inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2]) const
          {
             return (
                      details::is_break_node   (branch[0]) ||
@@ -26135,7 +26524,7 @@ namespace exprtk
                    );
          }
 
-         inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
+         inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
          {
             const bool b0_string = is_generally_string_node(branch[0]);
             const bool b1_string = is_generally_string_node(branch[1]);
@@ -26155,7 +26544,7 @@ namespace exprtk
             return result;
          }
 
-         inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3])
+         inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const
          {
             const bool b0_string = is_generally_string_node(branch[0]);
             const bool b1_string = is_generally_string_node(branch[1]);
@@ -26176,7 +26565,7 @@ namespace exprtk
             return result;
          }
 
-         inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
+         inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
          {
             const bool b0_string = is_generally_string_node(branch[0]);
             const bool b1_string = is_generally_string_node(branch[1]);
@@ -26184,7 +26573,7 @@ namespace exprtk
             return (b0_string && b1_string && valid_string_operation(operation));
          }
 
-         inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3])
+         inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const
          {
             const bool b0_string = is_generally_string_node(branch[0]);
             const bool b1_string = is_generally_string_node(branch[1]);
@@ -26617,7 +27006,7 @@ namespace exprtk
 
                return result;
             }
-            else if (details::is_null_node(condition))
+            else if (details::is_null_node(condition) || (0 == condition))
             {
                free_node(*node_allocator_, initialiser);
                free_node(*node_allocator_,   condition);
@@ -27194,7 +27583,7 @@ namespace exprtk
             return node_allocator_->allocate<literal_node_t>(v);
          }
 
-         inline bool special_one_parameter_vararg(const details::operator_type& operation)
+         inline bool special_one_parameter_vararg(const details::operator_type& operation) const
          {
             return (
                      (details::e_sum  == operation) ||
@@ -28204,7 +28593,7 @@ namespace exprtk
             }
          }
 
-         inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c)
+         inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const
          {
             return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
          }
@@ -28408,8 +28797,9 @@ namespace exprtk
                {
                   expression_node_ptr result = error_node();
 
-                  const bool synthesis_result = synthesize_sf4ext_expression::template compile_right<vtype>
-                                                  (expr_gen, v, operation, branch[1], result);
+                  const bool synthesis_result =
+                     synthesize_sf4ext_expression::template compile_right<vtype>
+                        (expr_gen, v, operation, branch[1], result);
 
                   if (synthesis_result)
                   {
@@ -28482,8 +28872,9 @@ namespace exprtk
                {
                   expression_node_ptr result = error_node();
 
-                  const bool synthesis_result = synthesize_sf4ext_expression::template compile_left<vtype>
-                                                   (expr_gen, v, operation, branch[0], result);
+                  const bool synthesis_result =
+                     synthesize_sf4ext_expression::template compile_left<vtype>
+                        (expr_gen, v, operation, branch[0], result);
 
                   if (synthesis_result)
                   {
@@ -28664,7 +29055,11 @@ namespace exprtk
                {
                   expression_node_ptr result = error_node();
 
-                  if (synthesize_sf4ext_expression::template compile_right<ctype>(expr_gen,c,operation,branch[1],result))
+                  const bool synthesis_result =
+                     synthesize_sf4ext_expression::template compile_right<ctype>
+                        (expr_gen, c, operation, branch[1], result);
+
+                  if (synthesis_result)
                   {
                      free_node(*expr_gen.node_allocator_,branch[1]);
 
@@ -28779,8 +29174,9 @@ namespace exprtk
                {
                   expression_node_ptr result = error_node();
 
-                  const bool synthesis_result = synthesize_sf4ext_expression::template compile_left<ctype>
-                                                   (expr_gen, c, operation, branch[0], result);
+                  const bool synthesis_result =
+                     synthesize_sf4ext_expression::template compile_left<ctype>
+                        (expr_gen, c, operation, branch[0], result);
 
                   if (synthesis_result)
                   {
@@ -29330,7 +29726,8 @@ namespace exprtk
                if (!expr_gen.sf3_optimisable(id,sf3opr))
                   return false;
                else
-                  result = synthesize_sf3ext_expression::template process<T0,T1,T2>(expr_gen,sf3opr,t0,t1,t2);
+                  result = synthesize_sf3ext_expression::template process<T0, T1, T2>
+                              (expr_gen, sf3opr, t0, t1, t2);
 
                return true;
             }
@@ -29397,7 +29794,7 @@ namespace exprtk
                if (!expr_gen.sf4_optimisable(id,sf4opr))
                   return false;
                else
-                  result = synthesize_sf4ext_expression::template process<T0,T1,T2,T3>
+                  result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3>
                               (expr_gen, sf4opr, t0, t1, t2, t3);
 
                return true;
@@ -29422,23 +29819,23 @@ namespace exprtk
                switch (n->type())
                {
                   case details::expression_node<Type>::e_covoc : return compile_right_impl
-                                                                    <typename covoc_t::sf3_type_node,ExternalType,ctype,vtype,ctype>
+                                                                    <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_covov : return compile_right_impl
-                                                                    <typename covov_t::sf3_type_node,ExternalType,ctype,vtype,vtype>
+                                                                    <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_vocov : return compile_right_impl
-                                                                    <typename vocov_t::sf3_type_node,ExternalType,vtype,ctype,vtype>
+                                                                    <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_vovoc : return compile_right_impl
-                                                                    <typename vovoc_t::sf3_type_node,ExternalType,vtype,vtype,ctype>
+                                                                    <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_vovov : return compile_right_impl
-                                                                    <typename vovov_t::sf3_type_node,ExternalType,vtype,vtype,vtype>
+                                                                    <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   default                                      : return false;
@@ -29465,23 +29862,23 @@ namespace exprtk
                switch (n->type())
                {
                   case details::expression_node<Type>::e_covoc : return compile_left_impl
-                                                                    <typename covoc_t::sf3_type_node,ExternalType,ctype,vtype,ctype>
+                                                                    <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_covov : return compile_left_impl
-                                                                    <typename covov_t::sf3_type_node,ExternalType,ctype,vtype,vtype>
+                                                                    <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_vocov : return compile_left_impl
-                                                                    <typename vocov_t::sf3_type_node,ExternalType,vtype,ctype,vtype>
+                                                                    <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_vovoc : return compile_left_impl
-                                                                    <typename vovoc_t::sf3_type_node,ExternalType,vtype,vtype,ctype>
+                                                                    <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   case details::expression_node<Type>::e_vovov : return compile_left_impl
-                                                                    <typename vovov_t::sf3_type_node,ExternalType,vtype,vtype,vtype>
+                                                                    <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
                                                                        (expr_gen, id, t, sf3node, result);
 
                   default                                      : return false;
@@ -29503,7 +29900,7 @@ namespace exprtk
                   T1 t1 = n->t1();
                   T2 t2 = n->t2();
 
-                  return synthesize_sf4ext_expression::template compile<ExternalType,T0,T1,T2>
+                  return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2>
                             (expr_gen, id, t, t0, t1, t2, result);
                }
                else
@@ -29525,7 +29922,7 @@ namespace exprtk
                   T1 t1 = n->t1();
                   T2 t2 = n->t2();
 
-                  return synthesize_sf4ext_expression::template compile<T0,T1,T2,ExternalType>
+                  return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType>
                             (expr_gen, id, t0, t1, t2, t, result);
                }
                else
@@ -30133,7 +30530,7 @@ namespace exprtk
 
                const bool synthesis_result =
                   synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
-                     (expr_gen, id(expr_gen, o0, o1), c0, v, c1,result);
+                     (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
 
                if (synthesis_result)
                   return result;
@@ -30629,7 +31026,7 @@ namespace exprtk
 
                const bool synthesis_result =
                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
-                     (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3,result);
+                     (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
 
                if (synthesis_result)
                   return result;
@@ -34255,8 +34652,8 @@ namespace exprtk
          {
             const std::string  s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  ();
                   std::string& s1 = static_cast<details::string_range_node<Type>*>      (branch[1])->ref  ();
-            range_t           rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
-            range_t           rp1 = static_cast<details::string_range_node<Type>*>      (branch[1])->range();
+            const range_t     rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
+            const range_t     rp1 = static_cast<details::string_range_node<Type>*>      (branch[1])->range();
 
             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
             static_cast<details::string_range_node<Type>*>      (branch[1])->range_ref().clear();
@@ -34269,9 +34666,9 @@ namespace exprtk
 
          inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
          {
-            std::string       s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  ();
+            const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  ();
             const std::string s1 = static_cast<details::string_literal_node<Type>*>    (branch[1])->str  ();
-            range_t          rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
+            const range_t    rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
 
             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
 
@@ -34282,10 +34679,10 @@ namespace exprtk
 
          inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
          {
-            std::string   s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  ();
-            std::string   s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  ();
-            range_t      rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
-            range_t      rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
+            const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  ();
+            const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  ();
+            const range_t    rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
+            const range_t    rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
 
             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
@@ -34435,9 +34832,9 @@ namespace exprtk
                std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
                std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
 
-               typedef typename details::sosos_node<Type,std::string&,std::string&,std::string&,details::inrange_op<Type> > inrange_t;
+               typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
 
-               return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string&>(s0,s1,s2);
+               return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2);
             }
             else if (
                       details::is_const_string_node(branch[0]) &&
@@ -34449,12 +34846,12 @@ namespace exprtk
                std::string& s1 = static_cast<     details::stringvar_node<Type>*>(branch[1])->ref();
                std::string  s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
 
-               typedef typename details::sosos_node<Type,std::string,std::string&,std::string,details::inrange_op<Type> > inrange_t;
+               typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t;
 
                details::free_node(*node_allocator_,branch[0]);
                details::free_node(*node_allocator_,branch[2]);
 
-               return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string>(s0,s1,s2);
+               return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2);
             }
             else if (
                             details::is_string_node(branch[0]) &&
@@ -34466,11 +34863,11 @@ namespace exprtk
                std::string   s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
                std::string&  s2 = static_cast<     details::stringvar_node<Type>*>(branch[2])->ref();
 
-               typedef typename details::sosos_node<Type,std::string&,std::string,std::string&,details::inrange_op<Type> > inrange_t;
+               typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t;
 
                details::free_node(*node_allocator_,branch[1]);
 
-               return node_allocator_->allocate_type<inrange_t,std::string&,std::string,std::string&>(s0,s1,s2);
+               return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2);
             }
             else if (
                       details::is_string_node(branch[0]) &&
@@ -34482,11 +34879,11 @@ namespace exprtk
                std::string& s1 = static_cast<     details::stringvar_node<Type>*>(branch[1])->ref();
                std::string  s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
 
-               typedef typename details::sosos_node<Type,std::string&,std::string&,std::string,details::inrange_op<Type> > inrange_t;
+               typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t;
 
                details::free_node(*node_allocator_,branch[2]);
 
-               return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string>(s0,s1,s2);
+               return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2);
             }
             else if (
                       details::is_const_string_node(branch[0]) &&
@@ -34498,11 +34895,11 @@ namespace exprtk
                std::string& s1 = static_cast<     details::stringvar_node<Type>*>(branch[1])->ref();
                std::string& s2 = static_cast<     details::stringvar_node<Type>*>(branch[2])->ref();
 
-               typedef typename details::sosos_node<Type,std::string,std::string&,std::string&,details::inrange_op<Type> > inrange_t;
+               typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
 
                details::free_node(*node_allocator_,branch[0]);
 
-               return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string&>(s0,s1,s2);
+               return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2);
             }
             else
                return error_node();
@@ -34530,8 +34927,8 @@ namespace exprtk
 
             typedef typename details::null_eq_node<T> nulleq_node_t;
 
-            bool b0_null = details::is_null_node(branch[0]);
-            bool b1_null = details::is_null_node(branch[1]);
+            const bool b0_null = details::is_null_node(branch[0]);
+            const bool b1_null = details::is_null_node(branch[1]);
 
             if (b0_null && b1_null)
             {
@@ -34636,7 +35033,7 @@ namespace exprtk
 
                if (is_constant_foldable<N>(branch))
                {
-                  Type v = expression_point->value();
+                  const Type v = expression_point->value();
                   details::free_node(*node_allocator_,expression_point);
 
                   return node_allocator_->allocate<literal_node_t>(v);
@@ -35015,36 +35412,110 @@ namespace exprtk
       friend void details::disable_type_checking(ParserType& p);
    };
 
+   namespace details
+   {
+      template <typename T>
+      struct collector_helper
+      {
+         typedef exprtk::symbol_table<T> symbol_table_t;
+         typedef exprtk::expression<T>     expression_t;
+         typedef exprtk::parser<T>             parser_t;
+         typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
+         typedef typename parser_t::unknown_symbol_resolver usr_t;
+
+         struct resolve_as_vector : public parser_t::unknown_symbol_resolver
+         {
+            typedef exprtk::parser<T> parser_t;
+
+            resolve_as_vector()
+            : usr_t(usr_t::e_usrmode_extended)
+            {}
+
+            virtual bool process(const std::string& unknown_symbol,
+                                 symbol_table_t& symbol_table,
+                                 std::string&)
+            {
+               static T v[1];
+               symbol_table.add_vector(unknown_symbol,v);
+               return true;
+            }
+         };
+
+         static inline bool collection_pass(const std::string& expression_string,
+                                            std::set<std::string>& symbol_set,
+                                            const bool collect_variables,
+                                            const bool collect_functions,
+                                            const bool vector_pass,
+                                            symbol_table_t& ext_symbol_table)
+         {
+            symbol_table_t symbol_table;
+            expression_t   expression;
+            parser_t       parser;
+
+            resolve_as_vector vect_resolver;
+
+            expression.register_symbol_table(symbol_table    );
+            expression.register_symbol_table(ext_symbol_table);
+
+            if (vector_pass)
+               parser.enable_unknown_symbol_resolver(&vect_resolver);
+            else
+               parser.enable_unknown_symbol_resolver();
+
+            if (collect_variables)
+               parser.dec().collect_variables() = true;
+
+            if (collect_functions)
+               parser.dec().collect_functions() = true;
+
+            bool pass_result = false;
+
+            details::disable_type_checking(parser);
+
+            if (parser.compile(expression_string, expression))
+            {
+               pass_result = true;
+
+               std::deque<symbol_t> symb_list;
+               parser.dec().symbols(symb_list);
+
+               for (std::size_t i = 0; i < symb_list.size(); ++i)
+               {
+                  symbol_set.insert(symb_list[i].first);
+               }
+            }
+
+            return pass_result;
+         }
+      };
+   }
+
    template <typename Allocator,
              template <typename, typename> class Sequence>
-   inline bool collect_variables(const std::string& expr_str,
+   inline bool collect_variables(const std::string& expression,
                                  Sequence<std::string, Allocator>& symbol_list)
    {
       typedef double T;
-      typedef exprtk::symbol_table<T> symbol_table_t;
-      typedef exprtk::expression<T>     expression_t;
-      typedef exprtk::parser<T>             parser_t;
-      typedef parser_t::dependent_entity_collector::symbol_t symbol_t;
+      typedef details::collector_helper<T> collect_t;
 
-      symbol_table_t symbol_table;
-      expression_t   expression;
-      parser_t       parser;
+      collect_t::symbol_table_t null_symbol_table;
 
-      expression.register_symbol_table(symbol_table);
+      std::set<std::string> symbol_set;
 
-      parser.enable_unknown_symbol_resolver();
-      parser.dec().collect_variables() = true;
+      const bool variable_pass = collect_t::collection_pass
+                                    (expression, symbol_set, true, false, false, null_symbol_table);
+      const bool vector_pass   = collect_t::collection_pass
+                                    (expression, symbol_set, true, false,  true, null_symbol_table);
 
-      if (!parser.compile(expr_str, expression))
+      if (!variable_pass && !vector_pass)
          return false;
 
-      std::deque<symbol_t> symb_list;
+      std::set<std::string>::iterator itr = symbol_set.begin();
 
-      parser.dec().symbols(symb_list);
-
-      for (std::size_t i = 0; i < symb_list.size(); ++i)
+      while (symbol_set.end() != itr)
       {
-         symbol_list.push_back(symb_list[i].first);
+         symbol_list.push_back(*itr);
+         ++itr;
       }
 
       return true;
@@ -35053,37 +35524,28 @@ namespace exprtk
    template <typename T,
              typename Allocator,
              template <typename, typename> class Sequence>
-   inline bool collect_variables(const std::string& expr_str,
+   inline bool collect_variables(const std::string& expression,
                                  exprtk::symbol_table<T>& extrnl_symbol_table,
                                  Sequence<std::string, Allocator>& symbol_list)
    {
-      typedef exprtk::symbol_table<T> symbol_table_t;
-      typedef exprtk::expression<T>     expression_t;
-      typedef exprtk::parser<T>             parser_t;
-      typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
+      typedef details::collector_helper<T> collect_t;
 
-      symbol_table_t symbol_table;
-      expression_t   expression;
-      parser_t       parser;
+      std::set<std::string> symbol_set;
 
-      expression.register_symbol_table(symbol_table);
-      expression.register_symbol_table(extrnl_symbol_table);
+      const bool variable_pass = collect_t::collection_pass
+                                    (expression, symbol_set, true, false, false, extrnl_symbol_table);
+      const bool vector_pass   = collect_t::collection_pass
+                                    (expression, symbol_set, true, false,  true, extrnl_symbol_table);
 
-      parser.enable_unknown_symbol_resolver();
-      parser.dec().collect_variables() = true;
-
-      details::disable_type_checking(parser);
-
-      if (!parser.compile(expr_str, expression))
+      if (!variable_pass && !vector_pass)
          return false;
 
-      std::deque<symbol_t> symb_list;
+      std::set<std::string>::iterator itr = symbol_set.begin();
 
-      parser.dec().symbols(symb_list);
-
-      for (std::size_t i = 0; i < symb_list.size(); ++i)
+      while (symbol_set.end() != itr)
       {
-         symbol_list.push_back(symb_list[i].first);
+         symbol_list.push_back(*itr);
+         ++itr;
       }
 
       return true;
@@ -35091,34 +35553,30 @@ namespace exprtk
 
    template <typename Allocator,
              template <typename, typename> class Sequence>
-   inline bool collect_functions(const std::string& expr_str,
+   inline bool collect_functions(const std::string& expression,
                                  Sequence<std::string, Allocator>& symbol_list)
    {
       typedef double T;
-      typedef exprtk::symbol_table<T> symbol_table_t;
-      typedef exprtk::expression<T>     expression_t;
-      typedef exprtk::parser<T>             parser_t;
-      typedef parser_t::dependent_entity_collector::symbol_t symbol_t;
+      typedef details::collector_helper<T> collect_t;
 
-      symbol_table_t symbol_table;
-      expression_t   expression;
-      parser_t       parser;
+      collect_t::symbol_table_t null_symbol_table;
 
-      expression.register_symbol_table(symbol_table);
+      std::set<std::string> symbol_set;
 
-      parser.enable_unknown_symbol_resolver();
-      parser.dec().collect_functions() = true;
+      const bool variable_pass = collect_t::collection_pass
+                                    (expression, symbol_set, false, true, false, null_symbol_table);
+      const bool vector_pass   = collect_t::collection_pass
+                                    (expression, symbol_set, false, true,  true, null_symbol_table);
 
-      if (!parser.compile(expr_str, expression))
+      if (!variable_pass && !vector_pass)
          return false;
 
-      std::deque<symbol_t> symb_list;
+      std::set<std::string>::iterator itr = symbol_set.begin();
 
-      parser.dec().symbols(symb_list);
-
-      for (std::size_t i = 0; i < symb_list.size(); ++i)
+      while (symbol_set.end() != itr)
       {
-         symbol_list.push_back(symb_list[i].first);
+         symbol_list.push_back(*itr);
+         ++itr;
       }
 
       return true;
@@ -35127,37 +35585,28 @@ namespace exprtk
    template <typename T,
              typename Allocator,
              template <typename, typename> class Sequence>
-   inline bool collect_functions(const std::string& expr_str,
+   inline bool collect_functions(const std::string& expression,
                                  exprtk::symbol_table<T>& extrnl_symbol_table,
                                  Sequence<std::string, Allocator>& symbol_list)
    {
-      typedef exprtk::symbol_table<T> symbol_table_t;
-      typedef exprtk::expression<T>     expression_t;
-      typedef exprtk::parser<T>             parser_t;
-      typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
+      typedef details::collector_helper<T> collect_t;
 
-      symbol_table_t symbol_table;
-      expression_t   expression;
-      parser_t       parser;
+      std::set<std::string> symbol_set;
 
-      expression.register_symbol_table(symbol_table);
-      expression.register_symbol_table(extrnl_symbol_table);
+      const bool variable_pass = collect_t::collection_pass
+                                    (expression, symbol_set, false, true, false, extrnl_symbol_table);
+      const bool vector_pass   = collect_t::collection_pass
+                                    (expression, symbol_set, false, true,  true, extrnl_symbol_table);
 
-      parser.enable_unknown_symbol_resolver();
-      parser.dec().collect_functions() = true;
-
-      details::disable_type_checking(parser);
-
-      if (!parser.compile(expr_str, expression))
+      if (!variable_pass && !vector_pass)
          return false;
 
-      std::deque<symbol_t> symb_list;
+      std::set<std::string>::iterator itr = symbol_set.begin();
 
-      parser.dec().symbols(symb_list);
-
-      for (std::size_t i = 0; i < symb_list.size(); ++i)
+      while (symbol_set.end() != itr)
       {
-         symbol_list.push_back(symb_list[i].first);
+         symbol_list.push_back(*itr);
+         ++itr;
       }
 
       return true;
@@ -35204,7 +35653,7 @@ namespace exprtk
       {
          T& x = var->ref();
          T  x_original = x;
-         T result = integrate(e,x,r0,r1,number_of_intervals);
+         T result = integrate(e, x, r0, r1, number_of_intervals);
          x = x_original;
 
          return result;
@@ -35295,7 +35744,7 @@ namespace exprtk
       {
          T& x = var->ref();
          T x_original = x;
-         T result = derivative(e,x,h);
+         T result = derivative(e, x, h);
          x = x_original;
 
          return result;
@@ -35322,7 +35771,7 @@ namespace exprtk
       {
          T& x = var->ref();
          const T x_original = x;
-         const T result = second_derivative(e,x,h);
+         const T result = second_derivative(e, x, h);
          x = x_original;
 
          return result;
@@ -35349,7 +35798,7 @@ namespace exprtk
       {
          T& x = var->ref();
          const T x_original = x;
-         const T result = third_derivative(e,x,h);
+         const T result = third_derivative(e, x, h);
          x = x_original;
 
          return result;
@@ -35642,62 +36091,62 @@ namespace exprtk
 
       inline virtual T operator() (const T& x, const T& c1, const T& c0)
       {
-         poly_rtrn(1) poly_impl<T,1>::evaluate(x,c1,c0);
+         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)
       {
-         poly_rtrn(2) poly_impl<T,2>::evaluate(x,c2,c1,c0);
+         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)
       {
-         poly_rtrn(3) poly_impl<T,3>::evaluate(x,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(4) poly_impl<T,4>::evaluate(x,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(5) poly_impl<T,5>::evaluate(x,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(6) poly_impl<T,6>::evaluate(x,c6,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(7) poly_impl<T,7>::evaluate(x,c7,c6,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(8) poly_impl<T,8>::evaluate(x,c8,c7,c6,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(9) poly_impl<T,9>::evaluate(x,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(10) poly_impl<T,10>::evaluate(x,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(11) poly_impl<T,11>::evaluate(x,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
+         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)
       {
-         poly_rtrn(12) poly_impl<T,12>::evaluate(x,c12,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
+         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
@@ -36464,89 +36913,90 @@ namespace exprtk
    template <typename T>
    inline bool pgo_primer()
    {
-      static const std::string expression_list[]
-                                        = {
-                                             "(y + x)",
-                                             "2 * (y + x)",
-                                             "(2 * y + 2 * x)",
-                                             "(y + x / y) * (x - y / x)",
-                                             "x / ((x + y) * (x - y)) / y",
-                                             "1 - ((x * y) + (y / x)) - 3",
-                                             "sin(2 * x) + cos(pi / y)",
-                                             "1 - sin(2 * x) + cos(pi / y)",
-                                             "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
-                                             "(x^2 / sin(2 * pi / y)) -x / 2",
-                                             "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
-                                             "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
-                                             "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
-                                             "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
-                                             "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
-                                             "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
-                                             "(yy + xx)",
-                                             "2 * (yy + xx)",
-                                             "(2 * yy + 2 * xx)",
-                                             "(yy + xx / yy) * (xx - yy / xx)",
-                                             "xx / ((xx + yy) * (xx - yy)) / yy",
-                                             "1 - ((xx * yy) + (yy / xx)) - 3",
-                                             "sin(2 * xx) + cos(pi / yy)",
-                                             "1 - sin(2 * xx) + cos(pi / yy)",
-                                             "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
-                                             "(xx^2 / sin(2 * pi / yy)) -xx / 2",
-                                             "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
-                                             "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
-                                             "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
-                                             "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
-                                             "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55",
-                                             "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))",
-                                             "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)",
-                                             "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)",
-                                             "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)",
-                                             "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)",
-                                             "(x + 2) * 3", "x + (2 * 3)",
-                                             "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)",
-                                             "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)",
-                                             "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))",
-                                             "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))",
-                                             "2 + (x * (y / 3))", "x + (2 * (3 / y))",
-                                             "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)",
-                                             "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)",
-                                             "x + ((2 * 3) / y)", "(((x + y) * z) / w)",
-                                             "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)",
-                                             "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)",
-                                             "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)",
-                                             "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)",
-                                             "((x + (2 * 3)) / y)",
-                                             "(xx + yy) * zz", "xx + (yy * zz)",
-                                             "(xx + yy) * 7", "xx + (yy * 7)",
-                                             "(xx + 7) * yy", "xx + (7 * yy)",
-                                             "(7 + xx) * yy", "7 + (xx * yy)",
-                                             "(2 + x) * 3", "2 + (x * 3)",
-                                             "(2 + 3) * x", "2 + (3 * x)",
-                                             "(x + 2) * 3", "x + (2 * 3)",
-                                             "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)",
-                                             "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)",
-                                             "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)",
-                                             "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)",
-                                             "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))",
-                                             "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))",
-                                             "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))",
-                                             "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))",
-                                             "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))",
-                                             "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)",
-                                             "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)",
-                                             "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)",
-                                             "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)",
-                                             "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)",
-                                             "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)",
-                                             "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)",
-                                             "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)",
-                                             "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)",
-                                             "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)",
-                                             "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)",
-                                             "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)",
-                                             "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)",
-                                             "((xx + (2 * 3)) / yy)"
-                                          };
+      static const std::string expression_list[] =
+             {
+                "(y + x)",
+                "2 * (y + x)",
+                "(2 * y + 2 * x)",
+                "(y + x / y) * (x - y / x)",
+                "x / ((x + y) * (x - y)) / y",
+                "1 - ((x * y) + (y / x)) - 3",
+                "sin(2 * x) + cos(pi / y)",
+                "1 - sin(2 * x) + cos(pi / y)",
+                "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
+                "(x^2 / sin(2 * pi / y)) -x / 2",
+                "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
+                "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
+                "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
+                "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
+                "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
+                "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
+                "(yy + xx)",
+                "2 * (yy + xx)",
+                "(2 * yy + 2 * xx)",
+                "(yy + xx / yy) * (xx - yy / xx)",
+                "xx / ((xx + yy) * (xx - yy)) / yy",
+                "1 - ((xx * yy) + (yy / xx)) - 3",
+                "sin(2 * xx) + cos(pi / yy)",
+                "1 - sin(2 * xx) + cos(pi / yy)",
+                "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
+                "(xx^2 / sin(2 * pi / yy)) -xx / 2",
+                "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
+                "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
+                "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
+                "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
+                "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55",
+                "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))",
+                "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)",
+                "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)",
+                "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)",
+                "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)",
+                "(x + 2) * 3", "x + (2 * 3)",
+                "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)",
+                "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)",
+                "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))",
+                "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))",
+                "2 + (x * (y / 3))", "x + (2 * (3 / y))",
+                "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)",
+                "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)",
+                "x + ((2 * 3) / y)", "(((x + y) * z) / w)",
+                "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)",
+                "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)",
+                "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)",
+                "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)",
+                "((x + (2 * 3)) / y)",
+                "(xx + yy) * zz", "xx + (yy * zz)",
+                "(xx + yy) * 7", "xx + (yy * 7)",
+                "(xx + 7) * yy", "xx + (7 * yy)",
+                "(7 + xx) * yy", "7 + (xx * yy)",
+                "(2 + x) * 3", "2 + (x * 3)",
+                "(2 + 3) * x", "2 + (3 * x)",
+                "(x + 2) * 3", "x + (2 * 3)",
+                "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)",
+                "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)",
+                "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)",
+                "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)",
+                "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))",
+                "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))",
+                "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))",
+                "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))",
+                "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))",
+                "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)",
+                "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)",
+                "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)",
+                "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)",
+                "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)",
+                "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)",
+                "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)",
+                "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)",
+                "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)",
+                "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)",
+                "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)",
+                "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)",
+                "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)",
+                "((xx + (2 * 3)) / yy)"
+             };
+
       static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
 
       T  x = T(0);
@@ -36731,14 +37181,14 @@ namespace exprtk
          {
             if (stop_time_.tv_sec >= start_time_.tv_sec)
             {
-               return 1000000LLU * static_cast<unsigned long long int>(stop_time_.tv_sec  - start_time_.tv_sec ) +
-                                   static_cast<unsigned long long int>(stop_time_.tv_usec - start_time_.tv_usec) ;
+               return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec  - start_time_.tv_sec ) +
+                                   static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ;
             }
             else
-               return std::numeric_limits<unsigned long long int>::max();
+               return std::numeric_limits<details::_uint64_t>::max();
          }
          else
-            return std::numeric_limits<unsigned long long int>::max();
+            return std::numeric_limits<details::_uint64_t>::max();
       }
 
       inline double time() const
@@ -38531,7 +38981,7 @@ namespace exprtk
          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("copy"         ,cp)
          exprtk_register_function("rotate_left"  ,rl)
          exprtk_register_function("rol"          ,rl)
          exprtk_register_function("rotate_right" ,rr)
@@ -38565,9 +39015,9 @@ namespace exprtk
    namespace information
    {
       static const char* library = "Mathematical Expression Toolkit";
-      static const char* version = "2.71828182845904523536028747135266249775724709369995"
-                                   "9574966967627724076630353547594571382178525166427427";
-      static const char* date    = "20190101";
+      static const char* version = "2.7182818284590452353602874713526624977572470936999595749"
+                                   "669676277240766303535475945713821785251664274274663919320";
+      static const char* date    = "20200101";
 
       static inline std::string data()
       {
diff --git a/exprtk_benchmark.cpp b/exprtk_benchmark.cpp
index 318a042..8e9c5fa 100644
--- a/exprtk_benchmark.cpp
+++ b/exprtk_benchmark.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * ExprTk vs Native Benchmarks                                *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
diff --git a/exprtk_simple_example_01.cpp b/exprtk_simple_example_01.cpp
index 7a586ce..80eafe1 100644
--- a/exprtk_simple_example_01.cpp
+++ b/exprtk_simple_example_01.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 1                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,8 @@ void trig_function()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
+   const std::string expression_string =
+                     "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
 
    T x;
 
@@ -45,8 +46,8 @@ void trig_function()
 
    for (x = T(-5); x <= T(+5); x += T(0.001))
    {
-      T y = expression.value();
-      printf("%19.15f\t%19.15f\n",x,y);
+      const T y = expression.value();
+      printf("%19.15f\t%19.15f\n", x, y);
    }
 }
 
diff --git a/exprtk_simple_example_02.cpp b/exprtk_simple_example_02.cpp
index 94f18aa..56b9c9b 100644
--- a/exprtk_simple_example_02.cpp
+++ b/exprtk_simple_example_02.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 2                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,14 +29,15 @@ void square_wave()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string expr_string = "a*(4/pi)*"
-                             "((1 /1)*sin( 2*pi*f*t)+(1 /3)*sin( 6*pi*f*t)+"
-                             " (1 /5)*sin(10*pi*f*t)+(1 /7)*sin(14*pi*f*t)+"
-                             " (1 /9)*sin(18*pi*f*t)+(1/11)*sin(22*pi*f*t)+"
-                             " (1/13)*sin(26*pi*f*t)+(1/15)*sin(30*pi*f*t)+"
-                             " (1/17)*sin(34*pi*f*t)+(1/19)*sin(38*pi*f*t)+"
-                             " (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
-                             " (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
+   const std::string expr_string =
+                  "a*(4/pi)*"
+                  "((1 /1)*sin( 2*pi*f*t)+(1 /3)*sin( 6*pi*f*t)+"
+                  " (1 /5)*sin(10*pi*f*t)+(1 /7)*sin(14*pi*f*t)+"
+                  " (1 /9)*sin(18*pi*f*t)+(1/11)*sin(22*pi*f*t)+"
+                  " (1/13)*sin(26*pi*f*t)+(1/15)*sin(30*pi*f*t)+"
+                  " (1/17)*sin(34*pi*f*t)+(1/19)*sin(38*pi*f*t)+"
+                  " (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
+                  " (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
 
    static const T pi = T(3.141592653589793238462643383279502);
 
@@ -60,8 +61,8 @@ void square_wave()
 
    for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta)
    {
-      T result = expression.value();
-      printf("%19.15f\t%19.15f\n",t,result);
+      const T result = expression.value();
+      printf("%19.15f\t%19.15f\n", t, result);
    }
 }
 
diff --git a/exprtk_simple_example_03.cpp b/exprtk_simple_example_03.cpp
index 6d1528e..8e5a164 100644
--- a/exprtk_simple_example_03.cpp
+++ b/exprtk_simple_example_03.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 3                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,8 @@ void polynomial()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string expression_string = "25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1";
+   const std::string expression_string =
+                  "25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1";
 
    const T r0 = T(0);
    const T r1 = T(1);
@@ -48,7 +49,7 @@ void polynomial()
 
    for (x = r0; x <= r1; x += delta)
    {
-      printf("%19.15f\t%19.15f\n",x,expression.value());
+      printf("%19.15f\t%19.15f\n", x, expression.value());
    }
 }
 
diff --git a/exprtk_simple_example_04.cpp b/exprtk_simple_example_04.cpp
index 6a8c81e..aca7014 100644
--- a/exprtk_simple_example_04.cpp
+++ b/exprtk_simple_example_04.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 4                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -73,7 +73,7 @@ void fibonacci()
    {
       x = static_cast<T>(i);
 
-      T result = expression.value();
+      const T result = expression.value();
 
       printf("fibonacci(%3d) = %10.0f\n",
              static_cast<int>(i),
diff --git a/exprtk_simple_example_05.cpp b/exprtk_simple_example_05.cpp
index 2902f8b..50d7987 100644
--- a/exprtk_simple_example_05.cpp
+++ b/exprtk_simple_example_05.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 5                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -50,7 +50,7 @@ void custom_function()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string expression_string =
+   const std::string expression_string =
                   "myfunc(sin(x / pi), otherfunc(3 * y, x / 2, x * y))";
 
    T x = T(1);
@@ -70,7 +70,7 @@ void custom_function()
    parser_t parser;
    parser.compile(expression_string,expression);
 
-   T result = expression.value();
+   const T result = expression.value();
    printf("Result: %10.5f\n",result);
 }
 
diff --git a/exprtk_simple_example_06.cpp b/exprtk_simple_example_06.cpp
index 9cb6dc0..0af6f8b 100644
--- a/exprtk_simple_example_06.cpp
+++ b/exprtk_simple_example_06.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 6                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,7 @@ void vector_function()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string expression_string =
+   const std::string expression_string =
                   " for (var i := 0; i < min(x[],y[],z[]); i += 1) "
                   " {                                              "
                   "   z[i] := 3sin(x[i]) + 2log(y[i]);             "
diff --git a/exprtk_simple_example_07.cpp b/exprtk_simple_example_07.cpp
index 208ae06..bdf3c3b 100644
--- a/exprtk_simple_example_07.cpp
+++ b/exprtk_simple_example_07.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 7                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,7 @@ void logic()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string expression_string = "not(A and B) or C";
+   const std::string expression_string = "not(A and B) or C";
 
    symbol_table_t symbol_table;
    symbol_table.create_variable("A");
@@ -53,7 +53,7 @@ void logic()
       symbol_table.get_variable("B")->ref() = T((i & 0x02) ? 1 : 0);
       symbol_table.get_variable("C")->ref() = T((i & 0x04) ? 1 : 0);
 
-      int result = static_cast<int>(expression.value());
+      const int result = static_cast<int>(expression.value());
 
       printf(" %d | %d | %d | %d | %d \n",
              i,
diff --git a/exprtk_simple_example_08.cpp b/exprtk_simple_example_08.cpp
index 2ebe90c..4565098 100644
--- a/exprtk_simple_example_08.cpp
+++ b/exprtk_simple_example_08.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 8                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -65,7 +65,7 @@ void composite()
 
       for (std::size_t i = 0; i < parser.error_count(); ++i)
       {
-         err_t error = parser.get_error(i);
+         const err_t error = parser.get_error(i);
 
          printf("Error: %02d  Position: %02d Type: [%14s] Msg: %s\tExpression: %s\n",
                 static_cast<unsigned int>(i),
@@ -78,7 +78,7 @@ void composite()
       return;
    }
 
-   T result = expression.value();
+   const T result = expression.value();
 
    printf("%s = %e\n", expression_string.c_str(), result);
 }
diff --git a/exprtk_simple_example_09.cpp b/exprtk_simple_example_09.cpp
index 7a7ccb8..b11f193 100644
--- a/exprtk_simple_example_09.cpp
+++ b/exprtk_simple_example_09.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 9                                           *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -133,9 +133,9 @@ void primes()
    {
       x = static_cast<T>(i);
 
-      T result1 = expression1.value();
-      T result2 = expression2.value();
-      T result3 = expression3.value();
+      const T result1 = expression1.value();
+      const T result2 = expression2.value();
+      const T result3 = expression3.value();
 
       printf("%03d  Result1: %c  Result2: %c  Result3: %c\n",
              static_cast<unsigned int>(i),
diff --git a/exprtk_simple_example_10.cpp b/exprtk_simple_example_10.cpp
index 4cb66f2..13728da 100644
--- a/exprtk_simple_example_10.cpp
+++ b/exprtk_simple_example_10.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 10                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -64,7 +64,7 @@ void newton_sqrt()
            " }                                                     ",
            "x"));
 
-   std::string expression_str = "newton_sqrt(x)";
+   const std::string expression_str = "newton_sqrt(x)";
 
    expression_t expression;
    expression.register_symbol_table(symbol_table);
@@ -76,7 +76,7 @@ void newton_sqrt()
    {
       x = static_cast<T>(i);
 
-      T result = expression.value();
+      const T result = expression.value();
 
       printf("sqrt(%03d) - Result: %15.13f\tReal: %15.13f\n",
              static_cast<unsigned int>(i),
diff --git a/exprtk_simple_example_11.cpp b/exprtk_simple_example_11.cpp
index b625bc1..454c8f0 100644
--- a/exprtk_simple_example_11.cpp
+++ b/exprtk_simple_example_11.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 11                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,7 @@ void square_wave2()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string wave_program =
+   const std::string wave_program =
                   " var r := 0;                                         "
                   " for (var i := 0; i < 1000; i += 1)                  "
                   " {                                                   "
@@ -59,8 +59,8 @@ void square_wave2()
 
    for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta)
    {
-      T result = expression.value();
-      printf("%19.15f\t%19.15f\n",t,result);
+      const T result = expression.value();
+      printf("%19.15f\t%19.15f\n", t, result);
    }
 }
 
diff --git a/exprtk_simple_example_12.cpp b/exprtk_simple_example_12.cpp
index 3863c6f..ce398bd 100644
--- a/exprtk_simple_example_12.cpp
+++ b/exprtk_simple_example_12.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 12                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,7 @@ void bubble_sort()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string bubblesort_program =
+   const std::string bubblesort_program =
                   " var upper_bound := v[];                           "
                   " var swapped := false;                             "
                   " repeat                                            "
diff --git a/exprtk_simple_example_13.cpp b/exprtk_simple_example_13.cpp
index 24f3c22..e1922e8 100644
--- a/exprtk_simple_example_13.cpp
+++ b/exprtk_simple_example_13.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 13                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -31,7 +31,7 @@ void savitzky_golay_filter()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string sgfilter_program =
+   const std::string sgfilter_program =
                   " var weight[9] :=                                          "
                   "       {                                                   "
                   "         -21, 14,  39,                                     "
@@ -89,7 +89,7 @@ void savitzky_golay_filter()
 
    for (std::size_t i = 0; i < v_out.size(); ++i)
    {
-      printf("%10.6f\t%10.6f\n",v_in[i],v_out[i]);
+      printf("%10.6f\t%10.6f\n", v_in[i], v_out[i]);
    }
 }
 
diff --git a/exprtk_simple_example_14.cpp b/exprtk_simple_example_14.cpp
index 5541e63..bc508a2 100644
--- a/exprtk_simple_example_14.cpp
+++ b/exprtk_simple_example_14.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 14                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -28,7 +28,7 @@ void stddev_example()
    typedef exprtk::expression<T> expression_t;
    typedef exprtk::parser<T>         parser_t;
 
-   std::string stddev_program =
+   const std::string stddev_program =
                   " var x[25] := {                     "
                   "                 1,  2,  3,  4,  5, "
                   "                 6,  7,  8,  9, 10, "
@@ -44,7 +44,7 @@ void stddev_example()
    parser_t parser;
    parser.compile(stddev_program,expression);
 
-   T stddev = expression.value();
+   const T stddev = expression.value();
 
    printf("stddev(1..25) = %10.6f\n",stddev);
 }
diff --git a/exprtk_simple_example_15.cpp b/exprtk_simple_example_15.cpp
index 4c34b93..f7364fd 100644
--- a/exprtk_simple_example_15.cpp
+++ b/exprtk_simple_example_15.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 15                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,7 @@ void black_scholes_merton_model()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string bsm_model_program =
+   const std::string bsm_model_program =
                   " var d1 := (log(s / x) + (r + v^2 / 2) * t) / (v * sqrt(t)); "
                   " var d2 := d1 - v * sqrt(t);                                 "
                   "                                                             "
@@ -71,7 +71,7 @@ void black_scholes_merton_model()
 
       printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
              callput_flag.c_str(),
-             s,x,t,r,v,
+             s, x, t, r, v,
              bsm);
    }
 
@@ -82,7 +82,7 @@ void black_scholes_merton_model()
 
       printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
              callput_flag.c_str(),
-             s,x,t,r,v,
+             s, x, t, r, v,
              bsm);
    }
 }
diff --git a/exprtk_simple_example_16.cpp b/exprtk_simple_example_16.cpp
index 5ce1489..cd76f84 100644
--- a/exprtk_simple_example_16.cpp
+++ b/exprtk_simple_example_16.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 16                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -30,7 +30,7 @@ void linear_least_squares()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string linear_least_squares_program =
+   const std::string linear_least_squares_program =
                   " if (x[] == y[])                                       "
                   " {                                                     "
                   "   beta  := (sum(x * y) - sum(x) * sum(y) / x[]) /     "
diff --git a/exprtk_simple_example_17.cpp b/exprtk_simple_example_17.cpp
index 1b92298..50263aa 100644
--- a/exprtk_simple_example_17.cpp
+++ b/exprtk_simple_example_17.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 17                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -47,7 +47,7 @@ void monte_carlo_pi()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string monte_carlo_pi_program =
+   const std::string monte_carlo_pi_program =
                   " var experiments[5 * 10^7] := [(rnd_01^2 + rnd_01^2) <= 1]; "
                   " 4 * sum(experiments) / experiments[];                      ";
 
diff --git a/exprtk_simple_example_18.cpp b/exprtk_simple_example_18.cpp
index 615cb83..4fabc72 100644
--- a/exprtk_simple_example_18.cpp
+++ b/exprtk_simple_example_18.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 18                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -29,7 +29,7 @@ void file_io()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string fileio_program =
+   const std::string fileio_program =
                 " var file_name := 'file.txt';                         "
                 " var stream    := null;                               "
                 "                                                      "
diff --git a/exprtk_simple_example_19.cpp b/exprtk_simple_example_19.cpp
index 8c786d1..5d0fc20 100644
--- a/exprtk_simple_example_19.cpp
+++ b/exprtk_simple_example_19.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Simple Example 19                                          *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -55,7 +55,7 @@ public:
       if (
            (1 == ps_index) &&
            !exprtk::rtl::vecops::helper::
-              load_vector_range<T>::process(parameters,r0,r1,1,2,0)
+              load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
          )
          return T(0);
 
@@ -84,7 +84,7 @@ void vector_randu()
    typedef exprtk::expression<T>     expression_t;
    typedef exprtk::parser<T>             parser_t;
 
-   std::string vecrandu_program =
+   const std::string vecrandu_program =
                 " var noise[6] := [0];                     "
                 "                                          "
                 " if (randu(noise,0,5) == false)           "
diff --git a/exprtk_test.cpp b/exprtk_test.cpp
index bb2960a..91e7593 100644
--- a/exprtk_test.cpp
+++ b/exprtk_test.cpp
@@ -3,7 +3,7 @@
  *         C++ Mathematical Expression Toolkit Library        *
  *                                                            *
  * Examples and Unit-Tests                                    *
- * Author: Arash Partow (1999-2019)                           *
+ * Author: Arash Partow (1999-2020)                           *
  * URL: http://www.partow.net/programming/exprtk/index.html   *
  *                                                            *
  * Copyright notice:                                          *
@@ -23,6 +23,7 @@
 #include <deque>
 #include <fstream>
 #include <iostream>
+#include <numeric>
 #include <string>
 #include <vector>
 
@@ -2839,7 +2840,14 @@ inline bool run_test03()
                                    "1+-+-+",
                                    "1===",
                                    "1====",
-                                   "[*][*][*][*][*]"
+                                   "[*][*][*][*][*]",
+
+                                   "var v[1] := {}; var s0appe0 := false; repeat s0appe0 false for(){(){}}",
+                                   "var v[2] := {}; repeat var s0appe0 := false; s0appe0 false for(){(){}}",
+                                   "var v[3] := {}; repeat var s0appe0 := false; for(){(){}} s0appe0 false",
+                                   "var v[4] := {}; repeat var s0appe0 := false; s0appe0 for(){(){}} false",
+                                   "var v[5] := {}; repeat for(){(){}} var s0appe0 := false; s0appe0 false",
+                                   "var v{};v ;v  60;v 60;v o5"
                                  };
 
       const std::size_t invalid_expr_size = sizeof(invalid_expr) / sizeof(std::string);
@@ -4242,6 +4250,62 @@ inline bool run_test10()
       }
    }
 
+   {
+      const std::string expression =
+                           "for (var i := 0; i < min(x[],y[],z[]); i += 1)"
+                           "{ z[i] := 3sin(x[i]) + 2log(y[i]); }";
+
+      std::vector<std::string> var_symbol_list;
+      std::vector<std::string> func_symbol_list;
+
+      if (!exprtk::collect_variables(expression, var_symbol_list))
+      {
+         printf("run_test10() - Failed to collect variables.\n");
+         return false;
+      }
+
+      if (!exprtk::collect_functions(expression, func_symbol_list))
+      {
+         printf("run_test10() - Failed to collect functions.\n");
+         return false;
+      }
+
+      std::sort(var_symbol_list .begin(), var_symbol_list .end());
+      std::sort(func_symbol_list.begin(), func_symbol_list.end());
+
+      std::vector<std::string> expected_var_symbol_list;
+      std::vector<std::string> expected_func_symbol_list;
+
+      expected_var_symbol_list.push_back("i");
+      expected_var_symbol_list.push_back("x");
+      expected_var_symbol_list.push_back("y");
+      expected_var_symbol_list.push_back("z");
+
+      expected_func_symbol_list.push_back("log");
+      expected_func_symbol_list.push_back("min");
+      expected_func_symbol_list.push_back("sin");
+
+      const bool var_result = (var_symbol_list.size() == expected_var_symbol_list.size()) &&
+                               std::equal(var_symbol_list.begin(),
+                                          var_symbol_list.end(),
+                                          expected_var_symbol_list.begin());
+      if (!var_result)
+      {
+         printf("run_test10() - Failed collected variable comparison between recieved and expected variables\n");
+         return false;
+      }
+
+      const bool func_result = (func_symbol_list.size() == expected_func_symbol_list.size()) &&
+                               std::equal(func_symbol_list.begin(),
+                                          func_symbol_list.end(),
+                                          expected_func_symbol_list.begin());
+      if (!func_result)
+      {
+         printf("run_test10() - Failed collected fuctions comparison between recieved and expected functions\n");
+         return false;
+      }
+   }
+
    {
       std::string expression_list[] =
       {
@@ -5746,6 +5810,109 @@ struct vararg_func : public exprtk::igeneric_function<T>
    }
 };
 
+template <typename T>
+struct vecrebase_func : public exprtk::igeneric_function<T>
+{
+   typedef typename exprtk::igeneric_function<T>::parameter_list_t
+                                                  parameter_list_t;
+
+   typedef typename exprtk::igeneric_function<T>::generic_type
+                                                  generic_type;
+
+   typedef typename generic_type::vector_view vector_t;
+
+   using exprtk::igeneric_function<T>::operator();
+
+   vecrebase_func()
+   : exprtk::igeneric_function<T>("V")
+   {}
+
+   inline T operator()(parameter_list_t params)
+   {
+      vector_t v(params[0]);
+      return std::accumulate(v.begin(), v.end(), T(0));
+   }
+};
+
+template <typename T>
+struct overload_func : exprtk::igeneric_function<T>
+{
+   typedef typename exprtk::igeneric_function<T> igfun_t;
+   typedef typename igfun_t::parameter_list_t    parameter_list_t;
+   typedef typename igfun_t::generic_type        generic_type;
+   typedef typename generic_type::vector_view    vector_t;
+
+   using exprtk::igeneric_function<T>::operator();
+
+   overload_func(const std::string& param_seq_list)
+   : exprtk::igeneric_function<T>(param_seq_list, igfun_t::e_rtrn_overload),
+     current_ps_index(std::numeric_limits<std::size_t>::max())
+   {
+      clear();
+   }
+
+   void clear()
+   {
+      current_ps_index  = std::numeric_limits<std::size_t>::max();
+      current_param_seq = "";
+   }
+
+   inline T operator()(const std::size_t& ps_index,
+                       parameter_list_t parameters)
+   {
+      current_ps_index = ps_index;
+      determine_param_seq(parameters);
+      return T(1);
+   }
+
+   inline T operator()(const std::size_t& ps_index,
+                       std::string& result,
+                       parameter_list_t parameters)
+   {
+      current_ps_index = ps_index;
+      determine_param_seq(parameters);
+      result = "string result";
+      return T(1);
+   }
+
+   void determine_param_seq(parameter_list_t parameters)
+   {
+      current_param_seq = "";
+
+      for (std::size_t i = 0; i < parameters.size(); ++i)
+      {
+         generic_type& gt = parameters[i];
+
+         switch (gt.type)
+         {
+            case generic_type::e_scalar : current_param_seq += "T";
+                                          break;
+
+            case generic_type::e_vector : current_param_seq += "V";
+                                          break;
+
+            case generic_type::e_string : current_param_seq += "S";
+                                          break;
+
+            default                     : continue;
+         }
+      }
+   }
+
+   std::size_t current_ps_index;
+   std::string current_param_seq;
+
+   struct test_result_t
+   {
+      test_result_t(const std::size_t psi, const std::string& ps)
+      : ps_index(psi),
+        param_seq(ps)
+      {}
+
+      std::size_t ps_index;
+      std::string param_seq;
+   };
+};
 
 template <typename T>
 inline bool run_test18()
@@ -6684,6 +6851,68 @@ inline bool run_test18()
          return false;
    }
 
+   {
+      typedef exprtk::symbol_table<T> symbol_table_t;
+      typedef exprtk::expression<T>     expression_t;
+      typedef exprtk::parser<T>             parser_t;
+
+      T v0[] = { T(0), T(1), T(2), T(3), T(4) };
+      T v1[] = { T(5), T(6), T(7), T(8), T(9) };
+
+      const std::size_t v0_size = sizeof(v0) / sizeof (T);
+      const std::size_t v1_size = sizeof(v1) / sizeof (T);
+
+      exprtk::vector_view<T> v = exprtk::make_vector_view(v0, v0_size);
+
+      vecrebase_func<T> vec_sum;
+
+      symbol_table_t symbol_table;
+      symbol_table.add_vector("v",v);
+      symbol_table.add_function("vec_sum",vec_sum);
+
+      expression_t expression;
+      expression.register_symbol_table(symbol_table);
+
+      parser_t parser;
+
+      const std::string expr_string = "vec_sum(v)";
+
+      if (!parser.compile(expr_string,expression))
+      {
+         printf("run_test18() - Error: %s\tExpression: %s\n",
+                parser.error().c_str(),
+                expr_string.c_str());
+
+         return false;
+      }
+
+      const T expected_result0 = std::accumulate(v0, v0 + v0_size,T(0));
+
+      if (expression.value() != expected_result0)
+      {
+         printf("run_test18() - Error in evaluation! (10.1) Expression: %s  Expected: %5.3f  Computed: %5.3f\n",
+                expr_string.c_str(),
+                expected_result0,
+                expression.value());
+
+         return false;
+      }
+
+      v.rebase(v1);
+
+      const T expected_result1 = std::accumulate(v1, v1 + v1_size,T(0));
+
+      if (expression.value() != expected_result1)
+      {
+         printf("run_test18() - Error in evaluation! (10.2) Expression: %s  Expected: %5.3f  Computed: %5.3f\n",
+                expr_string.c_str(),
+                expected_result1,
+                expression.value());
+
+         return false;
+      }
+   }
+
    {
       bool failure = false;
 
@@ -6816,7 +7045,7 @@ inline bool run_test18()
 
          if (result != T(1))
          {
-            printf("run_test18() - Error in evaluation! (10) Expression: %s\n",
+            printf("run_test18() - Error in evaluation! (11) Expression: %s\n",
                    expr_str_list[i].c_str());
 
             failure = true;
@@ -6827,6 +7056,295 @@ inline bool run_test18()
          return false;
    }
 
+   {
+      typedef exprtk::expression<T> expression_t;
+
+      std::string a = "a";
+      std::string b = "b";
+      std::string c = "c";
+      std::string d = "d";
+
+      T x = T(1.1);
+      T y = T(2.2);
+      T z = T(3.3);
+      T w = T(4.4);
+
+      overload_func<T> ovrld_func
+                        (
+                          "T:T|T:TT|T:TTT|T:TTTT|"
+                          "T:S|T:SS|T:SSS|T:SSSS|"
+                          "T:ST|T:STS|T:STST|"
+                          "T:TS|T:TST|T:TSTS|"
+                          "T:TTSS|T:SSTT|T:STTS|T:TSST"
+                        );
+
+      exprtk::symbol_table<T> symbol_table;
+
+      symbol_table.add_constants();
+      symbol_table.add_variable ("x",x);
+      symbol_table.add_variable ("y",y);
+      symbol_table.add_variable ("z",z);
+      symbol_table.add_variable ("w",w);
+
+      symbol_table.add_stringvar("a",a);
+      symbol_table.add_stringvar("b",b);
+      symbol_table.add_stringvar("c",c);
+      symbol_table.add_stringvar("d",d);
+
+      symbol_table.add_function("foo",ovrld_func);
+
+      typedef typename overload_func<T>::test_result_t test_result_t;
+      typedef std::pair<std::string, typename overload_func<T>::test_result_t> test_pack_t;
+
+      static const test_pack_t test_pack_list[] =
+                                  {
+                                    test_pack_t("foo(x)"                          , test_result_t( 0, "T"   )),
+                                    test_pack_t("foo(x, y)"                       , test_result_t( 1, "TT"  )),
+                                    test_pack_t("foo(x, y, z)"                    , test_result_t( 2, "TTT" )),
+                                    test_pack_t("foo(x, y, z, w)"                 , test_result_t( 3, "TTTT")),
+                                    test_pack_t("foo(x + y)"                      , test_result_t( 0, "T"   )),
+                                    test_pack_t("foo(x + y, y + z)"               , test_result_t( 1, "TT"  )),
+                                    test_pack_t("foo(x + y, y + z, z + w)"        , test_result_t( 2, "TTT" )),
+                                    test_pack_t("foo(x + y, y + z, z + w, w)"     , test_result_t( 3, "TTTT")),
+                                    test_pack_t("foo(a)"                          , test_result_t( 4, "S"   )),
+                                    test_pack_t("foo(a, b)"                       , test_result_t( 5, "SS"  )),
+                                    test_pack_t("foo(a, b, c)"                    , test_result_t( 6, "SSS" )),
+                                    test_pack_t("foo(a, b, c, d)"                 , test_result_t( 7, "SSSS")),
+                                    test_pack_t("foo(a + b)"                      , test_result_t( 4, "S"   )),
+                                    test_pack_t("foo(a + b, b + c)"               , test_result_t( 5, "SS"  )),
+                                    test_pack_t("foo(a + b, b + c, c + d)"        , test_result_t( 6, "SSS" )),
+                                    test_pack_t("foo(a + b, b + c, c + d, d)"     , test_result_t( 7, "SSSS")),
+                                    test_pack_t("foo(a, x)"                       , test_result_t( 8, "ST"  )),
+                                    test_pack_t("foo(a, x, b)"                    , test_result_t( 9, "STS" )),
+                                    test_pack_t("foo(a, x, b, y)"                 , test_result_t(10, "STST")),
+                                    test_pack_t("foo(a + b, x + y)"               , test_result_t( 8, "ST"  )),
+                                    test_pack_t("foo(a + b, x + y, b + c)"        , test_result_t( 9, "STS" )),
+                                    test_pack_t("foo(a + b, x + y, b + c, y + z)" , test_result_t(10, "STST")),
+                                    test_pack_t("foo(x, a)"                       , test_result_t(11, "TS"  )),
+                                    test_pack_t("foo(x, a, y)"                    , test_result_t(12, "TST" )),
+                                    test_pack_t("foo(x, a, y, b)"                 , test_result_t(13, "TSTS")),
+                                    test_pack_t("foo(x + y, a + b)"               , test_result_t(11, "TS"  )),
+                                    test_pack_t("foo(x + y, a + b, y + z)"        , test_result_t(12, "TST" )),
+                                    test_pack_t("foo(x + y, a + b, y + z, b + c)" , test_result_t(13, "TSTS")),
+                                    test_pack_t("foo(x, y, a, b)"                 , test_result_t(14, "TTSS")),
+                                    test_pack_t("foo(a, b, x, y)"                 , test_result_t(15, "SSTT")),
+                                    test_pack_t("foo(a, x, y, b)"                 , test_result_t(16, "STTS")),
+                                    test_pack_t("foo(x, a, b, y)"                 , test_result_t(17, "TSST")),
+                                    test_pack_t("foo(x + y, y + z, a + b, b + c)" , test_result_t(14, "TTSS")),
+                                    test_pack_t("foo(a + b, b + c, x + y, y + z)" , test_result_t(15, "SSTT")),
+                                    test_pack_t("foo(a + b, x + y, y + z, b + c)" , test_result_t(16, "STTS")),
+                                    test_pack_t("foo(x + y, a + b, b + c, y + z)" , test_result_t(17, "TSST"))
+                                  };
+
+      static const std::size_t test_pack_list_size = sizeof(test_pack_list) / sizeof(test_pack_t);
+
+      std::deque<expression_t> expression_list;
+
+      for (std::size_t i = 0; i < test_pack_list_size; ++i)
+      {
+         expression_t expression;
+         expression.register_symbol_table(symbol_table);
+
+         exprtk::parser<T> parser;
+
+         if (!parser.compile(test_pack_list[i].first, expression))
+         {
+            printf("run_test18() - (12) Overload VarArg Error: %s   Expression: %s\n",
+                   parser.error().c_str(),
+                   test_pack_list[i].first.c_str());
+
+            return false;
+         }
+         else
+            expression_list.push_back(expression);
+      }
+
+      bool failure = false;
+
+      for (std::size_t i = 0; i < expression_list.size(); ++i)
+      {
+         ovrld_func.clear();
+
+         if (T(1) != expression_list[i].value())
+         {
+            printf("run_test18() - Error in evaluation! (12) Expression: %s\n",
+                   test_pack_list[i].first.c_str());
+
+            failure = true;
+         }
+
+         if (ovrld_func.current_ps_index != test_pack_list[i].second.ps_index)
+         {
+            printf("run_test18() - Error with ps_index (12) Expression: %s  Expected: %d  Got: %d\n",
+                   test_pack_list[i].first.c_str(),
+                   static_cast<int>(test_pack_list[i].second.ps_index),
+                   static_cast<int>(ovrld_func.current_ps_index));
+
+            failure = true;
+         }
+
+         if (ovrld_func.current_param_seq != test_pack_list[i].second.param_seq)
+         {
+            printf("run_test18() - Error with parameter seq (12) Expression: %s  Expected: %s  Got: %s\n",
+                   test_pack_list[i].first.c_str(),
+                   test_pack_list[i].second.param_seq.c_str(),
+                   ovrld_func.current_param_seq.c_str());
+
+            failure = true;
+         }
+         ::fflush(stdout);
+      }
+
+      if (failure)
+         return false;
+   }
+
+   {
+      typedef exprtk::expression<T> expression_t;
+
+      std::string a = "a";
+      std::string b = "b";
+      std::string c = "c";
+      std::string d = "d";
+      std::string result = "";
+
+      T x = T(1.1);
+      T y = T(2.2);
+      T z = T(3.3);
+      T w = T(4.4);
+
+      overload_func<T> ovrld_func
+                        (
+                          "S:T|S:TT|S:TTT|S:TTTT|"
+                          "S:S|S:SS|S:SSS|S:SSSS|"
+                          "S:ST|S:STS|S:STST|"
+                          "S:TS|S:TST|S:TSTS|"
+                          "S:TTSS|S:SSTT|S:STTS|S:TSST"
+                        );
+
+      exprtk::symbol_table<T> symbol_table;
+
+      symbol_table.add_constants();
+      symbol_table.add_variable ("x",x);
+      symbol_table.add_variable ("y",y);
+      symbol_table.add_variable ("z",z);
+      symbol_table.add_variable ("w",w);
+
+      symbol_table.add_stringvar("a",a);
+      symbol_table.add_stringvar("b",b);
+      symbol_table.add_stringvar("c",c);
+      symbol_table.add_stringvar("d",d);
+      symbol_table.add_stringvar("result",result);
+
+      symbol_table.add_function("foo",ovrld_func);
+
+      typedef typename overload_func<T>::test_result_t test_result_t;
+      typedef std::pair<std::string, typename overload_func<T>::test_result_t> test_pack_t;
+
+      static const test_pack_t test_pack_list[] =
+                                  {
+                                    test_pack_t("result := foo(x)"                          , test_result_t( 0, "T"   )),
+                                    test_pack_t("result := foo(x, y)"                       , test_result_t( 1, "TT"  )),
+                                    test_pack_t("result := foo(x, y, z)"                    , test_result_t( 2, "TTT" )),
+                                    test_pack_t("result := foo(x, y, z, w)"                 , test_result_t( 3, "TTTT")),
+                                    test_pack_t("result := foo(x + y)"                      , test_result_t( 0, "T"   )),
+                                    test_pack_t("result := foo(x + y, y + z)"               , test_result_t( 1, "TT"  )),
+                                    test_pack_t("result := foo(x + y, y + z, z + w)"        , test_result_t( 2, "TTT" )),
+                                    test_pack_t("result := foo(x + y, y + z, z + w, w)"     , test_result_t( 3, "TTTT")),
+                                    test_pack_t("result := foo(a)"                          , test_result_t( 4, "S"   )),
+                                    test_pack_t("result := foo(a, b)"                       , test_result_t( 5, "SS"  )),
+                                    test_pack_t("result := foo(a, b, c)"                    , test_result_t( 6, "SSS" )),
+                                    test_pack_t("result := foo(a, b, c, d)"                 , test_result_t( 7, "SSSS")),
+                                    test_pack_t("result := foo(a + b)"                      , test_result_t( 4, "S"   )),
+                                    test_pack_t("result := foo(a + b, b + c)"               , test_result_t( 5, "SS"  )),
+                                    test_pack_t("result := foo(a + b, b + c, c + d)"        , test_result_t( 6, "SSS" )),
+                                    test_pack_t("result := foo(a + b, b + c, c + d, d)"     , test_result_t( 7, "SSSS")),
+                                    test_pack_t("result := foo(a, x)"                       , test_result_t( 8, "ST"  )),
+                                    test_pack_t("result := foo(a, x, b)"                    , test_result_t( 9, "STS" )),
+                                    test_pack_t("result := foo(a, x, b, y)"                 , test_result_t(10, "STST")),
+                                    test_pack_t("result := foo(a + b, x + y)"               , test_result_t( 8, "ST"  )),
+                                    test_pack_t("result := foo(a + b, x + y, b + c)"        , test_result_t( 9, "STS" )),
+                                    test_pack_t("result := foo(a + b, x + y, b + c, y + z)" , test_result_t(10, "STST")),
+                                    test_pack_t("result := foo(x, a)"                       , test_result_t(11, "TS"  )),
+                                    test_pack_t("result := foo(x, a, y)"                    , test_result_t(12, "TST" )),
+                                    test_pack_t("result := foo(x, a, y, b)"                 , test_result_t(13, "TSTS")),
+                                    test_pack_t("result := foo(x + y, a + b)"               , test_result_t(11, "TS"  )),
+                                    test_pack_t("result := foo(x + y, a + b, y + z)"        , test_result_t(12, "TST" )),
+                                    test_pack_t("result := foo(x + y, a + b, y + z, b + c)" , test_result_t(13, "TSTS")),
+                                    test_pack_t("result := foo(x, y, a, b)"                 , test_result_t(14, "TTSS")),
+                                    test_pack_t("result := foo(a, b, x, y)"                 , test_result_t(15, "SSTT")),
+                                    test_pack_t("result := foo(a, x, y, b)"                 , test_result_t(16, "STTS")),
+                                    test_pack_t("result := foo(x, a, b, y)"                 , test_result_t(17, "TSST")),
+                                    test_pack_t("result := foo(x + y, y + z, a + b, b + c)" , test_result_t(14, "TTSS")),
+                                    test_pack_t("result := foo(a + b, b + c, x + y, y + z)" , test_result_t(15, "SSTT")),
+                                    test_pack_t("result := foo(a + b, x + y, y + z, b + c)" , test_result_t(16, "STTS")),
+                                    test_pack_t("result := foo(x + y, a + b, b + c, y + z)" , test_result_t(17, "TSST"))
+                                  };
+
+      static const std::size_t test_pack_list_size = sizeof(test_pack_list) / sizeof(test_pack_t);
+
+      std::deque<expression_t> expression_list;
+
+      for (std::size_t i = 0; i < test_pack_list_size; ++i)
+      {
+         expression_t expression;
+         expression.register_symbol_table(symbol_table);
+
+         exprtk::parser<T> parser;
+
+         if (!parser.compile(test_pack_list[i].first, expression))
+         {
+            printf("run_test18() - (13) Overload VarArg Error: %s   Expression: %s\n",
+                   parser.error().c_str(),
+                   test_pack_list[i].first.c_str());
+
+            return false;
+         }
+         else
+            expression_list.push_back(expression);
+      }
+
+      bool failure = false;
+
+      for (std::size_t i = 0; i < expression_list.size(); ++i)
+      {
+         ovrld_func.clear();
+         result = "";
+         expression_list[i].value();
+
+         if (result != "string result")
+         {
+            printf("run_test18() - Error in evaluation! (13) Expression: %s\n",
+                   test_pack_list[i].first.c_str());
+
+            failure = true;
+         }
+
+         if (ovrld_func.current_ps_index != test_pack_list[i].second.ps_index)
+         {
+            printf("run_test18() - Error with ps_index (13) Expression: %s  Expected: %d  Got: %d\n",
+                   test_pack_list[i].first.c_str(),
+                   static_cast<int>(test_pack_list[i].second.ps_index),
+                   static_cast<int>(ovrld_func.current_ps_index));
+
+            failure = true;
+         }
+
+         if (ovrld_func.current_param_seq != test_pack_list[i].second.param_seq)
+         {
+            printf("run_test18() - Error with parameter seq (13) Expression: %s  Expected: %s  Got: %s\n",
+                   test_pack_list[i].first.c_str(),
+                   test_pack_list[i].second.param_seq.c_str(),
+                   ovrld_func.current_param_seq.c_str());
+
+            failure = true;
+         }
+      }
+
+      if (failure)
+         return false;
+   }
+
    return true;
 }
 
diff --git a/readme.txt b/readme.txt
index 9191b83..65b812f 100644
--- a/readme.txt
+++ b/readme.txt
@@ -428,8 +428,8 @@ of C++ compilers:
 | [r0:r1]  | The closed interval [r0,r1] of the specified string.    |
 |          | eg: Given a string x with a value of 'abcdefgh' then:   |
 |          | 1. x[1:4] == 'bcde'                                     |
-|          | 2. x[ :5] == x[:5] == 'abcdef'                          |
-|          | 3. x[3: ] == x[3:] =='cdefgh'                           |
+|          | 2. x[ :5] == x[:10 / 2] == 'abcdef'                     |
+|          | 3. x[2 + 1: ] == x[3:] =='defgh'                        |
 |          | 4. x[ : ] == x[:] == 'abcdefgh'                         |
 |          | 5. x[4/2:3+2] == x[2:5] == 'cdef'                       |
 |          |                                                         |
@@ -920,7 +920,7 @@ The above denoted AST will be evaluated in the following order:
 Generally an expression in ExprTk can be thought of as a free function
 similar to those  found in imperative  languages. This form  of pseudo
 function will have a name, it may have a set of one or more inputs and
-will return at least one value as its result. Futhermore the  function
+will return at least one value as its result. Furthermore the function
 when invoked, may  cause a side-effect  that changes the  state of the
 host program.
 
@@ -1023,7 +1023,7 @@ copied,  it  will then  result  in two  or more  identical expressions
 utilizing the exact same  references for variables. This  obviously is
 not the  default assumed  scenario and  will give  rise to non-obvious
 behaviours  when  using the  expressions in  various contexts such  as
-muli-threading et al.
+multi-threading et al.
 
 The prescribed method for cloning an expression is to compile it  from
 its string  form. Doing so will allow the 'user' to  properly consider
@@ -1315,7 +1315,7 @@ in a statement will cause it to have a side-effect:
    (b) Invoking a user-defined function that has side-effects
 
 The following are examples of expressions where the side-effect status
-of the statements (or sub-exressions) within the expressions have been
+of the  statements (sub-expressions) within the expressions  have been
 noted:
 
   +-+----------------------+------------------------------+
@@ -1869,15 +1869,16 @@ embedded into the expression.
 
 There are five types of function interface:
 
-  +---+----------------------+-------------+----------------------+
-  | # |         Name         | Return Type | Input Types          |
-  +---+----------------------+-------------+----------------------+
-  | 1 | ifunction            | Scalar      | Scalar               |
-  | 2 | ivararg_function     | Scalar      | Scalar               |
-  | 3 | igeneric_function    | Scalar      | Scalar,Vector,String |
-  | 4 | igeneric_function II | String      | Scalar,Vector,String |
-  | 5 | function_compositor  | Scalar      | Scalar               |
-  +---+----------------------+-------------+----------------------+
+  +---+----------------------+--------------+----------------------+
+  | # |         Name         | Return Type  | Input Types          |
+  +---+----------------------+--------------+----------------------+
+  | 1 | ifunction            | Scalar       | Scalar               |
+  | 2 | ivararg_function     | Scalar       | Scalar               |
+  | 3 | igeneric_function    | Scalar       | Scalar,Vector,String |
+  | 4 | igeneric_function II | String       | Scalar,Vector,String |
+  | 5 | igeneric_function III| String/Scalar| Scalar,Vector,String |
+  | 6 | function_compositor  | Scalar       | Scalar               |
+  +---+----------------------+--------------+----------------------+
 
 (1) ifunction
 This interface supports zero to 20 input parameters of only the scalar
@@ -2253,7 +2254,60 @@ as follows:
    (4) Scalar                                (4) String
 
 
-(5) function_compositor
+(5) igeneric_function III
+In this section we will discuss an extension of the  igeneric_function
+interface that will allow for the overloading of a user defined custom
+function, where by it can return either a scalar or string value  type
+depending on the input parameter  sequence with which the function  is
+invoked.
+
+   template <typename T>
+   struct foo : public exprtk::igeneric_function<T>
+   {
+      typedef typename exprtk::igeneric_function<T>::parameter_list_t
+                                                     parameter_list_t;
+
+      foo()
+      : exprtk::igeneric_function<T>
+        (
+          "T:T|S:TS",
+          igfun_t::e_rtrn_overload
+        )
+      {}
+
+      // Scalar value returning invocations
+      inline T operator()(const std::size_t& ps_index,
+                          parameter_list_t parameters)
+      {
+         ...
+      }
+
+      // String value returning invocations
+      inline T operator()(const std::size_t& ps_index,
+                          std::string& result,
+                          parameter_list_t& parameters)
+      {
+         ...
+      }
+   };
+
+
+In the  example above  the custom  user defined  function "foo" can be
+invoked by using  either one of  two input parameter  sequences, which
+are defined as follows:
+
+   Sequence-0    Sequence-1
+   'T' -> T      'TS' -> S
+   (1) Scalar    (1) Scalar
+                 (2) String
+
+
+The parameter  sequence definitions  are identical  to the  previously
+define igeneric_function, with the  exception of the inclusion  of the
+return type - which can only be either a scalar T or a string S.
+
+
+(6) function_compositor
 The function  compositor is  a factory  that allows  one to define and
 construct a function using ExprTk syntax. The functions are limited to
 returning a single scalar value and consuming up to six parameters  as
@@ -2770,7 +2824,7 @@ expression being compiled.
 
 This can become problematic, as in the default scenario it is  assumed
 the symbol_table that is registered with the expression instance  will
-already  posses  the  externally  available  variables,  functions and
+already possess  the  externally  available  variables,  functions and
 constants needed during the compilation of the expression.
 
 In the event there are symbols in the expression that can't be  mapped
@@ -2893,7 +2947,7 @@ after which the expression itself can be evaluated.
 
    for (auto& var_name : variable_list)
    {
-      T& v = symbol_table.variable_ref(var_name);
+      T& v = unknown_var_symbol_table.variable_ref(var_name);
 
       v = ...;
    }
@@ -3789,7 +3843,7 @@ follows:
       }
    }
    else
-     printf("An error occured.");
+     printf("An error occurred.");
 
 
 (b) collect_functions
@@ -3813,7 +3867,7 @@ follows:
       }
    }
    else
-     printf("An error occured.");
+     printf("An error occurred.");
 
 
 Note: When either the 'collect_variables'  or 'collect_functions' free
@@ -3825,10 +3879,10 @@ true.
 
 Note: The  default interface  provided for  both the collect_variables
 and collect_functions  free_functions, assumes  that expressions  will
-only be utilising  the ExprTk reserved  funnctions (eg: abs,  cos, min
+only be utilising  the ExprTk  reserved  functions (eg: abs,  cos, min
 etc). When user defined functions are  to be used in an expression,  a
 symbol_table  instance  containing  said functions  can  be  passed to
-either routine, and  will be incorparated  during the compilation  and
+either routine, and  will be incorporated  during the compilation  and
 Dependent Entity  Collection processes.  In the  following example,  a
 user  defined  free  function   named  'foo'  is  registered   with  a
 symbol_table.  Finally  the   symbol_table  instance  and   associated
@@ -3858,7 +3912,7 @@ expression string are passed to the exprtk::collect_functions routine.
       }
    }
    else
-     printf("An error occured.");
+     printf("An error occurred.");
 
 
 (c) compute