/src/muparser/include/muParserTemplateMagic.h
Line | Count | Source |
1 | | /* |
2 | | |
3 | | _____ __ _____________ _______ ______ ___________ |
4 | | / \| | \____ \__ \\_ __ \/ ___// __ \_ __ \ |
5 | | | Y Y \ | / |_> > __ \| | \/\___ \\ ___/| | \/ |
6 | | |__|_| /____/| __(____ /__| /____ >\___ >__| |
7 | | \/ |__| \/ \/ \/ |
8 | | Copyright (C) 2004 - 2022 Ingo Berg |
9 | | |
10 | | Redistribution and use in source and binary forms, with or without modification, are permitted |
11 | | provided that the following conditions are met: |
12 | | |
13 | | * Redistributions of source code must retain the above copyright notice, this list of |
14 | | conditions and the following disclaimer. |
15 | | * Redistributions in binary form must reproduce the above copyright notice, this list of |
16 | | conditions and the following disclaimer in the documentation and/or other materials provided |
17 | | with the distribution. |
18 | | |
19 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR |
20 | | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
21 | | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
22 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 | | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
25 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
26 | | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | | */ |
28 | | |
29 | | #ifndef MU_PARSER_TEMPLATE_MAGIC_H |
30 | | #define MU_PARSER_TEMPLATE_MAGIC_H |
31 | | |
32 | | #include <algorithm> |
33 | | #include <random> |
34 | | #include <cmath> |
35 | | #include "muParserError.h" |
36 | | |
37 | | |
38 | | namespace mu |
39 | | { |
40 | | //----------------------------------------------------------------------------------------------- |
41 | | // |
42 | | // Compile time type detection |
43 | | // |
44 | | //----------------------------------------------------------------------------------------------- |
45 | | |
46 | | /** \brief A class singling out integer types at compile time using |
47 | | template meta programming. |
48 | | */ |
49 | | template<typename T> |
50 | | struct TypeInfo |
51 | | { |
52 | 3.93k | static bool IsInteger() { return false; } |
53 | | }; |
54 | | |
55 | | template<> |
56 | | struct TypeInfo<char> |
57 | | { |
58 | 0 | static bool IsInteger() { return true; } |
59 | | }; |
60 | | |
61 | | template<> |
62 | | struct TypeInfo<short> |
63 | | { |
64 | 0 | static bool IsInteger() { return true; } |
65 | | }; |
66 | | |
67 | | template<> |
68 | | struct TypeInfo<int> |
69 | | { |
70 | 0 | static bool IsInteger() { return true; } |
71 | | }; |
72 | | |
73 | | template<> |
74 | | struct TypeInfo<long> |
75 | | { |
76 | 0 | static bool IsInteger() { return true; } |
77 | | }; |
78 | | |
79 | | template<> |
80 | | struct TypeInfo<unsigned char> |
81 | | { |
82 | 0 | static bool IsInteger() { return true; } |
83 | | }; |
84 | | |
85 | | template<> |
86 | | struct TypeInfo<unsigned short> |
87 | | { |
88 | 0 | static bool IsInteger() { return true; } |
89 | | }; |
90 | | |
91 | | template<> |
92 | | struct TypeInfo<unsigned int> |
93 | | { |
94 | 0 | static bool IsInteger() { return true; } |
95 | | }; |
96 | | |
97 | | template<> |
98 | | struct TypeInfo<unsigned long> |
99 | | { |
100 | 0 | static bool IsInteger() { return true; } |
101 | | }; |
102 | | |
103 | | |
104 | | //----------------------------------------------------------------------------------------------- |
105 | | // |
106 | | // Standard math functions with dummy overload for integer types |
107 | | // |
108 | | //----------------------------------------------------------------------------------------------- |
109 | | |
110 | | /** \brief A template class for providing wrappers for essential math functions. |
111 | | |
112 | | This template is spezialized for several types in order to provide a unified interface |
113 | | for parser internal math function calls regardless of the data type. |
114 | | */ |
115 | | template<typename T> |
116 | | struct MathImpl |
117 | | { |
118 | 207 | static T Sin(T v) { return sin(v); } |
119 | 201 | static T Cos(T v) { return cos(v); } |
120 | 251 | static T Tan(T v) { return tan(v); } |
121 | 203 | static T ASin(T v) { return asin(v); } |
122 | 483 | static T ACos(T v) { return acos(v); } |
123 | 195 | static T ATan(T v) { return atan(v); } |
124 | 487 | static T ATan2(T v1, T v2) { return atan2(v1, v2); } |
125 | 203 | static T Sinh(T v) { return sinh(v); } |
126 | 198 | static T Cosh(T v) { return cosh(v); } |
127 | 211 | static T Tanh(T v) { return tanh(v); } |
128 | 198 | static T ASinh(T v) { return log(v + sqrt(v * v + 1)); } |
129 | 325 | static T ACosh(T v) { return log(v + sqrt(v * v - 1)); } |
130 | 196 | static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); } |
131 | 320 | static T Log(T v) { return log(v); } |
132 | 198 | static T Log2(T v) { return log(v) / log((T)2); } // Logarithm base 2 |
133 | 395 | static T Log10(T v) { return log10(v); } // Logarithm base 10 |
134 | 198 | static T Exp(T v) { return exp(v); } |
135 | 408 | static T Abs(T v) { return (v >= 0) ? v : -v; } |
136 | 195 | static T Sqrt(T v) { return sqrt(v); } |
137 | 441 | static T Rint(T v) { return floor(v + (T)0.5); } |
138 | 392 | static T Sign(T v) { return (T)((v < 0) ? -1 : (v > 0) ? 1 : 0); } |
139 | 42.0k | static T Pow(T v1, T v2) { return std::pow(v1, v2); } |
140 | | static T Rnd() |
141 | 541 | { |
142 | 541 | static std::random_device rd; |
143 | 541 | static std::mt19937 gen(rd()); |
144 | 541 | static std::uniform_real_distribution<T> dis(0.0, 1.0); // Range [0, 1) |
145 | | |
146 | 541 | return dis(gen); |
147 | 541 | } |
148 | | |
149 | 3.27k | static T UnaryMinus(T v) { return -v; } |
150 | 0 | static T UnaryPlus(T v) { return v; } |
151 | | |
152 | | static T Sum(const T *a_afArg, int a_iArgc) |
153 | 697 | { |
154 | 697 | if (!a_iArgc) |
155 | 0 | throw ParserError(_T("too few arguments for function sum.")); |
156 | | |
157 | 697 | T fRes = 0; |
158 | 47.6k | for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i]; |
159 | 697 | return fRes; |
160 | 697 | } |
161 | | |
162 | | static T Avg(const T *a_afArg, int a_iArgc) |
163 | 508 | { |
164 | 508 | if (!a_iArgc) |
165 | 0 | throw ParserError(_T("too few arguments for function avg.")); |
166 | | |
167 | 508 | T fRes = 0; |
168 | 39.9k | for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i]; |
169 | 508 | return fRes / (T)a_iArgc; |
170 | 508 | } |
171 | | |
172 | | static T Min(const T *a_afArg, int a_iArgc) |
173 | 1.13k | { |
174 | 1.13k | if (!a_iArgc) |
175 | 0 | throw ParserError(_T("too few arguments for function min.")); |
176 | | |
177 | 1.13k | T fRes = a_afArg[0]; |
178 | 54.4k | for (int i = 0; i < a_iArgc; ++i) |
179 | 53.3k | fRes = std::min(fRes, a_afArg[i]); |
180 | | |
181 | 1.13k | return fRes; |
182 | 1.13k | } |
183 | | |
184 | | static T Max(const T *a_afArg, int a_iArgc) |
185 | 1.11k | { |
186 | 1.11k | if (!a_iArgc) |
187 | 0 | throw ParserError(_T("too few arguments for function max.")); |
188 | | |
189 | 1.11k | T fRes = a_afArg[0]; |
190 | 60.9k | for (int i = 0; i < a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]); |
191 | | |
192 | 1.11k | return fRes; |
193 | 1.11k | } |
194 | | |
195 | | |
196 | | #if defined (__GNUG__) |
197 | | // Bei zu genauer definition von pi kann die Berechnung von |
198 | | // sin(pi*a) mit a=1 10 x langsamer sein! |
199 | | static constexpr T CONST_PI = (T)3.141592653589; |
200 | | #else |
201 | | static constexpr T CONST_PI = (T)3.141592653589793238462643; |
202 | | #endif |
203 | | |
204 | | static constexpr T CONST_E = (T)2.718281828459045235360287; |
205 | | }; |
206 | | } |
207 | | |
208 | | #endif |