1 /***************************************************************************\
2 |* Function Parser for C++ v4.3 *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma *|
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 \***************************************************************************/
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"
16 #ifndef ONCE_FPARSER_AUX_H_
17 #define ONCE_FPARSER_AUX_H_
24 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
25 #include "mpfr/MpfrFloat.hh"
28 #ifdef FP_SUPPORT_GMP_INT_TYPE
29 #include "mpfr/GmpInt.hh"
32 #ifdef ONCE_FPARSER_H_
33 namespace FUNCTIONPARSERTYPES
35 template<typename value_t>
38 enum { result = false };
41 struct IsIntType<long>
43 enum { result = true };
45 #ifdef FP_SUPPORT_GMP_INT_TYPE
47 struct IsIntType<GmpInt>
49 enum { result = true };
53 //==========================================================================
55 //==========================================================================
56 template<typename ValueT>
57 ValueT fp_pow(const ValueT& x, const ValueT& y);
59 template<typename Value_t>
60 inline void fp_sinCos(Value_t& sin, Value_t& cos, const Value_t& a)
62 // Assuming that "cos" and "a" don't overlap, but "sin" and "a" may.
67 template<typename Value_t>
68 inline Value_t fp_hypot(Value_t x, Value_t y) { return fp_sqrt(x*x + y*y); }
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); }
81 template<typename Value_t>
82 inline Value_t fp_const_pi() // CONSTANT_PI
84 return Value_t(3.1415926535897932384626433832795028841971693993751L);
87 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
89 inline MpfrFloat fp_const_pi<MpfrFloat>() { return MpfrFloat::const_pi(); }
92 template<typename Value_t>
93 inline Value_t fp_const_e() // CONSTANT_E
95 return Value_t(2.7182818284590452353602874713526624977572L);
97 template<typename Value_t>
98 inline Value_t fp_const_einv() // CONSTANT_EI
100 return Value_t(0.367879441171442321595523770161460867445811131L);
102 template<typename Value_t>
103 inline Value_t fp_const_log2() // CONSTANT_L2, CONSTANT_L2EI
105 return Value_t(0.69314718055994530941723212145817656807550013436025525412L);
107 template<typename Value_t>
108 inline Value_t fp_const_log10() // CONSTANT_L10, CONSTANT_L10EI
110 return Value_t(2.302585092994045684017991454684364207601101488628772976L);
112 template<typename Value_t>
113 inline Value_t fp_const_log2inv() // CONSTANT_L2I, CONSTANT_L2E
115 return Value_t(1.442695040888963407359924681001892137426645954L);
117 template<typename Value_t>
118 inline Value_t fp_const_log10inv() // CONSTANT_L10I, CONSTANT_L10E
120 return Value_t(0.434294481903251827651128918916605082294397L);
123 template<typename Value_t>
124 inline const Value_t& fp_const_deg_to_rad() // CONSTANT_DR
126 static const Value_t factor = fp_const_pi<Value_t>() / Value_t(180); // to rad from deg
130 template<typename Value_t>
131 inline const Value_t& fp_const_rad_to_deg() // CONSTANT_RD
133 static const Value_t factor = Value_t(180) / fp_const_pi<Value_t>(); // to deg from rad
137 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
139 inline MpfrFloat fp_const_e<MpfrFloat>() { return MpfrFloat::const_e(); }
142 inline MpfrFloat fp_const_einv<MpfrFloat>() { return MpfrFloat(1) / MpfrFloat::const_e(); }
145 inline MpfrFloat fp_const_log2<MpfrFloat>() { return MpfrFloat::const_log2(); }
149 inline MpfrFloat fp_const_log10<MpfrFloat>() { return fp_log(MpfrFloat(10)); }
152 inline MpfrFloat fp_const_log2inv<MpfrFloat>() { return MpfrFloat(1) / MpfrFloat::const_log2(); }
155 inline MpfrFloat fp_const_log10inv<MpfrFloat>() { return fp_log10(MpfrFloat::const_e()); }
160 // -------------------------------------------------------------------------
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); }
171 inline double fp_cbrt(double x) { return x>0 ? exp(log( x)/3.0)
172 : x<0 ? -exp(log(-x)/3.0)
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)
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); }
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); }
201 inline double fp_trunc(double x) { return x<0.0 ? ceil(x) : floor(x); }
203 inline double fp_pow_base(double x, double y) { return pow(x, y); }
205 #ifndef FP_SUPPORT_LOG2
206 inline double fp_log2(double x)
207 { return log(x) * 1.4426950408889634073599246810018921374266459541529859; }
209 inline double fp_log2(double x) { return log2(x); }
210 #endif // FP_SUPPORT_LOG2
212 inline double fp_exp2(double x) { return fp_pow(2.0, x); }
215 template<typename Value_t>
216 inline Value_t fp_epsilon() { return FP_EPSILON; }
218 template<typename Value_t>
219 inline Value_t fp_epsilon() { return 0.0; }
224 inline void fp_sinCos<double>(double& sin, double& cos, const double& a)
226 sincos(a, &sin, &cos);
230 // -------------------------------------------------------------------------
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); }
242 inline float fp_cbrt(float x) { return x>0 ? expf(logf( x)/3.0f)
243 : x<0 ? -expf(logf(-x)/3.0f)
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)
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); }
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); }
272 inline float fp_trunc(float x) { return x<0.0F ? ceilf(x) : floorf(x); }
274 inline float fp_pow_base(float x, float y) { return powf(x, y); }
276 #ifndef FP_SUPPORT_LOG2
277 inline float fp_log2(float x)
279 1.4426950408889634073599246810018921374266459541529859F; }
281 inline float fp_log2(float x) { return log2f(x); }
282 #endif // FP_SUPPORT_LOG2
284 inline float fp_exp2(float x) { return fp_pow(2.0F, x); }
288 inline float fp_epsilon<float>() { return 1e-6F; }
291 inline float fp_epsilon<float>() { return 0.0F; }
294 #endif // FP_SUPPORT_FLOAT_TYPE
297 inline void fp_sinCos<float>(float& sin, float& cos, const float& a)
299 sincosf(a, &sin, &cos);
305 // -------------------------------------------------------------------------
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); }
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)
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)
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); }
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); }
350 inline long double fp_trunc(long double x)
351 { return x<0.0L ? ceill(x) : floorl(x); }
353 inline long double fp_pow_base(long double x, long double y)
354 { return powl(x, y); }
356 #ifndef FP_SUPPORT_LOG2
357 inline long double fp_log2(long double x)
358 { return fp_log(x) * 1.4426950408889634073599246810018921374266459541529859L; }
360 inline long double fp_log2(long double x) { return log2l(x); }
361 #endif // FP_SUPPORT_LOG2
363 inline long double fp_exp2(long double x) { return fp_pow(2.0L, x); }
365 #endif // FP_SUPPORT_LONG_DOUBLE_TYPE
369 inline void fp_sinCos<long double>(long double& sin, long double& cos, const long double& a)
371 sincosl(a, &sin, &cos);
376 // -------------------------------------------------------------------------
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; }
409 inline long fp_epsilon<long>() { return 0; }
412 // -------------------------------------------------------------------------
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); }
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); }
447 inline MpfrFloat fp_log2(const MpfrFloat& x) { return MpfrFloat::log2(x); }
448 inline MpfrFloat fp_exp2(const MpfrFloat& x) { return MpfrFloat::exp2(x); }
451 inline void fp_sinCos<MpfrFloat>(MpfrFloat& sin, MpfrFloat& cos, const MpfrFloat& a)
453 MpfrFloat::sincos(a, sin, cos);
457 inline MpfrFloat fp_epsilon<MpfrFloat>() { return MpfrFloat::someEpsilon(); }
458 #endif // FP_SUPPORT_MPFR_FLOAT_TYPE
461 // -------------------------------------------------------------------------
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; }
496 inline GmpInt fp_epsilon<GmpInt>() { return 0; }
497 #endif // FP_SUPPORT_GMP_INT_TYPE
500 // -------------------------------------------------------------------------
502 // -------------------------------------------------------------------------
504 template<typename Value_t>
505 inline bool fp_equal(const Value_t& x, const Value_t& y)
506 { return IsIntType<Value_t>::result
508 : (fp_abs(x - y) <= fp_epsilon<Value_t>()); }
510 template<typename Value_t>
511 inline bool fp_nequal(const Value_t& x, const Value_t& y)
512 { return IsIntType<Value_t>::result
514 : (fp_abs(x - y) > fp_epsilon<Value_t>()); }
516 template<typename Value_t>
517 inline bool fp_less(const Value_t& x, const Value_t& y)
518 { return IsIntType<Value_t>::result
520 : (x < y - fp_epsilon<Value_t>()); }
522 template<typename Value_t>
523 inline bool fp_lessOrEq(const Value_t& x, const Value_t& y)
524 { return IsIntType<Value_t>::result
526 : (x <= y + fp_epsilon<Value_t>()); }
528 template<typename Value_t>
529 inline bool fp_equal(const Value_t& x, const Value_t& y) { return x == y; }
531 template<typename Value_t>
532 inline bool fp_nequal(const Value_t& x, const Value_t& y) { return x != y; }
534 template<typename Value_t>
535 inline bool fp_less(const Value_t& x, const Value_t& y) { return x < y; }
537 template<typename Value_t>
538 inline bool fp_lessOrEq(const Value_t& x, const Value_t& y) { return x <= y; }
541 template<typename Value_t>
542 inline bool fp_greater(const Value_t& x, const Value_t& y)
543 { return fp_less(y, x); }
545 template<typename Value_t>
546 inline bool fp_greaterOrEq(const Value_t& x, const Value_t& y)
547 { return fp_lessOrEq(y, x); }
549 template<typename Value_t>
550 inline bool fp_truth(const Value_t& d)
552 return IsIntType<Value_t>::result
554 : fp_abs(d) >= Value_t(0.5);
557 template<typename Value_t>
558 inline bool fp_absTruth(const Value_t& abs_d)
560 return IsIntType<Value_t>::result
562 : abs_d >= Value_t(0.5);
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; }
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; }
573 template<typename Value_t>
574 inline const Value_t fp_not(const Value_t& b)
575 { return Value_t(!fp_truth(b)); }
577 template<typename Value_t>
578 inline const Value_t fp_notNot(const Value_t& b)
579 { return Value_t(fp_truth(b)); }
581 template<typename Value_t>
582 inline const Value_t fp_absNot(const Value_t& b)
583 { return Value_t(!fp_absTruth(b)); }
585 template<typename Value_t>
586 inline const Value_t fp_absNotNot(const Value_t& b)
587 { return Value_t(fp_absTruth(b)); }
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)); }
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)); }
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)); }
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)); }
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
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);
619 template<typename Value_t>
620 inline Value_t DegreesToRadians(Value_t degrees)
622 return degrees * fp_const_deg_to_rad<Value_t>();
625 template<typename Value_t>
626 inline Value_t RadiansToDegrees(Value_t radians)
628 return radians * fp_const_rad_to_deg<Value_t>();
631 template<typename Value_t>
632 inline bool isEvenInteger(Value_t value)
634 const Value_t halfValue = value * Value_t(0.5);
635 return fp_equal(halfValue, fp_floor(halfValue));
638 template<typename Value_t>
639 inline bool isInteger(Value_t value)
641 return fp_equal(value, fp_floor(value));
644 // Is value an integer that fits in "long" datatype?
645 template<typename Value_t>
646 inline bool isLongInteger(Value_t value)
648 return value == Value_t( makeLongInteger(value) );
651 template<typename Value_t>
652 inline long makeLongInteger(Value_t value)
654 return (long) fp_int(value);
657 #ifdef FP_SUPPORT_LONG_INT_TYPE
659 inline bool isEvenInteger(long value)
665 inline bool isInteger(long) { return true; }
668 inline bool isLongInteger(long) { return true; }
671 inline long makeLongInteger(long value)
677 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
679 inline bool isInteger(MpfrFloat value) { return value.isInteger(); }
682 inline bool isEvenInteger(MpfrFloat value)
684 return isInteger(value) && value%2 == 0;
688 inline long makeLongInteger(MpfrFloat value)
690 return (long) value.toInt();
694 #ifdef FP_SUPPORT_GMP_INT_TYPE
696 inline bool isEvenInteger(GmpInt value)
702 inline bool isInteger(GmpInt) { return true; }
705 inline long makeLongInteger(GmpInt value)
707 return (long) value.toInt();
711 template<typename Value_t>
712 inline bool isOddInteger(Value_t value)
714 const Value_t halfValue = (value + Value_t(1)) * Value_t(0.5);
715 return fp_equal(halfValue, fp_floor(halfValue));
718 #ifdef FP_SUPPORT_LONG_INT_TYPE
720 inline bool isOddInteger(long value)
726 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
728 inline bool isOddInteger(MpfrFloat value)
730 return value.isInteger() && value%2 != 0;
734 #ifdef FP_SUPPORT_GMP_INT_TYPE
736 inline bool isOddInteger(GmpInt value)
741 } // namespace FUNCTIONPARSERTYPES
743 #endif // ONCE_FPARSER_H_
746 #ifndef FP_DISABLE_DOUBLE_TYPE
747 # define FUNCTIONPARSER_INSTANTIATE_D(g) g(double)
749 # define FUNCTIONPARSER_INSTANTIATE_D(g)
752 #ifdef FP_SUPPORT_FLOAT_TYPE
753 # define FUNCTIONPARSER_INSTANTIATE_F(g) g(float)
755 # define FUNCTIONPARSER_INSTANTIATE_F(g)
758 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
759 # define FUNCTIONPARSER_INSTANTIATE_LD(g) g(long double)
761 # define FUNCTIONPARSER_INSTANTIATE_LD(g)
764 #ifdef FP_SUPPORT_LONG_INT_TYPE
765 # define FUNCTIONPARSER_INSTANTIATE_LI(g) g(long)
767 # define FUNCTIONPARSER_INSTANTIATE_LI(g)
770 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
771 # define FUNCTIONPARSER_INSTANTIATE_MF(g) g(MpfrFloat)
773 # define FUNCTIONPARSER_INSTANTIATE_MF(g)
776 #ifdef FP_SUPPORT_GMP_INT_TYPE
777 # define FUNCTIONPARSER_INSTANTIATE_GI(g) g(GmpInt)
779 # define FUNCTIONPARSER_INSTANTIATE_GI(g)
782 /* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cc files
783 containing FunctionParserBase implementations.
785 #define FUNCTIONPARSER_INSTANTIATE_BASE(type) \
786 template class FunctionParserBase<type>;
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)
796 #endif // ONCE_FPARSER_AUX_H_