]> Shamusworld >> Repos - architektonas/blob - fparser/fpaux.hh
Adding fparser v4.3...
[architektonas] / fparser / fpaux.hh
1 /***************************************************************************\
2 |* Function Parser for C++ v4.3                                            *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma                                 *|
5 |*                                                                         *|
6 |* This library is distributed under the terms of the                      *|
7 |* GNU Lesser General Public License version 3.                            *|
8 |* (See lgpl.txt and gpl.txt for the license text.)                        *|
9 \***************************************************************************/
10
11 // NOTE:
12 // This file contains only internal types for the function parser library.
13 // You don't need to include this file in your code. Include "fparser.hh"
14 // only.
15
16 #ifndef ONCE_FPARSER_AUX_H_
17 #define ONCE_FPARSER_AUX_H_
18
19 #include <cmath>
20 #include <cstring>
21
22 #include "fptypes.hh"
23
24 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
25 #include "mpfr/MpfrFloat.hh"
26 #endif
27
28 #ifdef FP_SUPPORT_GMP_INT_TYPE
29 #include "mpfr/GmpInt.hh"
30 #endif
31
32 #ifdef ONCE_FPARSER_H_
33 namespace FUNCTIONPARSERTYPES
34 {
35     template<typename value_t>
36     struct IsIntType
37     {
38         enum { result = false };
39     };
40     template<>
41     struct IsIntType<long>
42     {
43         enum { result = true };
44     };
45 #ifdef FP_SUPPORT_GMP_INT_TYPE
46     template<>
47     struct IsIntType<GmpInt>
48     {
49         enum { result = true };
50     };
51 #endif
52
53 //==========================================================================
54 // Math funcs
55 //==========================================================================
56     template<typename ValueT>
57     ValueT fp_pow(const ValueT& x, const ValueT& y);
58
59     template<typename Value_t>
60     inline void fp_sinCos(Value_t& sin, Value_t& cos, const Value_t& a)
61     {
62         // Assuming that "cos" and "a" don't overlap, but "sin" and "a" may.
63         cos = fp_cos(a);
64         sin = fp_sin(a);
65     }
66
67     template<typename Value_t>
68     inline Value_t fp_hypot(Value_t x, Value_t y) { return fp_sqrt(x*x + y*y); }
69
70     template<typename Value_t>
71     inline Value_t fp_asinh(Value_t x)
72         { return fp_log(x + fp_sqrt(x*x + Value_t(1))); }
73     template<typename Value_t>
74     inline Value_t fp_acosh(Value_t x)
75         { return fp_log(x + fp_sqrt(x*x - Value_t(1))); }
76     template<typename Value_t>
77     inline Value_t fp_atanh(Value_t x)
78         { return fp_log( (Value_t(1)+x) / (Value_t(1)-x)) * Value_t(0.5); }
79
80
81     template<typename Value_t>
82     inline Value_t fp_const_pi() // CONSTANT_PI
83     {
84         return Value_t(3.1415926535897932384626433832795028841971693993751L);
85     }
86
87 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
88     template<>
89     inline MpfrFloat fp_const_pi<MpfrFloat>() { return MpfrFloat::const_pi(); }
90 #endif
91
92     template<typename Value_t>
93     inline Value_t fp_const_e() // CONSTANT_E
94     {
95         return Value_t(2.7182818284590452353602874713526624977572L);
96     }
97     template<typename Value_t>
98     inline Value_t fp_const_einv() // CONSTANT_EI
99     {
100         return Value_t(0.367879441171442321595523770161460867445811131L);
101     }
102     template<typename Value_t>
103     inline Value_t fp_const_log2() // CONSTANT_L2, CONSTANT_L2EI
104     {
105         return Value_t(0.69314718055994530941723212145817656807550013436025525412L);
106     }
107     template<typename Value_t>
108     inline Value_t fp_const_log10() // CONSTANT_L10, CONSTANT_L10EI
109     {
110         return Value_t(2.302585092994045684017991454684364207601101488628772976L);
111     }
112     template<typename Value_t>
113     inline Value_t fp_const_log2inv() // CONSTANT_L2I, CONSTANT_L2E
114     {
115         return Value_t(1.442695040888963407359924681001892137426645954L);
116     }
117     template<typename Value_t>
118     inline Value_t fp_const_log10inv() // CONSTANT_L10I, CONSTANT_L10E
119     {
120         return Value_t(0.434294481903251827651128918916605082294397L);
121     }
122
123     template<typename Value_t>
124     inline const Value_t& fp_const_deg_to_rad() // CONSTANT_DR
125     {
126         static const Value_t factor = fp_const_pi<Value_t>() / Value_t(180); // to rad from deg
127         return factor;
128     }
129
130     template<typename Value_t>
131     inline const Value_t& fp_const_rad_to_deg() // CONSTANT_RD
132     {
133         static const Value_t factor = Value_t(180) / fp_const_pi<Value_t>(); // to deg from rad
134         return factor;
135     }
136
137 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
138     template<>
139     inline MpfrFloat fp_const_e<MpfrFloat>() { return MpfrFloat::const_e(); }
140
141     template<>
142     inline MpfrFloat fp_const_einv<MpfrFloat>() { return MpfrFloat(1) / MpfrFloat::const_e(); }
143
144     template<>
145     inline MpfrFloat fp_const_log2<MpfrFloat>() { return MpfrFloat::const_log2(); }
146
147     /*
148     template<>
149     inline MpfrFloat fp_const_log10<MpfrFloat>() { return fp_log(MpfrFloat(10)); }
150
151     template<>
152     inline MpfrFloat fp_const_log2inv<MpfrFloat>() { return MpfrFloat(1) / MpfrFloat::const_log2(); }
153
154     template<>
155     inline MpfrFloat fp_const_log10inv<MpfrFloat>() { return fp_log10(MpfrFloat::const_e()); }
156     */
157 #endif
158
159
160 // -------------------------------------------------------------------------
161 // double
162 // -------------------------------------------------------------------------
163     inline double fp_abs(double x) { return fabs(x); }
164     inline double fp_acos(double x) { return acos(x); }
165     inline double fp_asin(double x) { return asin(x); }
166     inline double fp_atan(double x) { return atan(x); }
167     inline double fp_atan2(double x, double y) { return atan2(x, y); }
168 #ifdef FP_SUPPORT_CBRT
169     inline double fp_cbrt(double x) { return cbrt(x); }
170 #else
171     inline double fp_cbrt(double x) { return x>0 ?  exp(log( x)/3.0)
172                                            : x<0 ? -exp(log(-x)/3.0)
173                                            : 0.0; }
174 #endif
175     inline double fp_ceil(double x) { return ceil(x); }
176     inline double fp_cos(double x) { return cos(x); }
177     inline double fp_cosh(double x) { return cosh(x); }
178     inline double fp_exp(double x) { return exp(x); }
179     inline double fp_floor(double x) { return floor(x); }
180     inline double fp_int(double x) { return floor(x + .5); }
181     inline double fp_log(double x) { return log(x); }
182     inline double fp_log10(double x)
183     { return log(x) *
184             0.434294481903251827651128918916605082294397005803666566; }
185     inline double fp_mod(double x, double y) { return fmod(x, y); }
186     inline double fp_sin(double x) { return sin(x); }
187     inline double fp_sinh(double x) { return sinh(x); }
188     inline double fp_sqrt(double x) { return sqrt(x); }
189     inline double fp_tan(double x) { return tan(x); }
190     inline double fp_tanh(double x) { return tanh(x); }
191
192 #ifdef FP_SUPPORT_ASINH
193     inline double fp_asinh(double x) { return asinh(x); }
194     inline double fp_acosh(double x) { return acosh(x); }
195     inline double fp_atanh(double x) { return atanh(x); }
196 #endif // FP_SUPPORT_ASINH
197 #ifdef FP_SUPPORT_HYPOT
198     inline double fp_hypot(double x, double y) { return hypot(x,y); }
199 #endif
200
201     inline double fp_trunc(double x) { return x<0.0 ? ceil(x) : floor(x); }
202
203     inline double fp_pow_base(double x, double y) { return pow(x, y); }
204
205 #ifndef FP_SUPPORT_LOG2
206     inline double fp_log2(double x)
207     { return log(x) * 1.4426950408889634073599246810018921374266459541529859; }
208 #else
209     inline double fp_log2(double x) { return log2(x); }
210 #endif // FP_SUPPORT_LOG2
211
212     inline double fp_exp2(double x) { return fp_pow(2.0, x); }
213
214 #ifdef FP_EPSILON
215     template<typename Value_t>
216     inline Value_t fp_epsilon() { return FP_EPSILON; }
217 #else
218     template<typename Value_t>
219     inline Value_t fp_epsilon() { return 0.0; }
220 #endif
221
222   #ifdef _GNU_SOURCE
223     template<>
224     inline void fp_sinCos<double>(double& sin, double& cos, const double& a)
225     {
226         sincos(a, &sin, &cos);
227     }
228   #endif
229
230 // -------------------------------------------------------------------------
231 // float
232 // -------------------------------------------------------------------------
233 #ifdef FP_SUPPORT_FLOAT_TYPE
234     inline float fp_abs(float x) { return fabsf(x); }
235     inline float fp_acos(float x) { return acosf(x); }
236     inline float fp_asin(float x) { return asinf(x); }
237     inline float fp_atan(float x) { return atanf(x); }
238     inline float fp_atan2(float x, float y) { return atan2f(x, y); }
239 #ifdef FP_SUPPORT_CBRT
240     inline float fp_cbrt(float x) { return cbrtf(x); }
241 #else
242     inline float fp_cbrt(float x) { return x>0 ?  expf(logf( x)/3.0f)
243                                          : x<0 ? -expf(logf(-x)/3.0f)
244                                          : 0.0f; }
245 #endif
246     inline float fp_ceil(float x) { return ceilf(x); }
247     inline float fp_cos(float x) { return cosf(x); }
248     inline float fp_cosh(float x) { return coshf(x); }
249     inline float fp_exp(float x) { return expf(x); }
250     inline float fp_floor(float x) { return floorf(x); }
251     inline float fp_int(float x) { return floorf(x + .5F); }
252     inline float fp_log(float x) { return logf(x); }
253     inline float fp_log10(float x)
254     { return logf(x) *
255             0.434294481903251827651128918916605082294397005803666566F; }
256     inline float fp_mod(float x, float y) { return fmodf(x, y); }
257     inline float fp_sin(float x) { return sinf(x); }
258     inline float fp_sinh(float x) { return sinhf(x); }
259     inline float fp_sqrt(float x) { return sqrtf(x); }
260     inline float fp_tan(float x) { return tanf(x); }
261     inline float fp_tanh(float x) { return tanhf(x); }
262
263 #ifdef FP_SUPPORT_ASINH
264     inline float fp_asinh(float x) { return asinhf(x); }
265     inline float fp_acosh(float x) { return acoshf(x); }
266     inline float fp_atanh(float x) { return atanhf(x); }
267 #endif // FP_SUPPORT_ASINH
268 #ifdef FP_SUPPORT_HYPOT
269     inline float fp_hypot(float x, float y) { return hypotf(x,y); }
270 #endif
271
272     inline float fp_trunc(float x) { return x<0.0F ? ceilf(x) : floorf(x); }
273
274     inline float fp_pow_base(float x, float y) { return powf(x, y); }
275
276 #ifndef FP_SUPPORT_LOG2
277     inline float fp_log2(float x)
278     { return logf(x) *
279             1.4426950408889634073599246810018921374266459541529859F; }
280 #else
281     inline float fp_log2(float x) { return log2f(x); }
282 #endif // FP_SUPPORT_LOG2
283
284     inline float fp_exp2(float x) { return fp_pow(2.0F, x); }
285
286 #ifdef FP_EPSILON
287     template<>
288     inline float fp_epsilon<float>() { return 1e-6F; }
289 #else
290     template<>
291     inline float fp_epsilon<float>() { return 0.0F; }
292 #endif
293
294 #endif // FP_SUPPORT_FLOAT_TYPE
295   #ifdef _GNU_SOURCE
296     template<>
297     inline void fp_sinCos<float>(float& sin, float& cos, const float& a)
298     {
299         sincosf(a, &sin, &cos);
300     }
301   #endif
302
303
304
305 // -------------------------------------------------------------------------
306 // long double
307 // -------------------------------------------------------------------------
308 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
309     inline long double fp_abs(long double x) { return fabsl(x); }
310     inline long double fp_acos(long double x) { return acosl(x); }
311     inline long double fp_asin(long double x) { return asinl(x); }
312     inline long double fp_atan(long double x) { return atanl(x); }
313     inline long double fp_atan2(long double x, long double y)
314     { return atan2l(x, y); }
315 #ifdef FP_SUPPORT_CBRT
316     inline long double fp_cbrt(long double x) { return cbrtl(x); }
317 #else
318     inline long double fp_cbrt(long double x)
319         { return x>0 ?  expl(logl( x)/3.0l)
320                : x<0 ? -expl(logl(-x)/3.0l)
321                : 0.0l; }
322 #endif
323     inline long double fp_ceil(long double x) { return ceill(x); }
324     inline long double fp_cos(long double x) { return cosl(x); }
325     inline long double fp_cosh(long double x) { return coshl(x); }
326     inline long double fp_exp(long double x) { return expl(x); }
327     inline long double fp_floor(long double x) { return floorl(x); }
328     inline long double fp_int(long double x) { return floorl(x + .5L); }
329     inline long double fp_log(long double x) { return logl(x); }
330     inline long double fp_log10(long double x)
331     { return logl(x) *
332             0.434294481903251827651128918916605082294397005803666566L; }
333     inline long double fp_mod(long double x, long double y)
334     { return fmodl(x, y); }
335     inline long double fp_sin(long double x) { return sinl(x); }
336     inline long double fp_sinh(long double x) { return sinhl(x); }
337     inline long double fp_sqrt(long double x) { return sqrtl(x); }
338     inline long double fp_tan(long double x) { return tanl(x); }
339     inline long double fp_tanh(long double x) { return tanhl(x); }
340
341 #ifdef FP_SUPPORT_ASINH
342     inline long double fp_asinh(long double x) { return asinhl(x); }
343     inline long double fp_acosh(long double x) { return acoshl(x); }
344     inline long double fp_atanh(long double x) { return atanhl(x); }
345 #endif // FP_SUPPORT_ASINH
346 #ifdef FP_SUPPORT_HYPOT
347     inline long double fp_hypot(long double x, long double y) { return hypotl(x,y); }
348 #endif
349
350     inline long double fp_trunc(long double x)
351     { return x<0.0L ? ceill(x) : floorl(x); }
352
353     inline long double fp_pow_base(long double x, long double y)
354     { return powl(x, y); }
355
356 #ifndef FP_SUPPORT_LOG2
357     inline long double fp_log2(long double x)
358     { return fp_log(x) * 1.4426950408889634073599246810018921374266459541529859L; }
359 #else
360     inline long double fp_log2(long double x) { return log2l(x); }
361 #endif // FP_SUPPORT_LOG2
362
363     inline long double fp_exp2(long double x) { return fp_pow(2.0L, x); }
364
365 #endif // FP_SUPPORT_LONG_DOUBLE_TYPE
366
367   #ifdef _GNU_SOURCE
368     template<>
369     inline void fp_sinCos<long double>(long double& sin, long double& cos, const long double& a)
370     {
371         sincosl(a, &sin, &cos);
372     }
373   #endif
374
375
376 // -------------------------------------------------------------------------
377 // Long int
378 // -------------------------------------------------------------------------
379     inline long fp_abs(long x) { return x < 0 ? -x : x; }
380     inline long fp_acos(long) { return 0; }
381     inline long fp_asin(long) { return 0; }
382     inline long fp_atan(long) { return 0; }
383     inline long fp_atan2(long, long) { return 0; }
384     inline long fp_cbrt(long) { return 0; }
385     inline long fp_ceil(long x) { return x; }
386     inline long fp_cos(long) { return 0; }
387     inline long fp_cosh(long) { return 0; }
388     inline long fp_exp(long) { return 0; }
389     inline long fp_floor(long x) { return x; }
390     inline long fp_int(long x) { return x; }
391     inline long fp_log(long) { return 0; }
392     inline long fp_log10(long) { return 0; }
393     inline long fp_mod(long x, long y) { return x % y; }
394     inline long fp_pow(long, long) { return 0; }
395     inline long fp_sin(long) { return 0; }
396     inline long fp_sinh(long) { return 0; }
397     inline long fp_sqrt(long) { return 1; }
398     inline long fp_tan(long) { return 0; }
399     inline long fp_tanh(long) { return 0; }
400     inline long fp_asinh(long) { return 0; }
401     inline long fp_acosh(long) { return 0; }
402     inline long fp_atanh(long) { return 0; }
403     inline long fp_trunc(long x) { return x; }
404     inline long fp_pow_base(long, long) { return 0; }
405     inline long fp_log2(long) { return 0; }
406     inline long fp_exp2(long) { return 0; }
407
408     template<>
409     inline long fp_epsilon<long>() { return 0; }
410
411
412 // -------------------------------------------------------------------------
413 // MpfrFloat
414 // -------------------------------------------------------------------------
415 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
416     inline MpfrFloat fp_abs(const MpfrFloat& x) { return MpfrFloat::abs(x); }
417     inline MpfrFloat fp_acos(const MpfrFloat& x) { return MpfrFloat::acos(x); }
418     inline MpfrFloat fp_asin(const MpfrFloat& x) { return MpfrFloat::asin(x); }
419     inline MpfrFloat fp_atan(const MpfrFloat& x) { return MpfrFloat::atan(x); }
420     inline MpfrFloat fp_atan2(const MpfrFloat& x, const MpfrFloat& y)
421         { return MpfrFloat::atan2(x, y); }
422     inline MpfrFloat fp_cbrt(const MpfrFloat& x) { return MpfrFloat::cbrt(x); }
423     inline MpfrFloat fp_ceil(const MpfrFloat& x) { return MpfrFloat::ceil(x); }
424     inline MpfrFloat fp_cos(const MpfrFloat& x) { return MpfrFloat::cos(x); }
425     inline MpfrFloat fp_cosh(const MpfrFloat& x) { return MpfrFloat::cosh(x); }
426     inline MpfrFloat fp_exp(const MpfrFloat& x) { return MpfrFloat::exp(x); }
427     inline MpfrFloat fp_floor(const MpfrFloat& x) { return MpfrFloat::floor(x); }
428     inline MpfrFloat fp_hypot(const MpfrFloat& x, const MpfrFloat& y)
429         { return MpfrFloat::hypot(x, y); }
430     inline MpfrFloat fp_int(const MpfrFloat& x) { return MpfrFloat::round(x); }
431     inline MpfrFloat fp_log(const MpfrFloat& x) { return MpfrFloat::log(x); }
432     inline MpfrFloat fp_log10(const MpfrFloat& x) { return MpfrFloat::log10(x); }
433     inline MpfrFloat fp_mod(const MpfrFloat& x, const MpfrFloat& y) { return x % y; }
434     inline MpfrFloat fp_sin(const MpfrFloat& x) { return MpfrFloat::sin(x); }
435     inline MpfrFloat fp_sinh(const MpfrFloat& x) { return MpfrFloat::sinh(x); }
436     inline MpfrFloat fp_sqrt(const MpfrFloat& x) { return MpfrFloat::sqrt(x); }
437     inline MpfrFloat fp_tan(const MpfrFloat& x) { return MpfrFloat::tan(x); }
438     inline MpfrFloat fp_tanh(const MpfrFloat& x) { return MpfrFloat::tanh(x); }
439     inline MpfrFloat fp_asinh(const MpfrFloat& x) { return MpfrFloat::asinh(x); }
440     inline MpfrFloat fp_acosh(const MpfrFloat& x) { return MpfrFloat::acosh(x); }
441     inline MpfrFloat fp_atanh(const MpfrFloat& x) { return MpfrFloat::atanh(x); }
442     inline MpfrFloat fp_trunc(const MpfrFloat& x) { return MpfrFloat::trunc(x); }
443
444     inline MpfrFloat fp_pow(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); }
445     inline MpfrFloat fp_pow_base(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); }
446
447     inline MpfrFloat fp_log2(const MpfrFloat& x) { return MpfrFloat::log2(x); }
448     inline MpfrFloat fp_exp2(const MpfrFloat& x) { return MpfrFloat::exp2(x); }
449
450     template<>
451     inline void fp_sinCos<MpfrFloat>(MpfrFloat& sin, MpfrFloat& cos, const MpfrFloat& a)
452     {
453         MpfrFloat::sincos(a, sin, cos);
454     }
455
456     template<>
457     inline MpfrFloat fp_epsilon<MpfrFloat>() { return MpfrFloat::someEpsilon(); }
458 #endif // FP_SUPPORT_MPFR_FLOAT_TYPE
459
460
461 // -------------------------------------------------------------------------
462 // GMP int
463 // -------------------------------------------------------------------------
464 #ifdef FP_SUPPORT_GMP_INT_TYPE
465     inline GmpInt fp_abs(GmpInt x) { return GmpInt::abs(x); }
466     inline GmpInt fp_acos(GmpInt) { return 0; }
467     inline GmpInt fp_asin(GmpInt) { return 0; }
468     inline GmpInt fp_atan(GmpInt) { return 0; }
469     inline GmpInt fp_atan2(GmpInt, GmpInt) { return 0; }
470     inline GmpInt fp_cbrt(GmpInt) { return 0; }
471     inline GmpInt fp_ceil(GmpInt x) { return x; }
472     inline GmpInt fp_cos(GmpInt) { return 0; }
473     inline GmpInt fp_cosh(GmpInt) { return 0; }
474     inline GmpInt fp_exp(GmpInt) { return 0; }
475     inline GmpInt fp_floor(GmpInt x) { return x; }
476     inline GmpInt fp_hypot(GmpInt, GmpInt) { return 0; }
477     inline GmpInt fp_int(GmpInt x) { return x; }
478     inline GmpInt fp_log(GmpInt) { return 0; }
479     inline GmpInt fp_log10(GmpInt) { return 0; }
480     inline GmpInt fp_mod(GmpInt x, GmpInt y) { return x % y; }
481     inline GmpInt fp_pow(GmpInt, GmpInt) { return 0; }
482     inline GmpInt fp_sin(GmpInt) { return 0; }
483     inline GmpInt fp_sinh(GmpInt) { return 0; }
484     inline GmpInt fp_sqrt(GmpInt) { return 0; }
485     inline GmpInt fp_tan(GmpInt) { return 0; }
486     inline GmpInt fp_tanh(GmpInt) { return 0; }
487     inline GmpInt fp_asinh(GmpInt) { return 0; }
488     inline GmpInt fp_acosh(GmpInt) { return 0; }
489     inline GmpInt fp_atanh(GmpInt) { return 0; }
490     inline GmpInt fp_trunc(GmpInt x) { return x; }
491     inline GmpInt fp_pow_base(GmpInt, GmpInt) { return 0; }
492     inline GmpInt fp_log2(GmpInt) { return 0; }
493     inline GmpInt fp_exp2(GmpInt) { return 0; }
494
495     template<>
496     inline GmpInt fp_epsilon<GmpInt>() { return 0; }
497 #endif // FP_SUPPORT_GMP_INT_TYPE
498
499
500 // -------------------------------------------------------------------------
501 // Comparison
502 // -------------------------------------------------------------------------
503 #ifdef FP_EPSILON
504     template<typename Value_t>
505     inline bool fp_equal(const Value_t& x, const Value_t& y)
506     { return IsIntType<Value_t>::result
507         ? (x == y)
508         : (fp_abs(x - y) <= fp_epsilon<Value_t>()); }
509
510     template<typename Value_t>
511     inline bool fp_nequal(const Value_t& x, const Value_t& y)
512     { return IsIntType<Value_t>::result
513         ? (x != y)
514         : (fp_abs(x - y) > fp_epsilon<Value_t>()); }
515
516     template<typename Value_t>
517     inline bool fp_less(const Value_t& x, const Value_t& y)
518     { return IsIntType<Value_t>::result
519         ? (x < y)
520         : (x < y - fp_epsilon<Value_t>()); }
521
522     template<typename Value_t>
523     inline bool fp_lessOrEq(const Value_t& x, const Value_t& y)
524     { return IsIntType<Value_t>::result
525         ? (x <= y)
526         : (x <= y + fp_epsilon<Value_t>()); }
527 #else // FP_EPSILON
528     template<typename Value_t>
529     inline bool fp_equal(const Value_t& x, const Value_t& y) { return x == y; }
530
531     template<typename Value_t>
532     inline bool fp_nequal(const Value_t& x, const Value_t& y) { return x != y; }
533
534     template<typename Value_t>
535     inline bool fp_less(const Value_t& x, const Value_t& y) { return x < y; }
536
537     template<typename Value_t>
538     inline bool fp_lessOrEq(const Value_t& x, const Value_t& y) { return x <= y; }
539 #endif // FP_EPSILON
540
541     template<typename Value_t>
542     inline bool fp_greater(const Value_t& x, const Value_t& y)
543     { return fp_less(y, x); }
544
545     template<typename Value_t>
546     inline bool fp_greaterOrEq(const Value_t& x, const Value_t& y)
547     { return fp_lessOrEq(y, x); }
548
549     template<typename Value_t>
550     inline bool fp_truth(const Value_t& d)
551     {
552         return IsIntType<Value_t>::result
553                 ? d != 0
554                 : fp_abs(d) >= Value_t(0.5);
555     }
556
557     template<typename Value_t>
558     inline bool fp_absTruth(const Value_t& abs_d)
559     {
560         return IsIntType<Value_t>::result
561                 ? abs_d > 0
562                 : abs_d >= Value_t(0.5);
563     }
564
565     template<typename Value_t>
566     inline const Value_t& fp_min(const Value_t& d1, const Value_t& d2)
567         { return d1<d2 ? d1 : d2; }
568
569     template<typename Value_t>
570     inline const Value_t& fp_max(const Value_t& d1, const Value_t& d2)
571         { return d1>d2 ? d1 : d2; }
572
573     template<typename Value_t>
574     inline const Value_t fp_not(const Value_t& b)
575         { return Value_t(!fp_truth(b)); }
576
577     template<typename Value_t>
578     inline const Value_t fp_notNot(const Value_t& b)
579         { return Value_t(fp_truth(b)); }
580
581     template<typename Value_t>
582     inline const Value_t fp_absNot(const Value_t& b)
583         { return Value_t(!fp_absTruth(b)); }
584
585     template<typename Value_t>
586     inline const Value_t fp_absNotNot(const Value_t& b)
587         { return Value_t(fp_absTruth(b)); }
588
589     template<typename Value_t>
590     inline const Value_t fp_and(const Value_t& a, const Value_t& b)
591         { return Value_t(fp_truth(a) && fp_truth(b)); }
592
593     template<typename Value_t>
594     inline const Value_t fp_or(const Value_t& a, const Value_t& b)
595         { return Value_t(fp_truth(a) || fp_truth(b)); }
596
597     template<typename Value_t>
598     inline const Value_t fp_absAnd(const Value_t& a, const Value_t& b)
599         { return Value_t(fp_absTruth(a) && fp_absTruth(b)); }
600
601     template<typename Value_t>
602     inline const Value_t fp_absOr(const Value_t& a, const Value_t& b)
603         { return Value_t(fp_absTruth(a) || fp_absTruth(b)); }
604
605     /////////////
606     /* Opcode analysis functions are used by fp_opcode_add.inc */
607     /* Moved here from fparser.cc because fp_opcode_add.inc
608      * is also now included by fpoptimizer.cc
609      */
610     bool IsLogicalOpcode(unsigned op);
611     bool IsComparisonOpcode(unsigned op);
612     unsigned OppositeComparisonOpcode(unsigned op);
613     bool IsNeverNegativeValueOpcode(unsigned op);
614     bool IsAlwaysIntegerOpcode(unsigned op);
615     bool IsUnaryOpcode(unsigned op);
616     bool IsBinaryOpcode(unsigned op);
617     bool HasInvalidRangesOpcode(unsigned op);
618
619     template<typename Value_t>
620     inline Value_t DegreesToRadians(Value_t degrees)
621     {
622         return degrees * fp_const_deg_to_rad<Value_t>();
623     }
624
625     template<typename Value_t>
626     inline Value_t RadiansToDegrees(Value_t radians)
627     {
628         return radians * fp_const_rad_to_deg<Value_t>();
629     }
630
631     template<typename Value_t>
632     inline bool isEvenInteger(Value_t value)
633     {
634         const Value_t halfValue = value * Value_t(0.5);
635         return fp_equal(halfValue, fp_floor(halfValue));
636     }
637
638     template<typename Value_t>
639     inline bool isInteger(Value_t value)
640     {
641         return fp_equal(value, fp_floor(value));
642     }
643
644     // Is value an integer that fits in "long" datatype?
645     template<typename Value_t>
646     inline bool isLongInteger(Value_t value)
647     {
648         return value == Value_t( makeLongInteger(value) );
649     }
650
651     template<typename Value_t>
652     inline long makeLongInteger(Value_t value)
653     {
654         return (long) fp_int(value);
655     }
656
657 #ifdef FP_SUPPORT_LONG_INT_TYPE
658     template<>
659     inline bool isEvenInteger(long value)
660     {
661         return value%2 == 0;
662     }
663
664     template<>
665     inline bool isInteger(long) { return true; }
666
667     template<>
668     inline bool isLongInteger(long) { return true; }
669
670     template<>
671     inline long makeLongInteger(long value)
672     {
673         return value;
674     }
675 #endif
676
677 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
678     template<>
679     inline bool isInteger(MpfrFloat value) { return value.isInteger(); }
680
681     template<>
682     inline bool isEvenInteger(MpfrFloat value)
683     {
684         return isInteger(value) && value%2 == 0;
685     }
686
687     template<>
688     inline long makeLongInteger(MpfrFloat value)
689     {
690         return (long) value.toInt();
691     }
692 #endif
693
694 #ifdef FP_SUPPORT_GMP_INT_TYPE
695     template<>
696     inline bool isEvenInteger(GmpInt value)
697     {
698         return value%2 == 0;
699     }
700
701     template<>
702     inline bool isInteger(GmpInt) { return true; }
703
704     template<>
705     inline long makeLongInteger(GmpInt value)
706     {
707         return (long) value.toInt();
708     }
709 #endif
710
711     template<typename Value_t>
712     inline bool isOddInteger(Value_t value)
713     {
714         const Value_t halfValue = (value + Value_t(1)) * Value_t(0.5);
715         return fp_equal(halfValue, fp_floor(halfValue));
716     }
717
718 #ifdef FP_SUPPORT_LONG_INT_TYPE
719     template<>
720     inline bool isOddInteger(long value)
721     {
722         return value%2 != 0;
723     }
724 #endif
725
726 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
727     template<>
728     inline bool isOddInteger(MpfrFloat value)
729     {
730         return value.isInteger() && value%2 != 0;
731     }
732 #endif
733
734 #ifdef FP_SUPPORT_GMP_INT_TYPE
735     template<>
736     inline bool isOddInteger(GmpInt value)
737     {
738         return value%2 != 0;
739     }
740 #endif
741 } // namespace FUNCTIONPARSERTYPES
742
743 #endif // ONCE_FPARSER_H_
744
745
746 #ifndef FP_DISABLE_DOUBLE_TYPE
747 # define FUNCTIONPARSER_INSTANTIATE_D(g) g(double)
748 #else
749 # define FUNCTIONPARSER_INSTANTIATE_D(g)
750 #endif
751
752 #ifdef FP_SUPPORT_FLOAT_TYPE
753 # define FUNCTIONPARSER_INSTANTIATE_F(g) g(float)
754 #else
755 # define FUNCTIONPARSER_INSTANTIATE_F(g)
756 #endif
757
758 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
759 # define FUNCTIONPARSER_INSTANTIATE_LD(g) g(long double)
760 #else
761 # define FUNCTIONPARSER_INSTANTIATE_LD(g)
762 #endif
763
764 #ifdef FP_SUPPORT_LONG_INT_TYPE
765 # define FUNCTIONPARSER_INSTANTIATE_LI(g) g(long)
766 #else
767 # define FUNCTIONPARSER_INSTANTIATE_LI(g)
768 #endif
769
770 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
771 # define FUNCTIONPARSER_INSTANTIATE_MF(g) g(MpfrFloat)
772 #else
773 # define FUNCTIONPARSER_INSTANTIATE_MF(g)
774 #endif
775
776 #ifdef FP_SUPPORT_GMP_INT_TYPE
777 # define FUNCTIONPARSER_INSTANTIATE_GI(g) g(GmpInt)
778 #else
779 # define FUNCTIONPARSER_INSTANTIATE_GI(g)
780 #endif
781
782 /* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cc files
783    containing FunctionParserBase implementations.
784  */
785 #define FUNCTIONPARSER_INSTANTIATE_BASE(type) \
786     template class FunctionParserBase<type>;
787
788 #define FUNCTIONPARSER_INSTANTIATE_TYPES \
789     FUNCTIONPARSER_INSTANTIATE_D(FUNCTIONPARSER_INSTANTIATE_BASE) \
790     FUNCTIONPARSER_INSTANTIATE_F(FUNCTIONPARSER_INSTANTIATE_BASE) \
791     FUNCTIONPARSER_INSTANTIATE_LD(FUNCTIONPARSER_INSTANTIATE_BASE) \
792     FUNCTIONPARSER_INSTANTIATE_LI(FUNCTIONPARSER_INSTANTIATE_BASE) \
793     FUNCTIONPARSER_INSTANTIATE_MF(FUNCTIONPARSER_INSTANTIATE_BASE) \
794     FUNCTIONPARSER_INSTANTIATE_GI(FUNCTIONPARSER_INSTANTIATE_BASE)
795
796 #endif // ONCE_FPARSER_AUX_H_