Browse code

exprtk updated

ramon diaz-uriarte (at Phelsuma) authored on 12/09/2022 16:47:53
Showing1 changed files

... ...
@@ -2,14 +2,14 @@
2 2
  ******************************************************************
3 3
  *           C++ Mathematical Expression Toolkit Library          *
4 4
  *                                                                *
5
- * Author: Arash Partow (1999-2020)                               *
6
- * URL: http://www.partow.net/programming/exprtk/index.html       *
5
+ * Author: Arash Partow (1999-2022)                               *
6
+ * URL: https://www.partow.net/programming/exprtk/index.html      *
7 7
  *                                                                *
8 8
  * Copyright notice:                                              *
9 9
  * Free use of the C++ Mathematical Expression Toolkit Library is *
10 10
  * permitted under the guidelines and in accordance with the most *
11 11
  * current version of the MIT License.                            *
12
- * http://www.opensource.org/licenses/MIT                         *
12
+ * https://www.opensource.org/licenses/MIT                        *
13 13
  *                                                                *
14 14
  * Example expressions:                                           *
15 15
  * (00) (y + x / y) * (x - y / x)                                 *
... ...
@@ -35,6 +35,7 @@
35 35
 
36 36
 
37 37
 #include <algorithm>
38
+#include <cassert>
38 39
 #include <cctype>
39 40
 #include <cmath>
40 41
 #include <complex>
... ...
@@ -81,16 +82,26 @@ namespace exprtk
81 82
       #define exprtk_disable_fallthrough_end   (void)0;
82 83
    #endif
83 84
 
85
+   #if __cplusplus >= 201103L
86
+      #define exprtk_override override
87
+      #define exprtk_final    final
88
+      #define exprtk_delete   = delete
89
+   #else
90
+      #define exprtk_override
91
+      #define exprtk_final
92
+      #define exprtk_delete
93
+   #endif
94
+
84 95
    namespace details
85 96
    {
86
-      typedef unsigned char            uchar_t;
87
-      typedef char                      char_t;
88
-      typedef uchar_t*               uchar_ptr;
89
-      typedef char_t*                 char_ptr;
90
-      typedef uchar_t const*        uchar_cptr;
97
+      typedef char                   char_t;
98
+      typedef char_t*                char_ptr;
91 99
       typedef char_t const*          char_cptr;
100
+      typedef unsigned char          uchar_t;
101
+      typedef uchar_t*               uchar_ptr;
102
+      typedef uchar_t const*         uchar_cptr;
92 103
       typedef unsigned long long int _uint64_t;
93
-      typedef long long int           _int64_t;
104
+      typedef long long int          _int64_t;
94 105
 
95 106
       inline bool is_whitespace(const char_t c)
96 107
       {
... ...
@@ -166,7 +177,7 @@ namespace exprtk
166 177
 
167 178
       inline bool is_valid_string_char(const char_t c)
168 179
       {
169
-         return std::isprint(static_cast<unsigned char>(c)) ||
180
+         return std::isprint(static_cast<uchar_t>(c)) ||
170 181
                 is_whitespace(c);
171 182
       }
172 183
 
... ...
@@ -210,8 +221,8 @@ namespace exprtk
210 221
 
211 222
             for (std::size_t i = 0; i < length;  ++i)
212 223
             {
213
-               const char_t c1 = static_cast<char>(std::tolower(s1[i]));
214
-               const char_t c2 = static_cast<char>(std::tolower(s2[i]));
224
+               const char_t c1 = static_cast<char_t>(std::tolower(s1[i]));
225
+               const char_t c2 = static_cast<char_t>(std::tolower(s2[i]));
215 226
 
216 227
                if (c1 > c2)
217 228
                   return false;
... ...
@@ -273,25 +284,21 @@ namespace exprtk
273 284
 
274 285
          std::string result;
275 286
 
276
-         if (i < 0)
277
-         {
278
-            for ( ; i; i /= 10)
279
-            {
280
-               result += '0' + char(-(i % 10));
281
-            }
287
+         const int sign = (i < 0) ? -1 : 1;
282 288
 
283
-            result += '-';
289
+         for ( ; i; i /= 10)
290
+         {
291
+            result += '0' + static_cast<char_t>(sign * (i % 10));
284 292
          }
285
-         else
293
+
294
+         if (sign < 0)
286 295
          {
287
-            for ( ; i; i /= 10)
288
-            {
289
-               result += '0' + char(i % 10);
290
-            }
296
+            result += '-';
291 297
          }
292 298
 
293 299
          std::reverse(result.begin(), result.end());
294 300
 
301
+
295 302
          return result;
296 303
       }
297 304
 
... ...
@@ -300,7 +307,7 @@ namespace exprtk
300 307
          return to_str(static_cast<int>(i));
301 308
       }
302 309
 
303
-      inline bool is_hex_digit(const std::string::value_type digit)
310
+      inline bool is_hex_digit(const uchar_t digit)
304 311
       {
305 312
          return (('0' <= digit) && (digit <= '9')) ||
306 313
                 (('A' <= digit) && (digit <= 'F')) ||
... ...
@@ -312,12 +319,12 @@ namespace exprtk
312 319
          if (('0' <= h) && (h <= '9'))
313 320
             return (h - '0');
314 321
          else
315
-            return static_cast<unsigned char>(std::toupper(h) - 'A');
322
+            return static_cast<uchar_t>(std::toupper(h) - 'A');
316 323
       }
317 324
 
318 325
       template <typename Iterator>
319 326
       inline bool parse_hex(Iterator& itr, Iterator end,
320
-                            std::string::value_type& result)
327
+                            char_t& result)
321 328
       {
322 329
          if (
323 330
               (end ==  (itr    ))               ||
... ...
@@ -596,82 +603,75 @@ namespace exprtk
596 603
                              const Iterator data_begin   ,
597 604
                              const Iterator data_end     ,
598 605
                              const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
599
-                             const typename std::iterator_traits<Iterator>::value_type& zero_or_one )
606
+                             const typename std::iterator_traits<Iterator>::value_type& exactly_one )
600 607
       {
601 608
          const Iterator null_itr(0);
602 609
 
603
-         Iterator d_itr    = data_begin;
604
-         Iterator p_itr    = pattern_begin;
605
-         Iterator tb_p_itr = null_itr;
606
-         Iterator tb_d_itr = null_itr;
610
+         Iterator p_itr  = pattern_begin;
611
+         Iterator d_itr  = data_begin;
612
+         Iterator np_itr = null_itr;
613
+         Iterator nd_itr = null_itr;
607 614
 
608
-         while (d_itr != data_end)
615
+         for ( ; ; )
609 616
          {
610
-            if (zero_or_more == *p_itr)
611
-            {
612
-               while ((pattern_end != p_itr) && ((zero_or_more == *p_itr) || (zero_or_one == *p_itr)))
613
-               {
614
-                  ++p_itr;
615
-               }
617
+            const bool pvalid = p_itr != pattern_end;
618
+            const bool dvalid = d_itr != data_end;
616 619
 
617
-               if (pattern_end == p_itr)
618
-                  return true;
620
+            if (!pvalid && !dvalid)
621
+               break;
619 622
 
623
+            if (pvalid)
624
+            {
620 625
                const typename std::iterator_traits<Iterator>::value_type c = *(p_itr);
621 626
 
622
-               while ((data_end != d_itr) && !Compare::cmp(c,*d_itr))
627
+               if (zero_or_more == c)
628
+               {
629
+                  np_itr = p_itr;
630
+                  nd_itr = d_itr + 1;
631
+                  ++p_itr;
632
+                  continue;
633
+               }
634
+               else if (dvalid && ((exactly_one == c) || Compare::cmp(c,*(d_itr))))
623 635
                {
636
+                  ++p_itr;
624 637
                   ++d_itr;
638
+                  continue;
625 639
                }
626
-
627
-               tb_p_itr = p_itr;
628
-               tb_d_itr = d_itr;
629
-
630
-               continue;
631 640
             }
632
-            else if (!Compare::cmp(*p_itr, *d_itr) && (zero_or_one != *p_itr))
633
-            {
634
-               if (null_itr == tb_d_itr)
635
-                  return false;
636
-
637
-               d_itr = tb_d_itr++;
638
-               p_itr = tb_p_itr;
639 641
 
642
+            if ((null_itr != nd_itr) && (nd_itr <= data_end))
643
+            {
644
+               p_itr = np_itr;
645
+               d_itr = nd_itr;
640 646
                continue;
641 647
             }
642 648
 
643
-            ++p_itr;
644
-            ++d_itr;
645
-         }
646
-
647
-         while ((pattern_end != p_itr) && ((zero_or_more == *p_itr) || (zero_or_one == *p_itr)))
648
-         {
649
-            ++p_itr;
649
+            return false;
650 650
          }
651 651
 
652
-         return (pattern_end == p_itr);
652
+         return true;
653 653
       }
654 654
 
655 655
       inline bool wc_match(const std::string& wild_card,
656 656
                            const std::string& str)
657 657
       {
658
-         return match_impl<char_cptr,cs_match>(wild_card.data(),
659
-                                               wild_card.data() + wild_card.size(),
660
-                                               str.data(),
661
-                                               str.data() + str.size(),
662
-                                               '*',
663
-                                               '?');
658
+         return match_impl<char_cptr,cs_match>(
659
+                   wild_card.data(),
660
+                   wild_card.data() + wild_card.size(),
661
+                   str.data(),
662
+                   str.data() + str.size(),
663
+                   '*', '?');
664 664
       }
665 665
 
666 666
       inline bool wc_imatch(const std::string& wild_card,
667 667
                             const std::string& str)
668 668
       {
669
-         return match_impl<char_cptr,cis_match>(wild_card.data(),
670
-                                                wild_card.data() + wild_card.size(),
671
-                                                str.data(),
672
-                                                str.data() + str.size(),
673
-                                                '*',
674
-                                                '?');
669
+         return match_impl<char_cptr,cis_match>(
670
+                   wild_card.data(),
671
+                   wild_card.data() + wild_card.size(),
672
+                   str.data(),
673
+                   str.data() + str.size(),
674
+                   '*', '?');
675 675
       }
676 676
 
677 677
       inline bool sequence_match(const std::string& pattern,
... ...
@@ -691,19 +691,19 @@ namespace exprtk
691 691
          itr_t p_itr = pattern.begin();
692 692
          itr_t s_itr = str    .begin();
693 693
 
694
-         itr_t p_end = pattern.end();
695
-         itr_t s_end = str    .end();
694
+         const itr_t p_end = pattern.end();
695
+         const itr_t s_end = str    .end();
696 696
 
697 697
          while ((s_end != s_itr) && (p_end != p_itr))
698 698
          {
699 699
             if ('*' == (*p_itr))
700 700
             {
701
-               const char_t target = static_cast<char>(std::toupper(*(p_itr - 1)));
701
+               const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1)));
702 702
 
703 703
                if ('*' == target)
704 704
                {
705 705
                   diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
706
-                  diff_value = static_cast<char>(std::toupper(*p_itr));
706
+                  diff_value = static_cast<char_t>(std::toupper(*p_itr));
707 707
 
708 708
                   return false;
709 709
                }
... ...
@@ -726,7 +726,7 @@ namespace exprtk
726 726
                     )
727 727
             {
728 728
                diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
729
-               diff_value = static_cast<char>(std::toupper(*p_itr));
729
+               diff_value = static_cast<char_t>(std::toupper(*p_itr));
730 730
 
731 731
                return false;
732 732
             }
... ...
@@ -785,15 +785,15 @@ namespace exprtk
785 785
             };
786 786
 
787 787
             #define exprtk_register_real_type_tag(T)             \
788
-            template<> struct number_type<T>                     \
788
+            template <> struct number_type<T>                    \
789 789
             { typedef real_type_tag type; number_type() {} };    \
790 790
 
791 791
             #define exprtk_register_complex_type_tag(T)          \
792
-            template<> struct number_type<std::complex<T> >      \
792
+            template <> struct number_type<std::complex<T> >     \
793 793
             { typedef complex_type_tag type; number_type() {} }; \
794 794
 
795 795
             #define exprtk_register_int_type_tag(T)              \
796
-            template<> struct number_type<T>                     \
796
+            template <> struct number_type<T>                    \
797 797
             { typedef int_type_tag type; number_type() {} };     \
798 798
 
799 799
             exprtk_register_real_type_tag(double     )
... ...
@@ -815,34 +815,23 @@ namespace exprtk
815 815
             #undef exprtk_register_int_type_tag
816 816
 
817 817
             template <typename T>
818
-            struct epsilon_type
819
-            {
820
-               static inline T value()
821
-               {
822
-                  const T epsilon = T(0.0000000001);
823
-                  return epsilon;
824
-               }
825
-            };
818
+            struct epsilon_type {};
826 819
 
827
-            template <>
828
-            struct epsilon_type <float>
829
-            {
830
-               static inline float value()
831
-               {
832
-                  const float epsilon = float(0.000001f);
833
-                  return epsilon;
834
-               }
835
-            };
820
+            #define exprtk_define_epsilon_type(Type, Epsilon)      \
821
+            template <> struct epsilon_type<Type>                  \
822
+            {                                                      \
823
+               static inline Type value()                          \
824
+               {                                                   \
825
+                  const Type epsilon = static_cast<Type>(Epsilon); \
826
+                  return epsilon;                                  \
827
+               }                                                   \
828
+            };                                                     \
836 829
 
837
-            template <>
838
-            struct epsilon_type <long double>
839
-            {
840
-               static inline long double value()
841
-               {
842
-                  const long double epsilon = (long double)(0.000000000001);
843
-                  return epsilon;
844
-               }
845
-            };
830
+            exprtk_define_epsilon_type(float      , 0.00000100000f)
831
+            exprtk_define_epsilon_type(double     , 0.000000000100)
832
+            exprtk_define_epsilon_type(long double, 0.000000000001)
833
+
834
+            #undef exprtk_define_epsilon_type
846 835
 
847 836
             template <typename T>
848 837
             inline bool is_nan_impl(const T v, real_type_tag)
... ...
@@ -1040,7 +1029,7 @@ namespace exprtk
1040 1029
             template <typename T>
1041 1030
             inline T roundn_impl(const T v0, const T v1, real_type_tag)
1042 1031
             {
1043
-               const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1)));
1032
+               const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1))));
1044 1033
                const T p10 = T(pow10[index]);
