From: <wel...@us...> - 2012-04-15 08:02:40
|
Revision: 8207 http://planeshift.svn.sourceforge.net/planeshift/?rev=8207&view=rev Author: weltall2 Date: 2012-04-15 08:02:30 +0000 (Sun, 15 Apr 2012) Log Message: ----------- updated fparser to 4.5 - Removed support for the "eval()" function from the supported syntax. (This function was too dangerous, too difficult to maintain internally, not very useful, and more or less a gimmick in the first place.) - Removed several of the conditional compiling macro definitions, namely FP_SUPPORT_TR1_MATH, FP_ENABLE_EVAL, FP_EVAL_MAX_REC_LEVEL, FP_NO_EVALUATION_CHECKS and FP_EPSILON. - The epsilon value used in comparisons is now set with a member function of FunctionParser (which allows setting different values for different versions of the parser). - The math functions previously turned on with FP_SUPPORT_TR1_MATH are now automatically used if __cplusplus indicates that C++11 is in use. - Fixed some compilation problems with clang++. Modified Paths: -------------- trunk/src/tools/fparser/additions/GmpInt.cpp trunk/src/tools/fparser/additions/MpfrFloat.cpp trunk/src/tools/fparser/docs/fparser.html trunk/src/tools/fparser/extrasrc/fp_identifier_parser.inc trunk/src/tools/fparser/extrasrc/fp_opcode_add.inc trunk/src/tools/fparser/extrasrc/fpaux.h trunk/src/tools/fparser/extrasrc/fptypes.h trunk/src/tools/fparser/fparser.cpp trunk/src/tools/fparser/fparser.h trunk/src/tools/fparser/fparser_gmpint.h trunk/src/tools/fparser/fparser_mpfr.h trunk/src/tools/fparser/fpconfig.h trunk/src/tools/fparser/fpoptimizer.cpp Modified: trunk/src/tools/fparser/additions/GmpInt.cpp =================================================================== --- trunk/src/tools/fparser/additions/GmpInt.cpp 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/additions/GmpInt.cpp 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,4 +1,4 @@ -#include "GmpInt.h" +#include "GmpInt.hh" #include <gmp.h> #include <deque> #include <vector> Modified: trunk/src/tools/fparser/additions/MpfrFloat.cpp =================================================================== --- trunk/src/tools/fparser/additions/MpfrFloat.cpp 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/additions/MpfrFloat.cpp 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,4 +1,4 @@ -#include "MpfrFloat.h" +#include "MpfrFloat.hh" #include <stdio.h> #include <mpfr.h> #include <deque> Modified: trunk/src/tools/fparser/docs/fparser.html =================================================================== --- trunk/src/tools/fparser/docs/fparser.html 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/docs/fparser.html 2012-04-15 08:02:30 UTC (rev 8207) @@ -3,11 +3,11 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <link href="style.css" rel="stylesheet" type="text/css" title="normal" media=screen> - <title>Function Parser for C++ v4.4.3 : Documentation</title> + <title>Function Parser for C++ v4.5 : Documentation</title> </head> <body> -<h1>Function Parser for C++ v4.4.3 </h1> +<h1>Function Parser for C++ v4.5 </h1> <p>Authors: Juha Nieminen (<a href="http://iki.fi/warp/">http://iki.fi/warp/</a>), @@ -70,48 +70,27 @@ <a name="whatsnew"></a> <h2>What's new</h2> -<p>What's new in v4.4.3 +<p>What's new in v4.5 <ul> - <li>Added support for user-specialized function pointer objects for - user-defined functions (besides the existing support for raw C++ - function pointers). See documentation for details. + <li>Removed support for the <code>"eval()"</code> function from the + supported syntax. (This function was too dangerous, too difficult to + maintain internally, not very useful, and more or less a gimmick in + the first place.) + <li>Removed several of the conditional compiling macro definitions, namely + <code>FP_SUPPORT_TR1_MATH</code>, <code>FP_ENABLE_EVAL</code>, + <code>FP_EVAL_MAX_REC_LEVEL</code>, <code>FP_NO_EVALUATION_CHECKS</code> + and <code>FP_EPSILON</code>. + <li>The epsilon value used in comparisons is now set with a member function + of FunctionParser (which allows setting different values for different + versions of the parser). + <li>The math functions previously turned on with + <code>FP_SUPPORT_TR1_MATH</code> are now automatically used if + <code>__cplusplus</code> indicates that C++11 is in use. + <li>Fixed some compilation problems with clang++. </ul> -<p>What's new in v4.4.2 - <ul> - <li>Complex-only internal functions were being not properly disabled in the - non-complex versions of the parser, causing mayhem if they were called - from those. - </ul> -<p>What's new in v4.4.1 - <ul> - <li>Added missing documentation on complex literals. - <li>Fixed problem when using <code>std::complex</code> with TR1 math - functions enabled. (TR1 does not define any new math functions for - <code>std::complex</code> even though C++0x does. When attempting to - use them, the implementation of TR1 in the current gcc misbehaves - instead of giving a compiler error. This has now been replaced with - the equivalent formulas using standard math functions.) - <li>Fixed some compilation issues in the development version of the - library (which happened with certain combinations of disabled parsers - and compiler settings). - </ul> -<p>What's new in v4.4 - <ul> - <li>Added support for <code>std::complex</code> (of type - <code>double</code>, <code>float</code> and <code>long double</code>) - as the numerical type, along with new complex-specific functions. - <li>Removed all dependencies on C99 functions, making the non-double - versions of the library usable with older compilers (such as Visual - Studio 2005). (But consult the documentation on the <code>long - double</code> literal parsing accuracy.) - <li>Several minor bugfixes. - <li>Fixed some compilation issues with gcc 4.6. - </ul> - - <!-- -------------------------------------------------------------------- --> <a name="preface"></a> <h2>Preface</h2> @@ -342,35 +321,10 @@ literals will be parsed with double precision only, which in most systems is less accurate than long double precision, which will cause small rounding errors. (This setting has no effect on the other parser - types.) + types.) Note that <code>strtold()</code> will also be automatically used + if <code>__cplusplus</code> indicates that C++11 is in use. </dd> - <dt><p><code>FP_SUPPORT_TR1_MATH_FUNCS</code> : (Default off)</dt> - <dd><p>Define this precompiler constant to make the library use additional - math functions defined in the C99 standard and the C++ TR1 standard - proposal (but not yet in the official C++ standard). This can make - evaluation faster when these functions are involved. - <p>The C++ TR1 math functions in question are: <code>asinh()</code>, - <code>acosh()</code>, <code>atanh()</code>, <code>exp2()</code> and - <code>log2()</code>. (Note that these functions are assumed to be - inside the <code>std::tr1</code> namespace and declared in the - <code><tr1/cmath></code> header.) - </dd> - - <dt><p><code>FP_ENABLE_EVAL</code> : (Default off)</dt> - <dd><p>Even though the maximum recursion level of the <code>eval()</code> - function is limited, it is still possible to write functions which never - reach this maximum recursion level but take enormous amounts of - time to evaluate (this can be undesirable eg. in web server-side - applications). For this reason this function is disabled by default. - You can add support for the <code>eval()</code> function by - defining this precompiler constant. - </dd> - - <dt><p><code>FP_EVAL_MAX_REC_LEVEL</code> : (Default 1000)</dt> - <dd><p>Sets the maximum recursion level allowed for <code>eval()</code>. - </dd> - <dt><p><code>FP_SUPPORT_OPTIMIZER</code> : (Default on)</dt> <dd><p>If you are not going to use the <code>Optimize()</code> method, you can comment this line out to speed-up the compilation a bit, as @@ -382,11 +336,6 @@ compiler settings. </dd> - <dt><p><code>FP_EPSILON</code> : (Default <code>1e-14</code>)</dt> - <dd><p>Epsilon value used in comparison operators. - If this line is commented out, then no epsilon will be used. - </dd> - <dt><p><code>FP_USE_THREAD_SAFE_EVAL</code> : (Default off)</dt> <dd><p>Define this precompiler constant to make <code>Eval()</code> thread-safe. Refer to the <a href="#threadsafety">thread safety @@ -402,13 +351,6 @@ This will make it faster, but the <code>alloca()</code> function is not standard and thus not supported by all compilers. </dd> - - <dt><p><code>FP_NO_EVALUATION_CHECKS</code> : (Default off)</dt> - <dd><p>If this precompiler constant is defined, no evaluation-time checks - will be performed. This may give a slight boost in speed in certain - situations. Consult the <a href="#evaluationchecks">evaluation - checks section</a> below for more information on this subject. - </dd> </dl> @@ -460,6 +402,14 @@ <hr> <pre> +static double epsilon(); +static void setEpsilon(double); +</pre> + +<p>Setter and getter for the epsilon value used with comparison operators. + +<hr> +<pre> const char* ErrorMsg(void) const; </pre> @@ -678,6 +628,27 @@ <hr> +<a name="longdesc_Epsilon"></a> +<pre> +static double epsilon(); +static void setEpsilon(double); +</pre> + +<p>Comparison operators (for the non-integral versions of the parser) use an +epsilon value to account for floating point calculation rounding errors. +This epsilon value can be set and read with these functions. (Note that the +specified value will be used by all instances of FunctionParser.) If not +specified, the default values are: + +<ul> + <li>double: 1e-12 + <li>float: 1e-5 + <li>long double: 1e-14 + <li>MpfrFloat: The value of MpfrFloat::someEpsilon() +</ul> + + +<hr> <a name="longdesc_ErrorMsg"></a> <pre> const char* ErrorMsg(void) const; @@ -1665,7 +1636,7 @@ <a name="evaluationchecks"></a> <h3>About evaluation-time checks</h3> -<p>By default <code>FunctionParser::Eval()</code> will perform certain sanity +<p><code>FunctionParser::Eval()</code> will perform certain sanity checks before performing certain operations. For example, before calling the <code>sqrt</code> function, it will check if the parameter is negative, and if so, it will set the proper error code instead of calling the function. @@ -1702,12 +1673,6 @@ architecture and/or when using certain compiler settings, this library cannot guarantee that it will never happen. -<p>Since not all error situations can be caught, and since the sanity checks -only slow down the evaluation (although only very slightly), the precompiler -constant <code>FP_NO_EVALUATION_CHECKS</code> can be used to turn all the -checks off. This might make the evaluation slightly faster in certain -situations. - <p>Note that the optimizer never performs any sanity checks. Modified: trunk/src/tools/fparser/extrasrc/fp_identifier_parser.inc =================================================================== --- trunk/src/tools/fparser/extrasrc/fp_identifier_parser.inc 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/extrasrc/fp_identifier_parser.inc 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,7 +1,7 @@ /* NOTE: - Do not include this file in your project. The fparser.cc file #includes + Do not include this file in your project. The fparser.cpp file #includes this file internally and thus you don't need to do anything (other than keep -this file in the same directory as fparser.cc). +this file in the same directory as fparser.cpp). Part of this file is generated code (by using the make_function_name_parser utility, found in the development version of this library). It's not intended @@ -134,162 +134,156 @@ break; } - /* This function generated with make_function_name_parser.cc */ -#define lO l1 lE -#define lN l4 lE -#define lM if('i'l5 -#define lL 'n'l5 -#define lK l2 3]={ + /* This function generated with make_function_name_parser.cpp */ +#define lO l3 lH +#define lN switch( +#define lM l4 lH +#define lL if('i'l5 +#define lK 'n'l5 #define lJ 0x80000003U; -#define lI )==0)l0( -#define lH l3 3 lI +#define lI l1 3]={ +#define lH case #define lG 0x80000005U; -#define lF :l9 uptr[ -#define lE case -#define lD l8 3;}lE -#define lC std::memcmp(uptr+ -#define lB lF 1]){lE -#define lA 'a'lB -#define l9 switch( +#define lF )==0)l0( +#define lE l8 3;}lH +#define lD std::memcmp(uptr+ +#define lC l2 3 lF +#define lB lA 1]){lH +#define lA :lN uptr[ +#define l9 'a'lB #define l8 default:l0 -#define l7 lG l0 5;}lE +#define l7 lG l0 5;}lH #define l6 <<16)| #define l5 ==uptr[ #define l4 lJ l0 3; -#define l3 lC 1,tmp, -#define l2 static const char tmp[ -#define l1 0x80000004U;l0 4; +#define l3 0x80000004U;l0 4; +#define l2 lD 1,tmp, +#define l1 static const char tmp[ #define l0 return -l9 -nameLength){lE -2:lM +lN +nameLength){lH +2:lL 0]&&'f'l5 1])l0(cIf l6 0x80000002U;l0 -2;lE +2;lH 3 -lF -0]){lE -lA'b':if('s'l5 +lA +0]){lH +l9'b':if('s'l5 2])l0(cAbs l6 -lN'r':if('g'l5 +lM'r':if('g'l5 2])l0(cArg l6 l4 -lD'c'lB'o'lF -2]){lE's':l0(cCos +lE'c'lB'o'lA +2]){lH's':l0(cCos l6 lJ -lE't':l0(cCot +lH't':l0(cCot l6 lJ -lD's':if('c'l5 +lE's':if('c'l5 2])l0(cCsc l6 l4 -lD'e':if('x'l5 +lE'e':if('x'l5 1]&&'p'l5 2])l0(cExp l6 -lN'i':if(lL +lM'i':if(lK 1]&&'t'l5 2])l0(cInt l6 -lN'l':if('o'l5 +lM'l':if('o'l5 1]&&'g'l5 2])l0(cLog l6 -lN'm'lB'a':if('x'l5 +lM'm'lB'a':if('x'l5 2])l0(cMax l6 -lN'i':if(lL +lM'i':if(lK 2])l0(cMin l6 l4 -lD'p':if('o'l5 +lE'p':if('o'l5 1]&&'w'l5 2])l0(cPow l6 -lN's'lB'e':if('c'l5 +lM's'lB'e':if('c'l5 2])l0(cSec l6 -lN'i':if(lL +lM'i':if(lK 2])l0(cSin l6 l4 -lD't':if('a'l5 -1]&&lL +lE't':if('a'l5 +1]&&lK 2])l0(cTan l6 l4 -lD +lE 4 -lF -0]){lE -lA'c':if('o'l5 +lA +0]){lH +l9'c':if('o'l5 2]&&'s'l5 3])l0(cAcos l6 -lO's':lM -2]&&lL +lO's':lL +2]&&lK 3])l0(cAsin l6 lO't':if('a'l5 -2]&&lL +2]&&lK 3])l0(cAtan l6 -l1 +l3 l8 4;} -lE'c'lB'b':if('r'l5 +lH'c'lB'b':if('r'l5 2]&&'t'l5 3])l0(cCbrt l6 -lO'e':lM +lO'e':lL 2]&&'l'l5 3])l0(cCeil l6 -lO'o'lF -2]){lE'n':if('j'l5 +lO'o'lA +2]){lH'n':if('j'l5 3])l0(cConj l6 lO's':if('h'l5 3])l0(cCosh l6 -l1 +l3 l8 4;} l8 4;} -lE'e'lB'v':if('a'l5 -2]&&'l'l5 -3])l0(cEval +lH'e':{lI'x','p','2'} +;if(lC +cExp2 l6 -lO'x':if('p'l5 -2]&&'2'l5 -3])l0(cExp2 -l6 -l1 -l8 -4;} -lE'i':{lK'm','a','g'} -;if(lH +l3} +lH'i':{lI'm','a','g'} +;if(lC cImag l6 -l1} -lE'l':{lK'o','g','2'} -;if(lH +l3} +lH'l':{lI'o','g','2'} +;if(lC cLog2 l6 -l1} -lE'r':{lK'e','a','l'} -;if(lH +l3} +lH'r':{lI'e','a','l'} +;if(lC cReal l6 -l1} -lE's'lB'i':if(lL +l3} +lH's'lB'i':if(lK 2]&&'h'l5 3])l0(cSinh l6 @@ -297,39 +291,39 @@ 2]&&'t'l5 3])l0(cSqrt l6 -l1 +l3 l8 4;} -lE't':{lK'a','n','h'} -;if(lH +lH't':{lI'a','n','h'} +;if(lC cTanh l6 -l1} +l3} l8 4;} -lE +lH 5 -lF -0]){lE -lA'c':{lK'o','s','h'} -;if(lC +lA +0]){lH +l9'c':{lI'o','s','h'} +;if(lD 2,tmp,3 -lI +lF cAcosh l6 -l7's':{lK'i','n','h'} -;if(lC +l7's':{lI'i','n','h'} +;if(lD 2,tmp,3 -lI +lF cAsinh l6 l7't':if('a'l5 -2]){if(lL -3]){l9 -uptr[4]){lE'2':l0(cAtan2 +2]){if(lK +3]){lN +uptr[4]){lH'2':l0(cAtan2 l6 lG -lE'h':l0(cAtanh +lH'h':l0(cAtanh l6 lG l8 @@ -340,39 +334,39 @@ l0 5;l8 5;} -lE'f':{l2 +lH'f':{l1 4]={'l','o','o','r'} -;if(l3 +;if(l2 4 -lI +lF cFloor l6 -l7'h':{l2 +l7'h':{l1 4]={'y','p','o','t'} -;if(l3 +;if(l2 4 -lI +lF cHypot l6 -l7'l':{l2 +l7'l':{l1 4]={'o','g','1','0'} -;if(l3 +;if(l2 4 -lI +lF cLog10 l6 -l7'p':{l2 +l7'p':{l1 4]={'o','l','a','r'} -;if(l3 +;if(l2 4 -lI +lF cPolar l6 -l7't':{l2 +l7't':{l1 4]={'r','u','n','c'} -;if(l3 +;if(l2 4 -lI +lF cTrunc l6 lG @@ -382,4 +376,4 @@ 5;} default:break;} l0 -nameLength; \ No newline at end of file +nameLength; Modified: trunk/src/tools/fparser/extrasrc/fp_opcode_add.inc =================================================================== --- trunk/src/tools/fparser/extrasrc/fp_opcode_add.inc 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/extrasrc/fp_opcode_add.inc 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,9 +1,9 @@ -/* Function Parser for C++ v4.4.3 +/* Function Parser for C++ v4.5 NOTE: - Do not include this file in your project. The fparser.cc file #includes + Do not include this file in your project. The fparser.cpp file #includes this file internally and thus you don't need to do anything (other than keep -this file in the same directory as fparser.cc). +this file in the same directory as fparser.cpp). This file contains generated code and is thus not intended to be to be modified by hand. It was generated by util/bytecoderules_parser, which Modified: trunk/src/tools/fparser/extrasrc/fpaux.h =================================================================== --- trunk/src/tools/fparser/extrasrc/fpaux.h 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/extrasrc/fpaux.h 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen, Joel Yliluoma *| |* *| @@ -19,9 +19,6 @@ #include "fptypes.h" #include <cmath> -#ifdef FP_SUPPORT_TR1_MATH_FUNCS -#include <tr1/cmath> -#endif #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE #include "mpfr/MpfrFloat.h" @@ -69,55 +66,7 @@ }; #endif - // Commented versions in fparser.cc - template<typename Value_t> - inline Value_t fp_pow_with_exp_log(const Value_t& x, const Value_t& y) - { - return fp_exp(fp_log(x) * y); - } - template<typename Value_t> - inline Value_t fp_powi(Value_t x, unsigned long y) - { - Value_t result(1); - while(y != 0) - { - if(y & 1) { result *= x; y -= 1; } - else { x *= x; y /= 2; } - } - return result; - } - - template<typename Value_t> - Value_t fp_pow(const Value_t& x, const Value_t& y) - { - if(x == Value_t(1)) return Value_t(1); - if(isLongInteger(y)) - { - if(y >= Value_t(0)) - return fp_powi(x, makeLongInteger(y)); - else - return Value_t(1) / fp_powi(x, -makeLongInteger(y)); - } - if(y >= Value_t(0)) - { - if(x > Value_t(0)) return fp_pow_with_exp_log(x, y); - if(x == Value_t(0)) return Value_t(0); - if(!isInteger(y*Value_t(16))) - return -fp_pow_with_exp_log(-x, y); - } - else - { - if(x > Value_t(0)) return fp_pow_with_exp_log(Value_t(1) / x, -y); - if(x < Value_t(0)) - { - if(!isInteger(y*Value_t(-16))) - return -fp_pow_with_exp_log(Value_t(-1) / x, -y); - } - } - return fp_pow_base(x, y); - } - //========================================================================== // Constants //========================================================================== @@ -217,20 +166,7 @@ inline Value_t fp_atan2(const Value_t& x, const Value_t& y) { return std::atan2(x, y); } -#ifdef FP_SUPPORT_CBRT template<typename Value_t> - inline Value_t fp_cbrt(const Value_t& x) { return std::tr1::cbrt(x); } -#else - template<typename Value_t> - inline Value_t fp_cbrt(const Value_t& x) - { - return (x > Value_t() ? fp_exp(fp_log( x) / Value_t(3)) : - x < Value_t() ? -fp_exp(fp_log(-x) / Value_t(3)) : - Value_t()); - } -#endif - - template<typename Value_t> inline Value_t fp_ceil(const Value_t& x) { return std::ceil(x); } template<typename Value_t> @@ -267,15 +203,15 @@ template<typename Value_t> inline Value_t fp_tanh(const Value_t& x) { return std::tanh(x); } -#ifdef FP_SUPPORT_ASINH +#if __cplusplus > 201100 template<typename Value_t> - inline Value_t fp_asinh(const Value_t& x) { return std::tr1::asinh(x); } + inline Value_t fp_asinh(const Value_t& x) { return std::asinh(x); } template<typename Value_t> - inline Value_t fp_acosh(const Value_t& x) { return std::tr1::acosh(x); } + inline Value_t fp_acosh(const Value_t& x) { return std::acosh(x); } template<typename Value_t> - inline Value_t fp_atanh(const Value_t& x) { return std::tr1::atanh(x); } + inline Value_t fp_atanh(const Value_t& x) { return std::atanh(x); } #else template<typename Value_t> inline Value_t fp_asinh(const Value_t& x) @@ -295,10 +231,10 @@ } #endif // FP_SUPPORT_ASINH -#ifdef FP_SUPPORT_HYPOT +#if __cplusplus > 201100 template<typename Value_t> inline Value_t fp_hypot(const Value_t& x, const Value_t& y) - { return std::tr1::hypot(x,y); } + { return std::hypot(x,y); } #else template<typename Value_t> inline Value_t fp_hypot(const Value_t& x, const Value_t& y) @@ -309,9 +245,9 @@ inline Value_t fp_pow_base(const Value_t& x, const Value_t& y) { return std::pow(x, y); } -#ifdef FP_SUPPORT_LOG2 +#if __cplusplus > 201100 template<typename Value_t> - inline Value_t fp_log2(const Value_t& x) { return std::tr1::log2(x); } + inline Value_t fp_log2(const Value_t& x) { return std::log2(x); } #else template<typename Value_t> inline Value_t fp_log2(const Value_t& x) @@ -327,12 +263,6 @@ } template<typename Value_t> - inline Value_t fp_exp2(const Value_t& x) - { - return fp_pow(Value_t(2), x); - } - - template<typename Value_t> inline Value_t fp_trunc(const Value_t& x) { return x < Value_t() ? fp_ceil(x) : fp_floor(x); @@ -364,13 +294,11 @@ coshvalue = Value_t(0.5)*(ex+emx); } -#ifdef FP_EPSILON template<typename Value_t> - inline Value_t fp_epsilon() { return Value_t(FP_EPSILON); } -#else - template<typename Value_t> - inline Value_t fp_epsilon() { return Value_t(0); } -#endif + inline Value_t fp_epsilon() + { + return FunctionParserBase<Value_t>::epsilon(); + } #ifdef _GNU_SOURCE @@ -521,6 +449,20 @@ inline GmpInt fp_epsilon<GmpInt>() { return 0; } #endif // FP_SUPPORT_GMP_INT_TYPE + +#if __cplusplus > 201100 + template<typename Value_t> + inline Value_t fp_cbrt(const Value_t& x) { return std::cbrt(x); } +#else + template<typename Value_t> + inline Value_t fp_cbrt(const Value_t& x) + { + return (x > Value_t() ? fp_exp(fp_log( x) / Value_t(3)) : + x < Value_t() ? -fp_exp(fp_log(-x) / Value_t(3)) : + Value_t()); + } +#endif + // ------------------------------------------------------------------------- // Synthetic functions and fallbacks for when an optimized // implementation or a library function is not available @@ -785,7 +727,8 @@ // const std::complex<T> exp2x=fp_exp(x+x); // return (exp2x-T(1)) / (exp2x+T(1)); } -#ifdef FP_SUPPORT_ASINH + +#if __cplusplus > 201100 template<typename T> inline std::complex<T> fp_acosh(const std::complex<T>& x) { return fp_log(x + fp_sqrt(x*x - std::complex<T>(1))); } @@ -970,7 +913,6 @@ // ------------------------------------------------------------------------- // Comparison // ------------------------------------------------------------------------- -#ifdef FP_EPSILON template<typename Value_t> inline bool fp_equal(const Value_t& x, const Value_t& y) { return IsIntType<Value_t>::result @@ -994,21 +936,9 @@ { return IsIntType<Value_t>::result ? (x <= y) : (x <= y + fp_epsilon<Value_t>()); } -#else // FP_EPSILON - template<typename Value_t> - inline bool fp_equal(const Value_t& x, const Value_t& y) { return x == y; } - template<typename Value_t> - inline bool fp_nequal(const Value_t& x, const Value_t& y) { return x != y; } template<typename Value_t> - inline bool fp_less(const Value_t& x, const Value_t& y) { return x < y; } - - template<typename Value_t> - inline bool fp_lessOrEq(const Value_t& x, const Value_t& y) { return x <= y; } -#endif // FP_EPSILON - - template<typename Value_t> inline bool fp_greater(const Value_t& x, const Value_t& y) { return fp_less(y, x); } @@ -1080,8 +1010,8 @@ ///////////// /* Opcode analysis functions are used by fp_opcode_add.inc */ - /* Moved here from fparser.cc because fp_opcode_add.inc - * is also now included by fpoptimizer.cc + /* Moved here from fparser.cpp because fp_opcode_add.inc + * is also now included by fpoptimizer.cpp */ bool IsLogicalOpcode(unsigned op); bool IsComparisonOpcode(unsigned op); @@ -1110,17 +1040,18 @@ } template<typename Value_t> - inline bool isEvenInteger(const Value_t& value) + inline long makeLongInteger(const Value_t& value) { - const Value_t halfValue = value * Value_t(0.5); - return fp_equal(halfValue, fp_floor(halfValue)); + return (long) fp_int(value); } - template<typename Value_t> - inline bool isInteger(const Value_t& value) +#ifdef FP_SUPPORT_COMPLEX_NUMBERS + template<typename T> + inline long makeLongInteger(const std::complex<T>& value) { - return fp_equal(value, fp_floor(value)); + return (long) fp_int( std::abs(value) ); } +#endif // Is value an integer that fits in "long" datatype? template<typename Value_t> @@ -1130,19 +1061,25 @@ } template<typename Value_t> - inline long makeLongInteger(const Value_t& value) + inline bool isOddInteger(const Value_t& value) { - return (long) fp_int(value); + const Value_t halfValue = (value + Value_t(1)) * Value_t(0.5); + return fp_equal(halfValue, fp_floor(halfValue)); } -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template<typename T> - inline long makeLongInteger(const std::complex<T>& value) + template<typename Value_t> + inline bool isEvenInteger(const Value_t& value) { - return (long) fp_int( std::abs(value) ); + const Value_t halfValue = value * Value_t(0.5); + return fp_equal(halfValue, fp_floor(halfValue)); } -#endif + template<typename Value_t> + inline bool isInteger(const Value_t& value) + { + return fp_equal(value, fp_floor(value)); + } + #ifdef FP_SUPPORT_LONG_INT_TYPE template<> inline bool isEvenInteger(const long& value) @@ -1197,13 +1134,6 @@ } #endif - template<typename Value_t> - inline bool isOddInteger(const Value_t& value) - { - const Value_t halfValue = (value + Value_t(1)) * Value_t(0.5); - return fp_equal(halfValue, fp_floor(halfValue)); - } - #ifdef FP_SUPPORT_LONG_INT_TYPE template<> inline bool isOddInteger(const long& value) @@ -1227,6 +1157,65 @@ return value%2 != 0; } #endif + + +// ------------------------------------------------------------------------- +// fp_pow +// ------------------------------------------------------------------------- + // Commented versions in fparser.cpp + template<typename Value_t> + inline Value_t fp_pow_with_exp_log(const Value_t& x, const Value_t& y) + { + return fp_exp(fp_log(x) * y); + } + + template<typename Value_t> + inline Value_t fp_powi(Value_t x, unsigned long y) + { + Value_t result(1); + while(y != 0) + { + if(y & 1) { result *= x; y -= 1; } + else { x *= x; y /= 2; } + } + return result; + } + + template<typename Value_t> + Value_t fp_pow(const Value_t& x, const Value_t& y) + { + if(x == Value_t(1)) return Value_t(1); + if(isLongInteger(y)) + { + if(y >= Value_t(0)) + return fp_powi(x, makeLongInteger(y)); + else + return Value_t(1) / fp_powi(x, -makeLongInteger(y)); + } + if(y >= Value_t(0)) + { + if(x > Value_t(0)) return fp_pow_with_exp_log(x, y); + if(x == Value_t(0)) return Value_t(0); + if(!isInteger(y*Value_t(16))) + return -fp_pow_with_exp_log(-x, y); + } + else + { + if(x > Value_t(0)) return fp_pow_with_exp_log(Value_t(1) / x, -y); + if(x < Value_t(0)) + { + if(!isInteger(y*Value_t(-16))) + return -fp_pow_with_exp_log(Value_t(-1) / x, -y); + } + } + return fp_pow_base(x, y); + } + + template<typename Value_t> + inline Value_t fp_exp2(const Value_t& x) + { + return fp_pow(Value_t(2), x); + } } // namespace FUNCTIONPARSERTYPES #endif // ONCE_FPARSER_H_ @@ -1286,7 +1275,7 @@ # define FUNCTIONPARSER_INSTANTIATE_CLD(cd) #endif -/* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cc files +/* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cpp files containing FunctionParserBase implementations. */ #define FUNCTIONPARSER_INSTANTIATE_BASE(type) \ Modified: trunk/src/tools/fparser/extrasrc/fptypes.h =================================================================== --- trunk/src/tools/fparser/extrasrc/fptypes.h 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/extrasrc/fptypes.h 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen, Joel Yliluoma *| |* *| @@ -37,7 +37,6 @@ cCbrt, cCeil, cConj, /* get the complex conjugate of a complex value */ cCos, cCosh, cCot, cCsc, - cEval, cExp, cExp2, cFloor, cHypot, cIf, cImag, /* get imaginary part of a complex value */ @@ -97,8 +96,7 @@ AngleIn = 0x02, AngleOut = 0x04, OkForInt = 0x08, - ComplexOnly = 0x10, - EvalOnly = 0x20 + ComplexOnly = 0x10 }; #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING @@ -111,7 +109,6 @@ inline bool okForInt() const { return (flags & OkForInt) != 0; } inline bool complexOnly() const { return (flags & ComplexOnly) != 0; } - inline bool evalOnly() const { return (flags & EvalOnly) != 0; } }; #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING @@ -140,7 +137,6 @@ /*cCosh */ { FP_FNAME("cosh"), 1, FuncDefinition::AngleIn }, /*cCot */ { FP_FNAME("cot"), 1, FuncDefinition::AngleIn }, /*cCsc */ { FP_FNAME("csc"), 1, FuncDefinition::AngleIn }, - /*cEval */ { FP_FNAME("eval"), 0, FuncDefinition::EvalOnly | FuncDefinition::OkForInt }, /*cExp */ { FP_FNAME("exp"), 1, 0 }, /*cExp2 */ { FP_FNAME("exp2"), 1, 0 }, /*cFloor*/ { FP_FNAME("floor"), 1, 0 }, @@ -228,7 +224,6 @@ int mEvalErrorType; bool mUseDegreeConversion; bool mHasByteCodeFlags; - unsigned mEvalRecursionLevel; const char* mErrorLocation; unsigned mVariablesAmount; Modified: trunk/src/tools/fparser/fparser.cpp =================================================================== --- trunk/src/tools/fparser/fparser.cpp 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/fparser.cpp 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen, Joel Yliluoma *| |* *| @@ -205,7 +205,6 @@ template<bool ComplexType> bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op) { -#ifndef FP_NO_EVALUATION_CHECKS // Returns true, if the given opcode has a range of // input values that gives an error. if(ComplexType) @@ -265,7 +264,6 @@ return true; } } -#endif return false; } @@ -424,15 +422,6 @@ if( (value & 0x80000000U) != 0) // Function? { // Verify that the function actually exists for this datatype - #ifdef FP_DISABLE_EVAL - //if(!Functions[(value >> 16) & 0x7FFF].evalOnly()) - if( value == ((cEval << 16) | 0x80000004U) ) // faster test - { - // If it's cEval, return it as an identifier instead - //return value & 0xFFFFu; - return 4; - } - #endif if(IsIntType<Value_t>::result && !Functions[(value >> 16) & 0x7FFF].okForInt()) { @@ -467,7 +456,7 @@ return std::strtod(str, endptr); } -#ifdef FP_USE_STRTOLD +#if defined(FP_USE_STRTOLD) || __cplusplus > 201100 template<> inline long double fp_parseLiteral<long double>(const char* str, char** endptr) @@ -728,7 +717,6 @@ mParseErrorType(NO_FUNCTION_PARSED_YET), mEvalErrorType(0), mUseDegreeConversion(false), - mEvalRecursionLevel(0), mErrorLocation(0), mVariablesAmount(0), mStackSize(0) @@ -741,7 +729,6 @@ mParseErrorType(rhs.mParseErrorType), mEvalErrorType(rhs.mEvalErrorType), mUseDegreeConversion(rhs.mUseDegreeConversion), - mEvalRecursionLevel(rhs.mEvalRecursionLevel), mErrorLocation(rhs.mErrorLocation), mVariablesAmount(rhs.mVariablesAmount), mVariablesString(rhs.mVariablesString), @@ -927,6 +914,45 @@ //========================================================================= +// Epsilon +//========================================================================= +template<> double FunctionParserBase<double>::sEpsilon = 1E-12; +template<> float FunctionParserBase<float>::sEpsilon = 1E-5F; +template<> long double FunctionParserBase<long double>::sEpsilon = 1E-14L; +template<> long FunctionParserBase<long>::sEpsilon = 0; + +template<> std::complex<double> +FunctionParserBase<std::complex<double> >::sEpsilon = 1E-12; + +template<> std::complex<float> +FunctionParserBase<std::complex<float> >::sEpsilon = 1E-5F; + +template<> std::complex<long double> +FunctionParserBase<std::complex<long double> >::sEpsilon = 1E-14L; + +#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE +template<> MpfrFloat +FunctionParserBase<MpfrFloat>::sEpsilon(MpfrFloat::someEpsilon()); +#endif + +#ifdef FP_SUPPORT_GMP_INT_TYPE +template<> GmpInt FunctionParserBase<GmpInt>::sEpsilon = 0; +#endif + +template<typename Value_t> +Value_t FunctionParserBase<Value_t>::epsilon() +{ + return sEpsilon; +} + +template<typename Value_t> +void FunctionParserBase<Value_t>::setEpsilon(Value_t value) +{ + sEpsilon = value; +} + + +//========================================================================= // User-defined identifier addition functions //========================================================================= template<typename Value_t> @@ -1502,12 +1528,6 @@ #endif } -#ifdef FP_EPSILON - const double EpsilonOrZero = FP_EPSILON; -#else - const double EpsilonOrZero = 0.0; -#endif - /* Needed by fp_opcode_add.inc if tracing is enabled */ template<typename Value_t> std::string findName(const NamePtrsMap<Value_t>& nameMap, @@ -2009,10 +2029,6 @@ return CompileIf(function); unsigned requiredParams = funcDef.params; -#ifndef FP_DISABLE_EVAL - if(func_opcode == cEval) - requiredParams = mData->mVariablesAmount; -#endif function = CompileFunctionParams(function, requiredParams); if(!function) return 0; @@ -2634,27 +2650,21 @@ case cAbs: Stack[SP] = fp_abs(Stack[SP]); break; case cAcos: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result == false && (Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))) { mData->mEvalErrorType=4; return Value_t(0); } -# endif Stack[SP] = fp_acos(Stack[SP]); break; case cAcosh: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result == false && Stack[SP] < Value_t(1)) { mData->mEvalErrorType=4; return Value_t(0); } -# endif Stack[SP] = fp_acosh(Stack[SP]); break; case cAsin: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result == false && (Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))) { mData->mEvalErrorType=4; return Value_t(0); } -# endif Stack[SP] = fp_asin(Stack[SP]); break; case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break; @@ -2665,12 +2675,10 @@ --SP; break; case cAtanh: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result ? (Stack[SP] == Value_t(-1) || Stack[SP] == Value_t(1)) : (Stack[SP] <= Value_t(-1) || Stack[SP] >= Value_t(1))) { mData->mEvalErrorType=4; return Value_t(0); } -# endif Stack[SP] = fp_atanh(Stack[SP]); break; case cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break; @@ -2684,61 +2692,20 @@ case cCot: { const Value_t t = fp_tan(Stack[SP]); -# ifndef FP_NO_EVALUATION_CHECKS if(t == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP] = Value_t(1)/t; break; } case cCsc: { const Value_t s = fp_sin(Stack[SP]); -# ifndef FP_NO_EVALUATION_CHECKS if(s == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP] = Value_t(1)/s; break; } -# ifndef FP_DISABLE_EVAL - case cEval: - { - const unsigned varAmount = mData->mVariablesAmount; - Value_t retVal = Value_t(0); - if(mData->mEvalRecursionLevel == FP_EVAL_MAX_REC_LEVEL) - { - mData->mEvalErrorType = 5; - } - else - { - ++mData->mEvalRecursionLevel; -# ifndef FP_USE_THREAD_SAFE_EVAL - /* Eval() will use mData->mStack for its storage. - * Swap the current stack with an empty one. - * This is the not-thread-safe method. - */ - std::vector<Value_t> tmpStack(Stack.size()); - mData->mStack.swap(tmpStack); - retVal = Eval(&tmpStack[SP - varAmount + 1]); - mData->mStack.swap(tmpStack); -# else - /* Thread safety mode. We don't need to - * worry about stack reusing here, because - * each instance of Eval() will allocate - * their own stack. - */ - retVal = Eval(&Stack[SP - varAmount + 1]); -# endif - --mData->mEvalRecursionLevel; - } - SP -= varAmount-1; - Stack[SP] = retVal; - break; - } -# endif - case cExp: Stack[SP] = fp_exp(Stack[SP]); break; case cExp2: Stack[SP] = fp_exp2(Stack[SP]); break; @@ -2763,31 +2730,25 @@ case cInt: Stack[SP] = fp_int(Stack[SP]); break; case cLog: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result ? Stack[SP] == Value_t(0) : !(Stack[SP] > Value_t(0))) { mData->mEvalErrorType=3; return Value_t(0); } -# endif Stack[SP] = fp_log(Stack[SP]); break; case cLog10: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result ? Stack[SP] == Value_t(0) : !(Stack[SP] > Value_t(0))) { mData->mEvalErrorType=3; return Value_t(0); } -# endif Stack[SP] = fp_log10(Stack[SP]); break; case cLog2: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result ? Stack[SP] == Value_t(0) : !(Stack[SP] > Value_t(0))) { mData->mEvalErrorType=3; return Value_t(0); } -# endif Stack[SP] = fp_log2(Stack[SP]); break; @@ -2798,7 +2759,6 @@ --SP; break; case cPow: -# ifndef FP_NO_EVALUATION_CHECKS // x:Negative ^ y:NonInteger is failure, // except when the reciprocal of y forms an integer /*if(IsComplexType<Value_t>::result == false @@ -2810,7 +2770,6 @@ if(Stack[SP-1] == Value_t(0) && Stack[SP] < Value_t(0)) { mData->mEvalErrorType=3; return Value_t(0); } -# endif Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]); --SP; break; @@ -2819,10 +2778,8 @@ case cSec: { const Value_t c = fp_cos(Stack[SP]); -# ifndef FP_NO_EVALUATION_CHECKS if(c == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP] = Value_t(1)/c; break; } @@ -2831,11 +2788,9 @@ case cSinh: Stack[SP] = fp_sinh(Stack[SP]); break; case cSqrt: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result == false && Stack[SP] < Value_t(0)) { mData->mEvalErrorType=2; return Value_t(0); } -# endif Stack[SP] = fp_sqrt(Stack[SP]); break; case cTan: Stack[SP] = fp_tan(Stack[SP]); break; @@ -2861,13 +2816,8 @@ case cMul: Stack[SP-1] *= Stack[SP]; --SP; break; case cDiv: -# ifndef FP_NO_EVALUATION_CHECKS if(Stack[SP] == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# else - if(IsIntType<Value_t>::result && Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP-1] /= Stack[SP]; --SP; break; case cMod: @@ -2969,12 +2919,10 @@ } case cLog2by: -# ifndef FP_NO_EVALUATION_CHECKS if(IsComplexType<Value_t>::result ? Stack[SP-1] == Value_t(0) : !(Stack[SP-1] > Value_t(0))) { mData->mEvalErrorType=3; return Value_t(0); } -# endif Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP]; --SP; break; @@ -3015,13 +2963,8 @@ case cDup: Stack[SP+1] = Stack[SP]; ++SP; break; case cInv: -# ifndef FP_NO_EVALUATION_CHECKS if(Stack[SP] == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# else - if(IsIntType<Value_t>::result && Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP] = Value_t(1)/Stack[SP]; break; @@ -3030,22 +2973,15 @@ break; case cRDiv: -# ifndef FP_NO_EVALUATION_CHECKS if(Stack[SP-1] == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# else - if(IsIntType<Value_t>::result && Stack[SP-1] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break; case cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break; case cRSqrt: -# ifndef FP_NO_EVALUATION_CHECKS if(Stack[SP] == Value_t(0)) { mData->mEvalErrorType=1; return Value_t(0); } -# endif Stack[SP] = Value_t(1) / fp_sqrt(Stack[SP]); break; #ifdef FP_SUPPORT_COMPLEX_NUMBERS @@ -3651,10 +3587,6 @@ case cDeg: n = "deg"; params = 1; break; case cRad: n = "rad"; params = 1; break; - #ifndef FP_DISABLE_EVAL - case cEval: n = "eval"; params = mData->mVariablesAmount; break; - #endif - case cFetch: { unsigned index = ByteCode[++IP]; Modified: trunk/src/tools/fparser/fparser.h =================================================================== --- trunk/src/tools/fparser/fparser.h 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/fparser.h 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen, Joel Yliluoma *| |* *| @@ -50,6 +50,9 @@ void setDelimiterChar(char); + static Value_t epsilon(); + static void setEpsilon(Value_t); + const char* ErrorMsg() const; ParseErrorType GetParseErrorType() const; @@ -135,6 +138,7 @@ // ------------ Data* mData; unsigned mStackPtr; + static Value_t sEpsilon; // Private methods: Modified: trunk/src/tools/fparser/fparser_gmpint.h =================================================================== --- trunk/src/tools/fparser/fparser_gmpint.h 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/fparser_gmpint.h 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen *| \***************************************************************************/ Modified: trunk/src/tools/fparser/fparser_mpfr.h =================================================================== --- trunk/src/tools/fparser/fparser_mpfr.h 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/fparser_mpfr.h 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen *| \***************************************************************************/ Modified: trunk/src/tools/fparser/fpconfig.h =================================================================== --- trunk/src/tools/fparser/fpconfig.h 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/fpconfig.h 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Copyright: Juha Nieminen *| |* *| @@ -40,7 +40,7 @@ //#define FP_USE_STRTOLD -/* Uncomment this line of define it in your compiler settings if you want +/* Uncomment this line or define it in your compiler settings if you want to disable compiling the basic double version of the library, in case one of the above types is used but not the double type. (If the double type is not used, then disabling it makes compiling faster and the @@ -49,45 +49,6 @@ //#define FP_DISABLE_DOUBLE_TYPE /* - Note that these do not change what FunctionParser supports, they only - change how the function is evaluated, potentially making it faster when - these functions are involved. - These will make the source code use asinh(), acosh(), atanh(), exp2() - and log2(). -*/ -//#define FP_SUPPORT_TR1_MATH_FUNCS - -#ifdef FP_SUPPORT_TR1_MATH_FUNCS -#define FP_SUPPORT_ASINH -#define FP_SUPPORT_EXP2 -#define FP_SUPPORT_LOG2 -#define FP_SUPPORT_CBRT -#define FP_SUPPORT_HYPOT -#endif - -/* - Comment out the following line to enable the eval() function, which can - be used in the function string to recursively call the same function. - Note that enabling this function may be dangerous even if the maximum - recursion level is limited because it is still possible to write functions - using it which take enormous amounts of time to evaluate even though the - maximum recursion is never reached. This may be undesirable in some - applications. - Alternatively you can define the FP_ENABLE_EVAL precompiler constant in - your compiler settings. -*/ -#ifndef FP_ENABLE_EVAL -#define FP_DISABLE_EVAL -#endif - - -/* - Maximum recursion level for eval() calls: -*/ -#define FP_EVAL_MAX_REC_LEVEL 1000 - - -/* Whether to use shortcut evaluation for the & and | operators: */ #ifndef FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION @@ -95,15 +56,6 @@ #endif /* - Whether to enable optimizations that may ignore side effects - of if() calls, such as changing if(x,!y,0) into x&!y. - This is basically the polar opposite of "shortcut logical evaluation". - Disabled by default, because it makes eval() rather unsafe. -*/ -#ifdef FP_ENABLE_IGNORE_IF_SIDEEFFECTS -#endif - -/* Comment out the following lines out if you are not going to use the optimizer and want a slightly smaller library. The Optimize() method can still be called, but it will not do anything. @@ -120,15 +72,6 @@ /* - Epsilon value used with the comparison operators (must be non-negative): - (Comment it out if you don't want to use epsilon in comparisons. Might - lead to marginally faster evaluation of the comparison operators, but - can introduce inaccuracies in comparisons.) -*/ -#define FP_EPSILON 1e-14 - - -/* No member function of FunctionParser is thread-safe. Most prominently, Eval() is not thread-safe. By uncommenting one of these lines the Eval() function can be made thread-safe at the cost of a possible small overhead. @@ -137,9 +80,3 @@ */ //#define FP_USE_THREAD_SAFE_EVAL //#define FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA - -/* - Uncomment (or define in your compiler options) to disable evaluation checks. - (Consult the documentation for details.) - */ -//#define FP_NO_EVALUATION_CHECKS Modified: trunk/src/tools/fparser/fpoptimizer.cpp =================================================================== --- trunk/src/tools/fparser/fpoptimizer.cpp 2012-04-15 06:51:09 UTC (rev 8206) +++ trunk/src/tools/fparser/fpoptimizer.cpp 2012-04-15 08:02:30 UTC (rev 8207) @@ -1,5 +1,5 @@ /***************************************************************************\ -|* Function Parser for C++ v4.4.3 *| +|* Function Parser for C++ v4.5 *| |*-------------------------------------------------------------------------*| |* Function optimizer *| |*-------------------------------------------------------------------------*| @@ -21,1343 +21,1325 @@ #include "fparser.h" #include "extrasrc/fptypes.h" #include "extrasrc/fpaux.h" -#define lN4 if(n6 l24 -#define lM4 .lD1 y3 -#define lL4 Needs -#define lK4 tree.xQ1 -#define lJ4 "Found " -#define lI4 stackpos -#define lH4 "PUSH "yA3 -#define lG4 "dup(%u) " -#define lF4 eV{assert -#define lE4 "%d, cost " -#define lD4 ::cout<<l44 -#define lC4 "immed "<< -#define lB4 mFuncParsers -#define lA4 stderr -#define l94 sep2=" " -#define l84 -iW2 63)-1; -#define l74 FPHASH_CONST -#define l64 cache_needed[ -#define l54 fprintf -#define l44 "Applying " -#define l34 ||tree.GetOpcode -#define l24 HANDLE_UNARY_CONST_FUNC -#define l14 {cSinh, -#define l04 },0,0x4 -#define iZ3 xZ a) -#define iY3 xI(i42 -#define iX3 tO info -#define iW3 &&IsLogicalValue( -#define iV3 xZ 1)nD== -#define iU3 .n8 synth. -#define iT3 known||(nW2 -#define iS3 ),Value( -#define iR3 );if( -#define iQ3 within, -#define iP3 ;return -#define iO3 )iP3 Ok;} -#define iN3 tK1){if -#define iM3 cLog2&& -#define iL3 eL3 yJ2 -#define iK3 c_count -#define iJ3 s_count -#define iI3 MaxOp -#define iH3 2)lT 2* -#define iG3 0));t0 -#define iF3 nM 0)); -#define iE3 tmp2.nM -#define iD3 Unknown -#define iC3 else nP -#define iB3 known&& -#define iA3 lT2 val -#define i93 tree.lV -#define i83 default_function_handling -#define i73 sim.x71 +#define l64 y91 a), +#define l54 if(n5 iK3 +#define l44 ,{ReplaceParams, +#define l34 cTan iO +#define l24 "Found " +#define l14 ,cPow, +#define l04 stackpos +#define iZ3 sim.nY 1, +#define iY3 ,tree,info +#define iX3 "dup(%u) " +#define iW3 "%d, cost " +#define iV3 "PUSH "i13( +#define iU3 "immed "<< +#define iT3 mFuncParsers +#define iS3 e62{assert +#define iR3 stderr +#define iQ3 sep2=" " +#define iP3 FPHASH_CONST +#define iO3 .SetParamsMove( +#define iN3 cache_needed[ +#define iM3 fprintf +#define iL3 ::cout<<"Applying " +#define iK3 HANDLE_UNARY_CONST_FUNC +#define iJ3 1)i61){ +#define iI3 c_count +#define iH3 s_count +#define iG3 2)lS 2* +#define iF3 tmp.yH1 +#define iE3 tmp2.nJ +#define iD3 ,tZ 2, +#define iC3 (p0 n51&& +#define iB3 else nM +#define iA3 max.val +#define i93 eK2 if( +#define i83 tree c9 +#define i73 sim.x61 #define i63 ].swap( #define i53 codes[b #define i43 whydump -#define i33 nparams -#define i23 444848, -#define i13 l2 2,2, -#define i03 ,cIf,cI3 -#define tZ3 l3 0,1, -#define tY3 cHypot, -#define tX3 t1 1,0, -#define tW3 nU 0, -#define tV3 cAbs nU -#define tU3 b.Value) -#define tT3 b.Opcode -#define tS3 Params[ -#define tR3 Params( -#define tQ3 )xC1 2) -#define tP3 leaf1 -#define tO3 cAbsIf) -#define tN3 AddFrom( -#define tM3 =fp_pow( -#define tL3 ,l5 2,1, -#define tK3 =false; -#define tJ3 ==cOr)l43 -#define tI3 cI cMul); -#define tH3 ;}static n02 -#define tG3 .size() -#define tF3 ].first -#define tE3 Ne_Mask -#define tD3 7168, -#define tC3 +=1;e31 -#define tB3 Gt_Mask -#define tA3 Lt_Mask -#define t93 opcode, -#define t83 public: -#define t73 {data-> -#define t63 },{l4:: -#define t53 pclone -#define t43 Immeds -#define t33 c0 nA2 -#define t23 c0 iE, -#define t13 cOr,l6 -#define t03 info. -#define eZ3 ){if(nA1 -#define eY3 );Value -#define eX3 };enum -#define eW3 ;}void -#define eV3 xR)eW3 -#define eU3 ParamHolder -#define eT3 NumConstant: -#define eS3 ){case -#define eR3 newpow -#define eQ3 change -#define eP3 (count -#define eO3 value) -#define eN3 ,lB1+1); -#define eM3 value] -#define eL3 value, +#define i33 );}case +#define i23 :if(eQ3 +#define i13 ;DumpTree +#define i03 :{lX1 r +#define tZ3 nparams +#define tY3 cLog iO +#define tX3 l4 16,1, +#define tW3 l4 0,1, +#define tV3 0x12 nH +#define tU3 ,0,0x16},{ +#define tT3 nQ 0, +#define tS3 cAbs nQ +#define tR3 false;} +#define tQ3 nE1 cF1 +#define tP3 xF1++b) +#define tO3 =false; +#define tN3 {data-> +#define tM3 info. +#define tL3 b.Value) +#define tK3 b.Opcode +#define tJ3 ,tB info +#define tI3 tree xD +#define tH3 xD cMul); +#define tG3 ParamHolder +#define tF3 size() +#define tE3 .second +#define tD3 ]tE3 +#define tC3 ].first +#define tB3 Ne_Mask +#define tA3 Gt_Mask +#define t93 Lt_Mask +#define t83 opcode, +#define t73 resize( +#define t63 t33 nC1; +#define t53 xD cond nC +#define t43 );}else +#define t33 lE2 a) +#define t23 AddFrom( +#define t13 max.known +#define t03 =fp_pow( +#define eZ3 (tree)!= +#define eY3 );if( +#define eX3 public: +#define eW3 pclone +#define eV3 Others +#define eU3 --cN1. +#define eT3 cOr,l6 +#define eS3 newpow +#define eR3 if(p0 yN +#define eQ3 &*(*x5 n71){ +#define eP3 ,lT 1,0, +#define eO3 lE2 1) +#define eN3 (op1== +#define eM3 change +#define eL3 (count #define eK3 133,2, -#define eJ3 eH3 l73 -#define eI3 eH3 c1 val -#define eH3 result -#define eG3 byteCode -#define eF3 eS cV1); -#define eE3 xR2 a eQ -#define eD3 n51 nD== -#define eC3 cLog2by -#define eB3 cPow&&tT -#define eA3 factor_t -#define e93 value1 -#define e83 Finite -#define e73 a)iR3! -#define e63 fp_mod( -#define e53 else{if( -#define e43 xI());nE -#define e33 c1 val)< -#define e23 p c1 val -#define e13 iZ);}if( -#define e03 {tree.xE +#define eJ3 Needs +#define eI3 byteCode +#define eH3 (p1 nC1 +#define eG3 lS1 nC== +#define eF3 cLog2by +#define eE3 factor_t +#define eD3 (*x5)[0].info +#define eC3 tree nC1 +#define eB3 value1 +#define eA3 Finite +#define e93 fp_mod( +#define e83 )const +#define e73 (e83{ +#define e63 else{if( +#define e53 xK());nD +#define e43 TreeCountItem +#define e33 if(op== +#define e23 yN val)< +#define e13 p yN val +#define e03 c9 ifp2 #define cZ3 cAbsNot #define cY3 stackptr -#define cX3 (tree)!= -#define cW3 1),l63(1)); -#define cV3 FP_GetOpcodeName( -#define cU3 cLog);xJ +#define cX3 cLog);xL +#define cW3 switch(tM +#define cV3 p1 cK p1); +#define cU3 );p1 c9 ifp1 #define cT3 .empty() #define cS3 opcodes #define cR3 did_muli -#define cQ3 &Value){ -#define cP3 yG const -#define cO3 used[b] -#define cN3 :if(&*lV1){ -#define cM3 :{nB1 r= -#define cL3 sizeof( -#define cK3 iY2 lI1 -#define cJ3 cAbsIf, -#define cI3 l3 16,1, -#define cH3 281856, -#define cG3 cLess,cS -#define cF3 cTan,yV2 -#define cE3 Ge0Lt1 -#define cD3 switch(n61 -#define cC3 )){data xB -#define cB3 xZ 0)nD -#define cA3 ))return -#define c93 IsLogicalValue(xZ -#define c83 cLog,yV2 -#define c73 lK 2},0, -#define c63 middle2 -#define c53 ::string -#define c43 param. -#define c33 ¶m=* -#define c23 l63(2))); -#define c13 ){switch( -#define c03 ()const{ -#define yZ3 .tV1 n] -#define yY3 break;} -#define yX3 default: -#define yW3 {l4::xD2 -#define yV3 =*(cX*xY1 -#define yU3 ;else eH3 -#define yT3 range x23 -#define yS3 )yT1 Rehash() -#define yR3 range<cG2 -#define yQ3 range xI -#define yP3 cAdd lX2 -#define yO3 (op1== -#define yN3 ))==IsAlways) -#define yM3 cZ1;++b) -#define yL3 iterator -#define yK3 begin(); -#define yJ3 TreeSet -#define yI3 parent -#define yH3 insert(i -#define yG3 newrel -#define yF3 void set -#define yE3 b_needed -#define yD3 cachepos -#define yC3 half,iB, -#define yB3 half= -#define yA3 ;DumpTree( -#define y93 ;o<<"\n"; -#define y83 fp_equal( -#define y73 (y83 -#define y63 131,4,1, -#define y53 131,8,1, -#define y43 4,1,2,1, -#define y33 ::vector -#define y23 FindPos( -#define y13 src_pos -#define y03 reserve( -#define xZ3 const std::eT -#define xY3 const char* -#define xX3 yP1 void -#define xW3 treeptr -#define xV3 .resize( -#define xU3 tS1 void -#define xT3 ImmedTag -#define xS3 );m c1 nV2 -#define xR3 ){half&=127; -#define xQ3 a,const -#define xP3 RefCount -#defi... [truncated message content] |