Browse code

3.99.8: unity build

ramon diaz-uriarte (at Phelsuma) authored on 15/09/2022 19:29:51
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,40735 @@
1
+/*
2
+ ******************************************************************
3
+ *           C++ Mathematical Expression Toolkit Library          *
4
+ *                                                                *
5
+ * Author: Arash Partow (1999-2022)                               *
6
+ * URL: https://www.partow.net/programming/exprtk/index.html      *
7
+ *                                                                *
8
+ * Copyright notice:                                              *
9
+ * Free use of the C++ Mathematical Expression Toolkit Library is *
10
+ * permitted under the guidelines and in accordance with the most *
11
+ * current version of the MIT License.                            *
12
+ * https://www.opensource.org/licenses/MIT                        *
13
+ *                                                                *
14
+ * Example expressions:                                           *
15
+ * (00) (y + x / y) * (x - y / x)                                 *
16
+ * (01) (x^2 / sin(2 * pi / y)) - x / 2                           *
17
+ * (02) sqrt(1 - (x^2))                                           *
18
+ * (03) 1 - sin(2 * x) + cos(pi / y)                              *
19
+ * (04) a * exp(2 * t) + c                                        *
20
+ * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z)        *
21
+ * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x          *
22
+ * (07) z := x + sin(2 * pi / y)                                  *
23
+ * (08) u := 2 * (pi * z) / (w := x + cos(y / pi))                *
24
+ * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1)            *
25
+ * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0)     *
26
+ * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1)  *
27
+ * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)]                  *
28
+ *                                                                *
29
+ ******************************************************************
30
+*/
31
+
32
+
33
+#ifndef INCLUDE_EXPRTK_HPP
34
+#define INCLUDE_EXPRTK_HPP
35
+
36
+
37
+#include <algorithm>
38
+#include <cassert>
39
+#include <cctype>
40
+#include <cmath>
41
+#include <complex>
42
+#include <cstdio>
43
+#include <cstdlib>
44
+#include <cstring>
45
+#include <deque>
46
+#include <exception>
47
+#include <functional>
48
+#include <iterator>
49
+#include <limits>
50
+#include <list>
51
+#include <map>
52
+#include <set>
53
+#include <stack>
54
+#include <stdexcept>
55
+#include <string>
56
+#include <utility>
57
+#include <vector>
58
+
59
+
60
+namespace exprtk
61
+{
62
+   #ifdef exprtk_enable_debugging
63
+     #define exprtk_debug(params) printf params
64
+   #else
65
+     #define exprtk_debug(params) (void)0
66
+   #endif
67
+
68
+   #define exprtk_error_location             \
69
+   "exprtk.hpp:" + details::to_str(__LINE__) \
70
+
71
+   #if defined(__GNUC__) && (__GNUC__  >= 7)
72
+
73
+      #define exprtk_disable_fallthrough_begin                      \
74
+      _Pragma ("GCC diagnostic push")                               \
75
+      _Pragma ("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
76
+
77
+      #define exprtk_disable_fallthrough_end                        \
78
+      _Pragma ("GCC diagnostic pop")                                \
79
+
80
+   #else
81
+      #define exprtk_disable_fallthrough_begin (void)0;
82
+      #define exprtk_disable_fallthrough_end   (void)0;
83
+   #endif
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
+
95
+   namespace details
96
+   {
97
+      typedef char                   char_t;
98
+      typedef char_t*                char_ptr;
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;
103
+      typedef unsigned long long int _uint64_t;
104
+      typedef long long int          _int64_t;
105
+
106
+      inline bool is_whitespace(const char_t c)
107
+      {
108
+         return (' '  == c) || ('\n' == c) ||
109
+                ('\r' == c) || ('\t' == c) ||
110
+                ('\b' == c) || ('\v' == c) ||
111
+                ('\f' == c) ;
112
+      }
113
+
114
+      inline bool is_operator_char(const char_t c)
115
+      {
116
+         return ('+' == c) || ('-' == c) ||
117
+                ('*' == c) || ('/' == c) ||
118
+                ('^' == c) || ('<' == c) ||
119
+                ('>' == c) || ('=' == c) ||
120
+                (',' == c) || ('!' == c) ||
121
+                ('(' == c) || (')' == c) ||
122
+                ('[' == c) || (']' == c) ||
123
+                ('{' == c) || ('}' == c) ||
124
+                ('%' == c) || (':' == c) ||
125
+                ('?' == c) || ('&' == c) ||
126
+                ('|' == c) || (';' == c) ;
127
+      }
128
+
129
+      inline bool is_letter(const char_t c)
130
+      {
131
+         return (('a' <= c) && (c <= 'z')) ||
132
+                (('A' <= c) && (c <= 'Z')) ;
133
+      }
134
+
135
+      inline bool is_digit(const char_t c)
136
+      {
137
+         return ('0' <= c) && (c <= '9');
138
+      }
139
+
140
+      inline bool is_letter_or_digit(const char_t c)
141
+      {
142
+         return is_letter(c) || is_digit(c);
143
+      }
144
+
145
+      inline bool is_left_bracket(const char_t c)
146
+      {
147
+         return ('(' == c) || ('[' == c) || ('{' == c);
148
+      }
149
+
150
+      inline bool is_right_bracket(const char_t c)
151
+      {
152
+         return (')' == c) || (']' == c) || ('}' == c);
153
+      }
154
+
155
+      inline bool is_bracket(const char_t c)
156
+      {
157
+         return is_left_bracket(c) || is_right_bracket(c);
158
+      }
159
+
160
+      inline bool is_sign(const char_t c)
161
+      {
162
+         return ('+' == c) || ('-' == c);
163
+      }
164
+
165
+      inline bool is_invalid(const char_t c)
166
+      {
167
+         return !is_whitespace   (c) &&
168
+                !is_operator_char(c) &&
169
+                !is_letter       (c) &&
170
+                !is_digit        (c) &&
171
+                ('.'  != c)          &&
172
+                ('_'  != c)          &&
173
+                ('$'  != c)          &&
174
+                ('~'  != c)          &&
175
+                ('\'' != c);
176
+      }
177
+
178
+      inline bool is_valid_string_char(const char_t c)
179
+      {
180
+         return std::isprint(static_cast<uchar_t>(c)) ||
181
+                is_whitespace(c);
182
+      }
183
+
184
+      #ifndef exprtk_disable_caseinsensitivity
185
+      inline void case_normalise(std::string& s)
186
+      {
187
+         for (std::size_t i = 0; i < s.size(); ++i)
188
+         {
189
+            s[i] = static_cast<std::string::value_type>(std::tolower(s[i]));
190
+         }
191
+      }
192
+
193
+      inline bool imatch(const char_t c1, const char_t c2)
194
+      {
195
+         return std::tolower(c1) == std::tolower(c2);
196
+      }
197
+
198
+      inline bool imatch(const std::string& s1, const std::string& s2)
199
+      {
200
+         if (s1.size() == s2.size())
201
+         {
202
+            for (std::size_t i = 0; i < s1.size(); ++i)
203
+            {
204
+               if (std::tolower(s1[i]) != std::tolower(s2[i]))
205
+               {
206
+                  return false;
207
+               }
208
+            }
209
+
210
+            return true;
211
+         }
212
+
213
+         return false;
214
+      }
215
+
216
+      struct ilesscompare
217
+      {
218
+         inline bool operator() (const std::string& s1, const std::string& s2) const
219
+         {
220
+            const std::size_t length = std::min(s1.size(),s2.size());
221
+
222
+            for (std::size_t i = 0; i < length;  ++i)
223
+            {
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]));
226
+
227
+               if (c1 > c2)
228
+                  return false;
229
+               else if (c1 < c2)
230
+                  return true;
231
+            }
232
+
233
+            return s1.size() < s2.size();
234
+         }
235
+      };
236
+
237
+      #else
238
+      inline void case_normalise(std::string&)
239
+      {}
240
+
241
+      inline bool imatch(const char_t c1, const char_t c2)
242
+      {
243
+         return c1 == c2;
244
+      }
245
+
246
+      inline bool imatch(const std::string& s1, const std::string& s2)
247
+      {
248
+         return s1 == s2;
249
+      }
250
+
251
+      struct ilesscompare
252
+      {
253
+         inline bool operator() (const std::string& s1, const std::string& s2) const
254
+         {
255
+            return s1 < s2;
256
+         }
257
+      };
258
+      #endif
259
+
260
+      inline bool is_valid_sf_symbol(const std::string& symbol)
261
+      {
262
+         // Special function: $f12 or $F34
263
+         return (4 == symbol.size())  &&
264
+                ('$' == symbol[0])    &&
265
+                imatch('f',symbol[1]) &&
266
+                is_digit(symbol[2])   &&
267
+                is_digit(symbol[3]);
268
+      }
269
+
270
+      inline const char_t& front(const std::string& s)
271
+      {
272
+         return s[0];
273
+      }
274
+
275
+      inline const char_t& back(const std::string& s)
276
+      {
277
+         return s[s.size() - 1];
278
+      }
279
+
280
+      inline std::string to_str(int i)
281
+      {
282
+         if (0 == i)
283
+            return std::string("0");
284
+
285
+         std::string result;
286
+
287
+         const int sign = (i < 0) ? -1 : 1;
288
+
289
+         for ( ; i; i /= 10)
290
+         {
291
+            result += '0' + static_cast<char_t>(sign * (i % 10));
292
+         }
293
+
294
+         if (sign < 0)
295
+         {
296
+            result += '-';
297
+         }
298
+
299
+         std::reverse(result.begin(), result.end());
300
+
301
+
302
+         return result;
303
+      }
304
+
305
+      inline std::string to_str(std::size_t i)
306
+      {
307
+         return to_str(static_cast<int>(i));
308
+      }
309
+
310
+      inline bool is_hex_digit(const uchar_t digit)
311
+      {
312
+         return (('0' <= digit) && (digit <= '9')) ||
313
+                (('A' <= digit) && (digit <= 'F')) ||
314
+                (('a' <= digit) && (digit <= 'f')) ;
315
+      }
316
+
317
+      inline uchar_t hex_to_bin(uchar_t h)
318
+      {
319
+         if (('0' <= h) && (h <= '9'))
320
+            return (h - '0');
321
+         else
322
+            return static_cast<uchar_t>(std::toupper(h) - 'A');
323
+      }
324
+
325
+      template <typename Iterator>
326
+      inline bool parse_hex(Iterator& itr, Iterator end,
327
+                            char_t& result)
328
+      {
329
+         if (
330
+              (end ==  (itr    ))               ||
331
+              (end ==  (itr + 1))               ||
332
+              (end ==  (itr + 2))               ||
333
+              (end ==  (itr + 3))               ||
334
+              ('0' != *(itr    ))               ||
335
+              ('X' != std::toupper(*(itr + 1))) ||
336
+              (!is_hex_digit(*(itr + 2)))       ||
337
+              (!is_hex_digit(*(itr + 3)))
338
+            )
339
+         {
340
+            return false;
341
+         }
342
+
343
+         result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 |
344
+                  hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ;
345
+
346
+         return true;
347
+      }
348
+
349
+      inline bool cleanup_escapes(std::string& s)
350
+      {
351
+         typedef std::string::iterator str_itr_t;
352
+
353
+         str_itr_t itr1 = s.begin();
354
+         str_itr_t itr2 = s.begin();
355
+         str_itr_t end  = s.end  ();
356
+
357
+         std::size_t removal_count  = 0;
358
+
359
+         while (end != itr1)
360
+         {
361
+            if ('\\' == (*itr1))
362
+            {
363
+               if (end == ++itr1)
364
+               {
365
+                  return false;
366
+               }
367
+               else if (parse_hex(itr1, end, *itr2))
368
+               {
369
+                  itr1+= 4;
370
+                  itr2+= 1;
371
+                  removal_count +=4;
372
+               }
373
+               else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; }
374
+               else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; }
375
+               else if ('f' == (*itr1)) { (*itr2++) = '\f'; ++itr1; ++removal_count; }
376
+               else if ('n' == (*itr1)) { (*itr2++) = '\n'; ++itr1; ++removal_count; }
377
+               else if ('r' == (*itr1)) { (*itr2++) = '\r'; ++itr1; ++removal_count; }
378
+               else if ('t' == (*itr1)) { (*itr2++) = '\t'; ++itr1; ++removal_count; }
379
+               else if ('v' == (*itr1)) { (*itr2++) = '\v'; ++itr1; ++removal_count; }
380
+               else if ('0' == (*itr1)) { (*itr2++) = '\0'; ++itr1; ++removal_count; }
381
+               else
382
+               {
383
+                  (*itr2++) = (*itr1++);
384
+                  ++removal_count;
385
+               }
386
+               continue;
387
+            }
388
+            else
389
+               (*itr2++) = (*itr1++);
390
+         }
391
+
392
+         if ((removal_count > s.size()) || (0 == removal_count))
393
+            return false;
394
+
395
+         s.resize(s.size() - removal_count);
396
+
397
+         return true;
398
+      }
399
+
400
+      class build_string
401
+      {
402
+      public:
403
+
404
+         build_string(const std::size_t& initial_size = 64)
405
+         {
406
+            data_.reserve(initial_size);
407
+         }
408
+
409
+         inline build_string& operator << (const std::string& s)
410
+         {
411
+            data_ += s;
412
+            return (*this);
413
+         }
414
+
415
+         inline build_string& operator << (char_cptr s)
416
+         {
417
+            data_ += std::string(s);
418
+            return (*this);
419
+         }
420
+
421
+         inline operator std::string () const
422
+         {
423
+            return data_;
424
+         }
425
+
426
+         inline std::string as_string() const
427
+         {
428
+            return data_;
429
+         }
430
+
431
+      private:
432
+
433
+         std::string data_;
434
+      };
435
+
436
+      static const std::string reserved_words[] =
437
+                                  {
438
+                                    "break",  "case",  "continue",  "default",  "false",  "for",
439
+                                    "if", "else", "ilike",  "in", "like", "and",  "nand", "nor",
440
+                                    "not",  "null",  "or",   "repeat", "return",  "shl",  "shr",
441
+                                    "swap", "switch", "true",  "until", "var",  "while", "xnor",
442
+                                    "xor", "&", "|"
443
+                                  };
444
+
445
+      static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
446
+
447
+      static const std::string reserved_symbols[] =
448
+                                  {
449
+                                    "abs",  "acos",  "acosh",  "and",  "asin",  "asinh", "atan",
450
+                                    "atanh", "atan2", "avg",  "break", "case", "ceil",  "clamp",
451
+                                    "continue",   "cos",   "cosh",   "cot",   "csc",  "default",
452
+                                    "deg2grad",  "deg2rad",   "equal",  "erf",   "erfc",  "exp",
453
+                                    "expm1",  "false",   "floor",  "for",   "frac",  "grad2deg",
454
+                                    "hypot", "iclamp", "if",  "else", "ilike", "in",  "inrange",
455
+                                    "like",  "log",  "log10", "log2",  "logn",  "log1p", "mand",
456
+                                    "max", "min",  "mod", "mor",  "mul", "ncdf",  "nand", "nor",
457
+                                    "not",   "not_equal",   "null",   "or",   "pow",  "rad2deg",
458
+                                    "repeat", "return", "root", "round", "roundn", "sec", "sgn",
459
+                                    "shl", "shr", "sin", "sinc", "sinh", "sqrt",  "sum", "swap",
460
+                                    "switch", "tan",  "tanh", "true",  "trunc", "until",  "var",
461
+                                    "while", "xnor", "xor", "&", "|"
462
+                                  };
463
+
464
+      static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
465
+
466
+      static const std::string base_function_list[] =
467
+                                  {
468
+                                    "abs", "acos",  "acosh", "asin",  "asinh", "atan",  "atanh",
469
+                                    "atan2",  "avg",  "ceil",  "clamp",  "cos",  "cosh",  "cot",
470
+                                    "csc",  "equal",  "erf",  "erfc",  "exp",  "expm1", "floor",
471
+                                    "frac", "hypot", "iclamp",  "like", "log", "log10",  "log2",
472
+                                    "logn", "log1p", "mand", "max", "min", "mod", "mor",  "mul",
473
+                                    "ncdf",  "pow",  "root",  "round",  "roundn",  "sec", "sgn",
474
+                                    "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
475
+                                    "trunc",  "not_equal",  "inrange",  "deg2grad",   "deg2rad",
476
+                                    "rad2deg", "grad2deg"
477
+                                  };
478
+
479
+      static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
480
+
481
+      static const std::string logic_ops_list[] =
482
+                                  {
483
+                                    "and", "nand", "nor", "not", "or",  "xnor", "xor", "&", "|"
484
+                                  };
485
+
486
+      static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
487
+
488
+      static const std::string cntrl_struct_list[] =
489
+                                  {
490
+                                     "if", "switch", "for", "while", "repeat", "return"
491
+                                  };
492
+
493
+      static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
494
+
495
+      static const std::string arithmetic_ops_list[] =
496
+                                  {
497
+                                    "+", "-", "*", "/", "%", "^"
498
+                                  };
499
+
500
+      static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
501
+
502
+      static const std::string assignment_ops_list[] =
503
+                                  {
504
+                                    ":=", "+=", "-=",
505
+                                    "*=", "/=", "%="
506
+                                  };
507
+
508
+      static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
509
+
510
+      static const std::string inequality_ops_list[] =
511
+                                  {
512
+                                     "<",  "<=", "==",
513
+                                     "=",  "!=", "<>",
514
+                                    ">=",  ">"
515
+                                  };
516
+
517
+      static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string);
518
+
519
+      inline bool is_reserved_word(const std::string& symbol)
520
+      {
521
+         for (std::size_t i = 0; i < reserved_words_size; ++i)
522
+         {
523
+            if (imatch(symbol, reserved_words[i]))
524
+            {
525
+               return true;
526
+            }
527
+         }
528
+
529
+         return false;
530
+      }
531
+
532
+      inline bool is_reserved_symbol(const std::string& symbol)
533
+      {
534
+         for (std::size_t i = 0; i < reserved_symbols_size; ++i)
535
+         {
536
+            if (imatch(symbol, reserved_symbols[i]))
537
+            {
538
+               return true;
539
+            }
540
+         }
541
+
542
+         return false;
543
+      }
544
+
545
+      inline bool is_base_function(const std::string& function_name)
546
+      {
547
+         for (std::size_t i = 0; i < base_function_list_size; ++i)
548
+         {
549
+            if (imatch(function_name, base_function_list[i]))
550
+            {
551
+               return true;
552
+            }
553
+         }
554
+
555
+         return false;
556
+      }
557
+
558
+      inline bool is_control_struct(const std::string& cntrl_strct)
559
+      {
560
+         for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
561
+         {
562
+            if (imatch(cntrl_strct, cntrl_struct_list[i]))
563
+            {
564
+               return true;
565
+            }
566
+         }
567
+
568
+         return false;
569
+      }
570
+
571
+      inline bool is_logic_opr(const std::string& lgc_opr)
572
+      {
573
+         for (std::size_t i = 0; i < logic_ops_list_size; ++i)
574
+         {
575
+            if (imatch(lgc_opr, logic_ops_list[i]))
576
+            {
577
+               return true;
578
+            }
579
+         }
580
+
581
+         return false;
582
+      }
583
+
584
+      struct cs_match
585
+      {
586
+         static inline bool cmp(const char_t c0, const char_t c1)
587
+         {
588
+            return (c0 == c1);
589
+         }
590
+      };
591
+
592
+      struct cis_match
593
+      {
594
+         static inline bool cmp(const char_t c0, const char_t c1)
595
+         {
596
+            return (std::tolower(c0) == std::tolower(c1));
597
+         }
598
+      };
599
+
600
+      template <typename Iterator, typename Compare>
601
+      inline bool match_impl(const Iterator pattern_begin,
602
+                             const Iterator pattern_end  ,
603
+                             const Iterator data_begin   ,
604
+                             const Iterator data_end     ,
605
+                             const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
606
+                             const typename std::iterator_traits<Iterator>::value_type& exactly_one )
607
+      {
608
+         const Iterator null_itr(0);
609
+
610
+         Iterator p_itr  = pattern_begin;
611
+         Iterator d_itr  = data_begin;
612
+         Iterator np_itr = null_itr;
613
+         Iterator nd_itr = null_itr;
614
+
615
+         for ( ; ; )
616
+         {
617
+            const bool pvalid = p_itr != pattern_end;
618
+            const bool dvalid = d_itr != data_end;
619
+
620
+            if (!pvalid && !dvalid)
621
+               break;
622
+
623
+            if (pvalid)
624
+            {
625
+               const typename std::iterator_traits<Iterator>::value_type c = *(p_itr);
626
+
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))))
635
+               {
636
+                  ++p_itr;
637
+                  ++d_itr;
638
+                  continue;
639
+               }
640
+            }
641
+
642
+            if ((null_itr != nd_itr) && (nd_itr <= data_end))
643
+            {
644
+               p_itr = np_itr;
645
+               d_itr = nd_itr;
646
+               continue;
647
+            }
648
+
649
+            return false;
650
+         }
651
+
652
+         return true;
653
+      }
654
+
655
+      inline bool wc_match(const std::string& wild_card,
656
+                           const std::string& str)
657
+      {
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
+      }
665
+
666
+      inline bool wc_imatch(const std::string& wild_card,
667
+                            const std::string& str)
668
+      {
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
+      }
676
+
677
+      inline bool sequence_match(const std::string& pattern,
678
+                                 const std::string& str,
679
+                                 std::size_t&       diff_index,
680
+                                 char_t&            diff_value)
681
+      {
682
+         if (str.empty())
683
+         {
684
+            return ("Z" == pattern);
685
+         }
686
+         else if ('*' == pattern[0])
687
+            return false;
688
+
689
+         typedef std::string::const_iterator itr_t;
690
+
691
+         itr_t p_itr = pattern.begin();
692
+         itr_t s_itr = str    .begin();
693
+
694
+         const itr_t p_end = pattern.end();
695
+         const itr_t s_end = str    .end();
696
+
697
+         while ((s_end != s_itr) && (p_end != p_itr))
698
+         {
699
+            if ('*' == (*p_itr))
700
+            {
701
+               const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1)));
702
+
703
+               if ('*' == target)
704
+               {
705
+                  diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
706
+                  diff_value = static_cast<char_t>(std::toupper(*p_itr));
707
+
708
+                  return false;
709
+               }
710
+               else
711
+                  ++p_itr;
712
+
713
+               while (s_itr != s_end)
714
+               {
715
+                  if (target != std::toupper(*s_itr))
716
+                     break;
717
+                  else
718
+                     ++s_itr;
719
+               }
720
+
721
+               continue;
722
+            }
723
+            else if (
724
+                      ('?' != *p_itr) &&
725
+                      std::toupper(*p_itr) != std::toupper(*s_itr)
726
+                    )
727
+            {
728
+               diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
729
+               diff_value = static_cast<char_t>(std::toupper(*p_itr));
730
+
731
+               return false;
732
+            }
733
+
734
+            ++p_itr;
735
+            ++s_itr;
736
+         }
737
+
738
+         return (
739
+                  (s_end == s_itr) &&
740
+                  (
741
+                    (p_end ==  p_itr) ||
742
+                    ('*'   == *p_itr)
743
+                  )
744
+                );
745
+      }
746
+
747
+      static const double pow10[] = {
748
+                                      1.0,
749
+                                      1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
750
+                                      1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
751
+                                      1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
752
+                                      1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
753
+                                    };
754
+
755
+      static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
756
+
757
+      namespace numeric
758
+      {
759
+         namespace constant
760
+         {
761
+            static const double e       =  2.71828182845904523536028747135266249775724709369996;
762
+            static const double pi      =  3.14159265358979323846264338327950288419716939937510;
763
+            static const double pi_2    =  1.57079632679489661923132169163975144209858469968755;
764
+            static const double pi_4    =  0.78539816339744830961566084581987572104929234984378;
765
+            static const double pi_180  =  0.01745329251994329576923690768488612713442871888542;
766
+            static const double _1_pi   =  0.31830988618379067153776752674502872406891929148091;
767
+            static const double _2_pi   =  0.63661977236758134307553505349005744813783858296183;
768
+            static const double _180_pi = 57.29577951308232087679815481410517033240547246656443;
769
+            static const double log2    =  0.69314718055994530941723212145817656807550013436026;
770
+            static const double sqrt2   =  1.41421356237309504880168872420969807856967187537695;
771
+         }
772
+
773
+         namespace details
774
+         {
775
+            struct unknown_type_tag { unknown_type_tag() {} };
776
+            struct real_type_tag    { real_type_tag   () {} };
777
+            struct complex_type_tag { complex_type_tag() {} };
778
+            struct int_type_tag     { int_type_tag    () {} };
779
+
780
+            template <typename T>
781
+            struct number_type
782
+            {
783
+               typedef unknown_type_tag type;
784
+               number_type() {}
785
+            };
786
+
787
+            #define exprtk_register_real_type_tag(T)             \
788
+            template <> struct number_type<T>                    \
789
+            { typedef real_type_tag type; number_type() {} };    \
790
+
791
+            #define exprtk_register_complex_type_tag(T)          \
792
+            template <> struct number_type<std::complex<T> >     \
793
+            { typedef complex_type_tag type; number_type() {} }; \
794
+
795
+            #define exprtk_register_int_type_tag(T)              \
796
+            template <> struct number_type<T>                    \
797
+            { typedef int_type_tag type; number_type() {} };     \
798
+
799
+            exprtk_register_real_type_tag(double     )
800
+            exprtk_register_real_type_tag(long double)
801
+            exprtk_register_real_type_tag(float      )
802
+
803
+            exprtk_register_complex_type_tag(double     )
804
+            exprtk_register_complex_type_tag(long double)
805
+            exprtk_register_complex_type_tag(float      )
806
+
807
+            exprtk_register_int_type_tag(short         )
808
+            exprtk_register_int_type_tag(int           )
809
+            exprtk_register_int_type_tag(_int64_t      )
810
+            exprtk_register_int_type_tag(unsigned short)
811
+            exprtk_register_int_type_tag(unsigned int  )
812
+            exprtk_register_int_type_tag(_uint64_t     )
813
+
814
+            #undef exprtk_register_real_type_tag
815
+            #undef exprtk_register_int_type_tag
816
+
817
+            template <typename T>
818
+            struct epsilon_type {};
819
+
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
+            };                                                     \
829
+
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
835
+
836
+            template <typename T>
837
+            inline bool is_nan_impl(const T v, real_type_tag)
838
+            {
839
+               return std::not_equal_to<T>()(v,v);
840
+            }
841
+
842
+            template <typename T>
843
+            inline int to_int32_impl(const T v, real_type_tag)
844
+            {
845
+               return static_cast<int>(v);
846
+            }
847
+
848
+            template <typename T>
849
+            inline _int64_t to_int64_impl(const T v, real_type_tag)
850
+            {
851
+               return static_cast<_int64_t>(v);
852
+            }
853
+
854
+            template <typename T>
855
+            inline bool is_true_impl(const T v)
856
+            {
857
+               return std::not_equal_to<T>()(T(0),v);
858
+            }
859
+
860
+            template <typename T>
861
+            inline bool is_false_impl(const T v)
862
+            {
863
+               return std::equal_to<T>()(T(0),v);
864
+            }
865
+
866
+            template <typename T>
867
+            inline T abs_impl(const T v, real_type_tag)
868
+            {
869
+               return ((v < T(0)) ? -v : v);
870
+            }
871
+
872
+            template <typename T>
873
+            inline T min_impl(const T v0, const T v1, real_type_tag)
874
+            {
875
+               return std::min<T>(v0,v1);
876
+            }
877
+
878
+            template <typename T>
879
+            inline T max_impl(const T v0, const T v1, real_type_tag)
880
+            {
881
+               return std::max<T>(v0,v1);
882
+            }
883
+
884
+            template <typename T>
885
+            inline T equal_impl(const T v0, const T v1, real_type_tag)
886
+            {
887
+               const T epsilon = epsilon_type<T>::value();
888
+               return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
889
+            }
890
+
891
+            inline float equal_impl(const float v0, const float v1, real_type_tag)
892
+            {
893
+               const float epsilon = epsilon_type<float>::value();
894
+               return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
895
+            }
896
+
897
+            template <typename T>
898
+            inline T equal_impl(const T v0, const T v1, int_type_tag)
899
+            {
900
+               return (v0 == v1) ? 1 : 0;
901
+            }
902
+
903
+            template <typename T>
904
+            inline T expm1_impl(const T v, real_type_tag)
905
+            {
906
+               // return std::expm1<T>(v);
907
+               if (abs_impl(v,real_type_tag()) < T(0.00001))
908
+                  return v + (T(0.5) * v * v);
909
+               else
910
+                  return std::exp(v) - T(1);
911
+            }
912
+
913
+            template <typename T>
914
+            inline T expm1_impl(const T v, int_type_tag)
915
+            {
916
+               return T(std::exp<double>(v)) - T(1);
917
+            }
918
+
919
+            template <typename T>
920
+            inline T nequal_impl(const T v0, const T v1, real_type_tag)
921
+            {
922
+               typedef real_type_tag rtg;
923
+               const T epsilon = epsilon_type<T>::value();
924
+               return (abs_impl(v0 - v1,rtg()) > (std::max(T(1),std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? T(1) : T(0);
925
+            }
926
+
927
+            inline float nequal_impl(const float v0, const float v1, real_type_tag)
928
+            {
929
+               typedef real_type_tag rtg;
930
+               const float epsilon = epsilon_type<float>::value();
931
+               return (abs_impl(v0 - v1,rtg()) > (std::max(1.0f,std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? 1.0f : 0.0f;
932
+            }
933
+
934
+            template <typename T>
935
+            inline T nequal_impl(const T v0, const T v1, int_type_tag)
936
+            {
937
+               return (v0 != v1) ? 1 : 0;
938
+            }
939
+
940
+            template <typename T>
941
+            inline T modulus_impl(const T v0, const T v1, real_type_tag)
942
+            {
943
+               return std::fmod(v0,v1);
944
+            }
945
+
946
+            template <typename T>
947
+            inline T modulus_impl(const T v0, const T v1, int_type_tag)
948
+            {
949
+               return v0 % v1;
950
+            }
951
+
952
+            template <typename T>
953
+            inline T pow_impl(const T v0, const T v1, real_type_tag)
954
+            {
955
+               return std::pow(v0,v1);
956
+            }
957
+
958
+            template <typename T>
959
+            inline T pow_impl(const T v0, const T v1, int_type_tag)
960
+            {
961
+               return std::pow(static_cast<double>(v0),static_cast<double>(v1));
962
+            }
963
+
964
+            template <typename T>
965
+            inline T logn_impl(const T v0, const T v1, real_type_tag)
966
+            {
967
+               return std::log(v0) / std::log(v1);
968
+            }
969
+
970
+            template <typename T>
971
+            inline T logn_impl(const T v0, const T v1, int_type_tag)
972
+            {
973
+               return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
974
+            }
975
+
976
+            template <typename T>
977
+            inline T log1p_impl(const T v, real_type_tag)
978
+            {
979
+               if (v > T(-1))
980
+               {
981
+                  if (abs_impl(v,real_type_tag()) > T(0.0001))
982
+                  {
983
+                     return std::log(T(1) + v);
984
+                  }
985
+                  else
986
+                     return (T(-0.5) * v + T(1)) * v;
987
+               }
988
+               else
989
+                  return std::numeric_limits<T>::quiet_NaN();
990
+            }
991
+
992
+            template <typename T>
993
+            inline T log1p_impl(const T v, int_type_tag)
994
+            {
995
+               if (v > T(-1))
996
+               {
997
+                  return std::log(T(1) + v);
998
+               }
999
+               else
1000
+                  return std::numeric_limits<T>::quiet_NaN();
1001
+            }
1002
+
1003
+            template <typename T>
1004
+            inline T root_impl(const T v0, const T v1, real_type_tag)
1005
+            {
1006
+               if (v1 < T(0))
1007
+                  return std::numeric_limits<T>::quiet_NaN();
1008
+
1009
+               const std::size_t n = static_cast<std::size_t>(v1);
1010
+
1011
+               if ((v0 < T(0)) && (0 == (n % 2)))
1012
+                  return std::numeric_limits<T>::quiet_NaN();
1013
+
1014
+               return std::pow(v0, T(1) / n);
1015
+            }
1016
+
1017
+            template <typename T>
1018
+            inline T root_impl(const T v0, const T v1, int_type_tag)
1019
+            {
1020
+               return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
1021
+            }
1022
+
1023
+            template <typename T>
1024
+            inline T round_impl(const T v, real_type_tag)
1025
+            {
1026
+               return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
1027
+            }
1028
+
1029
+            template <typename T>
1030
+            inline T roundn_impl(const T v0, const T v1, real_type_tag)
1031
+            {
1032
+               const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1))));
1033
+               const T p10 = T(pow10[index]);
1034
+
1035
+               if (v0 < T(0))
1036
+                  return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
1037
+               else
1038
+                  return T(std::floor((v0 * p10) + T(0.5)) / p10);
1039
+            }
1040
+
1041
+            template <typename T>
1042
+            inline T roundn_impl(const T v0, const T, int_type_tag)
1043
+            {
1044
+               return v0;
1045
+            }
1046
+
1047
+            template <typename T>
1048
+            inline T hypot_impl(const T v0, const T v1, real_type_tag)
1049
+            {
1050
+               return std::sqrt((v0 * v0) + (v1 * v1));
1051
+            }
1052
+
1053
+            template <typename T>
1054
+            inline T hypot_impl(const T v0, const T v1, int_type_tag)
1055
+            {
1056
+               return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
1057
+            }
1058
+
1059
+            template <typename T>
1060
+            inline T atan2_impl(const T v0, const T v1, real_type_tag)
1061
+            {
1062
+               return std::atan2(v0,v1);
1063
+            }
1064
+
1065
+            template <typename T>
1066
+            inline T atan2_impl(const T, const T, int_type_tag)
1067
+            {
1068
+               return 0;
1069
+            }
1070
+
1071
+            template <typename T>
1072
+            inline T shr_impl(const T v0, const T v1, real_type_tag)
1073
+            {
1074
+               return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
1075
+            }
1076
+
1077
+            template <typename T>
1078
+            inline T shr_impl(const T v0, const T v1, int_type_tag)
1079
+            {
1080
+               return v0 >> v1;
1081
+            }
1082
+
1083
+            template <typename T>
1084
+            inline T shl_impl(const T v0, const T v1, real_type_tag)
1085
+            {
1086
+               return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
1087
+            }
1088
+
1089
+            template <typename T>
1090
+            inline T shl_impl(const T v0, const T v1, int_type_tag)
1091
+            {
1092
+               return v0 << v1;
1093
+            }
1094
+
1095
+            template <typename T>
1096
+            inline T sgn_impl(const T v, real_type_tag)
1097
+            {
1098
+               if      (v > T(0)) return T(+1);
1099
+               else if (v < T(0)) return T(-1);
1100
+               else               return T( 0);
1101
+            }
1102
+
1103
+            template <typename T>
1104
+            inline T sgn_impl(const T v, int_type_tag)
1105
+            {
1106
+               if      (v > T(0)) return T(+1);
1107
+               else if (v < T(0)) return T(-1);
1108
+               else               return T( 0);
1109
+            }
1110
+
1111
+            template <typename T>
1112
+            inline T and_impl(const T v0, const T v1, real_type_tag)
1113
+            {
1114
+               return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
1115
+            }
1116
+
1117
+            template <typename T>
1118
+            inline T and_impl(const T v0, const T v1, int_type_tag)
1119
+            {
1120
+               return v0 && v1;
1121
+            }
1122
+
1123
+            template <typename T>
1124
+            inline T nand_impl(const T v0, const T v1, real_type_tag)
1125
+            {
1126
+               return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
1127
+            }
1128
+
1129
+            template <typename T>
1130
+            inline T nand_impl(const T v0, const T v1, int_type_tag)
1131
+            {
1132
+               return !(v0 && v1);
1133
+            }
1134
+
1135
+            template <typename T>
1136
+            inline T or_impl(const T v0, const T v1, real_type_tag)
1137
+            {
1138
+               return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
1139
+            }
1140
+
1141
+            template <typename T>
1142
+            inline T or_impl(const T v0, const T v1, int_type_tag)
1143
+            {
1144
+               return (v0 || v1);
1145
+            }
1146
+
1147
+            template <typename T>
1148
+            inline T nor_impl(const T v0, const T v1, real_type_tag)
1149
+            {
1150
+               return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
1151
+            }
1152
+
1153
+            template <typename T>
1154
+            inline T nor_impl(const T v0, const T v1, int_type_tag)
1155
+            {
1156
+               return !(v0 || v1);
1157
+            }
1158
+
1159
+            template <typename T>
1160
+            inline T xor_impl(const T v0, const T v1, real_type_tag)
1161
+            {
1162
+               return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
1163
+            }
1164
+
1165
+            template <typename T>
1166
+            inline T xor_impl(const T v0, const T v1, int_type_tag)
1167
+            {
1168
+               return v0 ^ v1;
1169
+            }
1170
+
1171
+            template <typename T>
1172
+            inline T xnor_impl(const T v0, const T v1, real_type_tag)
1173
+            {
1174
+               const bool v0_true = is_true_impl(v0);
1175
+               const bool v1_true = is_true_impl(v1);
1176
+
1177
+               if ((v0_true &&  v1_true) || (!v0_true && !v1_true))
1178
+                  return T(1);
1179
+               else
1180
+                  return T(0);
1181
+            }
1182
+
1183
+            template <typename T>
1184
+            inline T xnor_impl(const T v0, const T v1, int_type_tag)
1185
+            {
1186
+               const bool v0_true = is_true_impl(v0);
1187
+               const bool v1_true = is_true_impl(v1);
1188
+
1189
+               if ((v0_true &&  v1_true) || (!v0_true && !v1_true))
1190
+                  return T(1);
1191
+               else
1192
+                  return T(0);
1193
+            }
1194
+
1195
+            #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1196
+            #define exprtk_define_erf(TT, impl)                \
1197
+            inline TT erf_impl(const TT v) { return impl(v); } \
1198
+
1199
+            exprtk_define_erf(      float,::erff)
1200
+            exprtk_define_erf(     double,::erf )
1201
+            exprtk_define_erf(long double,::erfl)
1202
+            #undef exprtk_define_erf
1203
+            #endif
1204
+
1205
+            template <typename T>
1206
+            inline T erf_impl(const T v, real_type_tag)
1207
+            {
1208
+               #if defined(_MSC_VER) && (_MSC_VER < 1900)
1209
+               // Credits: Abramowitz & Stegun Equations 7.1.25-28
1210
+               static const T c[] = {
1211
+                                      T( 1.26551223), T(1.00002368),
1212
+                                      T( 0.37409196), T(0.09678418),
1213
+                                      T(-0.18628806), T(0.27886807),
1214
+                                      T(-1.13520398), T(1.48851587),
1215
+                                      T(-0.82215223), T(0.17087277)
1216
+                                    };
1217
+
1218
+               const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
1219
+
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]))))))))));
1226
+
1227
+               return (v >= T(0)) ? result : -result;
1228
+               #else
1229
+               return erf_impl(v);
1230
+               #endif
1231
+            }
1232
+
1233
+            template <typename T>
1234
+            inline T erf_impl(const T v, int_type_tag)
1235
+            {
1236
+               return erf_impl(static_cast<double>(v),real_type_tag());
1237
+            }
1238
+
1239
+            #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1240
+            #define exprtk_define_erfc(TT, impl)                \
1241
+            inline TT erfc_impl(const TT v) { return impl(v); } \
1242
+
1243
+            exprtk_define_erfc(float      ,::erfcf)
1244
+            exprtk_define_erfc(double     ,::erfc )
1245
+            exprtk_define_erfc(long double,::erfcl)
1246
+            #undef exprtk_define_erfc
1247
+            #endif
1248
+
1249
+            template <typename T>
1250
+            inline T erfc_impl(const T v, real_type_tag)
1251
+            {
1252
+               #if defined(_MSC_VER) && (_MSC_VER < 1900)
1253
+               return T(1) - erf_impl(v,real_type_tag());
1254
+               #else
1255
+               return erfc_impl(v);
1256
+               #endif
1257
+            }
1258
+
1259
+            template <typename T>
1260
+            inline T erfc_impl(const T v, int_type_tag)
1261
+            {
1262
+               return erfc_impl(static_cast<double>(v),real_type_tag());
1263
+            }
1264
+
1265
+            template <typename T>
1266
+            inline T ncdf_impl(const T v, real_type_tag)
1267
+            {
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()));
1271
+               return  (v < T(0)) ? (T(1) - cnd) : cnd;
1272
+            }
1273
+
1274
+            template <typename T>
1275
+            inline T ncdf_impl(const T v, int_type_tag)
1276
+            {
1277
+               return ncdf_impl(static_cast<double>(v),real_type_tag());
1278
+            }
1279
+
1280
+            template <typename T>
1281
+            inline T sinc_impl(const T v, real_type_tag)
1282
+            {
1283
+               if (std::abs(v) >= std::numeric_limits<T>::epsilon())
1284
+                   return(std::sin(v) / v);
1285
+               else
1286
+                  return T(1);
1287
+            }
1288
+
1289
+            template <typename T>
1290
+            inline T sinc_impl(const T v, int_type_tag)
1291
+            {
1292
+               return sinc_impl(static_cast<double>(v),real_type_tag());
1293
+            }
1294
+
1295
+            template <typename T> inline T  acos_impl(const T v, real_type_tag) { return std::acos (v); }
1296
+            template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
1297
+            template <typename T> inline T  asin_impl(const T v, real_type_tag) { return std::asin (v); }
1298
+            template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
1299
+            template <typename T> inline T  atan_impl(const T v, real_type_tag) { return std::atan (v); }
1300
+            template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); }
1301
+            template <typename T> inline T  ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
1302
+            template <typename T> inline T   cos_impl(const T v, real_type_tag) { return std::cos  (v); }
1303
+            template <typename T> inline T  cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
1304
+            template <typename T> inline T   exp_impl(const T v, real_type_tag) { return std::exp  (v); }
1305
+            template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
1306
+            template <typename T> inline T   log_impl(const T v, real_type_tag) { return std::log  (v); }
1307
+            template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
1308
+            template <typename T> inline T  log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1309
+            template <typename T> inline T   neg_impl(const T v, real_type_tag) { return -v;            }
1310
+            template <typename T> inline T   pos_impl(const T v, real_type_tag) { return +v;            }
1311
+            template <typename T> inline T   sin_impl(const T v, real_type_tag) { return std::sin  (v); }
1312
+            template <typename T> inline T  sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
1313
+            template <typename T> inline T  sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
1314
+            template <typename T> inline T   tan_impl(const T v, real_type_tag) { return std::tan  (v); }
1315
+            template <typename T> inline T  tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
1316
+            template <typename T> inline T   cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
1317
+            template <typename T> inline T   sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
1318
+            template <typename T> inline T   csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
1319
+            template <typename T> inline T   r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
1320
+            template <typename T> inline T   d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180));  }
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)); }
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)); }
1324
+            template <typename T> inline T  frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
1325
+            template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v));    }
1326
+
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(); }
1330
+
1331
+            template <typename T> inline T   abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
1332
+            template <typename T> inline T   exp_impl(const T v, int_type_tag) { return std::exp  (v); }
1333
+            template <typename T> inline T   log_impl(const T v, int_type_tag) { return std::log  (v); }
1334
+            template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
1335
+            template <typename T> inline T  log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1336
+            template <typename T> inline T   neg_impl(const T v, int_type_tag) { return -v;            }
1337
+            template <typename T> inline T   pos_impl(const T v, int_type_tag) { return +v;            }
1338
+            template <typename T> inline T  ceil_impl(const T v, int_type_tag) { return v;             }
1339
+            template <typename T> inline T floor_impl(const T v, int_type_tag) { return v;             }
1340
+            template <typename T> inline T round_impl(const T v, int_type_tag) { return v;             }
1341
+            template <typename T> inline T  notl_impl(const T v, int_type_tag) { return !v;            }
1342
+            template <typename T> inline T  sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
1343
+            template <typename T> inline T  frac_impl(const T  , int_type_tag) { return T(0);          }
1344
+            template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v;             }
1345
+            template <typename T> inline T  acos_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1346
+            template <typename T> inline T acosh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1347
+            template <typename T> inline T  asin_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1348
+            template <typename T> inline T asinh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1349
+            template <typename T> inline T  atan_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1350
+            template <typename T> inline T atanh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1351
+            template <typename T> inline T   cos_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1352
+            template <typename T> inline T  cosh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1353
+            template <typename T> inline T   sin_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1354
+            template <typename T> inline T  sinh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1355
+            template <typename T> inline T   tan_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1356
+            template <typename T> inline T  tanh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1357
+            template <typename T> inline T   cot_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1358
+            template <typename T> inline T   sec_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1359
+            template <typename T> inline T   csc_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1360
+
1361
+            template <typename T>
1362
+            inline bool is_integer_impl(const T& v, real_type_tag)
1363
+            {
1364
+               return std::equal_to<T>()(T(0),std::fmod(v,T(1)));
1365
+            }
1366
+
1367
+            template <typename T>
1368
+            inline bool is_integer_impl(const T&, int_type_tag)
1369
+            {
1370
+               return true;
1371
+            }
1372
+         }
1373
+
1374
+         template <typename Type>
1375
+         struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
1376
+
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 }; };
1381
+
1382
+         template <typename T>
1383
+         inline int to_int32(const T v)
1384
+         {
1385
+            const typename details::number_type<T>::type num_type;
1386