{"id":13419307,"url":"https://github.com/ArashPartow/exprtk","last_synced_at":"2025-03-15T05:30:46.006Z","repository":{"id":2331583,"uuid":"3293193","full_name":"ArashPartow/exprtk","owner":"ArashPartow","description":"C++ Mathematical Expression Parsing And Evaluation Library   https://www.partow.net/programming/exprtk/index.html","archived":false,"fork":false,"pushed_at":"2024-06-07T09:58:41.000Z","size":3793,"stargazers_count":604,"open_issues_count":4,"forks_count":252,"subscribers_count":50,"default_branch":"master","last_synced_at":"2024-07-31T22:46:51.317Z","etag":null,"topics":["ast","c-plus-plus","compiler","expression-evaluator","expression-parser","exprtk","grammar","high-performance","language","lexer","math","math-expressions","mathematics","mirrored-repository","mit-license","numerical-calculations","optimization-algorithms","parser","scientific-computing","semantic-analyzer"],"latest_commit_sha":null,"homepage":"https://www.partow.net/programming/exprtk/index.html","language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ArashPartow.png","metadata":{"files":{"readme":"readme.txt","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-01-28T20:47:19.000Z","updated_at":"2024-07-31T06:52:32.000Z","dependencies_parsed_at":"2024-10-26T16:04:24.888Z","dependency_job_id":"536454d8-6589-4f31-9a68-c556acd55a07","html_url":"https://github.com/ArashPartow/exprtk","commit_stats":{"total_commits":244,"total_committers":1,"mean_commits":244.0,"dds":0.0,"last_synced_commit":"f46bffcd6966d38a09023fb37ba9335214c9b959"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArashPartow%2Fexprtk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArashPartow%2Fexprtk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArashPartow%2Fexprtk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArashPartow%2Fexprtk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ArashPartow","download_url":"https://codeload.github.com/ArashPartow/exprtk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243690113,"owners_count":20331726,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","c-plus-plus","compiler","expression-evaluator","expression-parser","exprtk","grammar","high-performance","language","lexer","math","math-expressions","mathematics","mirrored-repository","mit-license","numerical-calculations","optimization-algorithms","parser","scientific-computing","semantic-analyzer"],"created_at":"2024-07-30T22:01:14.150Z","updated_at":"2025-03-15T05:30:45.989Z","avatar_url":"https://github.com/ArashPartow.png","language":"C++","funding_links":[],"categories":["TODO scan for Android support in followings"],"sub_categories":[],"readme":"C++ Mathematical Expression Toolkit Library Documentation\n\n  Section 00 - Introduction\n  Section 01 - Capabilities\n  Section 02 - Example Expressions\n  Section 03 - Copyright Notice\n  Section 04 - Downloads \u0026 Updates\n  Section 05 - Installation\n  Section 06 - Compilation\n  Section 07 - Compiler Compatibility\n  Section 08 - Built-In Operations \u0026 Functions\n  Section 09 - Fundamental Types\n  Section 10 - Components\n  Section 11 - Compilation Options\n  Section 12 - Expression Structures\n  Section 13 - Variable, Vector \u0026 String Definition\n  Section 14 - Vector Processing\n  Section 15 - User Defined Functions\n  Section 16 - Expression Dependents\n  Section 17 - Hierarchies Of Symbol Tables\n  Section 18 - Unknown Unknowns\n  Section 19 - Enabling \u0026 Disabling Features\n  Section 20 - Expression Return Values\n  Section 21 - Compilation Errors\n  Section 22 - Runtime Library Packages\n  Section 23 - Helpers \u0026 Utils\n  Section 24 - Runtime Checks\n  Section 25 - Benchmarking\n  Section 26 - Exprtk Notes\n  Section 27 - Simple Exprtk Example\n  Section 28 - Build Options\n  Section 29 - Files\n  Section 30 - Language Structure\n\n\n[SECTION 00 - INTRODUCTION]\nThe C++ Mathematical Expression  Toolkit Library (ExprTk) is  a simple\nto  use,   easy  to   integrate  and   extremely  efficient   run-time\nmathematical  expression parsing  and evaluation  engine. The  parsing\nengine  supports numerous  forms  of  functional and  logic processing\nsemantics and is easily extensible.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 01 - CAPABILITIES]\nThe  ExprTk expression  evaluator supports  the following  fundamental\narithmetic operations, functions and processes:\n\n (00) Types:           Scalar, Vector, String\n\n (01) Basic operators: +, -, *, /, %, ^\n\n (02) Assignment:      :=, +=, -=, *=, /=, %=\n\n (03) Equalities \u0026\n      Inequalities:    =, ==, \u003c\u003e, !=, \u003c, \u003c=, \u003e, \u003e=\n\n (04) Logic operators: and, mand, mor, nand, nor, not, or, shl, shr,\n                       xnor, xor, true, false\n\n (05) Functions:       abs, avg, ceil, clamp, equal, erf, erfc,  exp,\n                       expm1, floor, frac,  log, log10, log1p,  log2,\n                       logn, max,  min, mul,  ncdf,  not_equal, root,\n                       round, roundn, sgn, sqrt, sum, swap, trunc\n\n (06) Trigonometry:    acos, acosh, asin, asinh, atan, atanh,  atan2,\n                       cos,  cosh, cot,  csc, sec,  sin, sinc,  sinh,\n                       tan, tanh, hypot, rad2deg, deg2grad,  deg2rad,\n                       grad2deg\n\n (07) Control\n      structures:      if-then-else, ternary conditional, switch-case,\n                       return-statement\n\n (08) Loop statements: while, for, repeat-until, break, continue\n\n (09) String\n      processing:      in, like, ilike, concatenation\n\n (10) Optimisations:   constant-folding, simple strength reduction and\n                       dead code elimination\n\n (11) Runtime checks:  vector bounds, string bounds, loop iteration,\n                       execution-time bounds and compilation process\n                       checkpointing, assert statements\n\n (12) Calculus:        numerical integration and differentiation\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 02 - EXAMPLE EXPRESSIONS]\nThe following is  a short listing  of infix format  based mathematical\nexpressions that can be parsed and evaluated using the ExprTk library.\n\n  (01) sqrt(1 - (3 / x^2))\n  (02) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1)\n  (03) sin(2.34e-3 * x)\n  (04) if(((x[2] + 2) == 3) and ((y + 5) \u003c= 9),1 + w, 2 / z)\n  (05) inrange(-2,m,+2) == if(({-2 \u003c= m} and [m \u003c= +2]),1,0)\n  (06) ({1/1}*[1/2]+(1/3))-{1/4}^[1/5]+(1/6)-({1/7}+[1/8]*(1/9))\n  (07) a * exp(2.2 / 3.3 * t) + c\n  (08) z := x + sin(2.567 * pi / y)\n  (09) u := 2.123 * {pi * z} / (w := x + cos(y / pi))\n  (10) 2x + 3y + 4z + 5w == 2 * x + 3 * y + 4 * z + 5 * w\n  (11) 3(x + y) / 2.9 + 1.234e+12 == 3 * (x + y) / 2.9 + 1.234e+12\n  (12) (x + y)3.3 + 1 / 4.5 == [x + y] * 3.3 + 1 / 4.5\n  (13) (x + y[i])z + 1.1 / 2.7 == (x + y[i]) * z + 1.1 / 2.7\n  (14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1)\n  (15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1\n  (16) (avg(x,y) \u003c= x + y ? x - y : x * y) + 2.345 * pi / x\n  (17) while (x \u003c= 100) { x -= 1; }\n  (18) x \u003c= 'abc123' and (y in 'AString') or ('1x2y3z' != z)\n  (19) ((x + 'abc') like '*123*') or ('a123b' ilike y)\n  (20) sgn(+1.2^3.4z / -5.6y) \u003c= {-7.8^9 / -10.11x }\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 03 - COPYRIGHT NOTICE]\nFree  use  of  the  C++  Mathematical  Expression  Toolkit  Library is\npermitted under the guidelines and in accordance with the most current\nversion of the MIT License.\n\n   (1) https://www.opensource.org/licenses/MIT\n   (2) SPDX-License-Identifier: MIT\n   (3) SPDX-FileCopyrightText : Copyright (C) 1999-2024 Arash Partow\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 04 - DOWNLOADS \u0026 UPDATES]\nThe most  recent version  of the C++ Mathematical  Expression  Toolkit\nLibrary including all updates and tests can be found at the  following\nlocations:\n\n  (1) Download: https://www.partow.net/programming/exprtk/index.html\n  (2) Mirror Repository: https://github.com/ArashPartow/exprtk\n                         https://github.com/ArashPartow/exprtk-extras\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 05 - INSTALLATION]\nThe header  file exprtk.hpp  should be  placed in a project or  system\ninclude path (e.g: /usr/include/).\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 06 - COMPILATION]\nThe  ExprTk  package  contains  the ExprTk  header,  a  set  of simple\nexamples and a benchmark and unit test  suite. The following is a list\nof commands to build the various components:\n\n  (a) For a complete build: make clean all\n  (b) For a PGO build: make clean pgo\n  (c) To strip executables: make strip_bin\n  (d) Execute valgrind check: make valgrind_check\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 07 - COMPILER COMPATIBILITY]\nExprTk has been built error and warning free using the following set\nof C++ compilers:\n\n  (*) GNU Compiler Collection (3.5+)\n  (*) Clang/LLVM (1.1+)\n  (*) Microsoft Visual Studio C++ Compiler (7.1+)\n  (*) Intel C++ Compiler (8.x+)\n  (*) AMD Optimizing C++ Compiler (1.2+)\n  (*) Nvidia C++ Compiler (19.x+)\n  (*) PGI C++ (10.x+)\n  (*) Circle C++ (circa: b81c37d2bb227c)\n  (*) IBM XL C/C++ (9.x+)\n  (*) C++ Builder (XE4+)\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 08 - BUILT-IN OPERATIONS \u0026 FUNCTIONS]\n\n(0) Arithmetic \u0026 Assignment Operators\n+----------+---------------------------------------------------------+\n| OPERATOR | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n|  +       | Addition between x and y.  (eg: x + y)                  |\n+----------+---------------------------------------------------------+\n|  -       | Subtraction between x and y.  (eg: x - y)               |\n+----------+---------------------------------------------------------+\n|  *       | Multiplication between x and y.  (eg: x * y)            |\n+----------+---------------------------------------------------------+\n|  /       | Division between x and y.  (eg: x / y)                  |\n+----------+---------------------------------------------------------+\n|  %       | Modulus of x with respect to y.  (eg: x % y)            |\n+----------+---------------------------------------------------------+\n|  ^       | x to the power of y.  (eg: x ^ y)                       |\n+----------+---------------------------------------------------------+\n|  :=      | Assign the value of x to y. Where y is either a variable|\n|          | or vector type.  (eg: y := x)                           |\n+----------+---------------------------------------------------------+\n|  +=      | Increment x by the value of the expression on the right |\n|          | hand side. Where x is either a variable or vector type. |\n|          | (eg: x += abs(y - z))                                   |\n+----------+---------------------------------------------------------+\n|  -=      | Decrement x by the value of the expression on the right |\n|          | hand side. Where x is either a variable or vector type. |\n|          | (eg: x[i] -= abs(y + z))                                |\n+----------+---------------------------------------------------------+\n|  *=      | Assign the multiplication of x by the value of the      |\n|          | expression on the righthand side to x. Where x is either|\n|          | a variable or vector type.                              |\n|          | (eg: x *= abs(y / z))                                   |\n+----------+---------------------------------------------------------+\n|  /=      | Assign the division of x by the value of the expression |\n|          | on the right-hand side to x. Where x is either a        |\n|          | variable or vector type.  (eg: x[i + j] /= abs(y * z))  |\n+----------+---------------------------------------------------------+\n|  %=      | Assign x modulo the value of the expression on the right|\n|          | hand side to x. Where x is either a variable or vector  |\n|          | type.  (eg: x[2] %= y ^ 2)                              |\n+----------+---------------------------------------------------------+\n\n(1) Equalities \u0026 Inequalities\n+----------+---------------------------------------------------------+\n| OPERATOR | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n| == or =  | True only if x is strictly equal to y. (eg: x == y)     |\n+----------+---------------------------------------------------------+\n| \u003c\u003e or != | True only if x does not equal y. (eg: x \u003c\u003e y or x != y) |\n+----------+---------------------------------------------------------+\n|  \u003c       | True only if x is less than y. (eg: x \u003c y)              |\n+----------+---------------------------------------------------------+\n|  \u003c=      | True only if x is less than or equal to y. (eg: x \u003c= y) |\n+----------+---------------------------------------------------------+\n|  \u003e       | True only if x is greater than y. (eg: x \u003e y)           |\n+----------+---------------------------------------------------------+\n|  \u003e=      | True only if x greater than or equal to y. (eg: x \u003e= y) |\n+----------+---------------------------------------------------------+\n\n(2) Boolean Operations\n+----------+---------------------------------------------------------+\n| OPERATOR | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n| true     | True state or any value other than zero (typically 1).  |\n+----------+---------------------------------------------------------+\n| false    | False state, value of exactly zero.                     |\n+----------+---------------------------------------------------------+\n| and      | Logical AND, True only if x and y are both true.        |\n|          | (eg: x and y)                                           |\n+----------+---------------------------------------------------------+\n| mand     | Multi-input logical AND, True only if all inputs are    |\n|          | true. Left to right short-circuiting of expressions.    |\n|          | (eg: mand(x \u003e y, z \u003c w, u or v, w and x))               |\n+----------+---------------------------------------------------------+\n| mor      | Multi-input logical OR, True if at least one of the     |\n|          | inputs are true. Left to right short-circuiting of      |\n|          | expressions.  (eg: mor(x \u003e y, z \u003c w, u or v, w and x))  |\n+----------+---------------------------------------------------------+\n| nand     | Logical NAND, True only if either x or y is false.      |\n|          | (eg: x nand y)                                          |\n+----------+---------------------------------------------------------+\n| nor      | Logical NOR, True only if the result of x or y is false |\n|          | (eg: x nor y)                                           |\n+----------+---------------------------------------------------------+\n| not      | Logical NOT, Negate the logical sense of the input.     |\n|          | (eg: not(x and y) == x nand y)                          |\n+----------+---------------------------------------------------------+\n| or       | Logical OR, True if either x or y is true. (eg: x or y) |\n+----------+---------------------------------------------------------+\n| xor      | Logical XOR, True only if the logical states of x and y |\n|          | differ.  (eg: x xor y)                                  |\n+----------+---------------------------------------------------------+\n| xnor     | Logical XNOR, True iff the biconditional of x and y is  |\n|          | satisfied.  (eg: x xnor y)                              |\n+----------+---------------------------------------------------------+\n| \u0026        | Similar to AND but with left to right expression short  |\n|          | circuiting optimisation.  (eg: (x \u0026 y) == (y and x))    |\n+----------+---------------------------------------------------------+\n| |        | Similar to OR but with left to right expression short   |\n|          | circuiting optimisation.  (eg: (x | y) == (y or x))     |\n+----------+---------------------------------------------------------+\n\n(3) General Purpose Functions\n+----------+---------------------------------------------------------+\n| FUNCTION | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n| abs      | Absolute value of x.  (eg: abs(x))                      |\n+----------+---------------------------------------------------------+\n| avg      | Average of all the inputs.                              |\n|          | (eg: avg(x,y,z,w,u,v) == (x + y + z + w + u + v) / 6)   |\n+----------+---------------------------------------------------------+\n| ceil     | Smallest integer that is greater than or equal to x.    |\n+----------+---------------------------------------------------------+\n| clamp    | Clamp x in range between r0 and r1, where r0 \u003c r1.      |\n|          | (eg: clamp(r0,x,r1))                                    |\n+----------+---------------------------------------------------------+\n| equal    | Equality test between x and y using normalised epsilon  |\n+----------+---------------------------------------------------------+\n| erf      | Error function of x.  (eg: erf(x))                      |\n+----------+---------------------------------------------------------+\n| erfc     | Complimentary error function of x.  (eg: erfc(x))       |\n+----------+---------------------------------------------------------+\n| exp      | e to the power of x.  (eg: exp(x))                      |\n+----------+---------------------------------------------------------+\n| expm1    | e to the power of x minus 1, where x is very small.     |\n|          | (eg: expm1(x))                                          |\n+----------+---------------------------------------------------------+\n| floor    | Largest integer that is less than or equal to x.        |\n|          | (eg: floor(x))                                          |\n+----------+---------------------------------------------------------+\n| frac     | Fractional portion of x.  (eg: frac(x))                 |\n+----------+---------------------------------------------------------+\n| hypot    | Hypotenuse of x and y (eg: hypot(x,y) = sqrt(x*x + y*y))|\n+----------+---------------------------------------------------------+\n| iclamp   | Inverse-clamp x outside of the range r0 and r1. Where   |\n|          | r0 \u003c r1. If x is within the range it will snap to the   |\n|          | closest bound. (eg: iclamp(r0,x,r1)                     |\n+----------+---------------------------------------------------------+\n| inrange  | In-range returns 'true' when x is within the range r0   |\n|          | and r1. Where r0 \u003c r1.  (eg: inrange(r0,x,r1)           |\n+----------+---------------------------------------------------------+\n| log      | Natural logarithm of x.  (eg: log(x))                   |\n+----------+---------------------------------------------------------+\n| log10    | Base 10 logarithm of x.  (eg: log10(x))                 |\n+----------+---------------------------------------------------------+\n| log1p    | Natural logarithm of 1 + x, where x is very small.      |\n|          | (eg: log1p(x))                                          |\n+----------+---------------------------------------------------------+\n| log2     | Base 2 logarithm of x.  (eg: log2(x))                   |\n+----------+---------------------------------------------------------+\n| logn     | Base N logarithm of x. where n is a positive integer.   |\n|          | (eg: logn(x,8))                                         |\n+----------+---------------------------------------------------------+\n| max      | Largest value of all the inputs. (eg: max(x,y,z,w,u,v)) |\n+----------+---------------------------------------------------------+\n| min      | Smallest value of all the inputs. (eg: min(x,y,z,w,u))  |\n+----------+---------------------------------------------------------+\n| mul      | Product of all the inputs.                              |\n|          | (eg: mul(x,y,z,w,u,v,t) == (x * y * z * w * u * v * t)) |\n+----------+---------------------------------------------------------+\n| ncdf     | Normal cumulative distribution function.  (eg: ncdf(x)) |\n+----------+---------------------------------------------------------+\n| not_equal| Not-equal test between x and y using normalised epsilon |\n+----------+---------------------------------------------------------+\n| pow      | x to the power of y.  (eg: pow(x,y) == x ^ y)           |\n+----------+---------------------------------------------------------+\n| root     | Nth-Root of x. where n is a positive integer.           |\n|          | (eg: root(x,3) == x^(1/3))                              |\n+----------+---------------------------------------------------------+\n| round    | Round x to the nearest integer.  (eg: round(x))         |\n+----------+---------------------------------------------------------+\n| roundn   | Round x to n decimal places  (eg: roundn(x,3))          |\n|          | where n \u003e 0 and is an integer.                          |\n|          | (eg: roundn(1.2345678,4) == 1.2346)                     |\n+----------+---------------------------------------------------------+\n| sgn      | Sign of x, -1 where x \u003c 0, +1 where x \u003e 0, else zero.   |\n|          | (eg: sgn(x))                                            |\n+----------+---------------------------------------------------------+\n| sqrt     | Square root of x, where x \u003e= 0.  (eg: sqrt(x))          |\n+----------+---------------------------------------------------------+\n| sum      | Sum of all the inputs.                                  |\n|          | (eg: sum(x,y,z,w,u,v,t) == (x + y + z + w + u + v + t)) |\n+----------+---------------------------------------------------------+\n| swap     | Swap the values of the variables x and y and return the |\n| \u003c=\u003e      | current value of y.  (eg: swap(x,y) or x \u003c=\u003e y)         |\n+----------+---------------------------------------------------------+\n| trunc    | Integer portion of x.  (eg: trunc(x))                   |\n+----------+---------------------------------------------------------+\n\n(4) Trigonometry Functions\n+----------+---------------------------------------------------------+\n| FUNCTION | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n| acos     | Arc cosine of x expressed in radians. Interval [-1,+1]  |\n|          | (eg: acos(x))                                           |\n+----------+---------------------------------------------------------+\n| acosh    | Inverse hyperbolic cosine of x expressed in radians.    |\n|          | (eg: acosh(x))                                          |\n+----------+---------------------------------------------------------+\n| asin     | Arc sine of x expressed in radians. Interval [-1,+1]    |\n|          | (eg: asin(x))                                           |\n+----------+---------------------------------------------------------+\n| asinh    | Inverse hyperbolic sine of x expressed in radians.      |\n|          | (eg: asinh(x))                                          |\n+----------+---------------------------------------------------------+\n| atan     | Arc tangent of x expressed in radians. Interval [-1,+1] |\n|          | (eg: atan(x))                                           |\n+----------+---------------------------------------------------------+\n| atan2    | Arc tangent of (x / y) expressed in radians. [-pi,+pi]  |\n|          | eg: atan2(x,y)                                          |\n+----------+---------------------------------------------------------+\n| atanh    | Inverse hyperbolic tangent of x expressed in radians.   |\n|          | (eg: atanh(x))                                          |\n+----------+---------------------------------------------------------+\n| cos      | Cosine of x.  (eg: cos(x))                              |\n+----------+---------------------------------------------------------+\n| cosh     | Hyperbolic cosine of x.  (eg: cosh(x))                  |\n+----------+---------------------------------------------------------+\n| cot      | Cotangent of x.  (eg: cot(x))                           |\n+----------+---------------------------------------------------------+\n| csc      | Cosecant of x.  (eg: csc(x))                            |\n+----------+---------------------------------------------------------+\n| sec      | Secant of x.  (eg: sec(x))                              |\n+----------+---------------------------------------------------------+\n| sin      | Sine of x.  (eg: sin(x))                                |\n+----------+---------------------------------------------------------+\n| sinc     | Sine cardinal of x.  (eg: sinc(x))                      |\n+----------+---------------------------------------------------------+\n| sinh     | Hyperbolic sine of x.  (eg: sinh(x))                    |\n+----------+---------------------------------------------------------+\n| tan      | Tangent of x.  (eg: tan(x))                             |\n+----------+---------------------------------------------------------+\n| tanh     | Hyperbolic tangent of x.  (eg: tanh(x))                 |\n+----------+---------------------------------------------------------+\n| deg2rad  | Convert x from degrees to radians.  (eg: deg2rad(x))    |\n+----------+---------------------------------------------------------+\n| deg2grad | Convert x from degrees to gradians.  (eg: deg2grad(x))  |\n+----------+---------------------------------------------------------+\n| rad2deg  | Convert x from radians to degrees.  (eg: rad2deg(x))    |\n+----------+---------------------------------------------------------+\n| grad2deg | Convert x from gradians to degrees.  (eg: grad2deg(x))  |\n+----------+---------------------------------------------------------+\n\n(5) String Processing\n+----------+---------------------------------------------------------+\n| FUNCTION | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n|  = , ==  | All common equality/inequality operators are applicable |\n|  !=, \u003c\u003e  | to strings and are applied in a case sensitive manner.  |\n|  \u003c=, \u003e=  | In the following example x, y and z are of type string. |\n|  \u003c , \u003e   | (eg: not((x \u003c= 'AbC') and ('1x2y3z' \u003c\u003e y)) or (z == x)  |\n+----------+---------------------------------------------------------+\n| in       | True only if x is a substring of y.                     |\n|          | (eg: x in y or 'abc' in 'abcdefgh')                     |\n+----------+---------------------------------------------------------+\n| like     | True only if the string x matches the pattern y.        |\n|          | Available wildcard characters are '*' and '?' denoting  |\n|          | zero or more and zero or one matches respectively.      |\n|          | (eg: x like y or 'abcdefgh' like 'a?d*h')               |\n+----------+---------------------------------------------------------+\n| ilike    | True only if the string x matches the pattern y in a    |\n|          | case insensitive manner. Available wildcard characters  |\n|          | are '*' and '?' denoting zero or more and zero or one   |\n|          | matches respectively.                                   |\n|          | (eg: x ilike y or 'a1B2c3D4e5F6g7H' ilike 'a?d*h')      |\n+----------+---------------------------------------------------------+\n| [r0:r1]  | The closed interval[r0,r1] of the specified string.     |\n|          | eg: Given a string x with a value of 'abcdefgh' then:   |\n|          | 1. x[1:4] == 'bcde'                                     |\n|          | 2. x[ :4] == x[:8 / 2] == 'abcde'                       |\n|          | 3. x[2 + 1: ] == x[3:] =='defgh'                        |\n|          | 4. x[ : ] == x[:] == 'abcdefgh'                         |\n|          | 5. x[4/2:3+1] == x[2:4] == 'cde'                        |\n|          |                                                         |\n|          | Note: Both r0 and r1 are assumed to be integers, where  |\n|          | r0 \u003c= r1. They may also be the result of an expression, |\n|          | in the event they have fractional components truncation |\n|          | shall be performed. (eg: 1.67 --\u003e 1)                    |\n+----------+---------------------------------------------------------+\n|  :=      | Assign the value of x to y. Where y is a mutable string |\n|          | or string range and x is either a string or a string    |\n|          | range. eg:                                              |\n|          | 1. y := x                                               |\n|          | 2. y := 'abc'                                           |\n|          | 3. y := x[:i + j]                                       |\n|          | 4. y := '0123456789'[2:7]                               |\n|          | 5. y := '0123456789'[2i + 1:7]                          |\n|          | 6. y := (x := '0123456789'[2:7])                        |\n|          | 7. y[i:j] := x                                          |\n|          | 8. y[i:j] := (x + 'abcdefg'[8 / 4:5])[m:n]              |\n|          |                                                         |\n|          | Note: For options 7 and 8 the shorter of the two ranges |\n|          | will denote the number characters that are to be copied.|\n+----------+---------------------------------------------------------+\n|  +       | Concatenation of x and y. Where x and y are strings or  |\n|          | string ranges. eg                                       |\n|          | 1. x + y                                                |\n|          | 2. x + 'abc'                                            |\n|          | 3. x + y[:i + j]                                        |\n|          | 4. x[i:j] + y[2:3] + '0123456789'[2:7]                  |\n|          | 5. 'abc' + x + y                                        |\n|          | 6. 'abc' + '1234567'                                    |\n|          | 7. (x + 'a1B2c3D4' + y)[i:2j]                           |\n+----------+---------------------------------------------------------+\n|  +=      | Append to x the value of y. Where x is a mutable string |\n|          | and y is either a string or a string range. eg:         |\n|          | 1. x += y                                               |\n|          | 2. x += 'abc'                                           |\n|          | 3. x += y[:i + j] + 'abc'                               |\n|          | 4. x += '0123456789'[2:7]                               |\n+----------+---------------------------------------------------------+\n| \u003c=\u003e      | Swap the values of x and y. Where x and y are mutable   |\n|          | strings.  (eg: x \u003c=\u003e y)                                 |\n+----------+---------------------------------------------------------+\n| []       | The string size operator returns the size of the string |\n|          | being actioned.                                         |\n|          | eg:                                                     |\n|          | 1. 'abc'[] == 3                                         |\n|          | 2. var max_str_length := max(s0[], s1[], s2[], s3[])    |\n|          | 3. ('abc' + 'd')[] == 6                                 |\n|          | 4. (('abc' + 'xyz')[1:4])[] == 4                        |\n+----------+---------------------------------------------------------+\n\n(6) Control Structures\n+----------+---------------------------------------------------------+\n|STRUCTURE | DEFINITION                                              |\n+----------+---------------------------------------------------------+\n| if       | If x is true then return y else return z.               |\n|          | eg:                                                     |\n|          | 1. if (x, y, z)                                         |\n|          | 2. if ((x + 1) \u003e 2y, z + 1, w / v)                      |\n|          | 3. if (x \u003e y) z;                                        |\n|          | 4. if (x \u003c= 2*y) { z + w };                             |\n+----------+---------------------------------------------------------+\n| if-else  | The if-else/else-if statement. Subject to the condition |\n|          | branch the statement will return either the value of the|\n|          | consequent or the alternative branch.                   |\n|          | eg:                                                     |\n|          | 1. if (x \u003e y) z; else w;                                |\n|          | 2. if (x \u003e y) z; else if (w != u) v;                    |\n|          | 3. if (x \u003c y) { z; w + 1; } else u;                     |\n|          | 4. if ((x != y) and (z \u003e w))                            |\n|          |    {                                                    |\n|          |      y := sin(x) / u;                                   |\n|          |      z := w + 1;                                        |\n|          |    }                                                    |\n|          |    else if (x \u003e (z + 1))                                |\n|          |    {                                                    |\n|          |      w := abs (x - y) + z;                              |\n|          |      u := (x + 1) \u003e 2y ? 2u : 3u;                       |\n|          |    }                                                    |\n+----------+---------------------------------------------------------+\n| switch   | The first true case condition that is encountered will  |\n|          | determine the result of the switch. If none of the case |\n|          | conditions hold true, the default action is assumed as  |\n|          | the final return value. This is sometimes also known as |\n|          | a multi-way branch mechanism.                           |\n|          | eg:                                                     |\n|          | switch                                                  |\n|          | {                                                       |\n|          |    case x \u003e (y + z) : 2 * x / abs(y - z);               |\n|          |    case x \u003c 3       : sin(x + y);                       |\n|          |    default          : 1 + x;                            |\n|          | }                                                       |\n+----------+---------------------------------------------------------+\n| while    | The structure will repeatedly evaluate the internal     |\n|          | statement(s) 'while' the condition is true. The final   |\n|          | statement in the final iteration shall be used as the   |\n|          | return value of the loop.                               |\n|          | eg:                                                     |\n|          | while ((x -= 1) \u003e 0)                                    |\n|          | {                                                       |\n|          |    y := x + z;                                          |\n|          |    w := u + y;                                          |\n|          | }                                                       |\n+----------+---------------------------------------------------------+\n| repeat/  | The structure will repeatedly evaluate the internal     |\n| until    | statement(s) 'until' the condition is true. The final   |\n|          | statement in the final iteration shall be used as the   |\n|          | return value of the loop.                               |\n|          | eg:                                                     |\n|          | repeat                                                  |\n|          |    y := x + z;                                          |\n|          |    w := u + y;                                          |\n|          | until ((x += 1) \u003e 100)                                  |\n+----------+---------------------------------------------------------+\n| for      | The structure will repeatedly evaluate the internal     |\n|          | statement(s) while the condition is true. On each loop  |\n|          | iteration, an 'incrementing' expression is evaluated.   |\n|          | The conditional is mandatory whereas the initialiser    |\n|          | and incrementing expressions are optional.              |\n|          | eg:                                                     |\n|          | for (var x := 0; (x \u003c n) and (x != y); x += 1)          |\n|          | {                                                       |\n|          |    y := y + x / 2 - z;                                  |\n|          |    w := u + y;                                          |\n|          | }                                                       |\n+----------+---------------------------------------------------------+\n| break    | Break terminates the execution of the nearest enclosed  |\n| break[]  | loop, allowing for the execution to continue on external|\n|          | to the loop. The default break statement will set the   |\n|          | return value of the loop to NaN, where as the return    |\n|          | based form will set the value to that of the break      |\n|          | expression.                                             |\n|          | eg:                                                     |\n|          | while ((i += 1) \u003c 10)                                   |\n|          | {                                                       |\n|          |    if (i \u003c 5)                                           |\n|          |       j -= i + 2;                                       |\n|          |    else if (i % 2 == 0)                                 |\n|          |       break;                                            |\n|          |    else                                                 |\n|          |       break[2i + 3];                                    |\n|          | }                                                       |\n+----------+---------------------------------------------------------+\n| continue | Continue results in the remaining portion of the nearest|\n|          | enclosing loop body to be skipped.                      |\n|          | eg:                                                     |\n|          | for (var i := 0; i \u003c 10; i += 1)                        |\n|          | {                                                       |\n|          |    if (i \u003c 5)                                           |\n|          |       continue;                                         |\n|          |    j -= i + 2;                                          |\n|          | }                                                       |\n+----------+---------------------------------------------------------+\n| return   | Return immediately from within the current expression.  |\n|          | With the option of passing back a variable number of    |\n|          | values (scalar, vector or string). eg:                  |\n|          | 1. return [1];                                          |\n|          | 2. return [x, 'abx'];                                   |\n|          | 3. return [x, x + y,'abx'];                             |\n|          | 4. return [];                                           |\n|          | 5. if (x \u003c y)                                           |\n|          |     return [x, x - y, 'result-set1', 123.456];          |\n|          |    else                                                 |\n|          |     return [y, x + y, 'result-set2'];                   |\n+----------+---------------------------------------------------------+\n| ?:       | Ternary conditional statement, similar to that of the   |\n|          | above denoted if-statement.                             |\n|          | eg:                                                     |\n|          | 1. x ? y : z                                            |\n|          | 2. x + 1 \u003e 2y ? z + 1 : (w / v)                         |\n|          | 3. min(x,y) \u003e z ? (x \u003c y + 1) ? x : y : (w * v)         |\n+----------+---------------------------------------------------------+\n| ~        | Evaluate each sub-expression, then return as the result |\n|          | the value of the last sub-expression. This is sometimes |\n|          | known as multiple sequence point evaluation.            |\n|          | eg:                                                     |\n|          | ~(i := x + 1, j := y / z, k := sin(w/u)) == (sin(w/u))) |\n|          | ~{i := x + 1; j := y / z; k := sin(w/u)} == (sin(w/u))) |\n+----------+---------------------------------------------------------+\n| [*]      | Evaluate any consequent for which its case statement is |\n|          | true. The return value will be either zero or the result|\n|          | of the last consequent to have been evaluated.          |\n|          | eg:                                                     |\n|          | [*]                                                     |\n|          | {                                                       |\n|          |   case (x + 1) \u003e (y - 2)    : x := z / 2 + sin(y / pi); |\n|          |   case (x + 2) \u003c abs(y + 3) : w / 4 + min(5y,9);        |\n|          |   case (x + 3) == (y * 4)   : y := abs(z / 6) + 7y;     |\n|          | }                                                       |\n+----------+---------------------------------------------------------+\n| []       | The vector size operator returns the size of the vector |\n|          | being actioned.                                         |\n|          | eg:                                                     |\n|          | 1. v[]                                                  |\n|          | 2. max_size := max(v0[],v1[],v2[],v3[])                 |\n+----------+---------------------------------------------------------+\n\nNote01: In  the  tables above, the symbols x, y, z, w, u  and v  where\nappropriate may represent any of one the following:\n\n   1. Literal numeric/string value\n   2. A variable\n   3. A vector element\n   4. A vector\n   5. A string\n   6. An expression comprised of [1], [2] or [3] (eg: 2 + x / vec[3])\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 09 - FUNDAMENTAL TYPES]\nExprTk supports three fundamental types which can be used freely in\nexpressions. The types are as follows:\n\n   (1) Scalar\n   (2) Vector\n   (3) String\n\n\n(1) Scalar Type\nThe scalar type  is a singular  numeric value. The  underlying type is\nthat used  to specialise  the ExprTk  components (float,  double, long\ndouble, MPFR et al).\n\n\n(2) Vector Type\nThe vector type is a fixed size sequence of contiguous scalar  values.\nA  vector  can be  indexed  resulting in  a  scalar value.  Operations\nbetween a vector and scalar will result in a vector with a size  equal\nto that  of the  original vector,  whereas operations  between vectors\nwill result in a  vector of size equal  to that of the  smaller of the\ntwo. In both mentioned cases, the operations will occur element-wise.\n\n\n(3) String Type\nThe string type is a variable length sequence of 8-bit chars.  Strings\ncan be  assigned and  concatenated to  one another,  they can  also be\nmanipulated via sub-ranges using the range definition syntax.  Strings\nhowever can not interact with scalar or vector types.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 10 - COMPONENTS]\nThere are three primary components, that are specialised upon a  given\nnumeric type, which make up the core of ExprTk. The components are  as\nfollows:\n\n   (1) Symbol Table  exprtk::symbol_table\u003cNumericType\u003e\n   (2) Expression    exprtk::expression\u003cNumericType\u003e\n   (3) Parser        exprtk::parser\u003cNumericType\u003e\n\n\n(1) Symbol Table\nA structure that is used  to store references to variables,  constants\nand functions that are to  be used within expressions. Furthermore  in\nthe context  of composited  recursive functions  the symbol  table can\nalso be thought of as a simple representation of a stack specific  for\nthe expression(s) that reference it. The following is a list of the\ntypes a symbol table can handle:\n\n   (a) Numeric variables\n   (b) Numeric constants\n   (c) Numeric vector elements\n   (d) String variables\n   (e) String constants\n   (f) Functions\n   (g) Vararg functions\n\n\nDuring the compilation  process if an  expression is found  to require\nany  of  the  elements   noted  above,  the  expression's   associated\nsymbol_table  will  be  queried  for  the  element  and  if  present a\nreference to the element will be embedded within the expression's AST.\nThis allows for the original  element to be modified independently  of\nthe  expression  instance  and  to also  allow  the  expression  to be\nevaluated using the current value of the element.\n\nThe  example  below demonstrates  the  relationship between variables,\nsymbol_table and expression. Note  the variables are modified  as they\nnormally would in a program, and when the expression is  evaluated the\ncurrent values assigned to the variables shall be used.\n\n   typedef exprtk::symbol_table\u003cdouble\u003e symbol_table_t;\n   typedef exprtk::expression\u003cdouble\u003e   expression_t;\n   typedef exprtk::parser\u003cdouble\u003e       parser_t;\n\n   double x = 0;\n   double y = 0;\n\n   symbol_table_t symbol_table;\n   expression_t   expression;\n   parser_t       parser;\n\n   std::string expression_string = \"x * y + 3\";\n\n   symbol_table.add_variable(\"x\",x);\n   symbol_table.add_variable(\"y\",y);\n\n   expression.register_symbol_table(symbol_table);\n\n   parser.compile(expression_string,expression);\n\n   x = 1.0;\n   y = 2.0;\n   expression.value(); // 1 * 2 + 3\n\n   x = 3.7;\n   expression.value(); // 3.7 * 2 + 3\n\n   y = -9.0;\n   expression.value(); // 3.7 * -9 + 3\n\n   // 'x * -9 + 3' for x in range of [0,100) in steps of 0.0001\n   for (x = 0.0; x \u003c 100.0; x += 0.0001)\n   {\n      expression.value(); // x * -9 + 3\n   }\n\n\nNote02: Any  variable  reference  provided  to  a  given  symbol_table\ninstance, must have a lifetime at least as long as the lifetime of the\nsymbol_table  instance.  In  the  event  the  variable  reference   is\ninvalidated  before  the  symbol_table  or  any  dependent  expression\ninstances  have  been  destructed,  then  any  associated   expression\nevaluations or variable referencing via the symbol_table instance will\nresult in undefined behaviour.\n\nThe following bit of  code instantiates a symbol_table  and expression\ninstance,  then  proceeds  to   demonstrate  various  ways  in   which\nreferences to  variables can  be added  to the  symbol_table, and  how\nthose  references are  subsequently invalidated  resulting in  various\nforms of undefined behaviour.\n\n   typedef exprtk::symbol_table\u003cdouble\u003e symbol_table_t;\n   typedef exprtk::expression\u003cdouble\u003e   expression_t;\n\n   symbol_table_t symbol_table;\n   expression_t   expression;\n\n   std::deque\u003cdouble \u003e y {1.1, 2.2, 3.3};\n   std::vector\u003cdouble\u003e z {4.4, 5.5, 6.6};\n   double* w = new double(123.456);\n\n   {\n      double x = 123.4567;\n      symbol_table.add_variable(\"x\", x);\n   }             // Reference to variable x has been invalidated\n\n\n   symbol_table.add_variable(\"y\", y.back());\n\n   y.pop_back(); // Reference to variable y has been invalidated\n\n\n   symbol_table.add_variable(\"z\", z.front());\n\n   z.erase(z.begin());\n                 // Reference to variable z has been invalidated\n\n   symbol_table.add_variable(\"w\", *w);\n\n   delete w;     // Reference to variable w has been invalidated\n\n   const std::string expression_string = \"x + y / z * w\";\n\n                 // Compilation of expression will succeed\n   parser.compile(expression_string,expression);\n\n   expression.value();\n                 // Evaluation will result in undefined behaviour\n                 // due to 'x' and 'w' having been destroyed.\n\n   symbol_table.get_variable(\"x\")-\u003eref() = 135.791;\n                 // Assignment will result in undefined behaviour\n\n\nA compiled expression that references variables from a symbol_table is\ndependent on  that symbol_table  instance and  the variables  it holds\nbeing valid.\n\n   typedef exprtk::symbol_table\u003cdouble\u003e symbol_table_t;\n   typedef exprtk::expression\u003cdouble\u003e   expression_t;\n\n   symbol_table_t symbol_table;\n   expression_t   expression;\n\n   double x = 123.456;\n\n   symbol_table.add_variable(\"x\", x);\n\n   const std::string expression_string = \"(x + 1) / 2\";\n\n                 // Compilation of the expression will succeed\n   parser.compile(expression_string,expression);\n\n                 // Clear all variables from symbol_table\n   symbol_table.clear();\n\n   expression.value();\n                 // Evaluation will result in undefined behaviour\n                 // because the reference to 'x' having been destroyed\n                 // during the clearing of the symbol_table\n\n\nIn  the  above  example, an  expression  is  compiled that  references\nvariable \"x\". As part of the compilation process the node holding  the\nvariable \"x\" is obtained from the symbol_table and embedded in the AST\nof the  expression -  in short  the expression  is now referencing the\nnode that holds  the variable \"x\".  The following diagram  depicts the\ndependencies between  the  variable   x,  the  symbol  table  and  the\nexpression:\n\n      +--[Symbol Table]--+\n      |                  |\n      | +- ------+       |\n      | | x-node |       |\n      | +-----A--+       |    +--[Expression]--+\n      +---|---|----------+    |  +---------+   |\n          v   |               |  |  A.S.T  |   |\n          |   +--------\u003c--------[.]        |   |\n    +-----+                   |  +---------+   |\n    |                         +----------------+\n  +-v-[variable]---+\n  | x: 123.456     |\n  +----------------+\n\n\nWhen the  clear method  is called  on the  symbol table  the X-Node is\ndestroyed, so now the expression  is referencing a node that  has been\ndestroyed.  From  this point  onwards  any attempts  to  reference the\nexpression instance will result in undefined behaviour. Simply put the\nabove  example  violates  the requirement  that  the  lifetime of  any\nobjects referenced by  expressions should exceed  the lifetime of  the\nexpression instance.\n\n   typedef exprtk::symbol_table\u003cdouble\u003e symbol_table_t;\n   typedef exprtk::expression\u003cdouble\u003e   expression_t;\n\n   symbol_table_t symbol_table;\n   expression_t   expression;\n\n   double x = 123.456;\n\n   symbol_table.add_variable(\"x\", x);\n\n   const std::string expression_string = \"(x + 1) / 2\";\n\n                 // Compilation of the expression will succeed\n   parser.compile(expression_string,expression);\n\n   expression.value();\n\n                 // Release the expression and its dependents\n   expression.release();\n\n                 // Clear all variables from symbol_table\n   symbol_table.clear();\n\n   expression.value();\n                 // Will return null_node value of NaN\n\n\nIn the above example the expression is released before the  associated\nsymbol_table is cleared of its variables, which resolves the undefined\nbehaviour issue noted in the previous example.\n\nNote03: It  is possible  to  register  multiple  symbol_tables  with a\nsingle  expression object.  In the  event an  expression has  multiple\nsymbol tables, and where  there exists conflicts between  symbols, the\ncompilation stage  will resolve  the conflicts  based on  the order of\nregistration  of  the  symbol_tables to  the  expression.  For a  more\nexpansive discussion please review section [17 - Hierarchies Of Symbol\nTables]\n\n   typedef exprtk::symbol_table\u003cdouble\u003e symbol_table_t;\n   typedef exprtk::expression\u003cdouble\u003e   expression_t;\n   typedef exprtk::parser\u003cdouble\u003e       parser_t;\n\n   symbol_table_t symbol_table0;\n   symbol_table_t symbol_table1;\n\n   expression_t   expression;\n   parser_t       parser;\n\n   double x0 = 123.0;\n   double x1 = 678.0;\n\n   std::string expression_string = \"x + 1\";\n\n   symbol_table0.add_variable(\"x\",x0);\n   symbol_table1.add_variable(\"x\",x1);\n\n   expression.register_symbol_table(symbol_table0);\n   expression.register_symbol_table(symbol_table1);\n\n   parser.compile(expression_string,expression);\n\n   expression.value(); // 123 + 1\n\n\nThe symbol table supports  adding references to external  instances of\ntypes  that  can  be accessed  within  expressions  via the  following\nmethods:\n\n  1. bool add_variable    (const std::string\u0026 name, scalar_t\u0026        )\n  2. bool add_constant    (const std::string\u0026 name, const scalar_t\u0026  )\n  3. bool add_stringvar   (const std::string\u0026 name, std::string\u0026     )\n  4. bool add_vector      (const std::string\u0026 name, vector_type\u0026     )\n  5. bool add_function    (const std::string\u0026 name, function_t\u0026      )\n  6. bool create_stringvar(const std::string\u0026 name,const std::string\u0026)\n  7. bool create_variable (const std::string\u0026 name, const T\u0026         )\n\n\nNote04: The 'vector' type must be comprised from a contiguous array of\nscalars with a size that is  larger than zero. The vector type  itself\ncan be any one of the following:\n\n   1. std::vector\u003cscalar_t\u003e\n   2. scalar_t(\u0026v)[N]\n   3. scalar_t* and array size\n   4. exprtk::vector_view\u003cscalar_t\u003e\n\n\nWhen  registering  a variable,  vector,  string or  function  with  an\ninstance of a symbol_table, the call to 'add_...' may fail and  return\na false result due to one or more of the following reasons:\n\n  1. Variable name contains invalid characters or is ill-formed\n  2. Variable name conflicts with a reserved word (eg: 'while')\n  3. Variable name conflicts with a previously registered variable\n  4. A vector of size (length) zero is being registered\n  5. A free function exceeding fifteen parameters is being registered\n  6. The symbol_table instance is in an invalid state\n\n\nNote05: The symbol_table has a method called clear, which when invoked\nwill clear  all variables,  vectors, strings  and functions registered\nwith the symbol_table instance. If  this method is to be  called, then\none  must  make  sure  that  all  compiled  expression  instances that\nreference  variables  belonging  to  that  symbol_table  instance  are\nreleased (aka call  release method on  expression) before calling  the\nclear  method  on  the  symbol_table  instance,  otherwise   undefined\nbehaviours will occur.\n\nA further property of symbol tables is that they can be classified  at\ninstantiation as either being mutable (by default) or immutable.  This\nproperty determines if variables,  vectors or strings registered  with\nthe symbol  table can  undergo modifications  within expressions  that\nreference  them.  The   following  demonstrates  construction   of  an\nimmutable symbol table instance:\n\n  symbol_table_t immutable_symbol_table\n     (symbol_table_t::symtab_mutability_type::e_immutable);\n\n\nWhen a symbol table, that has been constructed as  being immutable, is\nregistered with an expression, any statements in the expression string\nthat modify  the variables  that are  managed by  the immutable symbol\ntable will result in a compilation error. The operations that  trigger\nthe mutability constraint are the following assignment operators:\n\n  1. Assignment:       :=\n  2. Assign operation: +=, -=, *=, /= , %=\n\n   const std::string expression_str = \"x += x + 123.456\";\n\n   symbol_table_t immutable_symbol_table\n      (symbol_table_t::symtab_mutability_type::e_immutable);\n\n   T x = 0.0;\n\n   immutable_symbol_table.add_variable(\"x\" , x);\n\n   expression_t expression;\n   expression.register_symbol_table(immutable_symbol_table);\n\n   parser_t parser;\n\n   parser.compile(expression_str, expression);\n      // Compile error because of assignment to variable x\n\n\nIn the above example, variable x is registered to an immutable  symbol\ntable,  making it  an immutable  variable within  the context  of any\nexpressions that  reference it.  The expression  string being compiled\nuses the addition assignment operator  which will modify the value  of\nvariable x.  The compilation  process detects  this semantic violation\nand proceeds to halt compilation and return the appropriate error.\n\nOne of the main reasons for  this functionality is that, one may  want\nthe immutability  properties that  come with  constness of  a variable\nsuch  as  scalars,  vectors  and  strings,  but  not  necessarily  the\naccompanying  compile  time  const-folding  optimisations,  that would\nresult in  the value  of the  variables being  retrieved only  once at\ncompile time, causing external updates to the variables to not be part\nof the expression evaluation.\n\n   symbol_table_t immutable_symbol_table\n      (symbol_table_t::symtab_mutability_type::e_immutable);\n\n   T x = 0.0;\n\n   const std::string expression_str = \"x + (y + y)\";\n\n   immutable_symbol_table.add_variable(\"x\" , x    );\n   immutable_symbol_table.add_constant(\"y\" , 123.0);\n\n   expression_t expression;\n   expression.register_symbol_table(immutable_symbol_table);\n\n   parser_t parser;\n   parser.compile(expression_str, expression);\n\n   for (; x \u003c 10.0; ++x)\n   {\n      const auto expected_value = x + (123.0 + 123.0);\n      const auto result_value   = expression.value();\n      assert(expression.value() !=  expected_value);\n   }\n\n\nIn the above example,  there are two variables  X and Y. Where  Y is a\nconstant and X is a normal variable. Both are registered with a symbol\ntable that is immutable. The  expression when compiled will result  in\nthe \"(y + y)\" part being  const-folded at compile time to the  literal\nvalue of 246. Whereas  the current value of  X, being updated via  the\nfor-loop, externally to  the expression and  the symbol table shall be\nobservable to the expression upon each evaluation.\n\n\n(2) Expression\nA structure that holds an Abstract Syntax Tree or AST for a  specified\nexpression and is used to evaluate said expression. Evaluation of  the\nexpression is accomplished by performing a post-order traversal of the\nAST.  If  a  compiled  Expression  uses  variables  or  user   defined\nfunctions, it will have an associated Symbol Table, which will contain\nreferences  to said  variables, functions  or strings. An example  AST\nstructure for the denoted expression is as follows:\n\nExpression:  z := (x + y^-2.345) * sin(pi / min(w - 7.3,v))\n\n                  [Root]\n                    |\n               [Assignment]\n        ________/        \\_____\n       /                       \\\n Variable(z)            [Multiplication]\n                ____________/      \\___________\n               /                               \\\n              /                      [Unary-Function(sin)]\n         [Addition]                            |\n      ____/      \\____                    [Division]\n     /                \\                 ___/      \\___\n Variable(x)   [Exponentiation]        /              \\\n              ______/   \\______  Constant(pi) [Binary-Function(min)]\n             /                 \\                ____/    \\___\n        Variable(y)        [Negation]          /             \\\n                               |              /          Variable(v)\n                        Constant(2.345)      /\n                                            /\n                                     [Subtraction]\n                                   ____/      \\____\n                                  /                \\\n                             Variable(w)      Constant(7.3)\n\n\nThe above denoted AST shall be evaluated in the following order:\n\n   (01) Load Variable  (z)        (10) Load Constant  (7.3)\n   (02) Load Variable  (x)        (11) Subtraction    (09 \u0026 10)\n   (03) Load Variable  (y)        (12) Load Variable  (v)\n   (04) Load Constant  (2.345)    (13) Min            (11 \u0026 12)\n   (05) Negation       (04)       (14) Division       (08 \u0026 13)\n   (06) Exponentiation (03 \u0026 05)  (15) Sin            (14)\n   (07) Addition       (02 \u0026 06)  (16) Multiplication (07 \u0026 15)\n   (08) Load Constant  (pi)       (17) Assignment     (01 \u0026 16)\n   (09) Load Variable  (w)\n\n\nGenerally an expression in ExprTk can be thought of as a free function\nsimilar to those  found in imperative  languages. This form  of pseudo\nfunction will have a name, it may have a set of one or more inputs and\nwill return at least one value as its result. Furthermore the function\nwhen invoked, may  cause a side-effect  that changes the  state of the\nhost program.\n\nAs an  example the  following is  a pseudo-code  definition of  a free\nfunction that performs a computation taking four inputs, modifying one\nof them and returning a value based on some arbitrary calculation:\n\n   ResultType foo(InputType x, InputType y, InputType z, InputType w)\n   {\n      w = 2 * x^y + z;        // Side-Effect\n      return abs(x - y) / z;  // Return Result\n   }\n\n\nGiven the above definition the following is a functionally  equivalent\nversion using ExprTk:\n\n   const std::string foo_str =\n      \" w := 2 * x^y + z; \"\n      \" abs(x - y) / z;   \";\n\n   T x, y, z, w;\n\n   symbol_table_t symbol_table;\n   symbol_table.add_variable(\"x\",x);\n   symbol_table.add_variable(\"y\",y);\n   symbol_table.add_variable(\"z\",z);\n   symbol_table.add_variable(\"w\",w);\n\n   expression_t foo;\n   foo.register_symbol_table(symbol_table);\n\n   parser_t parser;\n   if (!parser.compile(foo_str,foo))\n   {\n      // Error in expression...\n      return;\n   }\n\n   T result = foo.value();\n\n\n(3) Parser\nA  component  which  takes  as input  a  string  representation  of an\nexpression and attempts to compile said input with the result being an\ninstance  of  Expression.  If  an  error  is  encountered  during  the\ncompilation  process, the  parser will  stop compiling  and return  an\nerror status code,  with a more  detailed description of  the error(s)\nand  its  location  within  the  input  provided  by  the  'get_error'\ninterface.\n\nNote06: The exprtk::expression and exprtk::symbol_table components are\nreference counted entities. Copy constructing or assigning to or  from\neither component will result in  a shallow copy and a  reference count\nincrement,  rather  than  a  complete  replication.  Furthermore   the\nexpression  and symbol_table  components being  Default-Constructible,\nCopy-Constructible  and  Copy-Assignable  make  them  compatible  with\nvarious  C++  standard  library   containers  and  adaptors  such   as\nstd::vector, std::map, std::stack etc.\n\nThe following is  an example of  two unique expressions,  after having\nbeen instantiated and  compiled,  one expression  is  assigned to  the\nother. The diagrams depict  their initial and post  assignment states,\nincluding  which  control  block each  expression references and their\nassociated reference counts.\n\n\n    exprtk::expression e0; // constructed expression, eg: x + 1\n    exprtk::expression e1; // constructed expression, eg: 2z + y\n\n  +-----[ e0 cntrl block]----+     +-----[ e1 cntrl block]-----+\n  | 1. Expression Node 'x+1' |     | 1. Expression Node '2z+y' |\n  | 2. Ref Count: 1          |\u003c-+  | 2. Ref Count: 1           |\u003c-+\n  +--------------------------+  |  +---------------------------+  |\n                                |                                 |\n    +--[ e0 expression]--+      |    +--[ e1 expression]--+       |\n    | 1. Reference to    ]------+    | 1. Reference to    ]-------+\n    | e0 Control Block   |           | e1 Control Block   |\n    +--------------------+           +--------------------+\n\n\n   e0 = e1; // e0 and e1 are now 2z+y\n\n               +-----[ e1 cntrl block]-----+\n               | 1. Expression Node '2z+y' |\n  +-----------\u003e| 2. Ref Count: 2           |\u003c----------+\n  |            +---------------------------+           |\n  |                                                    |\n  |   +--[ e0 expression]--+  +--[ e1 expression]--+   |\n  +---[ 1. Reference to    |  | 1. Reference to    ]---+\n      | e1 Control Block   |  | e1 Control Block   |\n      +--------------------+  +--------------------+\n\nThe reason for  the above complexity  and restrictions of  deep copies\nfor the expression and symbol_table components is because  expressions\nmay include user defined variables or functions. These are embedded as\nreferences into the expression's AST. When copying an expression, said\nreferences  need to  also  be  copied. If  the references  are blindly\ncopied,  it  will then  result  in two  or more  identical expressions\nutilising the exact same  references for variables. This  obviously is\nnot the  default assumed  scenario and  will give  rise to non-obvious\nbehaviours  when  using the  expressions in  various contexts such  as\nmulti-threading et al.\n\nThe prescribed method for cloning an expression is to compile it  from\nits string  form. Doing so will allow the 'user' to  properly consider\nthe exact source of user defined variables and functions.\n\nNote07: The exprtk::parser  is  a  non-copyable  and  non-thread  safe\ncomponent, and should only be shared via either a reference, a  shared\npointer  or  a  std::ref  mechanism,  and  considerations  relating to\nsynchronisation  taken  into  account  where  appropriate.  The parser\nrepresents an object factory,  specifically a factory of  expressions,\nand generally should  not be instantiated  solely on a  per expression\ncompilation basis.\n\nThe  following  diagram  and  example depicts  the  flow  of  data and\noperations  for  compiling  multiple expressions  via  the  parser and\ninserting  the  newly  minted  exprtk::expression  instances  into   a\nstd::vector.\n\n                      +----[exprtk::parser]---+\n                      |   Expression Factory  |\n                      | parser_t::compile(...)|\n                    +--\u003e ~.~.~.~.~.~.~.~.~.~ -\u003e--+\n                    | +-----------------------+  |\n Expressions in     |                            |  Expressions as\n string form        ^                            V  exprtk::expression\n                    |                            |  instances\n [s0:'x+1']---\u003e--+  |                            |  +-[e0: x+1]\n                 |  |                            |  |\n [s1:'2z+y']--\u003e--+--+                            +-\u003e+-[e1: 2z+y]\n                 |                                  |\n [s2:'sin(k+w)']-+                                  +-[e2: sin(k+w)]\n\n\n   const std::string expression_str[3] =\n      {\n         \"x + 1\",\n         \"2x + y\",\n         \"sin(k + w)\"\n      };\n\n   std::vector\u003cexpression_t\u003e expression_list;\n\n   parser_t       parser;\n   expression_t   expression;\n   symbol_table_t symbol_table;\n\n   expression.register_symbol_table(symbol_table);\n\n   for (std::size_t i = 0; i \u003c 3; ++i)\n   {\n      if (parser.compile(expression_str[i],expression))\n      {\n         expression_list.push_back(expression);\n      }\n      else\n        std::cout \u003c\u003c \"Error in \" \u003c\u003c expression_str[i] \u003c\u003c \"\\n\";\n   }\n\n   for (auto\u0026 e : expression_list)\n   {\n      e.value();\n   }\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 11 - COMPILATION OPTIONS]\nThe exprtk::parser  when being  instantiated takes  as input  a set of\noptions  to be  used during  the compilation  process of  expressions.\nAn  example instantiation  of exprtk::parser  where only  the  joiner,\ncommutative and strength reduction options are enabled is as  follows:\n\n   typedef exprtk::parser\u003cNumericType\u003e::settings_t settings_t;\n\n   const std::size_t compile_options =\n                        settings_t::e_joiner            +\n                        settings_t::e_commutative_check +\n                        settings_t::e_strength_reduction;\n\n   parser_t parser(compile_options);\n\n\nCurrently  eight  types of  compile  time options  are  supported, and\nenabled by default. The options and their explanations are as follows:\n\n   (1) Replacer\n   (2) Joiner\n   (3) Numeric Check\n   (4) Bracket Check\n   (5) Sequence Check\n   (6) Commutative Check\n   (7) Strength Reduction Check\n   (8) Stack And Node Depth Check\n   (9) Vector Size Check\n\n\n(1) Replacer (e_replacer)\nEnable replacement of specific  tokens with other tokens.  For example\nthe token  \"true\" of  type symbol  shall be  replaced with the numeric\ntoken of value one.\n\n   (a) (x \u003c y) == true   ---\u003e  (x \u003c y) == 1\n   (b) false == (x \u003e y)  ---\u003e  0 == (x \u003e y)\n\n\n(2) Joiner (e_joiner)\nEnable  joining  of  multi-character  operators  that  may  have  been\nincorrectly  disjoint in the  string  representation  of the specified\nexpression. For example the consecutive tokens of \"\u003e\" \"=\" will  become\n\"\u003e=\" representing  the \"greater  than or  equal to\"  operator. If  not\nproperly resolved the  original form will  cause a compilation  error.\nThe  following  is  a listing  of the  scenarios that  the joiner  can\nhandle:\n\n   (a) '\u003e' '='  ---\u003e  '\u003e='  (gte)\n   (b) '\u003c' '='  ---\u003e  '\u003c='  (lte)\n   (c) '=' '='  ---\u003e  '=='  (equal)\n   (d) '!' '='  ---\u003e  '!='  (not-equal)\n   (e) '\u003c' '\u003e'  ---\u003e  '\u003c\u003e'  (not-equal)\n   (f) ':' '='  ---\u003e  ':='  (assignment)\n   (g) '+' '='  ---\u003e  '+='  (addition assignment)\n   (h) '-' '='  ---\u003e  '-='  (subtraction assignment)\n   (i) '*' '='  ---\u003e  '*='  (multiplication assignment)\n   (j) '/' '='  ---\u003e  '/='  (division assignment)\n   (k) '%' '='  ---\u003e  '%='  (modulo assignment)\n   (l) '+' '-'  ---\u003e  '-'   (subtraction)\n   (m) '-' '+'  ---\u003e  '-'   (subtraction)\n   (n) '-' '-'  ---\u003e  '+'   (addition)\n   (o) '\u003c=' '\u003e' ---\u003e  '\u003c=\u003e' (swap)\n\n\nAn example of the transformation that takes place is as follows:\n\n   (a) (x \u003e = y) and (z ! = w)  ---\u003e  (x \u003e= y) and (z != w)\n\n\n(3) Numeric Check (e_numeric_check)\nEnable validation of tokens representing numeric types so as to  catch\nany errors prior  to the costly  process of the  main compilation step\ncommencing.\n\n\n(4) Bracket Check (e_bracket_check)\nEnable  the  check for  validating  the ordering  of  brackets in  the\nspecified expression.\n\n\n(5) Sequence Check (e_sequence_check)\nEnable the  check for  validating that  sequences of  either pairs  or\ntriplets of tokens make sense.  For example the following sequence  of\ntokens when encountered will raise an error:\n\n   (a) (x + * 3)  ---\u003e  sequence error\n\n\n(6) Commutative Check (e_commutative_check)\nEnable the check that will transform sequences of pairs of tokens that\nimply a multiplication operation.  The following are some  examples of\nsuch transformations:\n\n   (a) 2x             ---\u003e  2 * x\n   (b) 25x^3          ---\u003e  25 * x^3\n   (c) 3(x + 1)       ---\u003e  3 * (x + 1)\n   (d) (x + 1)4       ---\u003e  (x + 1) * 4\n   (e) 5foo(x,y)      ---\u003e  5 * foo(x,y)\n   (f) foo(x,y)6 + 1  ---\u003e  foo(x,y) * 6 + 1\n   (g) (4((2x)3))     ---\u003e  4 * ((2 * x) * 3)\n   (h) w / (x - y)z   ---\u003e  w / (x - y) * z\n\n\n(7) Strength Reduction Check (e_strength_reduction)\nEnable  the  use  of  strength  reduction  optimisations  during   the\ncompilation  process.  In  ExprTk  strength  reduction   optimisations\npredominantly involve  transforming sub-expressions  into other  forms\nthat  are algebraically  equivalent yet  less costly  to compute.  The\nfollowing are examples of the various transformations that can occur:\n\n   (a) (x / y) / z               ---\u003e  x / (y * z)\n   (b) (x / y) / (z / w)         ---\u003e  (x * w) / (y * z)\n   (c) (2 * x) - (2 * y)         ---\u003e  2 * (x - y)\n   (d) (2 / x) / (3 / y)         ---\u003e  (2 / 3) / (x * y)\n   (e) (2 * x) * (3 * y)         ---\u003e  6 * (x * y)\n   (f) (2 * x) * (2 - 4 / 2)     ---\u003e  0\n   (g) (3 - 6 / 2) / (2 * x)     ---\u003e  0\n   (h) avg(x,y,z) * (2 - 4 / 2)  ---\u003e  0\n\n\nNote08: When using strength reduction in conjunction with  expressions\nwhose inputs or sub-expressions may result in values nearing either of\nthe bounds of the underlying  numeric type (eg: double), there  may be\nthe  possibility of a decrease in the precision of results.\n\nIn  the following  example the  given expression  which represents  an\nattempt at computing the average  between x and y will  be transformed\nas follows:\n\n   (0.5 * x) + (y * 0.5) ---\u003e 0.5 * (x + y)\n\nThere  may be  situations where  the above  transformation will  cause\nnumerical overflows and  that the original  form of the  expression is\ndesired over the strength reduced form. In these situations it is best\nto turn off strength reduction optimisations  or to use a type with  a\nlarger numerical bound.\n\n\n(8) Stack And Node Depth Check\nExprTk  incorporates   a  recursive   descent  parser.   When  parsing\nexpressions comprising inner sub-expressions, the recursive nature  of\nthe parsing process causes the stack to grow. If the expression causes\nthe stack to grow  beyond the stack size  limit, this would lead  to a\nstackoverflow  and  its  associated  stack  corruption  and   security\nvulnerability issues.\n\nSimilarly to parsing, evaluating an expression may cause the stack  to\ngrow. Such things like user defined functions, composite functions and\nthe general nature of the AST  being evaluated can cause the stack  to\ngrow,  and may  result in  potential stackoverflow  issues as  denoted\nabove.\n\nExprTk provides a set of checks that prevent both of the above denoted\nproblems at  compile time.  These checks rely on  two specific  limits\nbeing set on the parser settings instance, these limits are:\n\n   1. max_stack_depth (default: 400  )\n   2. max_node_depth  (default: 10000)\n\n\nThe following demonstrates how these two parser parameters can be set:\n\n   parser_t parser;\n\n   parser.settings().set_max_stack_depth(100);\n   parser.settings().set_max_node_depth(200);\n\n\nIn  the  above  code, during  parsing if  the stack  depth reaches  or\nexceeds  100 levels,  the parsing  process will  immediately halt  and\nreturn with a failure.  Similarly, during synthesizing the  AST nodes,\nif the  compilation process  detects an  AST tree  depth exceeding 200\nlevels the parsing process will halt and return a parsing failure.\n\n\n(9) Expression Size Check\nExprTk allows for expression  local variables, vectors and  strings to\nbe defined. As such the amount  of data in terms of bytes  consumed by\nthe  expression  locals  can  also  be  limited,  so  as  to   prevent\nexpressions once compiled from consuming large amounts of data.\n\nThe maximum number of bytes an expression's locally defined  variables\nmay use can  be set via  the parser settings  prior to compilation  as\nfollows:\n\n   using expression_t = exprtk::expression\u003cdouble\u003e;\n   using parser_t     = exprtk::parser\u003cdouble\u003e;\n\n   expression_t expression;\n   parser_t     parser;\n\n   parser.settings().set_max_total_local_symbol_size_bytes(16);\n\n   const std::string expression1 = \"var x := 1; var y := 1;\";\n   const std::string expression2 = \"var x := 1; var v[2] := [1];\";\n\n   expression_t expression;\n\n   parser.compile(expression1, expression); // compilation success\n   parser.compile(expression2, expression); // compilation error\n\nIn the above example, the expression's max total local symbol size has\nbeen set to 16 bytes. The numeric type being used is double which is 8\nbytes  per  instance.  The  first  expression  (expression1)  compiles\nsuccessfully because the total local symbol size is 16 bytes, 8  bytes\nfor each of the variables x and y.\n\nHowever the second expression (expression2) fails to compile. This  is\nbecause the  total number  of bytes  needed for  the expression  is 24\nbytes, 8 bytes for  the variable x and  16 bytes for the  vector v, as\nsuch  exceeding  the  previously  set limit  of  16  bytes.  The error\ndiagnostic generated by  the parser on  compilation failure will  look\nlike the following:\n\n   ERR161 - Adding vector 'v' of size 2 bytes will exceed max total\n   local symbol size of: 16 bytes, current total size: 8 bytes\n\n\n(10) Vector Size Check\nWhen  defining  an  expression local  vector,  ExprTk  uses a  default\nmaximum vector size of two billion elements. One may want to limit the\nmaximum vector size to be either smaller or larger than the  specified\ndefault value. The  maximum size value  can be changed  via the parser\nsettings.\n\n   parser_t parser;\n\n   parser.settings().set_max_local_vector_size(1000000);\n\n   std::string expression1 = \"var v[1e6] := [123]\";\n   std::string expression2 = \"var v[1e9] := [123]\";\n\n   expression_t expression;\n\n   parser.compile(expression1, expression); // compilation success\n   parser.compile(expression2, expression); // compilation error\n\n\nIn the above code, the maximum local vector size is set to one million\nelements. During  compilation of  an expression  if there  is a vector\ndefinition where the vector's size exceeds the maximum allowed  vector\nsize  a  compilation  error shall  be  emitted.  The error  diagnostic\ngenerated by  the parser  on compilation  failure will  look like  the\nfollowing:\n\n   ERR160 - Invalid vector size. Must be an integer in the\n   range [0,1000000], size: 1000000000\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 12 - EXPRESSION STRUCTURES]\nExprtk supports mathematical expressions in numerous forms based on  a\nsimple  imperative  programming  model. This  section  will  cover the\nfollowing  topics  related  to general  structure  and  programming of\nexpressions using ExprTk:\n\n   (1) Multi-Statement Expressions\n   (2) Statements And Side-Effects\n   (3) Conditional Statements\n   (4) Special Functions\n\n\n(1) Multi-Statement Expressions\nExpressions in ExprTk can be comprised of one or more statements, which\nmay  sometimes  be  called  sub-expressions.  The  following  are  two\nexamples of expressions stored  in std::string variables, the  first a\nsingle statement and the second a multi-statement expression:\n\n   std::string single_statement = \" z := x + y \";\n\n   std::string multi_statement  = \" var temp := x; \"\n                                  \" x := y + z;    \"\n                                  \" y := temp;     \";\n\n\nIn a  multi-statement expression,  the final  statement will determine\nthe overall result of the expression. In the following multi-statement\nexpression, the result of the expression when evaluated will be '2.3',\nwhich will also be the value stored in the 'y' variable.\n\n   z := x + y;\n   y := 2.3;\n\n\nAs  demonstrated  in  the  expression  above,  statements  within   an\nexpression are  separated using  the semi-colon  ';' operator.  In the\nevent  two  statements are  not  separated by  a  semi-colon, and  the\nimplied multiplication  feature is  active (enabled  by default),  the\ncompiler  will  assume  a  multiplication  operation  between  the two\nstatements.\n\nIn the following example we have a multi-statement expression composed\nof two variable definitions and initialisations for variables x and  y\nand two seemingly separate mathematical operations.\n\n   var x:= 2;\n   var y:= 3;\n   x + 1\n   y * 2\n\n\nHowever the result of  the expression will not  be 6 as may  have been\nassumed based on  the calculation of  'y * 2',  but rather the  result\nwill be 8. This  is because the compiler  will have conjoined the  two\nmathematical statements into one  via a multiplication operation.  The\nexpression when compiled will actually evaluate as the following:\n\n   var x:= 2;\n   var y:= 3;\n   x + 1 * y * 2;   // 2 + 1 * 3 * 2 == 8\n\n\nIn ExprTk any valid statement  will itself return a value.  This value\ncan  further  be  used  in  conjunction  with  other  statements. This\nincludes language structures such as if-statements, loops (for, while)\nand the switch statement. Typically the last statement executed in the\ngiven construct  (conditional, loop  etc), will  be the  value that is\nreturned.\n\nIn the following example, the  return value of the expression  will be\n11, which is the sum of the variable 'x' and the final value  computed\nwithin the loop body upon its last iteration:\n\n   var x := 1;\n   x + for (var i := x; i \u003c 10; i += 1)\n       {\n          i / 2;\n          i + 1;\n       }\n\n\n(2) Statements And Side-Effects\nStatements themselves may have side effects, which in-turn affect  the\nproceeding statements in multi-statement expressions.\n\nA statement is said  to have a side-effect  if it causes the  state of\nthe  expression to  change in  some way  -  this  includes but  is not\nlimited to the  modification of the  state of external  variables used\nwithin the expression. Currently  the following actions being  present\nin a statement will cause it to have a side-effect:\n\n   (a) Assignment operation (explicit or potentially)\n   (b) Invoking a user-defined function that has side-effects\n\nThe following are examples of expressions where the side-effect status\nof the  statements (sub-expressions) within the expressions  have been\nnoted:\n\n  +-+----------------------+------------------------------+\n  |#|      Expression      |      Side Effect Status      |\n  +-+----------------------+------------------------------+\n  |0| x + y                | False                        |\n  +-+----------------------+------------------------------+\n  |1| z := x + y           | True - Due to assignment     |\n  +-+----------------------+------------------------------+\n  |2| abs(x - y)           | False                        |\n  +-+----------------------+------------------------------+\n  |3| abs(x - y);          | False                        |\n  | | z := (x += y);       | True - Due to assignments    |\n  +-+----------------------+------------------------------+\n  |4| abs(x - y);          | False                        |\n  | | z := (x += y);       | True - Due to assignments    |\n  +-+----------------------+------------------------------+\n  |5| var t := abs(x - y); | True - Due to initialisation |\n  | | t + x;               | False                        |\n  | | z := (x += y);       | True - Due to assignments    |\n  +-+----------------------+------------------------------+\n  |6| foo(x - y)           | True - user defined function |\n  +-+----------------------+------------------------------+\n\n\nNote09: In example  6 from  the above  set, it  is  assumed  the  user\ndefined function foo has been  registered as having a side-effect.  By\ndefault all user defined  functions are assumed to  have side-effects,\nunless they  are configured  in their  constructors to  not have side-\neffects using the  'disable_has_side_effects' free function.  For more\ninformation review Section 15  - User Defined Functions  sub-section 7\nFunction Side-Effects.\n\nAt this point we  can see that there  will be expressions composed  of\ncertain kinds  of statements  that when  executed will  not affect the\nnature  of the  expression's  result.  These statements  are typically\ncalled 'dead code'.  These statements though  not affecting the  final\nresult will still be executed and as such they will consume processing\ntime that could otherwise be saved. As such ExprTk attempts to  detect\nand remove such statements from expressions.\n\nThe  'Dead  Code  Elimination' (DCE)  optimisation  process,  which is\nenabled by default, will remove any statements that are determined  to\nnot have a side-effect in a multi-statement expression, excluding  the\nfinal or last statement.\n\nBy default the final statement in an expression will always be present\nregardless of  its side-effect  status, as  it is  the statement whose\nvalue shall be used as the result of the expression.\n\nIn order to further explain the actions taken during the DCE  process,\nlets review the following expression:\n\n   var x := 2;      // Statement 1\n   var y := x + 2;  // Statement 2\n   x + y;           // Statement 3\n   y := x + 3y;     // Statement 4\n   x - y;           // Statement 5\n\n\nThe above expression has five statements.  Three of them (1, 2 and  4)\nactively have side-effects. The first two are variable declaration and\ninitialisations, where as the third is due to an assignment operation.\nThere  are  two  statements (3  and 5),  that do  not explicitly  have\nside-effects, however the latter, statement 5, is the final  statement\nin the expression and hence will be assumed to have a side-effect.\n\nDuring compilation when the DCE  optimisation is applied to the  above\nexpression, statement 3 will be removed from the expression, as it has\nno  bearing  on  the  final result  of  expression,  the  rest of  the\nstatements will all remain. The optimised form of the expression is as\nfollows:\n\n   var x := 2;      // Statement 1\n   var y := x + 2;  // Statement 2\n   y := x + 3y;     // Statement 3\n   x - y;           // Statement 4\n\n\n(3) Conditional Statements (If-Then-Else)\nExprTk supports two forms  of conditional branching or otherwise known\nas  if-statements.  The  first  form,  is  a  simple  function   based\nconditional  statement, that  takes exactly  three input  expressions:\ncondition, consequent  and alternative.  The following  is an  example\nexpression that utilises the function based if-statement.\n\n   x := if (y \u003c z, y + 1, 2 * z)\n\n\nIn the  example above,  if the  condition 'y  \u003c z'  is true,  then the\nconsequent 'y + 1' will be evaluated, its value shall be  returned and\nsubsequently assigned to the  variable 'x'. Otherwise the  alternative\n'2 *  z' will  be evaluated  and its  value will  be returned. This is\nessentially the  simplest form of  an if-then-else statement. A simple\nvariation of  the expression  where the  value of  the if-statement is\nused within another statement is as follows:\n\n   x := 3 * if (y \u003c z, y + 1, 2 * z) / 2\n\n\nThe second form of if-statement resembles the standard syntax found in\nmost imperative languages. There are two variations of the statement:\n\n   (a) If-Statement\n   (b) If-Then-Else Statement\n\n\n(a) If-Statement\nThis version  of the  conditional statement  returns the  value of the\nconsequent expression when the  condition expression is true,  else it\nwill return a quiet NaN value as its result.\n\n   Example 1:\n   x := if (y \u003c z) y + 3;\n\n   Example 2:\n   x := if (y \u003c z)\n        {\n           y + 3\n        };\n\nThe two  example expressions  above are  equivalent. If  the condition\n'y \u003c z' is true, the 'x' variable shall be  assigned the value of  the\nconsequent 'y + 3', otherwise it  will be assigned the value of  quiet\nNaN.  As  previously  discussed,  if-statements  are  value  returning\nconstructs, and if  not properly terminated  using a semi-colon,  will\nend-up  combining  with  the  next  statement  via  a   multiplication\noperation. The following example will NOT result in the expected value\nof 'w + x' being returned:\n\n   x := if (y \u003c z) y + 3  // missing semi-colon ';'\n   w + x\n\n\nWhen the  above supposed  multi-statement expression  is compiled, the\nexpression  will  have  a  multiplication  inserted  between  the  two\n'intended' statements resulting in the unanticipated expression:\n\n   x := (if (y \u003c z) y + 3) * w + x\n\n\nThe  solution  to  the  above situation  is  to  simply  terminate the\nconditional statement with a semi-colon as follows:\n\n   x := if (y \u003c z) y + 3;\n   w + x\n\n\n(b) If-Then-Else Statement\nThe second variation of  the if-statement is to  allow for the use  of\nElse and Else-If cascading statements. Examples of such statements are\nas follows:\n\n Example 1:             Example 2:         Example 3:\n if (x \u003c y)             if (x \u003c y)         if (x \u003e y + 1)\n    z := x + 3;         {                     y := abs(x - z);\n else                      y := z + x;     else\n    y := x - z;            z := x + 3;     {\n                        }                     y := z + x;\n                        else                  z := x + 3;\n                           y := x - z;     };\n\n\n Example 4:             Example 5:         Example 6:\n if (2 * x \u003c max(y,3))  if (x \u003c y)         if (x \u003c y or (x + z) \u003e y)\n {                         z := x + 3;     {\n    y := z + x;         else if (2y != z)     z := x + 3;\n    z := x + 3;         {                     y := x - z;\n }                         z := x + 3;     }\n else if (2y - z)          y := x - z;     else if (abs(2y - z) \u003e= 3)\n    y := x - z;         }                     y := x - z;\n                        else               else\n                           x * x;          {\n                                              z := abs(x * x);\n                                              x * y * z;\n                                           };\n\n\nIn  the case  where  there  is no  final else  statement and  the flow\nthrough the conditional  arrives at this  final point, the  same rules\napply to this form of if-statement as to the previous. That is a quiet\nNaN shall be returned as the  result of the  if-statement. Furthermore\nthe same requirements of  terminating the statement with  a semi-colon\napply.\n\n(4) Special Functions\nThe purpose  of special  functions in  ExprTk is  to provide  compiler\ngenerated equivalents of common mathematical expressions which can  be\ninvoked by  using the  'special function'  syntax (eg:  $f12(x,y,z) or\n$f82(x,y,z,w)).\n\nSpecial functions dramatically decrease  the total evaluation time  of\nexpressions which would otherwise  have been written using  the common\nform by reducing the total number  of nodes in the evaluation tree  of\nan  expression  and  by  also  leveraging  the  compiler's  ability to\ncorrectly optimise such expressions for a given architecture.\n\n          3-Parameter                       4-Parameter\n +-------------+-------------+    +--------------+------------------+\n |  Prototype  |  Operation  |    |  Prototype   |    Operation     |\n +-------------+-------------+    +--------------+------------------+\n   $f00(x,y,z) | (x + y) / z       $f48(x,y,z,w) | x + ((y + z) / w)\n   $f01(x,y,z) | (x + y) * z       $f49(x,y,z,w) | x + ((y + z) * w)\n   $f02(x,y,z) | (x + y) - z       $f50(x,y,z,w) | x + ((y - z) / w)\n   $f03(x,y,z) | (x + y) + z       $f51(x,y,z,w) | x + ((y - z) * w)\n   $f04(x,y,z) | (x - y) + z       $f52(x,y,z,w) | x + ((y * z) / w)\n   $f05(x,y,z) | (x - y) / z       $f53(x,y,z,w) | x + ((y * z) * w)\n   $f06(x,y,z) | (x - y) * z       $f54(x,y,z,w) | x + ((y / z) + w)\n   $f07(x,y,z) | (x * y) + z       $f55(x,y,z,w) | x + ((y / z) / w)\n   $f08(x,y,z) | (x * y) - z       $f56(x,y,z,w) | x + ((y / z) * w)\n   $f09(x,y,z) | (x * y) / z       $f57(x,y,z,w) | x - ((y + z) / w)\n   $f10(x,y,z) | (x * y) * z       $f58(x,y,z,w) | x - ((y + z) * w)\n   $f11(x,y,z) | (x / y) + z       $f59(x,y,z,w) | x - ((y - z) / w)\n   $f12(x,y,z) | (x / y) - z       $f60(x,y,z,w) | x - ((y - z) * w)\n   $f13(x,y,z) | (x / y) / z       $f61(x,y,z,w) | x - ((y * z) / w)\n   $f14(x,y,z) | (x / y) * z       $f62(x,y,z,w) | x - ((y * z) * w)\n   $f15(x,y,z) | x / (y + z)       $f63(x,y,z,w) | x - ((y / z) / w)\n   $f16(x,y,z) | x / (y - z)       $f64(x,y,z,w) | x - ((y / z) * w)\n   $f17(x,y,z) | x / (y * z)       $f65(x,y,z,w) | ((x + y) * z) - w\n   $f18(x,y,z) | x / (y / z)       $f66(x,y,z,w) | ((x - y) * z) - w\n   $f19(x,y,z) | x * (y + z)       $f67(x,y,z,w) | ((x * y) * z) - w\n   $f20(x,y,z) | x * (y - z)       $f68(x,y,z,w) | ((x / y) * z) - w\n   $f21(x,y,z) | x * (y * z)       $f69(x,y,z,w) | ((x + y) / z) - w\n   $f22(x,y,z) | x * (y / z)       $f70(x,y,z,w) | ((x - y) / z) - w\n   $f23(x,y,z) | x - (y + z)       $f71(x,y,z,w) | ((x * y) / z) - w\n   $f24(x,y,z) | x - (y - z)       $f72(x,y,z,w) | ((x / y) / z) - w\n   $f25(x,y,z) | x - (y / z)       $f73(x,y,z,w) | (x * y) + (z * w)\n   $f26(x,y,z) | x - (y * z)       $f74(x,y,z,w) | (x * y) - (z * w)\n   $f27(x,y,z) | x + (y * z)       $f75(x,y,z,w) | (x * y) + (z / w)\n   $f28(x,y,z) | x + (y / z)       $f76(x,y,z,w) | (x * y) - (z / w)\n   $f29(x,y,z) | x + (y + z)       $f77(x,y,z,w) | (x / y) + (z / w)\n   $f30(x,y,z) | x + (y - z)       $f78(x,y,z,w) | (x / y) - (z / w)\n   $f31(x,y,z) | x * y^2 + z       $f79(x,y,z,w) | (x / y) - (z * w)\n   $f32(x,y,z) | x * y^3 + z       $f80(x,y,z,w) | x / (y + (z * w))\n   $f33(x,y,z) | x * y^4 + z       $f81(x,y,z,w) | x / (y - (z * w))\n   $f34(x,y,z) | x * y^5 + z       $f82(x,y,z,w) | x * (y + (z * w))\n   $f35(x,y,z) | x * y^6 + z       $f83(x,y,z,w) | x * (y - (z * w))\n   $f36(x,y,z) | x * y^7 + z       $f84(x,y,z,w) | x*y^2 + z*w^2\n   $f37(x,y,z) | x * y^8 + z       $f85(x,y,z,w) | x*y^3 + z*w^3\n   $f38(x,y,z) | x * y^9 + z       $f86(x,y,z,w) | x*y^4 + z*w^4\n   $f39(x,y,z) | x * log(y)+z      $f87(x,y,z,w) | x*y^5 + z*w^5\n   $f40(x,y,z) | x * log(y)-z      $f88(x,y,z,w) | x*y^6 + z*w^6\n   $f41(x,y,z) | x * log10(y)+z    $f89(x,y,z,w) | x*y^7 + z*w^7\n   $f42(x,y,z) | x * log10(y)-z    $f90(x,y,z,w) | x*y^8 + z*w^8\n   $f43(x,y,z) | x * sin(y)+z      $f91(x,y,z,w) | x*y^9 + z*w^9\n   $f44(x,y,z) | x * sin(y)-z      $f92(x,y,z,w) | (x and y) ? z : w\n   $f45(x,y,z) | x * cos(y)+z      $f93(x,y,z,w) | (x or  y) ? z : w\n   $f46(x,y,z) | x * cos(y)-z      $f94(x,y,z,w) | (x \u003c   y) ? z : w\n   $f47(x,y,z) | x ? y : z         $f95(x,y,z,w) | (x \u003c=  y) ? z : w\n                                   $f96(x,y,z,w) | (x \u003e   y) ? z : w\n                                   $f97(x,y,z,w) | (x \u003e=  y) ? z : w\n                                   $f98(x,y,z,w) | (x ==  y) ? z : w\n                                   $f99(x,y,z,w) | x*sin(y)+z*cos(w)\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 13 - VARIABLE, VECTOR \u0026 STRING DEFINITION]\nExprTk supports the definition of expression local variables,  vectors\nand  strings.  The definitions  must  be unique  as  shadowing is  not\nallowed and object lifetimes are based  on scope. Definitions use  the\nfollowing general form:\n\n   var \u003cname\u003e := \u003cinitialiser\u003e;\n\n(1) Variable Definition\nVariables are  of numeric  type denoting  a single  value. They can be\nexplicitly initialised to a value, otherwise they will be defaulted to\nzero. The following are examples of variable definitions:\n\n   (a) Initialise x to zero\n       var x;\n\n   (b) Initialise y to three\n       var y := 3;\n\n   (c) Initialise z to the expression\n       var z := if (max(1, x + y) \u003e 2, w, v);\n\n   (d) Initialise const literal n\n       var n := 12 / 3;\n\n\n(2) Vector Definition\nVectors are arrays of a common numeric type. The elements in a  vector\ncan be explicitly initialised, otherwise they will all be defaulted to\nzero. The following are examples of vector definitions:\n\n   (a) Initialise all values to zero\n       var x[3];\n\n   (b) Initialise all values to zero\n       var x[3] := {};\n\n   (c) Initialise all values to given value or expression\n       var x[3]   := [ 42 ];\n       var y[x[]] := [ 123 + 3y + sin(w / z) ];\n\n   (d) Initialise all values iota style\n       var v[4] := [ 0 : +1];  //  0,  1,  2,  3\n       var v[5] := [-3 : -2];  // -3, -5, -7, -9, -11\n\n   (e) Initialise the first two values, all other elements to zero\n       var x[3] := { (1 + x[2]) / x[], (sin(y[0] / x[]) + 3) / x[] };\n\n   (f) Initialise the first three (all) values\n       const var size := 3;\n       var x[size] := { 1, 2, 3 };\n\n   (g) Initialise vector from a vector\n       var x[4] := { 1, 2, 3, 4 };\n       var y[3] := x;\n       var w[5] := { 1, 2 }; // 1, 2, 0, 0, 0\n\n   (h) Initialise vector from a smaller vector\n       var x[3] := { 1, 2, 3 };\n       var y[5] := x;   // 1, 2, 3, ??, ??\n\n   (i) Non-initialised vector\n       var x[3] := null; // ?? ?? ??\n\n   (j) Error as there are too many initialisers\n       var x[3] := { 1, 2, 3, 4 };\n\n   (k) Error as a vector of size zero is not allowed.\n       var x[0];\n\n\n(3) String Definition\nStrings are sequences comprised of 8-bit characters. They can only be\ndefined  with an explicit  initialisation  value. The  following  are\nexamples of string variable definitions:\n\n   (a) Initialise to a string\n       var x := 'abc';\n\n   (b) Initialise to an empty string\n       var x := '';\n\n   (c) Initialise to a string expression\n       var x := 'abc' + '123';\n\n   (d) Initialise to a string range\n       var x := 'abc123'[2:4];\n\n   (e) Initialise to another string variable\n       var x := 'abc';\n       var y := x;\n\n   (f) Initialise to another string variable range\n       var x := 'abc123';\n       var y := x[2:4];\n\n   (g) Initialise to a string expression\n       var x := 'abc';\n       var y := x + '123';\n\n   (h) Initialise to a string expression range\n       var x := 'abc';\n       var y := (x + '123')[1:3];\n\n\n(4) Return Value\nVariable and vector  definitions have a  return value. In  the case of\nvariable definitions, the value  to which the variable  is initialised\nwill be returned. Where as for vectors, the value of the first element\n(eg: v[0]) shall be returned.\n\n   8 == ((var x := 7;) + 1)\n   4 == (var y[3] := {4, 5, 6};)\n\n\n(5) Variable/Vector Assignment\nThe value of a variable can be assigned to a vector and a vector or  a\nvector expression can be assigned to a variable.\n\n  (a) Variable To Vector:\n      Every element of the vector is assigned the value of the variable\n      or expression.\n      var x    := 3;\n      var y[3] := { 1, 2, 3 };\n      y := x + 1;\n\n  (b) Vector To Variable:\n      The variable is assigned the value of the first element of the\n      vector (aka vec[0])\n      var x    := 3;\n      var y[3] := { 1, 2, 3 };\n      x := y + 1;\n\n\nNote10: During the expression compilation phase, tokens are classified\nbased on the following priorities:\n\n   (a) Reserved keywords or operators (+, -, and, or, etc)\n   (b) Base functions (abs, sin, cos, min, max etc)\n   (c) Symbol table variables\n   (d) Expression local defined variables\n   (e) Symbol table functions\n   (f) Unknown symbol resolver based variables\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[SECTION 14 - VECTOR PROCESSING]\nExprTk  provides  support  for   various  forms  of  vector   oriented\narithmetic, inequalities and  processing. The various  supported pairs\nare as follows:\n\n   (a) vector and vector (eg: v0 + v1)\n   (b) vector and scalar (eg: v  + 33)\n   (c) scalar and vector (eg: 22 *  v)\n\nThe following is a list of operations that can be used in  conjunction\nwith vectors:\n\n   (a) Arithmetic:       +, -, *, /, %\n   (b) Exponentiation:   vector ^ scalar\n   (c) Assignment:       :=, +=, -=, *=, /=, %=, \u003c=\u003e\n   (d) Inequalities:     \u003c, \u003c=, \u003e, \u003e=, ==, =, equal\n   (e) Boolean logic:    and, nand, nor, or, xnor, xor\n   (f) Unary operations:\n       abs, acos, acosh, asin, asinh, atan, atanh, ceil, cos,  cosh,\n       cot, csc,  deg2grad, deg2rad,  erf, erfc,  exp, expm1, floor,\n       frac, grad2deg, log, log10, log1p, log2, rad2deg, round, sec,\n       sgn, sin, sinc, sinh, sqrt, swap, tan, tanh, trunc,\n       thresholding\n   (g) Aggregate and Reduce operations:\n       avg, max, min, mul,  dot, dotk, sum, sumk,  count, all_true,\n       all_false, any_true, any_false\n   (h) Transformation operations:\n       copy, diff, reverse, rotate-left/right, shift-left/right, sort,\n       nth_element\n   (i) BLAS-L1:\n       axpy, axpby, axpyz, axpbyz, axpbz\n\nNote11: When one of the above  described operations is being performed\nbetween two  vectors, the  operation will  only span  the size  of the\nsmallest vector.  The elements  of the  larger vector  outside of  the\nrange will  not be included. The  operation  itself will  be processed\nelement-wise over values of the smaller of the two ranges.\n\nThe  following  simple  example  demonstrates  the  vector  processing\ncapabilities by computing the dot-product of the vectors v0 and v1 and\nthen assigning it to the variable v0dotv1:\n\n   var v0[3] := { 1, 2, 3 };\n   var v1[3] := { 4, 5, 6 };\n   var v0dotv1 := sum(v0 * v1);\n\n\nThe following is a for-loop based implementation that is equivalent to\nthe previously mentioned dot-product computation expression:\n\n   var v0[3] := { 1, 2, 3 };\n   var v1[3] := { 4, 5, 6 };\n   var v0dotv1;\n\n   for (var i := 0; i \u003c min(v0[],v1[]); i += 1)\n   {\n      v0dotv1 += (v0[i] * v1[i]);\n   }\n\n\nNote12: When the aggregate or reduction  operations denoted above  are\nused  in conjunction with a  vector or  vector  expression, the return\nvalue is not a vector but rather a single value.\n\n   var x[3] := { 1, 2, 3 };\n\n   sum(x)      ==  6\n   sum(1 + 2x) == 15\n   avg(3x + 1) ==  7\n   min(1 / x)  == (1 / 3)\n   max(x / 2)  == (3 / 2)\n   sum(x \u003e 0 and x \u003c 5) == x[]\n\n\nWhen utilising external user defined  vectors via the symbol table  as\nopposed to expression local defined vectors, the typical  'add_vector'\nmethod from the symbol table will register the entirety of the  vector\nthat is passed. The following example attempts to evaluate the sum  of\nelements of  the external  user defined  vector within  a typical  yet\ntrivial expression:\n\n   const std::string reduce_program = \" sum(2 * v + 1) \";\n\n   std::vector\u003cT\u003e v0 { T(1.1), T(2.2), ..... , T(99.99) };\n\n   symbol_table_t symbol_table;\n   symbol_table.add_vector(\"v\",v);\n\n   expression_t expression;\n   expression.register_symbol_table(symbol_table);\n\n   parser_t parser;\n   parser.compile(reduce_program,expression);\n\n   T sum = expression.value();\n\n\nFor the most part, this is  a very common use-case. However there  may\nbe situations where one may want to evaluate the same vector  oriented\nexpression many times over, but using different vectors or sub  ranges\nof the same vector of the same size to that of the original upon every\nevaluation.\n\nThe usual solution is to  either recompile the expression for  the new\nvector instance, or to  copy the contents from  the new vector to  the\nsymbol table registered vector  and then perform the  evaluation. When\nthe  vectors are  large or  the re-evaluation  attempts are  numerous,\nthese  solutions  can  become  rather  time  consuming  and  generally\ninefficient.\n\n   std::vector\u003cT\u003e v1 { T(2.2), T(2.2), ..... , T(2.2) };\n   std::vector\u003cT\u003e v2 { T(3.3), T(3.3), ..... , T(3.3) };\n   std::vector\u003cT\u003e v3 { T(4.4), T(4.4), ..... , T(4.4) };\n\n   std::vector\u003cstd::vector\u003cT\u003e\u003e vv { v1, v2, v3 };\n   ...\n   T sum = T(0);\n\n   for (auto\u0026 new_vec : vv)\n   {\n      v = new_vec; // update vector\n      sum += expression.value();\n   }\n\n\nA  solution  to  the  above  'efficiency'  problem,  is  to  use   the\nexprtk::vector_view  object. The  vector_view is  instantiated with  a\nsize and backing based upon a vector. Upon evaluations if the  backing\nneeds  to  be  'updated' to  either another  vector or  sub-range, the\nvector_view instance  can be  efficiently rebased,  and the expression\nevaluated as normal.\n\n   exprtk::vector_view\u003cT\u003e view = exprtk::make_vector_view(v,v.size());\n\n   symbol_table_t symbol_table;\n   symbol_table.add_vector(\"v\",view);\n\n   ...\n\n   T sum = T(0);\n\n   for (auto\u0026 new_vec : vv)\n   {\n      view.rebase(new_vec.data()); // update vector\n      sum += expression.value();\n   }\n\n\nAnother useful feature of exprtk::vector_view is that all such vectors\ncan have  their sizes  modified (or  \"resized\"). The  resizing of  the\nassociated vectors can happen either between or during evaluations.\n\n   std::vector\u003cT\u003e v = { 1, 2, 3, 4, 5, 6, 7, 8 };\n   exprtk::vector_view\u003cT\u003e view = exprtk::make_vector_view(v,v.size());\n\n   symbol_table_t symbol_table;\n   symbol_table.add_vector(\"v\",view);\n\n   const std::string expression_string = \"v[]\";\n\n   expression_t expression;\n   expression.register_symbol_table(symbol_table);\n\n   parser_t parser;\n   parser.compile(expression_string, expression);\n\n   for (std::size_t i = 1; i \u003c= v.size(); ++i)\n   {\n      vv.set_size(i);\n      expression.value();\n   }\n\n\nIn the example above, a vector_view is instantiated with a std::vector\ninstance with eight elements and registered to the given symbol_table.\nAn expression is then compiled,  which in this case simply returns the\nsize of the vector at that point in time. The expression is  evaluated\neight times (size of vector times","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FArashPartow%2Fexprtk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FArashPartow%2Fexprtk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FArashPartow%2Fexprtk/lists"}