1045 1034
 
1046 1035
                if (v0 < T(0))
... ...
@@ -1106,7 +1095,7 @@ namespace exprtk
1106 1095
             template <typename T>
1107 1096
             inline T sgn_impl(const T v, real_type_tag)
1108 1097
             {
1109
-                    if (v > T(0)) return T(+1);
1098
+               if      (v > T(0)) return T(+1);
1110 1099
                else if (v < T(0)) return T(-1);
1111 1100
                else               return T( 0);
1112 1101
             }
... ...
@@ -1114,7 +1103,7 @@ namespace exprtk
1114 1103
             template <typename T>
1115 1104
             inline T sgn_impl(const T v, int_type_tag)
1116 1105
             {
1117
-                    if (v > T(0)) return T(+1);
1106
+               if      (v > T(0)) return T(+1);
1118 1107
                else if (v < T(0)) return T(-1);
1119 1108
                else               return T( 0);
1120 1109
             }
... ...
@@ -1204,8 +1193,8 @@ namespace exprtk
1204 1193
             }
1205 1194
 
1206 1195
             #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1207
-            #define exprtk_define_erf(TT,impl)           \
1208
-            inline TT erf_impl(TT v) { return impl(v); } \
1196
+            #define exprtk_define_erf(TT, impl)                \
1197
+            inline TT erf_impl(const TT v) { return impl(v); } \
1209 1198
 
1210 1199
             exprtk_define_erf(      float,::erff)
1211 1200
             exprtk_define_erf(     double,::erf )
... ...
@@ -1214,7 +1203,7 @@ namespace exprtk
1214 1203
             #endif
1215 1204
 
1216 1205
             template <typename T>
1217
-            inline T erf_impl(T v, real_type_tag)
1206
+            inline T erf_impl(const T v, real_type_tag)
1218 1207
             {
1219 1208
                #if defined(_MSC_VER) && (_MSC_VER < 1900)
1220 1209
                // Credits: Abramowitz & Stegun Equations 7.1.25-28
... ...
@@ -1228,12 +1217,12 @@ namespace exprtk
1228 1217
 
1229 1218
                const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
1230 1219
 
1231
-               T result = T(1) - t * std::exp((-v * v) -
1232
-                                      c[0] + t * (c[1] + t *
1233
-                                     (c[2] + t * (c[3] + t *
1234
-                                     (c[4] + t * (c[5] + t *
1235
-                                     (c[6] + t * (c[7] + t *
1236
-                                     (c[8] + t * (c[9]))))))))));
1220
+               const T result = T(1) - t * std::exp((-v * v) -
1221
+                                            c[0] + t * (c[1] + t *
1222
+                                           (c[2] + t * (c[3] + t *
1223
+                                           (c[4] + t * (c[5] + t *
1224
+                                           (c[6] + t * (c[7] + t *
1225
+                                           (c[8] + t * (c[9]))))))))));
1237 1226
 
1238 1227
                return (v >= T(0)) ? result : -result;
1239 1228
                #else
... ...
@@ -1242,23 +1231,23 @@ namespace exprtk
1242 1231
             }
1243 1232
 
1244 1233
             template <typename T>
1245
-            inline T erf_impl(T v, int_type_tag)
1234
+            inline T erf_impl(const T v, int_type_tag)
1246 1235
             {
1247 1236
                return erf_impl(static_cast<double>(v),real_type_tag());
1248 1237
             }
1249 1238
 
1250 1239
             #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1251
-            #define exprtk_define_erfc(TT,impl)           \
1252
-            inline TT erfc_impl(TT v) { return impl(v); } \
1240
+            #define exprtk_define_erfc(TT, impl)                \
1241
+            inline TT erfc_impl(const TT v) { return impl(v); } \
1253 1242
 
1254
-            exprtk_define_erfc(      float,::erfcf)
1255
-            exprtk_define_erfc(     double,::erfc )
1243
+            exprtk_define_erfc(float      ,::erfcf)
1244
+            exprtk_define_erfc(double     ,::erfc )
1256 1245
             exprtk_define_erfc(long double,::erfcl)
1257 1246
             #undef exprtk_define_erfc
1258 1247
             #endif
1259 1248
 
1260 1249
             template <typename T>
1261
-            inline T erfc_impl(T v, real_type_tag)
1250
+            inline T erfc_impl(const T v, real_type_tag)
1262 1251
             {
1263 1252
                #if defined(_MSC_VER) && (_MSC_VER < 1900)
1264 1253
                return T(1) - erf_impl(v,real_type_tag());
... ...
@@ -1268,28 +1257,28 @@ namespace exprtk
1268 1257
             }
1269 1258
 
1270 1259
             template <typename T>
1271
-            inline T erfc_impl(T v, int_type_tag)
1260
+            inline T erfc_impl(const T v, int_type_tag)
1272 1261
             {
1273 1262
                return erfc_impl(static_cast<double>(v),real_type_tag());
1274 1263
             }
1275 1264
 
1276 1265
             template <typename T>
1277
-            inline T ncdf_impl(T v, real_type_tag)
1266
+            inline T ncdf_impl(const T v, real_type_tag)
1278 1267
             {
1279
-               T cnd = T(0.5) * (T(1) + erf_impl(
1280
-                                           abs_impl(v,real_type_tag()) /
1281
-                                           T(numeric::constant::sqrt2),real_type_tag()));
1268
+               const T cnd = T(0.5) * (T(1) +
1269
+                             erf_impl(abs_impl(v,real_type_tag()) /
1270
+                                      T(numeric::constant::sqrt2),real_type_tag()));
1282 1271
                return  (v < T(0)) ? (T(1) - cnd) : cnd;
1283 1272
             }
1284 1273
 
1285 1274
             template <typename T>
1286
-            inline T ncdf_impl(T v, int_type_tag)
1275
+            inline T ncdf_impl(const T v, int_type_tag)
1287 1276
             {
1288 1277
                return ncdf_impl(static_cast<double>(v),real_type_tag());
1289 1278
             }
1290 1279
 
1291 1280
             template <typename T>
1292
-            inline T sinc_impl(T v, real_type_tag)
1281
+            inline T sinc_impl(const T v, real_type_tag)
1293 1282
             {
1294 1283
                if (std::abs(v) >= std::numeric_limits<T>::epsilon())
1295 1284
                    return(std::sin(v) / v);
... ...
@@ -1298,7 +1287,7 @@ namespace exprtk
1298 1287
             }
1299 1288
 
1300 1289
             template <typename T>
1301
-            inline T sinc_impl(T v, int_type_tag)
1290
+            inline T sinc_impl(const T v, int_type_tag)
1302 1291
             {
1303 1292
                return sinc_impl(static_cast<double>(v),real_type_tag());
1304 1293
             }
... ...
@@ -1329,14 +1318,15 @@ namespace exprtk
1329 1318
             template <typename T> inline T   csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
1330 1319
             template <typename T> inline T   r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
1331 1320
             template <typename T> inline T   d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180));  }
1332
-            template <typename T> inline T   d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); }
1333
-            template <typename T> inline T   g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); }
1321
+            template <typename T> inline T   d2g_impl(const T v, real_type_tag) { return (v * T(10.0/9.0)); }
1322
+            template <typename T> inline T   g2d_impl(const T v, real_type_tag) { return (v * T(9.0/10.0)); }
1334 1323
             template <typename T> inline T  notl_impl(const T v, real_type_tag) { return (std::not_equal_to<T>()(T(0),v) ? T(0) : T(1)); }
1335 1324
             template <typename T> inline T  frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
1336 1325
             template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v));    }
1337 1326
 
1338
-            template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); }
1339
-            template <typename T> inline T const_e_impl (real_type_tag) { return T(numeric::constant::e);  }
1327
+            template <typename T> inline T   const_pi_impl(real_type_tag) { return T(numeric::constant::pi);            }
1328
+            template <typename T> inline T    const_e_impl(real_type_tag) { return T(numeric::constant::e);             }
1329
+            template <typename T> inline T const_qnan_impl(real_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1340 1330
 
1341 1331
             template <typename T> inline T   abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
1342 1332
             template <typename T> inline T   exp_impl(const T v, int_type_tag) { return std::exp  (v); }
... ...
@@ -1384,10 +1374,10 @@ namespace exprtk
1384 1374
          template <typename Type>
1385 1375
          struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
1386 1376
 
1387
-         template<> struct numeric_info<int>         { enum { length = 10, size = 16, bound_length = 9}; };
1388
-         template<> struct numeric_info<float>       { enum { min_exp =  -38, max_exp =  +38}; };
1389
-         template<> struct numeric_info<double>      { enum { min_exp = -308, max_exp = +308}; };
1390
-         template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
1377
+         template <> struct numeric_info<int        > { enum { length = 10, size = 16, bound_length = 9 }; };
1378
+         template <> struct numeric_info<float      > { enum { min_exp =  -38, max_exp =  +38 }; };
1379
+         template <> struct numeric_info<double     > { enum { min_exp = -308, max_exp = +308 }; };
1380
+         template <> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308 }; };
1391 1381
 
1392 1382
          template <typename T>
1393 1383
          inline int to_int32(const T v)
... ...
@@ -1560,31 +1550,31 @@ namespace exprtk
1560 1550
 
1561 1551
                while (k)
1562 1552
                {
1563
-                  if (k & 1)
1553
+                  if (1 == (k % 2))
1564 1554
                   {
1565 1555
                      l *= v;
1566 1556
                      --k;
1567 1557
                   }
1568 1558
 
1569 1559
                   v *= v;
1570
-                  k >>= 1;
1560
+                  k /= 2;
1571 1561
                }
1572 1562
 
1573 1563
                return l;
1574 1564
             }
1575 1565
          };
1576 1566
 
1577
-         template <typename T> struct fast_exp<T,10> { static inline T result(T v) { T v_5 = fast_exp<T,5>::result(v); return v_5 * v_5; } };
1578
-         template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
1579
-         template <typename T> struct fast_exp<T, 8> { static inline T result(T v) { T v_4 = fast_exp<T,4>::result(v); return v_4 * v_4; } };
1580
-         template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
1581
-         template <typename T> struct fast_exp<T, 6> { static inline T result(T v) { T v_3 = fast_exp<T,3>::result(v); return v_3 * v_3; } };
1582
-         template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
1583
-         template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
1584
-         template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
1585
-         template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v;     } };
1586
-         template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v;         } };
1587
-         template <typename T> struct fast_exp<T, 0> { static inline T result(T  ) { return T(1);      } };
1567
+         template <typename T> struct fast_exp<T,10> { static inline T result(const T v) { T v_5 = fast_exp<T,5>::result(v); return v_5 * v_5; } };
1568
+         template <typename T> struct fast_exp<T, 9> { static inline T result(const T v) { return fast_exp<T,8>::result(v) * v; } };
1569
+         template <typename T> struct fast_exp<T, 8> { static inline T result(const T v) { T v_4 = fast_exp<T,4>::result(v); return v_4 * v_4; } };
1570
+         template <typename T> struct fast_exp<T, 7> { static inline T result(const T v) { return fast_exp<T,6>::result(v) * v; } };
1571
+         template <typename T> struct fast_exp<T, 6> { static inline T result(const T v) { T v_3 = fast_exp<T,3>::result(v); return v_3 * v_3; } };
1572
+         template <typename T> struct fast_exp<T, 5> { static inline T result(const T v) { return fast_exp<T,4>::result(v) * v; } };
1573
+         template <typename T> struct fast_exp<T, 4> { static inline T result(const T v) { T v_2 = v * v; return v_2 * v_2; } };
1574
+         template <typename T> struct fast_exp<T, 3> { static inline T result(const T v) { return v * v * v; } };
1575
+         template <typename T> struct fast_exp<T, 2> { static inline T result(const T v) { return v * v;     } };
1576
+         template <typename T> struct fast_exp<T, 1> { static inline T result(const T v) { return v;         } };
1577
+         template <typename T> struct fast_exp<T, 0> { static inline T result(const T  ) { return T(1);      } };
1588 1578
 
1589 1579
          #define exprtk_define_unary_function(FunctionName)        \
1590 1580
          template <typename T>                                     \
... ...
@@ -1719,7 +1709,7 @@ namespace exprtk
1719 1709
 
1720 1710
          bool return_result = true;
1721 1711
          unsigned int digit = 0;
1722
-         const std::size_t length  = static_cast<std::size_t>(std::distance(itr,end));
1712
+         const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1723 1713
 
1724 1714
          if (length <= 4)
1725 1715
          {
... ...
@@ -1750,10 +1740,14 @@ namespace exprtk
1750 1740
 
1751 1741
                #endif
1752 1742
 
1753
-               case  4 : exprtk_process_digit
1754
-               case  3 : exprtk_process_digit
1755
-               case  2 : exprtk_process_digit
1756
-               case  1 : if ((digit = (*itr - zero))>= 10) { digit = 0; return_result = false; }
1743
+               case 4 : exprtk_process_digit
1744
+               case 3 : exprtk_process_digit
1745
+               case 2 : exprtk_process_digit
1746
+               case 1 : if ((digit = (*itr - zero))>= 10)
1747
+                        {
1748
+                           digit = 0;
1749
+                           return_result = false;
1750
+                        }
1757 1751
 
1758 1752
                #undef exprtk_process_digit
1759 1753
             }
... ...
@@ -1806,7 +1800,7 @@ namespace exprtk
1806 1800
       }
1807 1801
 
1808 1802
       template <typename Iterator, typename T>
1809
-      static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
1803
+      static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, const bool negative)
1810 1804
       {
1811 1805
          static const char_t inf_uc[] = "INFINITY";
1812 1806
          static const char_t inf_lc[] = "infinity";
... ...
@@ -1821,7 +1815,7 @@ namespace exprtk
1821 1815
 
1822 1816
          while (end != itr)
1823 1817
          {
1824
-            if (*inf_itr == static_cast<char>(*itr))
1818
+            if (*inf_itr == static_cast<char_t>(*itr))
1825 1819
             {
1826 1820
                ++itr;
1827 1821
                ++inf_itr;
... ...
@@ -1842,8 +1836,8 @@ namespace exprtk
1842 1836
       template <typename T>
1843 1837
       inline bool valid_exponent(const int exponent, numeric::details::real_type_tag)
1844 1838
       {
1845
-         return (std::numeric_limits<T>::min_exponent10 <= exponent) &&
1846
-                (exponent <= std::numeric_limits<T>::max_exponent10) ;
1839
+         using namespace details::numeric;
1840
+         return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp);
1847 1841
       }
1848 1842
 
1849 1843
       template <typename Iterator, typename T>
... ...
@@ -1877,7 +1871,8 @@ namespace exprtk
1877 1871
          #define parse_digit_2(d)          \
1878 1872
          if ((digit = (*itr - zero)) < 10) \
1879 1873
             { d = d * T(10) + digit; }     \
1880
-         else { break; }                   \
1874
+         else                              \
1875
+            { break; }                     \
1881 1876
             ++itr;                         \
1882 1877
 
1883 1878
          if ('.' != (*itr))
... ...
@@ -1888,14 +1883,7 @@ namespace exprtk
1888 1883
 
1889 1884
             while (end != itr)
1890 1885
             {
1891
-               // Note: For 'physical' superscalar architectures it
1892
-               // is advised that the following loop be: 4xPD1 and 1xPD2
1893 1886
                unsigned int digit;
1894
-
1895
-               #ifdef exprtk_enable_superscalar
1896
-               parse_digit_1(d)
1897
-               parse_digit_1(d)
1898
-               #endif
1899 1887
                parse_digit_1(d)
1900 1888
                parse_digit_1(d)
1901 1889
                parse_digit_2(d)
... ...
@@ -1916,12 +1904,6 @@ namespace exprtk
1916 1904
                while (end != itr)
1917 1905
                {
1918 1906
                   unsigned int digit;
1919
-
1920
-                  #ifdef exprtk_enable_superscalar
1921
-                  parse_digit_1(tmp_d)
1922
-                  parse_digit_1(tmp_d)
1923
-                  parse_digit_1(tmp_d)
1924
-                  #endif
1925 1907
                   parse_digit_1(tmp_d)
1926 1908
                   parse_digit_1(tmp_d)
1927 1909
                   parse_digit_2(tmp_d)
... ...
@@ -1931,12 +1913,12 @@ namespace exprtk
1931 1913
                {
1932 1914
                   instate = true;
1933 1915
 
1934
-                  const int exponent = static_cast<int>(-std::distance(curr, itr));
1916
+                  const int frac_exponent = static_cast<int>(-std::distance(curr, itr));
1935 1917
 
1936
-                  if (!valid_exponent<T>(exponent, numeric::details::real_type_tag()))
1918
+                  if (!valid_exponent<T>(frac_exponent, numeric::details::real_type_tag()))
1937 1919
                      return false;
1938 1920
 
1939
-                  d += compute_pow10(tmp_d, exponent);
1921
+                  d += compute_pow10(tmp_d, frac_exponent);
1940 1922
                }
1941 1923
 
1942 1924
                #undef parse_digit_1
... ...
@@ -2068,8 +2050,8 @@ namespace exprtk
2068 2050
       loop_types loop_set;
2069 2051
 
2070 2052
       loop_runtime_check()
2071
-      : loop_set(e_invalid),
2072
-        max_loop_iterations(0)
2053
+      : loop_set(e_invalid)
2054
+      , max_loop_iterations(0)
2073 2055
       {}
2074 2056
 
2075 2057
       details::_uint64_t max_loop_iterations;
... ...
@@ -2114,9 +2096,9 @@ namespace exprtk
2114 2096
          };
2115 2097
 
2116 2098
          token()
2117
-         : type(e_none),
2118
-           value(""),
2119
-           position(std::numeric_limits<std::size_t>::max())
2099
+         : type(e_none)
2100
+         , value("")
2101
+         , position(std::numeric_limits<std::size_t>::max())
2120 2102
          {}
2121 2103
 
2122 2104
          void clear()
... ...
@@ -2275,9 +2257,9 @@ namespace exprtk
2275 2257
          typedef details::char_t char_t;
2276 2258
 
2277 2259
          generator()
2278
-         : base_itr_(0),
2279
-           s_itr_   (0),
2280
-           s_end_   (0)
2260
+         : base_itr_(0)
2261
+         , s_itr_   (0)
2262
+         , s_end_   (0)
2281 2263
          {
2282 2264
             clear();
2283 2265
          }
... ...
@@ -2393,10 +2375,10 @@ namespace exprtk
2393 2375
             }
2394 2376
          }
2395 2377
 
2396
-         inline std::string substr(const std::size_t& begin, const std::size_t& end)
2378
+         inline std::string substr(const std::size_t& begin, const std::size_t& end) const
2397 2379
          {
2398 2380
             const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
2399
-            const details::char_cptr end_itr   = ((base_itr_ +   end) < s_end_) ? (base_itr_ +   end) : s_end_;
2381
+            const details::char_cptr end_itr   = ((base_itr_ + end  ) < s_end_) ? (base_itr_ + end  ) : s_end_;
2400 2382
 
2401 2383
             return std::string(begin_itr,end_itr);
2402 2384
          }
... ...
@@ -2413,14 +2395,14 @@ namespace exprtk
2413 2395
 
2414 2396
       private:
2415 2397
 
2416
-         inline bool is_end(details::char_cptr itr)
2398
+         inline bool is_end(details::char_cptr itr) const
2417 2399
          {
2418 2400
             return (s_end_ == itr);
2419 2401
          }
2420 2402
 
2421
-         inline bool is_comment_start(details::char_cptr itr)
2403
+         #ifndef exprtk_disable_comments
2404
+         inline bool is_comment_start(details::char_cptr itr) const
2422 2405
          {
2423
-            #ifndef exprtk_disable_comments
2424 2406
             const char_t c0 = *(itr + 0);
2425 2407
             const char_t c1 = *(itr + 1);
2426 2408
 
... ...
@@ -2431,9 +2413,14 @@ namespace exprtk
2431 2413
                if (('/' == c0) && ('/' == c1)) return true;
2432 2414
                if (('/' == c0) && ('*' == c1)) return true;
2433 2415
             }
2434
-            #endif
2435 2416
             return false;
2436 2417
          }
2418
+         #else
2419
+         inline bool is_comment_start(details::char_cptr) const
2420
+         {
2421
+            return false;
2422
+         }
2423
+         #endif
2437 2424
 
2438 2425
          inline void skip_whitespace()
2439 2426
          {
... ...
@@ -2455,10 +2442,10 @@ namespace exprtk
2455 2442
                static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr)
2456 2443
                {
2457 2444
                   mode = 0;
2458
-                       if ('#' == c0)    { mode = 1; incr = 1; }
2445
+                  if      ('#' == c0)    { mode = 1; incr = 1; }
2459 2446
                   else if ('/' == c0)
2460 2447
                   {
2461
-                          if ('/' == c1) { mode = 1; incr = 2; }
2448
+                     if      ('/' == c1) { mode = 1; incr = 2; }
2462 2449
                      else if ('*' == c1) { mode = 2; incr = 2; }
2463 2450
                   }
2464 2451
                   return (0 != mode);
... ...
@@ -2601,7 +2588,7 @@ namespace exprtk
2601 2588
 
2602 2589
                token_t::token_type ttype = token_t::e_none;
2603 2590
 
2604
-                    if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
2591
+               if      ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
2605 2592
                else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
2606 2593
                else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
2607 2594
                else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
... ...
@@ -2788,7 +2775,10 @@ namespace exprtk
2788 2775
             // $fdd(x,x,x) = at least 11 chars
2789 2776
             if (std::distance(s_itr_,s_end_) < 11)
2790 2777
             {
2791
-               t.set_error(token::e_err_sfunc, initial_itr, s_itr_, base_itr_);
2778
+               t.set_error(
2779
+                  token::e_err_sfunc,
2780
+                  initial_itr, std::min(initial_itr + 11, s_end_),
2781
+                  base_itr_);
2792 2782
                token_list_.push_back(t);
2793 2783
 
2794 2784
                return;
... ...
@@ -2801,7 +2791,10 @@ namespace exprtk
2801 2791
                    (details::is_digit(*(s_itr_ + 3))))
2802 2792
                )
2803 2793
             {
2804
-               t.set_error(token::e_err_sfunc, initial_itr, s_itr_, base_itr_);
2794
+               t.set_error(
2795
+                  token::e_err_sfunc,
2796
+                  initial_itr, std::min(initial_itr + 4, s_end_),
2797
+                  base_itr_);
2805 2798
                token_list_.push_back(t);
2806 2799
 
2807 2800
                return;
... ...
@@ -2933,7 +2926,7 @@ namespace exprtk
2933 2926
          friend class token_modifier;
2934 2927
          friend class token_inserter;
2935 2928
          friend class token_joiner;
2936
-      };
2929
+      }; // class generator
2937 2930
 
2938 2931
       class helper_interface
2939 2932
       {
... ...
@@ -2950,8 +2943,7 @@ namespace exprtk
2950 2943
       {
2951 2944
       public:
2952 2945
 
2953
-         virtual ~token_scanner()
2954
-         {}
2946
+         virtual ~token_scanner() {}
2955 2947
 
2956 2948
          explicit token_scanner(const std::size_t& stride)
2957 2949
          : stride_(stride)
... ...
@@ -2962,7 +2954,7 @@ namespace exprtk
2962 2954
             }
2963 2955
          }
2964 2956
 
2965
-         inline std::size_t process(generator& g)
2957
+         inline std::size_t process(generator& g) exprtk_override
2966 2958
          {
2967 2959
             if (g.token_list_.size() >= stride_)
2968 2960
             {
... ...
@@ -3051,13 +3043,13 @@ namespace exprtk
3051 3043
       private:
3052 3044
 
3053 3045
          const std::size_t stride_;
3054
-      };
3046
+      }; // class token_scanner
3055 3047
 
3056 3048
       class token_modifier : public helper_interface
3057 3049
       {
3058 3050
       public:
3059 3051
 
3060
-         inline std::size_t process(generator& g)
3052
+         inline std::size_t process(generator& g) exprtk_override
3061 3053
          {
3062 3054
             std::size_t changes = 0;
3063 3055
 
... ...
@@ -3085,7 +3077,7 @@ namespace exprtk
3085 3077
             }
3086 3078
          }
3087 3079
 
3088
-         inline std::size_t process(generator& g)
3080
+         inline std::size_t process(generator& g) exprtk_override
3089 3081
          {
3090 3082
             if (g.token_list_.empty())
3091 3083
                return 0;
... ...
@@ -3189,7 +3181,7 @@ namespace exprtk
3189 3181
          : stride_(stride)
3190 3182
          {}
3191 3183
 
3192
-         inline std::size_t process(generator& g)
3184
+         inline std::size_t process(generator& g) exprtk_override
3193 3185
          {
3194 3186
             if (g.token_list_.empty())
3195 3187
                return 0;
... ...
@@ -3235,13 +3227,15 @@ namespace exprtk
3235 3227
 
3236 3228
                   i+=2;
3237 3229
 
3238
-                  if (static_cast<std::size_t>(i) >= g.token_list_.size())
3230
+                  if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1))
3239 3231
                      break;
3240 3232
                }
3241 3233
             }
3242 3234
 
3243 3235
             token_list.push_back(g.token_list_.back());
3244 3236
 
3237
+            assert(token_list.size() <= g.token_list_.size());
3238
+
3245 3239
             std::swap(token_list, g.token_list_);
3246 3240
 
3247 3241
             return changes;
... ...
@@ -3275,7 +3269,7 @@ namespace exprtk
3275 3269
 
3276 3270
                   i+=3;
3277 3271
 
3278
-                  if (static_cast<std::size_t>(i) >= g.token_list_.size())
3272
+                  if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2))
3279 3273
                      break;
3280 3274
                }
3281 3275
             }
... ...
@@ -3283,6 +3277,8 @@ namespace exprtk
3283 3277
             token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 2));
3284 3278
             token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 1));
3285 3279
 
3280
+            assert(token_list.size() <= g.token_list_.size());
3281
+
3286 3282
             std::swap(token_list, g.token_list_);
3287 3283
 
3288 3284
             return changes;
... ...
@@ -3348,7 +3344,7 @@ namespace exprtk
3348 3344
                      return -1;
3349 3345
                   }
3350 3346
                }
3351
-                    if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_symbol     )) match = true;
3347
+               if      ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_symbol     )) match = true;
3352 3348
                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lbracket   )) match = true;
3353 3349
                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
3354 3350
                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
... ...
@@ -3461,7 +3457,7 @@ namespace exprtk
3461 3457
                   return true;
3462 3458
                }
3463 3459
                // '! =' --> '!='
3464
-               else if ((static_cast<char>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
3460
+               else if ((static_cast<details::char_t>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
3465 3461
                {
3466 3462
                   t.type     = lexer::token::e_ne;
3467 3463
                   t.value    = "!=";
... ...
@@ -3522,7 +3518,10 @@ namespace exprtk
3522 3518
                   return false;
3523 3519
             }
3524 3520
 
3525
-            inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, lexer::token& t)
3521
+            inline bool join(const lexer::token& t0,
3522
+                             const lexer::token& t1,
3523
+                             const lexer::token& t2,
3524
+                             lexer::token& t)
3526 3525
             {
3527 3526
                // '[ * ]' --> '[*]'
3528 3527
                if (
... ...
@@ -3549,8 +3548,8 @@ namespace exprtk
3549 3548
             using lexer::token_scanner::operator();
3550 3549
 
3551 3550
             bracket_checker()
3552
-            : token_scanner(1),
3553
-              state_(true)
3551
+            : token_scanner(1)
3552
+            , state_(true)
3554 3553
             {}
3555 3554
 
3556 3555
             bool result()
... ...
@@ -3593,7 +3592,7 @@ namespace exprtk
3593 3592
                {
3594 3593
                   details::char_t c = t.value[0];
3595 3594
 
3596
-                       if (t.type == lexer::token::e_lbracket   ) stack_.push(std::make_pair(')',t.position));
3595
+                  if      (t.type == lexer::token::e_lbracket   ) stack_.push(std::make_pair(')',t.position));
3597 3596
                   else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
3598 3597
                   else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
3599 3598
                   else if (exprtk::details::is_right_bracket(c))
... ...
@@ -3634,8 +3633,8 @@ namespace exprtk
3634 3633
             using lexer::token_scanner::operator();
3635 3634
 
3636 3635
             numeric_checker()
3637
-            : token_scanner (1),
3638
-              current_index_(0)
3636
+            : token_scanner (1)
3637
+            , current_index_(0)
3639 3638
             {}
3640 3639
 
3641 3640
             bool result()
... ...
@@ -3842,12 +3841,12 @@ namespace exprtk
3842 3841
 
3843 3842
          private:
3844 3843
 
3845
-            void add_invalid(lexer::token::token_type base, lexer::token::token_type t)
3844
+            void add_invalid(const lexer::token::token_type base, const lexer::token::token_type t)
3846 3845
             {
3847 3846
                invalid_comb_.insert(std::make_pair(base,t));
3848 3847
             }
3849 3848
 
3850
-            void add_invalid_set1(lexer::token::token_type t)
3849
+            void add_invalid_set1(const lexer::token::token_type t)
3851 3850
             {
3852 3851
                add_invalid(t, lexer::token::e_assign);
3853 3852
                add_invalid(t, lexer::token::e_shr   );
... ...
@@ -3866,9 +3865,9 @@ namespace exprtk
3866 3865
                add_invalid(t, lexer::token::e_colon );
3867 3866
             }
3868 3867
 
3869
-            bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
3868
+            bool invalid_bracket_check(const lexer::token::token_type base, const lexer::token::token_type t)
3870 3869
             {
3871
-               if (details::is_right_bracket(static_cast<char>(base)))
3870
+               if (details::is_right_bracket(static_cast<details::char_t>(base)))
3872 3871
                {
3873 3872
                   switch (t)
3874 3873
                   {
... ...
@@ -3877,11 +3876,11 @@ namespace exprtk
3877 3876
                      default                     : return false;
3878 3877
                   }
3879 3878
                }
3880
-               else if (details::is_left_bracket(static_cast<char>(base)))
3879
+               else if (details::is_left_bracket(static_cast<details::char_t>(base)))
3881 3880
                {
3882
-                  if (details::is_right_bracket(static_cast<char>(t)))
3881
+                  if (details::is_right_bracket(static_cast<details::char_t>(t)))
3883 3882
                      return false;
3884
-                  else if (details::is_left_bracket(static_cast<char>(t)))
3883
+                  else if (details::is_left_bracket(static_cast<details::char_t>(t)))
3885 3884
                      return false;
3886 3885
                   else
3887 3886
                   {
... ...
@@ -3898,7 +3897,7 @@ namespace exprtk
3898 3897
                      }
3899 3898
                   }
3900 3899
                }
3901
-               else if (details::is_right_bracket(static_cast<char>(t)))
3900
+               else if (details::is_right_bracket(static_cast<details::char_t>(t)))
3902 3901
                {
3903 3902
                   switch (base)
3904 3903
                   {
... ...
@@ -3911,7 +3910,7 @@ namespace exprtk
3911 3910
                      default                      : return true ;
3912 3911
                   }
3913 3912
                }
3914
-               else if (details::is_left_bracket(static_cast<char>(t)))
3913
+               else if (details::is_left_bracket(static_cast<details::char_t>(t)))
3915 3914
                {
3916 3915
                   switch (base)
3917 3916
                   {
... ...
@@ -3944,23 +3943,23 @@ namespace exprtk
3944 3943
             sequence_validator_3tokens()
3945 3944
             : lexer::token_scanner(3)
3946 3945
             {
3947
-               add_invalid(lexer::token::e_number, lexer::token::e_number, lexer::token::e_number);
3948
-               add_invalid(lexer::token::e_string, lexer::token::e_string, lexer::token::e_string);
3949
-               add_invalid(lexer::token::e_comma , lexer::token::e_comma , lexer::token::e_comma );
3946
+               add_invalid(lexer::token::e_number , lexer::token::e_number , lexer::token::e_number);
3947
+               add_invalid(lexer::token::e_string , lexer::token::e_string , lexer::token::e_string);
3948
+               add_invalid(lexer::token::e_comma  , lexer::token::e_comma  , lexer::token::e_comma );
3950 3949
 
3951
-               add_invalid(lexer::token::e_add   , lexer::token::e_add   , lexer::token::e_add   );
3952
-               add_invalid(lexer::token::e_sub   , lexer::token::e_sub   , lexer::token::e_sub   );
3953
-               add_invalid(lexer::token::e_div   , lexer::token::e_div   , lexer::token::e_div   );
3954
-               add_invalid(lexer::token::e_mul   , lexer::token::e_mul   , lexer::token::e_mul   );
3955
-               add_invalid(lexer::token::e_mod   , lexer::token::e_mod   , lexer::token::e_mod   );
3956
-               add_invalid(lexer::token::e_pow   , lexer::token::e_pow   , lexer::token::e_pow   );
3950
+               add_invalid(lexer::token::e_add    , lexer::token::e_add    , lexer::token::e_add   );
3951
+               add_invalid(lexer::token::e_sub    , lexer::token::e_sub    , lexer::token::e_sub   );
3952
+               add_invalid(lexer::token::e_div    , lexer::token::e_div    , lexer::token::e_div   );
3953
+               add_invalid(lexer::token::e_mul    , lexer::token::e_mul    , lexer::token::e_mul   );
3954
+               add_invalid(lexer::token::e_mod    , lexer::token::e_mod    , lexer::token::e_mod   );
3955
+               add_invalid(lexer::token::e_pow    , lexer::token::e_pow    , lexer::token::e_pow   );
3957 3956
 
3958
-               add_invalid(lexer::token::e_add   , lexer::token::e_sub   , lexer::token::e_add   );
3959
-               add_invalid(lexer::token::e_sub   , lexer::token::e_add   , lexer::token::e_sub   );
3960
-               add_invalid(lexer::token::e_div   , lexer::token::e_mul   , lexer::token::e_div   );
3961
-               add_invalid(lexer::token::e_mul   , lexer::token::e_div   , lexer::token::e_mul   );
3962
-               add_invalid(lexer::token::e_mod   , lexer::token::e_pow   , lexer::token::e_mod   );
3963
-               add_invalid(lexer::token::e_pow   , lexer::token::e_mod   , lexer::token::e_pow   );
3957
+               add_invalid(lexer::token::e_add    , lexer::token::e_sub    , lexer::token::e_add   );
3958
+               add_invalid(lexer::token::e_sub    , lexer::token::e_add    , lexer::token::e_sub   );
3959
+               add_invalid(lexer::token::e_div    , lexer::token::e_mul    , lexer::token::e_div   );
3960
+               add_invalid(lexer::token::e_mul    , lexer::token::e_div    , lexer::token::e_mul   );
3961
+               add_invalid(lexer::token::e_mod    , lexer::token::e_pow    , lexer::token::e_mod   );
3962
+               add_invalid(lexer::token::e_pow    , lexer::token::e_mod    , lexer::token::e_pow   );
3964 3963
             }
3965 3964
 
3966 3965
             bool result()
... ...
@@ -4005,7 +4004,7 @@ namespace exprtk
4005 4004
 
4006 4005
          private:
4007 4006
 
4008
-            void add_invalid(token_t t0, token_t t1, token_t t2)
4007
+            void add_invalid(const token_t t0, const token_t t1, const token_t t2)
4009 4008
             {
4010 4009
                invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2)));
4011 4010
             }
... ...
@@ -4176,7 +4175,7 @@ namespace exprtk
4176 4175
       {
4177 4176
       public:
4178 4177
 
4179
-         typedef token         token_t;
4178
+         typedef token     token_t;
4180 4179
          typedef generator generator_t;
4181 4180
 
4182 4181
          inline bool init(const std::string& str)
... ...
@@ -4294,15 +4293,15 @@ namespace exprtk
4294 4293
       typedef T* data_ptr_t;
4295 4294
 
4296 4295
       vector_view(data_ptr_t data, const std::size_t& size)
4297
-      : size_(size),
4298
-        data_(data),
4299
-        data_ref_(0)
4296
+      : size_(size)
4297
+      , data_(data)
4298
+      , data_ref_(0)
4300 4299
       {}
4301 4300
 
4302 4301
       vector_view(const vector_view<T>& vv)
4303
-      : size_(vv.size_),
4304
-        data_(vv.data_),
4305
-        data_ref_(0)
4302
+      : size_(vv.size_)
4303
+      , data_(vv.data_)
4304
+      , data_ref_(0)
4306 4305
       {}
4307 4306
 
4308 4307
       inline void rebase(data_ptr_t data)
... ...
@@ -4378,15 +4377,15 @@ namespace exprtk
4378 4377
       };
4379 4378
 
4380 4379
       type_store()
4381
-      : data(0),
4382
-        size(0),
4383
-        type(e_unknown)
4380
+      : data(0)
4381
+      , size(0)
4382
+      , type(e_unknown)
4384 4383
       {}
4385 4384
 
4386 4385
       union
4387 4386
       {
4388
-          void*  data;
4389
-          T*     vec_data;
4387
+         void* data;
4388
+         T*    vec_data;
4390 4389
       };
4391 4390
 
4392 4391
       std::size_t size;
... ...
@@ -4396,7 +4395,7 @@ namespace exprtk
4396 4395
       {
4397 4396
       public:
4398 4397
 
4399
-         parameter_list(std::vector<type_store>& pl)
4398
+         explicit parameter_list(std::vector<type_store>& pl)
4400 4399
          : parameter_list_(pl)
4401 4400
          {}
4402 4401
 
... ...
@@ -4453,14 +4452,14 @@ namespace exprtk
4453 4452
          typedef type_store<T> type_store_t;
4454 4453
          typedef ViewType      value_t;
4455 4454
 
4456
-         type_view(type_store_t& ts)
4457
-         : ts_(ts),
4458
-           data_(reinterpret_cast<value_t*>(ts_.data))
4455
+         explicit type_view(type_store_t& ts)
4456
+         : ts_(ts)
4457
+         , data_(reinterpret_cast<value_t*>(ts_.data))
4459 4458
          {}
4460 4459
 
4461
-         type_view(const type_store_t& ts)
4462
-         : ts_(const_cast<type_store_t&>(ts)),
4463
-           data_(reinterpret_cast<value_t*>(ts_.data))
4460
+         explicit type_view(const type_store_t& ts)
4461
+         : ts_(const_cast<type_store_t&>(ts))
4462
+         , data_(reinterpret_cast<value_t*>(ts_.data))
4464 4463
          {}
4465 4464
 
4466 4465
          inline std::size_t size() const
... ...
@@ -4503,11 +4502,11 @@ namespace exprtk
4503 4502
          typedef type_store<T> type_store_t;
4504 4503
          typedef T value_t;
4505 4504
 
4506
-         scalar_view(type_store_t& ts)
4505
+         explicit scalar_view(type_store_t& ts)
4507 4506
          : v_(*reinterpret_cast<value_t*>(ts.data))
4508 4507
          {}
4509 4508
 
4510
-         scalar_view(const type_store_t& ts)
4509
+         explicit scalar_view(const type_store_t& ts)
4511 4510
          : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
4512 4511
          {}
4513 4512
 
... ...
@@ -4728,8 +4727,8 @@ namespace exprtk
4728 4727
       struct base_operation_t
4729 4728
       {
4730 4729
          base_operation_t(const operator_type t, const unsigned int& np)
4731
-         : type(t),
4732
-           num_params(np)
4730
+         : type(t)
4731
+         , num_params(np)
4733 4732
          {}
4734 4733
 
4735 4734
          operator_type type;
... ...
@@ -4748,13 +4747,13 @@ namespace exprtk
4748 4747
          {
4749 4748
             explicit details(const std::size_t& vsize,
4750 4749
                              const unsigned int loop_batch_size = global_loop_batch_size)
4751
-            : batch_size(loop_batch_size   ),
4752
-              remainder (vsize % batch_size),
4753
-              upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
4750
+            : batch_size(loop_batch_size   )
4751
+            , remainder (vsize % batch_size)
4752
+            , upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
4754 4753
             {}
4755 4754
 
4756 4755
             unsigned int batch_size;
4757
-            int   remainder;
4756
+            int remainder;
4758 4757
             int upper_bound;
4759 4758
          };
4760 4759
       }
... ...
@@ -4788,24 +4787,24 @@ namespace exprtk
4788 4787
          struct control_block
4789 4788
          {
4790 4789
             control_block()
4791
-            : ref_count(1),
4792
-              size     (0),
4793
-              data     (0),
4794
-              destruct (true)
4790
+            : ref_count(1)
4791
+            , size     (0)
4792
+            , data     (0)
4793
+            , destruct (true)
4795 4794
             {}
4796 4795
 
4797
-            control_block(const std::size_t& dsize)
4798
-            : ref_count(1    ),
4799
-              size     (dsize),
4800
-              data     (0    ),
4801
-              destruct (true )
4796
+            explicit control_block(const std::size_t& dsize)
4797
+            : ref_count(1    )
4798
+            , size     (dsize)
4799
+            , data     (0    )
4800
+            , destruct (true )
4802 4801
             { create_data(); }
4803 4802
 
4804 4803
             control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false)
4805
-            : ref_count(1     ),
4806
-              size     (dsize ),
4807
-              data     (dptr  ),
4808
-              destruct (dstrct)
4804
+            : ref_count(1     )
4805
+            , size     (dsize )
4806
+            , data     (dptr  )
4807
+            , destruct (dstrct)
4809 4808
             {}
4810 4809
 
4811 4810
            ~control_block()
... ...
@@ -4854,15 +4853,15 @@ namespace exprtk
4854 4853
 
4855 4854
          private:
4856 4855
 
4857
-            control_block(const control_block&);
4858
-            control_block& operator=(const control_block&);
4856
+            control_block(const control_block&) exprtk_delete;
4857
+            control_block& operator=(const control_block&) exprtk_delete;
4859 4858
 
4860 4859
             inline void create_data()
4861 4860
             {
4862 4861
                destruct = true;
4863 4862
                data     = new T[size];
4864
-               std::fill_n(data,size,T(0));
4865
-               dump_ptr("control_block::create_data() - data",data,size);
4863
+               std::fill_n(data, size, T(0));
4864
+               dump_ptr("control_block::create_data() - data", data, size);
4866 4865
             }
4867 4866
          };
4868 4867
 
... ...
@@ -4872,8 +4871,8 @@ namespace exprtk
4872 4871
          : control_block_(control_block::create(0))
4873 4872
          {}
4874 4873
 
4875
-         vec_data_store(const std::size_t& size)
4876
-         : control_block_(control_block::create(size,(data_t)(0),true))
4874
+         explicit vec_data_store(const std::size_t& size)
4875
+         : control_block_(control_block::create(size,reinterpret_cast<data_t>(0),true))
4877 4876
          {}
4878 4877
 
4879 4878
          vec_data_store(const std::size_t& size, data_t data, bool dstrct = false)
... ...
@@ -4922,11 +4921,6 @@ namespace exprtk
4922 4921
             return control_block_->data;
4923 4922
          }
4924 4923
 
4925
-         inline std::size_t size()
4926
-         {
4927
-            return control_block_->size;
4928
-         }
4929
-
4930 4924
          inline std::size_t size() const
4931 4925
          {
4932 4926
             return control_block_->size;
... ...
@@ -4965,7 +4959,7 @@ namespace exprtk
4965 4959
 
4966 4960
       private:
4967 4961
 
4968
-         static inline std::size_t min_size(control_block* cb0, control_block* cb1)
4962
+         static inline std::size_t min_size(const control_block* cb0, const control_block* cb1)
4969 4963
          {
4970 4964
             const std::size_t size0 = cb0->size;
4971 4965
             const std::size_t size1 = cb1->size;
... ...
@@ -5184,8 +5178,8 @@ namespace exprtk
5184 5178
             e_vecdefass     , e_vecvalass     , e_vecvecass   , e_vecopvalass  ,
5185 5179
             e_vecopvecass   , e_vecfunc       , e_vecvecswap  , e_vecvecineq   ,
5186 5180
             e_vecvalineq    , e_valvecineq    , e_vecvecarith , e_vecvalarith  ,
5187
-            e_valvecarith   , e_vecunaryop    , e_break       , e_continue     ,
5188
-            e_swap
5181
+            e_valvecarith   , e_vecunaryop    , e_vecondition , e_break        ,
5182
+            e_continue      , e_swap
5189 5183
          };
5190 5184
 
5191 5185
          typedef T value_type;
... ...
@@ -5194,8 +5188,7 @@ namespace exprtk
5194 5188
          typedef typename nci_t::noderef_list_t noderef_list_t;
5195 5189
          typedef node_depth_base<expression_node<T> > ndb_t;
5196 5190
 
5197
-         virtual ~expression_node()
5198
-         {}
5191
+         virtual ~expression_node() {}
5199 5192
 
5200 5193
          inline virtual T value() const
5201 5194
          {
... ...
@@ -5211,7 +5204,7 @@ namespace exprtk
5211 5204
          {
5212 5205
             return e_none;
5213 5206
          }
5214
-      };
5207
+      }; // class expression_node
5215 5208
 
5216 5209
       template <typename T>
5217 5210
       inline bool is_generally_string_node(const expression_node<T>* node);
... ...
@@ -5243,12 +5236,24 @@ namespace exprtk
5243 5236
          return std::not_equal_to<T>()(T(0),node->value());
5244 5237
       }
5245 5238
 
5239
+      template <typename T>
5240
+      inline bool is_true(const std::pair<expression_node<T>*,bool>& node)
5241
+      {
5242
+         return std::not_equal_to<T>()(T(0),node.first->value());
5243
+      }
5244
+
5246 5245
       template <typename T>
5247 5246
       inline bool is_false(const expression_node<T>* node)
5248 5247
       {
5249 5248
          return std::equal_to<T>()(T(0),node->value());
5250 5249
       }
5251 5250
 
5251
+      template <typename T>
5252
+      inline bool is_false(const std::pair<expression_node<T>*,bool>& node)
5253
+      {
5254
+         return std::equal_to<T>()(T(0),node.first->value());
5255
+      }
5256
+
5252 5257
       template <typename T>
5253 5258
       inline bool is_unary_node(const expression_node<T>* node)
5254 5259
       {
... ...
@@ -5325,7 +5330,8 @@ namespace exprtk
5325 5330
                case details::expression_node<T>::e_vecvecarith :
5326 5331
                case details::expression_node<T>::e_vecvalarith :
5327 5332
                case details::expression_node<T>::e_valvecarith :
5328
-               case details::expression_node<T>::e_vecunaryop  : return true;
5333
+               case details::expression_node<T>::e_vecunaryop  :
5334
+               case details::expression_node<T>::e_vecondition : return true;
5329 5335
                default                                         : return false;
5330 5336
             }
5331 5337
          }
... ...
@@ -5568,9 +5574,12 @@ namespace exprtk
5568 5574
       template <typename Node>
5569 5575
       struct node_depth_base
5570 5576
       {
5577
+         typedef Node* node_ptr_t;
5578
+         typedef std::pair<node_ptr_t,bool> nb_pair_t;
5579
+
5571 5580
          node_depth_base()
5572
-         : depth_set(false),
5573
-           depth(0)
5581
+         : depth_set(false)
5582
+         , depth(0)
5574 5583
          {}
5575 5584
 
5576 5585
          virtual ~node_depth_base() {}
... ...
@@ -5588,7 +5597,7 @@ namespace exprtk
5588 5597
             return depth;
5589 5598
          }
5590 5599
 
5591
-         std::size_t compute_node_depth(const std::pair<Node*,bool>& branch) const
5600
+         std::size_t compute_node_depth(const nb_pair_t& branch) const
5592 5601
          {
5593 5602
             if (!depth_set)
5594 5603
             {
... ...
@@ -5600,7 +5609,7 @@ namespace exprtk
5600 5609
          }
5601 5610
 
5602 5611
          template <std::size_t N>
5603
-         std::size_t compute_node_depth(const std::pair<Node*,bool> (&branch)[N]) const
5612
+         std::size_t compute_node_depth(const nb_pair_t (&branch)[N]) const
5604 5613
          {
5605 5614
             if (!depth_set)
5606 5615
             {
... ...
@@ -5663,7 +5672,7 @@ namespace exprtk
5663 5672
 
5664 5673
          template <typename Allocator,
5665 5674
                    template <typename, typename> class Sequence>
5666
-         std::size_t compute_node_depth(const Sequence<Node*, Allocator>& branch_list) const
5675
+         std::size_t compute_node_depth(const Sequence<node_ptr_t, Allocator>& branch_list) const
5667 5676
          {
5668 5677
             if (!depth_set)
5669 5678
             {
... ...
@@ -5682,7 +5691,7 @@ namespace exprtk
5682 5691
 
5683 5692
          template <typename Allocator,
5684 5693
                    template <typename, typename> class Sequence>
5685
-         std::size_t compute_node_depth(const Sequence<std::pair<Node*,bool>,Allocator>& branch_list) const
5694
+         std::size_t compute_node_depth(const Sequence<nb_pair_t,Allocator>& branch_list) const
5686 5695
          {
5687 5696
             if (!depth_set)
5688 5697
             {
... ...
@@ -5703,18 +5712,18 @@ namespace exprtk
5703 5712
          mutable std::size_t depth;
5704 5713
 
5705 5714
          template <typename NodeSequence>
5706
-         void collect(Node*const& node,
5715
+         void collect(node_ptr_t const& node,
5707 5716
                       const bool deletable,
5708 5717
                       NodeSequence& delete_node_list) const
5709 5718
          {
5710 5719
             if ((0 != node) && deletable)
5711 5720
             {
5712
-               delete_node_list.push_back(const_cast<Node**>(&node));
5721
+               delete_node_list.push_back(const_cast<node_ptr_t*>(&node));
5713 5722
             }
5714 5723
          }
5715 5724
 
5716 5725
          template <typename NodeSequence>
5717
-         void collect(const std::pair<Node*, bool>& branch,
5726
+         void collect(const nb_pair_t& branch,
5718 5727
                       NodeSequence& delete_node_list) const
5719 5728
          {
5720 5729
             collect(branch.first, branch.second, delete_node_list);
... ...
@@ -5728,7 +5737,7 @@ namespace exprtk
5728 5737
          }
5729 5738
 
5730 5739
          template <std::size_t N, typename NodeSequence>
5731
-         void collect(const std::pair<Node*, bool>(&branch)[N],
5740
+         void collect(const nb_pair_t(&branch)[N],
5732 5741
                       NodeSequence& delete_node_list) const
5733 5742
          {
5734 5743
             for (std::size_t i = 0; i < N; ++i)
... ...
@@ -5740,7 +5749,7 @@ namespace exprtk
5740 5749
          template <typename Allocator,
5741 5750
                    template <typename, typename> class Sequence,
5742 5751
                    typename NodeSequence>
5743
-         void collect(const Sequence<std::pair<Node*, bool>, Allocator>& branch,
5752
+         void collect(const Sequence<nb_pair_t, Allocator>& branch,
5744 5753
                       NodeSequence& delete_node_list) const
5745 5754
          {
5746 5755
             for (std::size_t i = 0; i < branch.size(); ++i)
... ...
@@ -5752,7 +5761,7 @@ namespace exprtk
5752 5761
          template <typename Allocator,
5753 5762
                    template <typename, typename> class Sequence,
5754 5763
                    typename NodeSequence>
5755
-         void collect(const Sequence<Node*, Allocator>& branch_list,
5764
+         void collect(const Sequence<node_ptr_t, Allocator>& branch_list,
5756 5765
                       NodeSequence& delete_node_list) const
5757 5766
          {
5758 5767
             for (std::size_t i = 0; i < branch_list.size(); ++i)
... ...
@@ -5766,7 +5775,7 @@ namespace exprtk
5766 5775
                    typename AllocatorB,
5767 5776
                    template <typename, typename> class Sequence,
5768 5777
                    typename NodeSequence>
5769
-         void collect(const Sequence<Node*, AllocatorT>& branch_list,
5778
+         void collect(const Sequence<node_ptr_t, AllocatorT>& branch_list,
5770 5779
                       const Sequence<Boolean, AllocatorB>& branch_deletable_list,
5771 5780
                       NodeSequence& delete_node_list) const
5772 5781
          {
... ...
@@ -5825,8 +5834,8 @@ namespace exprtk
5825 5834
          public:
5826 5835
 
5827 5836
             array_vector_impl(const Type* vec, const std::size_t& vec_size)
5828
-            : vec_(vec),
5829
-              size_(vec_size)
5837
+            : vec_(vec)
5838
+            , size_(vec_size)
5830 5839
             {}
5831 5840
 
5832 5841
          protected:
... ...
@@ -5846,7 +5855,8 @@ namespace exprtk
5846 5855
 
5847 5856
          private:
5848 5857
 
5849
-            array_vector_impl operator=(const array_vector_impl&);
5858
+            array_vector_impl(const array_vector_impl&) exprtk_delete;
5859
+            array_vector_impl& operator=(const array_vector_impl&) exprtk_delete;
5850 5860
 
5851 5861
             const Type* vec_;
5852 5862
             const std::size_t size_;
... ...
@@ -5878,7 +5888,8 @@ namespace exprtk
5878 5888
 
5879 5889
          private:
5880 5890
 
5881
-            sequence_vector_impl operator=(const sequence_vector_impl&);
5891
+            sequence_vector_impl(const sequence_vector_impl&) exprtk_delete;
5892
+            sequence_vector_impl& operator=(const sequence_vector_impl&) exprtk_delete;
5882 5893
 
5883 5894
             sequence_t& sequence_;
5884 5895
          };
... ...
@@ -5917,7 +5928,8 @@ namespace exprtk
5917 5928
 
5918 5929
          private:
5919 5930
 
5920
-            vector_view_impl operator=(const vector_view_impl&);
5931
+            vector_view_impl(const vector_view_impl&) exprtk_delete;
5932
+            vector_view_impl& operator=(const vector_view_impl&) exprtk_delete;
5921 5933
 
5922 5934
             vector_view_t& vec_view_;
5923 5935
          };
... ...
@@ -5975,16 +5987,16 @@ namespace exprtk
5975 5987
       };
5976 5988
 
5977 5989
       template <typename T>
5978
-      class null_node : public expression_node<T>
5990
+      class null_node exprtk_final : public expression_node<T>
5979 5991
       {
5980 5992
       public:
5981 5993
 
5982
-         inline T value() const
5994
+         inline T value() const exprtk_override
5983 5995
          {
5984 5996
             return std::numeric_limits<T>::quiet_NaN();
5985 5997
          }
5986 5998
 
5987
-         inline typename expression_node<T>::node_type type() const
5999
+         inline typename expression_node<T>::node_type type() const exprtk_override
5988 6000
          {
5989 6001
             return expression_node<T>::e_null;
5990 6002
          }
... ...
@@ -6036,21 +6048,23 @@ namespace exprtk
6036 6048
       }
6037 6049
 
6038 6050
       template <typename T>
6039
-      class null_eq_node : public expression_node<T>
6051
+      class null_eq_node exprtk_final : public expression_node<T>
6040 6052
       {
6041 6053
       public:
6042 6054
 
6043 6055
          typedef expression_node<T>* expression_ptr;
6044 6056
          typedef std::pair<expression_ptr,bool> branch_t;
6045 6057
 
6046
-         explicit null_eq_node(expression_ptr brnch, const bool equality = true)
6058
+         explicit null_eq_node(expression_ptr branch, const bool equality = true)
6047 6059
          : equality_(equality)
6048 6060
          {
6049
-            construct_branch_pair(branch_, brnch);
6061
+            construct_branch_pair(branch_, branch);
6050 6062
          }
6051 6063
 
6052
-         inline T value() const
6064
+         inline T value() const exprtk_override
6053 6065
          {
6066
+            assert(branch_.first);
6067
+
6054 6068
             const T v = branch_.first->value();
6055 6069
             const bool result = details::numeric::is_nan(v);
6056 6070
 
... ...
@@ -6060,27 +6074,22 @@ namespace exprtk
6060 6074
                return (equality_) ? T(0) : T(1);
6061 6075
          }
6062 6076
 
6063
-         inline typename expression_node<T>::node_type type() const
6077
+         inline typename expression_node<T>::node_type type() const exprtk_override
6064 6078
          {
6065 6079
             return expression_node<T>::e_nulleq;
6066 6080
          }
6067 6081
 
6068
-         inline operator_type operation() const
6069
-         {
6070
-            return details::e_eq;
6071
-         }
6072
-
6073
-         inline expression_node<T>* branch(const std::size_t&) const
6082
+         inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6074 6083
          {
6075 6084
             return branch_.first;
6076 6085
          }
6077 6086
 
6078
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6087
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6079 6088
          {
6080
-            expression_node<T>::ndb_t::collect(branch_,node_delete_list);
6089
+            expression_node<T>::ndb_t::collect(branch_, node_delete_list);
6081 6090
          }
6082 6091
 
6083
-         std::size_t node_depth() const
6092
+         std::size_t node_depth() const exprtk_override
6084 6093
          {
6085 6094
             return expression_node<T>::ndb_t::compute_node_depth(branch_);
6086 6095
          }
... ...
@@ -6092,7 +6101,7 @@ namespace exprtk
6092 6101
       };
6093 6102
 
6094 6103
       template <typename T>
6095
-      class literal_node : public expression_node<T>
6104
+      class literal_node exprtk_final : public expression_node<T>
6096 6105
       {
6097 6106
       public:
6098 6107
 
... ...
@@ -6100,25 +6109,25 @@ namespace exprtk
6100 6109
          : value_(v)
6101 6110
          {}
6102 6111
 
6103
-         inline T value() const
6112
+         inline T value() const exprtk_override
6104 6113
          {
6105 6114
             return value_;
6106 6115
          }
6107 6116
 
6108
-         inline typename expression_node<T>::node_type type() const
6117
+         inline typename expression_node<T>::node_type type() const exprtk_override
6109 6118
          {
6110 6119
             return expression_node<T>::e_constant;
6111 6120
          }
6112 6121
 
6113
-         inline expression_node<T>* branch(const std::size_t&) const
6122
+         inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6114 6123
          {
6115 6124
             return reinterpret_cast<expression_node<T>*>(0);
6116 6125
          }
6117 6126
 
6118 6127
       private:
6119 6128
 
6120
-         literal_node(literal_node<T>&) {}
6121
-         literal_node<T>& operator=(literal_node<T>&) { return (*this); }
6129
+         literal_node(const literal_node<T>&) exprtk_delete;
6130
+         literal_node<T>& operator=(const literal_node<T>&) exprtk_delete;
6122 6131
 
6123 6132
          const T value_;
6124 6133
       };
... ...
@@ -6136,8 +6145,7 @@ namespace exprtk
6136 6145
 
6137 6146
          typedef range_pack<T> range_t;
6138 6147
 
6139
-         virtual ~range_interface()
6140
-         {}
6148
+         virtual ~range_interface() {}
6141 6149
 
6142 6150
          virtual range_t& range_ref() = 0;
6143 6151
 
... ...
@@ -6152,8 +6160,7 @@ namespace exprtk
6152 6160
 
6153 6161
          typedef range_data_type<T> range_data_type_t;
6154 6162
 
6155
-         virtual ~string_base_node()
6156
-         {}
6163
+         virtual ~string_base_node() {}
6157 6164
 
6158 6165
          virtual std::string str () const = 0;
6159 6166
 
... ...
@@ -6163,7 +6170,8 @@ namespace exprtk
6163 6170
       };
6164 6171
 
6165 6172
       template <typename T>
6166
-      class string_literal_node : public expression_node <T>,
6173
+      class string_literal_node exprtk_final
6174
+                                : public expression_node <T>,
6167 6175
                                   public string_base_node<T>,
6168 6176
                                   public range_interface <T>
6169 6177
       {
... ...
@@ -6180,50 +6188,50 @@ namespace exprtk
6180 6188
             rp_.cache.second = rp_.n1_c.second;
6181 6189
          }
6182 6190
 
6183
-         inline T value() const
6191
+         inline T value() const exprtk_override
6184 6192
          {
6185 6193
             return std::numeric_limits<T>::quiet_NaN();
6186 6194
          }
6187 6195
 
6188
-         inline typename expression_node<T>::node_type type() const
6196
+         inline typename expression_node<T>::node_type type() const exprtk_override
6189 6197
          {
6190 6198
             return expression_node<T>::e_stringconst;
6191 6199
          }
6192 6200
 
6193
-         inline expression_node<T>* branch(const std::size_t&) const
6201
+         inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6194 6202
          {
6195 6203
             return reinterpret_cast<expression_node<T>*>(0);
6196 6204
          }
6197 6205
 
6198
-         std::string str() const
6206
+         std::string str() const exprtk_override
6199 6207
          {
6200 6208
             return value_;
6201 6209
          }
6202 6210
 
6203
-         char_cptr base() const
6211
+         char_cptr base() const exprtk_override
6204 6212
          {
6205 6213
             return value_.data();
6206 6214
          }
6207 6215
 
6208
-         std::size_t size() const
6216
+         std::size_t size() const exprtk_override
6209 6217
          {
6210 6218
             return value_.size();
6211 6219
          }
6212 6220
 
6213
-         range_t& range_ref()
6221
+         range_t& range_ref() exprtk_override
6214 6222
          {
6215 6223
             return rp_;
6216 6224
          }
6217 6225
 
6218
-         const range_t& range_ref() const
6226
+         const range_t& range_ref() const exprtk_override
6219 6227
          {
6220 6228
             return rp_;
6221 6229
          }
6222 6230
 
6223 6231
       private:
6224 6232
 
6225
-         string_literal_node(const string_literal_node<T>&);
6226
-         string_literal_node<T>& operator=(const string_literal_node<T>&);
6233
+         string_literal_node(const string_literal_node<T>&) exprtk_delete;
6234
+         string_literal_node<T>& operator=(const string_literal_node<T>&) exprtk_delete;
6227 6235
 
6228 6236
          const std::string value_;
6229 6237
          range_t rp_;
... ...
@@ -6238,31 +6246,32 @@ namespace exprtk
6238 6246
          typedef expression_node<T>* expression_ptr;
6239 6247
          typedef std::pair<expression_ptr,bool> branch_t;
6240 6248
 
6241
-         unary_node(const operator_type& opr,
6242
-                    expression_ptr brnch)
6249
+         unary_node(const operator_type& opr, expression_ptr branch)
6243 6250
          : operation_(opr)
6244 6251
          {
6245
-            construct_branch_pair(branch_,brnch);
6252
+            construct_branch_pair(branch_,branch);
6246 6253
          }
6247 6254
 
6248
-         inline T value() const
6255
+         inline T value() const exprtk_override
6249 6256
          {
6257
+            assert(branch_.first);
6258
+
6250 6259
             const T arg = branch_.first->value();
6251 6260
 
6252 6261
             return numeric::process<T>(operation_,arg);
6253 6262
          }
6254 6263
 
6255
-         inline typename expression_node<T>::node_type type() const
6264
+         inline typename expression_node<T>::node_type type() const exprtk_override
6256 6265
          {
6257 6266
             return expression_node<T>::e_unary;
6258 6267
          }
6259 6268
 
6260
-         inline operator_type operation() const
6269
+         inline operator_type operation()
6261 6270
          {
6262 6271
             return operation_;
6263 6272
          }
6264 6273
 
6265
-         inline expression_node<T>* branch(const std::size_t&) const
6274
+         inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6266 6275
          {
6267 6276
             return branch_.first;
6268 6277
          }
... ...
@@ -6272,12 +6281,12 @@ namespace exprtk
6272 6281
             branch_.second = false;
6273 6282
          }
6274 6283
 
6275
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6284
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6276 6285
          {
6277 6286
             expression_node<T>::ndb_t::collect(branch_, node_delete_list);
6278 6287
          }
6279 6288
 
6280
-         std::size_t node_depth() const
6289
+         std::size_t node_depth() const exprtk_override exprtk_final
6281 6290
          {
6282 6291
             return expression_node<T>::ndb_t::compute_node_depth(branch_);
6283 6292
          }
... ...
@@ -6304,15 +6313,18 @@ namespace exprtk
6304 6313
             init_branches<2>(branch_, branch0, branch1);
6305 6314
          }
6306 6315
 
6307
-         inline T value() const
6316
+         inline T value() const exprtk_override
6308 6317
          {
6318
+            assert(branch_[0].first);
6319
+            assert(branch_[1].first);
6320
+
6309 6321
             const T arg0 = branch_[0].first->value();
6310 6322
             const T arg1 = branch_[1].first->value();
6311 6323
 
6312 6324
             return numeric::process<T>(operation_,arg0,arg1);
6313 6325
          }
6314 6326
 
6315
-         inline typename expression_node<T>::node_type type() const
6327
+         inline typename expression_node<T>::node_type type() const exprtk_override
6316 6328
          {
6317 6329
             return expression_node<T>::e_binary;
6318 6330
          }
... ...
@@ -6322,7 +6334,7 @@ namespace exprtk
6322 6334
             return operation_;
6323 6335
          }
6324 6336
 
6325
-         inline expression_node<T>* branch(const std::size_t& index = 0) const
6337
+         inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
6326 6338
          {
6327 6339
             if (0 == index)
6328 6340
                return branch_[0].first;
... ...
@@ -6332,12 +6344,12 @@ namespace exprtk
6332 6344
                return reinterpret_cast<expression_ptr>(0);
6333 6345
          }
6334 6346
 
6335
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6347
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6336 6348
          {
6337 6349
             expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
6338 6350
          }
6339 6351
 
6340
-         std::size_t node_depth() const
6352
+         std::size_t node_depth() const exprtk_override exprtk_final
6341 6353
          {
6342 6354
             return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
6343 6355
          }
... ...
@@ -6349,7 +6361,7 @@ namespace exprtk
6349 6361
       };
6350 6362
 
6351 6363
       template <typename T, typename Operation>
6352
-      class binary_ext_node : public expression_node<T>
6364
+      class binary_ext_node exprtk_final : public expression_node<T>
6353 6365
       {
6354 6366
       public:
6355 6367
 
... ...
@@ -6361,15 +6373,18 @@ namespace exprtk
6361 6373
             init_branches<2>(branch_, branch0, branch1);
6362 6374
          }
6363 6375
 
6364
-         inline T value() const
6376
+         inline T value() const exprtk_override
6365 6377
          {
6378
+            assert(branch_[0].first);
6379
+            assert(branch_[1].first);
6380
+
6366 6381
             const T arg0 = branch_[0].first->value();
6367 6382
             const T arg1 = branch_[1].first->value();
6368 6383
 
6369 6384
             return Operation::process(arg0,arg1);
6370 6385
          }
6371 6386
 
6372
-         inline typename expression_node<T>::node_type type() const
6387
+         inline typename expression_node<T>::node_type type() const exprtk_override
6373 6388
          {
6374 6389
             return expression_node<T>::e_binary_ext;
6375 6390
          }
... ...
@@ -6379,7 +6394,7 @@ namespace exprtk
6379 6394
             return Operation::operation();
6380 6395
          }
6381 6396
 
6382
-         inline expression_node<T>* branch(const std::size_t& index = 0) const
6397
+         inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
6383 6398
          {
6384 6399
             if (0 == index)
6385 6400
                return branch_[0].first;
... ...
@@ -6389,12 +6404,12 @@ namespace exprtk
6389 6404
                return reinterpret_cast<expression_ptr>(0);
6390 6405
          }
6391 6406
 
6392
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6407
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6393 6408
          {
6394 6409
             expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
6395 6410
          }
6396 6411
 
6397
-         std::size_t node_depth() const
6412
+         std::size_t node_depth() const exprtk_override
6398 6413
          {
6399 6414
             return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
6400 6415
          }
... ...
@@ -6421,8 +6436,12 @@ namespace exprtk
6421 6436
             init_branches<3>(branch_, branch0, branch1, branch2);
6422 6437
          }
6423 6438
 
6424
-         inline T value() const
6439
+         inline T value() const exprtk_override
6425 6440
          {
6441
+            assert(branch_[0].first);
6442
+            assert(branch_[1].first);
6443
+            assert(branch_[2].first);
6444
+
6426 6445
             const T arg0 = branch_[0].first->value();
6427 6446
             const T arg1 = branch_[1].first->value();
6428 6447
             const T arg2 = branch_[2].first->value();
... ...
@@ -6443,17 +6462,17 @@ namespace exprtk
6443 6462
             }
6444 6463
          }
6445 6464
 
6446
-         inline typename expression_node<T>::node_type type() const
6465
+         inline typename expression_node<T>::node_type type() const exprtk_override
6447 6466
          {
6448 6467
             return expression_node<T>::e_trinary;
6449 6468
          }
6450 6469
 
6451
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6470
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6452 6471
          {
6453 6472
             expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
6454 6473
          }
6455 6474
 
6456
-         std::size_t node_depth() const
6475
+         std::size_t node_depth() const exprtk_override exprtk_final
6457 6476
          {
6458 6477
             return expression_node<T>::ndb_t::template compute_node_depth<3>(branch_);
6459 6478
          }
... ...
@@ -6482,22 +6501,22 @@ namespace exprtk
6482 6501
             init_branches<4>(branch_, branch0, branch1, branch2, branch3);
6483 6502
          }
6484 6503
 
6485
-         inline T value() const
6504
+         inline T value() const exprtk_override
6486 6505
          {
6487 6506
             return std::numeric_limits<T>::quiet_NaN();
6488 6507
          }
6489 6508
 
6490
-         inline typename expression_node<T>::node_type type() const
6509
+         inline typename expression_node<T>::node_type type() const exprtk_override
6491 6510
          {
6492 6511
             return expression_node<T>::e_quaternary;
6493 6512
          }
6494 6513
 
6495
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6514
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6496 6515
          {
6497 6516
             expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
6498 6517
          }
6499 6518
 
6500
-         std::size_t node_depth() const
6519
+         std::size_t node_depth() const exprtk_override exprtk_final
6501 6520
          {
6502 6521
             return expression_node<T>::ndb_t::template compute_node_depth<4>(branch_);
6503 6522
          }
... ...
@@ -6509,56 +6528,61 @@ namespace exprtk
6509 6528
       };
6510 6529
 
6511 6530
       template <typename T>
6512
-      class conditional_node : public expression_node<T>
6531
+      class conditional_node exprtk_final : public expression_node<T>
6513 6532
       {
6514 6533
       public:
6515 6534
 
6516 6535
          typedef expression_node<T>* expression_ptr;
6517 6536
          typedef std::pair<expression_ptr,bool> branch_t;
6518 6537
 
6519
-         conditional_node(expression_ptr test,
6538
+         conditional_node(expression_ptr condition,
6520 6539
                           expression_ptr consequent,
6521 6540
                           expression_ptr alternative)
6522 6541
          {
6523
-            construct_branch_pair(test_       , test       );
6542
+            construct_branch_pair(condition_  , condition  );
6524 6543
             construct_branch_pair(consequent_ , consequent );
6525 6544
             construct_branch_pair(alternative_, alternative);
6526 6545
          }
6527 6546
 
6528
-         inline T value() const
6547
+         inline T value() const exprtk_override
6529 6548
          {
6530
-            if (is_true(test_.first))
6549
+            assert(condition_  .first);
6550
+            assert(consequent_ .first);
6551
+            assert(alternative_.first);
6552
+
6553
+            if (is_true(condition_))
6531 6554
                return consequent_.first->value();
6532 6555
             else
6533 6556
                return alternative_.first->value();
6534 6557
          }
6535 6558
 
6536
-         inline typename expression_node<T>::node_type type() const
6559
+         inline typename expression_node<T>::node_type type() const exprtk_override
6537 6560
          {
6538 6561
             return expression_node<T>::e_conditional;
6539 6562
          }
6540 6563
 
6541
-         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list)
6564
+         void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override
6542 6565
          {
6543
-            expression_node<T>::ndb_t::collect(test_       , node_delete_list);
6544