From: Matthias Maier Date: Mon, 1 Oct 2012 15:08:35 +0000 (+0000) Subject: One schould be able to use svn correctly :-/ X-Git-Tag: v8.0.0~1079^2~531 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82dd1cc2ef976fd4aa31f5c595eea2f571e30ca4;p=dealii.git One schould be able to use svn correctly :-/ git-svn-id: https://svn.dealii.org/branches/branch_cmake@26911 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/contrib/functionparser/CMakeLists.txt b/deal.II/contrib/functionparser/CMakeLists.txt deleted file mode 100644 index c32d8011da..0000000000 --- a/deal.II/contrib/functionparser/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -DEAL_II_ADD_LIBRARY(obj_functionparser OBJECT fparser.cc) diff --git a/deal.II/contrib/functionparser/README b/deal.II/contrib/functionparser/README deleted file mode 100644 index 00bdbc5b8d..0000000000 --- a/deal.II/contrib/functionparser/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains the functionparser project which is copyrighted -by Juha Nieminen and licensed under the GNU Lesser General Public License -(LGPL) Version 3. See functionparser/README, functionparser/lgpl-3.0.txt -or http://warp.povusers.org/FunctionParser/ - -A full version of the functionparser project can be downloaded at -http://warp.povusers.org/FunctionParser/. diff --git a/deal.II/contrib/functionparser/docs/fparser.html b/deal.II/contrib/functionparser/docs/fparser.html deleted file mode 100644 index da99f67247..0000000000 --- a/deal.II/contrib/functionparser/docs/fparser.html +++ /dev/null @@ -1,1848 +0,0 @@ - - - - - - Function Parser for C++ v4.5 : Documentation - - - -

Function Parser for C++ v4.5

- -

Authors: Juha Nieminen -(http://iki.fi/warp/), -Joel Yliluoma -(http://iki.fi/bisqwit/). - -

The usage license of this library is located at the end of this file. - -

Table of contents:

- - - - -

What's new

- -

What's new in v4.5 -

- - - - - -

Preface

- -

This C++ library offers a class which can be used to parse and evaluate a -mathematical function from a string (which might be eg. requested from the -user). The syntax of the function string is similar to mathematical expressions -written in C/C++ (the exact syntax is specified later in this document). -The function can then be evaluated with different values of variables. - -

For example, a function like "sin(sqrt(x*x+y*y))" can be -parsed from a string (either std::string or a C-style string) -and then evaluated with different values of x and y. -This library can be useful for evaluating user-inputted functions, or in -some cases interpreting mathematical expressions in a scripting language. - -

This library aims for maximum speed in both parsing and evaluation, while -keeping maximum portability. The library should compile and work with any -standard-conforming C++ compiler. - -

Different numerical types are supported: double, - float, long double, long int, - std::complex (of types double, - float and long double), - multiple-precision floating point numbers using the MPFR library, and - arbitrary precision integers using the GMP library. (Note that it's - not necessary for these two libraries to exist in the system in order - to use the Function Parser library with the other numerical types. Support - for these libraries is optionally compiled in using preprocessor settings.) - - - - -

Usage

- -

To use the FunctionParser class, you have to include -"fparser.hh" in your source code files which use the -FunctionParser class. - -

If you are going to use the MPFR version of the library, you need to -include "fparser_mpfr.hh". If you are going to use the GMP -version of the library, you need to include "fparser_gmpint.hh". -(Note that support for these special parser versions needs to be specified -with preprocessor macros. See the documentation -below for details.) - -

When compiling, you have to compile fparser.cc and -fpoptimizer.cc and link them to the main program. In many -developement environments it's enough to add those two files to your -current project (usually header files don't have to be added to the -project for the compilation to work). - -

If you are going to use the MPFR or the GMP versions of the library, -you also need to add mpfr/MpfrFloat.cc or -mpfr/GmpInt.cc files to your project, respectively. Otherwise -they should not be added to the project. - -

Note that part of the library source code is inside several -.inc files inside the extrasrc subdirectory -(these files contain auto-generated C++ code), provided in the library -package. These files are used by fparser.cc and don't need -to be added explicitly to the project in most IDEs (such as Visual Studio). -Basically, you don't need to do anything with these files, other than keep -them in the extrasrc subdirectory. - -

Simple usage example of the library: - -

-    FunctionParser fp;
-    fp.Parse("sqrt(x*x + y*y)", "x,y");
-    double variables[2] = { 1.5, 2.9 };
-    double result = fp.Eval(variables);
-
- - - -

Parser types

- -

Different versions of the function parser class are supported, using - different floating point or integral types for function evaluation. - -

All the classes other than the default one, FunctionParser, - need to be enabled at compile time by defining a preprocessor macro - (specified below) either in the fpconfig.hh file or your - compiler settings. (The reason for this is that every parser that is - included in the compilation process will make the compilation slower - and increase the size of the executable, so they are compiled only on - demand. Also, the GMP and MPFR versions of the parser require for those - libraries to be available, which is often not the case.) - -

Note that if you try to use the other class types without enabling them - with the correspondent preprocessor macro, you will get a linker error - (rather than a compiler error) because those classes will not have been - instantiated when the library was compiled. - -

Currently the Optimize() method works only for the - FunctionParser, FunctionParser_f and - FunctionParser_ld classes. For the other types it can be - called but it does nothing. - -

-

-

FunctionParser

-
-

This is the default class, which uses double as its - numerical type. This is the only class enabled by default. -

If you use some other type than this one, and you don't want this - version of the class compiled into the library, you can define the - preprocessor macro FP_DISABLE_DOUBLE_TYPE. -

- -

FunctionParser_f

-
-

This parser uses float as its numerical type. -

The FP_SUPPORT_FLOAT_TYPE preprocessor macro needs to be - defined for this class to be enabled. -

- -

FunctionParser_ld

-
-

This parser uses long double as its numerical type. -

The FP_SUPPORT_LONG_DOUBLE_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that the FP_USE_STRTOLD preprocessor macro should - also be defined when using this version of the parser if the compiler - supports the (C99) function strtold(). (See - documentation below.) -

- -

FunctionParser_li

-
-

This parser uses long int as its numerical type. -

The FP_SUPPORT_LONG_INT_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that this version of the class uses a reduced function syntax - with support only for functions which are feasible to be used with - integral types (namely abs(), eval(), - if(), min() and max(), besides - basic arithmetic operators, except for the power operator). -

- -

FunctionParser_cd, FunctionParser_cf, - FunctionParser_cld

-
-

These parsers use std::complex<double>, - std::complex<float> and - std::complex<long double> as their numerical type, - respectively. -

The preprocessor macros to enable them are - FP_SUPPORT_COMPLEX_DOUBLE_TYPE, - FP_SUPPORT_COMPLEX_FLOAT_TYPE and - FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE. -

If FunctionParser_cld is used, the - FP_USE_STRTOLD macro should also be defined if the compiler - supports the strtold() function. -

- -

FunctionParser_mpfr

-
-

This parser uses MpfrFloat as its numerical type. -

The FP_SUPPORT_MPFR_FLOAT_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that to use this version of the parser, - "fparser_mpfr.hh" needs to be included. -

MpfrFloat is an auxiliary class which uses the MPFR - library for multiple-precision floating point numbers. The class - behaves largely like a floating point type, and is declared in the - mpfr/MpfrFloat.hh file (see that file for info about - the public interface of the class). -

If this class is enabled, mpfr/MpfrFloat.cc - needs to be compiled into the project, as well as the GMP and MPFR - libraries. (With the gcc compiler this means using the linker options - "-lgmp -lmpfr".) -

- -

FunctionParser_gmpint

-
-

This parser uses GmpInt as its numerical type. -

The FP_SUPPORT_GMP_INT_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that to use this version of the parser, - "fparser_gmpint.hh" needs to be included. -

GmpInt is an auxiliary class which uses the GMP - library for arbitrary-precision integer numbers. The class - behaves largely like an integer type, and is declared in the - mpfr/GmpInt.hh file (see that file for info about - the public interface of the class). -

If this class is enabled, mpfr/GmpInt.cc - needs to be compiled into the project, as well as the GMP library. -

This version of the class also uses a reduced version of the syntax, - like the long int version. -

Note: Since there's no upper limit to the size of GMP - integers, this version of the class should be used with care in - situations where malicious users might be able to exploit it to - make the program run out of memory. An example of this would be - a server-side application usable through the WWW. -

-
- -

Note that these different classes are completely independent and - instances of different classes cannot be given to each other using the - AddFunction() method. Only objects of the same type can - be given to that method. - -

The rest of the documentation assumes that FunctionParser - (which uses the double type) is used. The usage of the other - classes is identical except that double is replaced with the - correspondent type used by that class. (In other words, whenever the - rest of this documentation uses the type keyword 'double', - the correspondent type should be used instead, when using another version - of the class.) - - - -

Configuring the compilation

- -

There is a set of precompiler options in the fpconfig.hh file -which can be used for setting certain features on or off. All of these options -can also be specified from the outside, using precompiler settings (eg. the --D option in gcc), and thus it's not necessary to modify this -file. - -

-

FP_USE_STRTOLD : (Default off)

-

If FunctionParser_ld or FunctionParser_cld - are used, this preprocessor macro should be defined if the compiler - supports the (C99) function strtold(). If not, then numeric - 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.) Note that strtold() will also be automatically used - if __cplusplus indicates that C++11 is in use. -

- -

FP_SUPPORT_OPTIMIZER : (Default on)

-

If you are not going to use the Optimize() method, you - can comment this line out to speed-up the compilation a bit, as - well as making the binary a bit smaller. (Optimize() can - still be called, but it will not do anything.) - -

You can also disable the optimizer by specifying the - FP_NO_SUPPORT_OPTIMIZER precompiler constant in your - compiler settings. -

- -

FP_USE_THREAD_SAFE_EVAL : (Default off)

-

Define this precompiler constant to make Eval() - thread-safe. Refer to the thread safety - section later in this document for more information. - Note that defining this may make Eval() slightly slower. -

Also note that the MPFR and GMP versions of the library cannot be - made thread-safe, and thus this setting has no effect on them. -

- -

FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA : (Default off)

-

This is like the previous, but makes Eval() use the - alloca() function (instead of std::vector). - This will make it faster, but the alloca() - function is not standard and thus not supported by all compilers. -

-
- - - - -

Copying and assignment

- -

The class implements a safe copy constructor and assignment operator. - -

It uses the copy-on-write technique for efficiency. This means that - when copying or assigning a FunctionParser instance, the internal data - (which in some cases can be quite lengthy) is not immediately copied - but only when the contents of the copy (or the original) are changed. - -

This means that copying/assigning is a very fast operation, and if - the copies are never modified then actual data copying never happens - either. - -

The Eval() and EvalError() methods of the -copy can be called without the internal data being copied. - -

Calling Parse(), Optimize() or the user-defined -constant/function adding methods will cause a deep-copy. - - - - -

Short descriptions of FunctionParser methods

- -
-int Parse(const std::string& Function, const std::string& Vars,
-          bool useDegrees = false);
-
-int Parse(const char* Function, const std::string& Vars,
-          bool useDegrees = false);
-
- -

Parses the given function and compiles it to internal format. - Return value is -1 if successful, else the index value to the location - of the error. - -


-
-void setDelimiterChar(char);
-
- -

Sets an ending delimiter character for the function string. (See the - long description for more details.) - -


-
-static double epsilon();
-static void setEpsilon(double);
-
- -

Setter and getter for the epsilon value used with comparison operators. - -


-
-const char* ErrorMsg(void) const;
-
- -

Returns an error message corresponding to the error in -Parse(), or an empty string if no such error occurred. - -


-
-ParseErrorType GetParseErrorType() const;
-
- -

Returns the type of parsing error which occurred. Possible return types - are described in the long description. - -


-
-double Eval(const double* Vars);
-
- -

Evaluates the function given to Parse(). - -


-
-int EvalError(void) const;
-
- -

Returns 0 if no error happened in the previous call to -Eval(), else an error code >0. - -


-
-void Optimize();
-
- -

Tries to optimize the bytecode for faster evaluation. - -


-
-bool AddConstant(const std::string& name, double value);
-
- -

Add a constant to the parser. Returns false if the name of -the constant is invalid, else true. - -


-
-bool AddUnit(const std::string& name, double value);
-
- -

Add a new unit to the parser. Returns false if the name of -the unit is invalid, else true. - -


-
-bool AddFunction(const std::string& name,
-                 double (*functionPtr)(const double*),
-                 unsigned paramsAmount);
-
- -

Add a user-defined function to the parser (as a function pointer). -Returns false if the name of the function is invalid, else -true. - -


-
-bool AddFunction(const std::string& name, FunctionParser&);
-
- -

Add a user-defined function to the parser (as a FunctionParser -instance). Returns false if the name of the function is invalid, -else true. - -


-
-bool RemoveIdentifier(const std::string& name);
-
- -

Removes the constant, unit or user-defined function with the specified -name from the parser. - -


-
-int ParseAndDeduceVariables(const std::string& function,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::string& resultVarString,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::vector<std::string>& resultVars,
-                            bool useDegrees = false);
-
- -

Like Parse(), but the variables in the function are deduced -automatically. The amount of found variables and the variable names themselves -are returned by the different versions of the function. - - - -

Long descriptions of FunctionParser methods

- -
- -
-int Parse(const std::string& Function, const std::string& Vars,
-          bool useDegrees = false);
-
-int Parse(const char* Function, const std::string& Vars,
-          bool useDegrees = false);
-
- -

Parses the given function (and compiles it to internal format). -Destroys previous function. Following calls to Eval() will evaluate -the given function. - -

The strings given as parameters are not needed anymore after parsing. - -

Parameters: - - - - - - - - - - - -
FunctionString containing the function to parse.
VarsString containing the variable names, separated by commas.
- Eg. "x,y", "VarX,VarY,VarZ,n" or - "x1,x2,x3,x4,__VAR__". -
useDegrees(Optional.) Whether to use degrees or radians in - trigonometric functions. (Default: radians)
- -

If a char* is given as the Function parameter, -it must be a null-terminated string. - -

Variables can have any size and they are case sensitive (ie. -"var", "VAR" and "Var" are -different variable names). Letters, digits, underscores and -UTF8-encoded characters can be used in variable names, but the name of -a variable can't begin with a digit. Each variable name can appear only -once in the 'Vars' string. Function names are not legal -variable names. - -

Using longer variable names causes no overhead whatsoever to the -Eval() method, so it's completely safe to use variable names -of any size. - -

The third, optional parameter specifies whether angles should be - interpreted as radians or degrees in trigonometrical functions. - If not specified, the default value is radians. - -

Return values: - -

- -

Example: parser.Parse("3*x+y", "x,y"); - - -


- -
-void setDelimiterChar(char);
-
- -

By default the parser expects the entire function string to be valid -(ie. the entire contents of the given std::string, or a C string -ending in the null character '\0'). - -

If a delimiter character is specified with this function, then if it's -encountered at the outermost parsing level by the Parse() -function, and the input function has been valid so far, Parse() -will return an index to this character inside the input string, but rather -than set an error code, FP_NO_ERROR will be set. - -

The idea is that this can be used to more easily parse functions which -are embedded inside larger strings, containing surrounding data, without -having to explicitly extract the function to a separate string. - -

For example, suppose you are writing an interpreter for a scripting - language, which can have commands like this: - -

let MyFunction(x,y) = { sin(x*x+y*y) } // A 2-dimensional function - -

Normally when parsing such a line you would have to extract the part -inside the curly brackets into a separate string and parse it that way. -With this feature what you can do instead is to set '}' as -the delimiter character and then simply give a pointer to the character -which comes after the '{'. If all goes well, the -Parse() function will return an index to the '}' -character (from the given starting point) and GetParseErrorType() -will return FP_NO_ERROR. You can use the return -value (if it's not -1) to jump forward in the string to the -delimiter character. - -

Note that a null character ('\0') or the end of the -std::string (if one was given) will still be a valid end of -the function string even if a delimiter character was specified. (In this -case Parse() will return -1 if there was no error, -as usual.) - -

Also note that the delimiter character cannot be any valid operator -or alphanumeric (including the underscore) character, nor the other -characters defined in the function syntax. It must be a character not -supported by the function parser (such as '}', -'"', ']', etc). - - -


- -
-static double epsilon();
-static void setEpsilon(double);
-
- -

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: - -

- - -
- -
-const char* ErrorMsg(void) const;
-
- -

Returns a pointer to an error message string corresponding to the error -caused by Parse() (you can use this to print the proper error -message to the user). If no such error has occurred, returns an empty string. - - -


- -
-ParseErrorType GetParseErrorType() const;
-
- -

Returns the type of parse error which occurred. - -

This method can be used to get the error type if ErrorMsg() -is not enough for printing the error message. In other words, this can be -used for printing customized error messages (eg. in another language). -If the default error messages suffice, then this method doesn't need -to be called. - -FunctionParser::ParseErrorType is an enumerated type inside -the class (ie. its values are accessed like -"FunctionParser::SYNTAX_ERROR"). - -

The possible values for FunctionParser::ParseErrorType are listed below, -along with their equivalent error message returned by the -ErrorMsg() method: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FP_NO_ERRORIf no error occurred in the previous call to Parse().
SYNTAX_ERROR"Syntax error"
MISM_PARENTH"Mismatched parenthesis"
MISSING_PARENTH"Missing ')'"
EMPTY_PARENTH"Empty parentheses"
EXPECT_OPERATOR"Syntax error: Operator expected"
OUT_OF_MEMORY"Not enough memory"
UNEXPECTED_ERROR"An unexpected error occurred. Please make a full bug report to the - author"
INVALID_VARS"Syntax error in parameter 'Vars' given to FunctionParser::Parse()"
ILL_PARAMS_AMOUNT"Illegal number of parameters to function"
PREMATURE_EOS"Syntax error: Premature end of string"
EXPECT_PARENTH_FUNC"Syntax error: Expecting ( after function"
UNKNOWN_IDENTIFIER"Syntax error: Unknown identifier"
NO_FUNCTION_PARSED_YET"(No function has been parsed yet)"
- - -


- -
-double Eval(const double* Vars);
-
- -

Evaluates the function given to Parse(). -The array given as parameter must contain the same amount of values as -the amount of variables given to Parse(). Each value corresponds -to each variable, in the same order. - -

Return values: -

- -

Example: - -

double Vars[] = {1, -2.5};
-double result = parser.Eval(Vars); - - -


- -
-int EvalError(void) const;
-
- -

Used to test if the call to Eval() succeeded. - -

Return values: - -

If there was no error in the previous call to Eval(), -returns 0, else returns a positive value as follows: -

- - -
- -
-void Optimize();
-
- -

This method can be called after calling the Parse() method. -It will try to simplify the internal bytecode so that it will evaluate faster -(it tries to reduce the amount of opcodes in the bytecode). - -

For example, the bytecode for the function "5+x*y-25*4/8" will -be reduced to a bytecode equivalent to the function "x*y-7.5" (the -original 11 opcodes will be reduced to 5). Besides calculating constant -expressions (like in the example), it also performs other types of -simplifications with variable and function expressions. - -

This method is quite slow and the decision of whether to use it or -not should depend on the type of application. If a function is parsed -once and evaluated millions of times, then calling Optimize() -may speed-up noticeably. However, if there are tons of functions to parse -and each one is evaluated once or just a few times, then calling -Optimize() will only slow down the program. - -

Also, if the original function is expected to be optimal, then calling -Optimize() would be useless. - -

Note: Currently this method does not make any checks (like -Eval() does) and thus things like "1/0" will cause -undefined behaviour. (On the other hand, if such expression is given to the -parser, Eval() will always give an error code, no matter what -the parameters.) If caching this type of errors is important, a work-around -is to call Eval() once before calling Optimize() -and checking EvalError(). - -

If the destination application is not going to use this method, -the compiler constant FP_SUPPORT_OPTIMIZER can be undefined in -fpconfig.hh to make the library smaller (Optimize() -can still be called, but it will not do anything). - -

(If you are interested in seeing how this method optimizes the opcode, -you can call the PrintByteCode() method before and after the -call to Optimize() to see the difference.) - - -


- -
-bool AddConstant(const std::string& name, double value);
-
- -

This method can be used to add constants to the parser. Syntactically - constants are identical to variables (ie. they follow the same naming - rules and they can be used in the function string in the same way as - variables), but internally constants are directly replaced with their - value at parse time. - -

Constants used by a function must be added before calling -Parse() for that function. Constants are preserved between -Parse() calls in the current FunctionParser instance, so -they don't need to be added but once. (If you use the same constant in -several instances of FunctionParser, you will need to add it to all the -instances separately.) - -

Constants can be added at any time and the value of old constants can -be changed, but new additions and changes will only have effect the next -time Parse() is called. (That is, changing the value of a constant -after calling Parse() and before calling Eval() -will have no effect.) - -

The return value will be false if the 'name' of -the constant was illegal, else true. If the name was illegal, -the method does nothing. - -

Example: parser.AddConstant("pi", 3.1415926535897932); - -

Now for example parser.Parse("x*pi", "x"); will be identical -to the call parser.Parse("x*3.1415926535897932", "x"); - - -


- -
-bool AddUnit(const std::string& name, double value);
-
- -

In some applications it is desirable to have units of measurement. -A typical example is an application which creates a page layout to be -printed. When printing, distances are usually measured in points -(defined by the resolution of the printer). However, it is often more -useful for the user to be able to specify measurements in other units -such as centimeters or inches. - -

A unit is simply a value by which the preceding element is multiplied. -For example, if the printing has been set up to 300 DPI, one inch is -then 300 points (dots). Thus saying eg. "5in" is the same as saying -"5*300" or "1500" (assuming "in" has -been added as a unit with the value 300). - -

Note that units are slightly different from a multiplication in -that they have a higher precedence than any other operator (except -parentheses). Thus for example "5/2in" is parsed as -"5/(2*300)". -(If 5/2 inches is what one wants, it has to be written "(5/2)in".) - -

You can use the AddUnit() method to add a new unit. The -unit can then be used after any element in the function (and will work as -a multiplier for that element). An element is a float literal, a constant, -a variable, a function or any expression in parentheses. When the element -is not a float literal nor an expression in parentheses, there has to naturally -be at least one whitespace between the element and the unit (eg. -"x in"). To change the value of a unit, call -AddUnit() again with the same unit name and the new value. - -

Unit names share the same namespace as constants, functions and - variables, and thus should be distinct from those. - -

Example: parser.AddUnit("in", 300); - -

Now for example the function "5in" will be identical to -"(5*300)". Other usage examples include "x in", -"3in+2", "pow(x,2)in", "(x+2)in". - - -


- -
-bool AddFunction(const std::string& name,
-                 double (*functionPtr)(const double*),
-                 unsigned paramsAmount);
-
- -This method can be used to add new functions to the parser. For example, -if you would like to add a function "sqr(A)" which squares the -value of A, you can do it with this method (so that you don't -need to touch the source code of the parser). - -

The method takes three parameters: - -

- -

The return value will be false if the given name was invalid -(either it did not follow the variable naming conventions, or the name was -already reserved), else true. If the return value is -false, nothing is added. - -

Example: Suppose we have a C++ function like this: - -

double Square(const double* p)
-{
-    return p[0]*p[0];
-} - -

Now we can add this function to the parser like this: - -

parser.AddFunction("sqr", Square, 1);
-parser.Parse("2*sqr(x)", "x"); - -

An example of a useful function taking no parameters is a function - returning a random value. For example: - -

double Rand(const double*)
-{
-    return drand48();
} - -

parser.AddFunction("rand", Rand, 0); - -

Important note: If you use the Optimize() method, -it will assume that the user-given function has no side-effects, that is, -it always returns the same value for the same parameters. The optimizer will -optimize the function call away in some cases, making this assumption. -(The Rand() function given as example above is one such -problematic case.) - - -


- -
-bool AddFunction(const std::string& name, FunctionParser&);
-
- -

This method is almost identical to the previous AddFunction(), -but instead of taking a C++ function, it takes another FunctionParser -instance. - -

There are some important restrictions on making a FunctionParser instance - call another: - -

- -

Example: - -

FunctionParser f1, f2;
-

f1.Parse("x*x", "x");
-

f2.AddFunction("sqr", f1); - -

This version of the AddFunction() method can be useful to -eg. chain user-given functions. For example, ask the user for a function F1, - and then ask the user another function F2, but now the user can - call F1 in this second function if he wants (and so on with a third - function F3, where he can call F1 and F2, etc). - -


- -
-template<typename DerivedWrapper>
-bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&,
-                        unsigned paramsAmount);
-
- -

See section on specialized function objects. - -


- -
-bool RemoveIdentifier(const std::string& name);
-
- -

If a constant, unit or user-defined function with the specified name -exists in the parser, it will be removed and the return value will be -true, else nothing will be done and the return value will be -false. - -

(Note: If you want to remove everything from an existing -FunctionParser instance, simply assign a fresh instance to it, ie. like -"parser = FunctionParser();") - -


- -
-int ParseAndDeduceVariables(const std::string& function,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::string& resultVarString,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::vector<std::string>& resultVars,
-                            bool useDegrees = false);
-
- -

These functions work in the same way as the Parse() function, -but the variables in the input function string are deduced automatically. The -parameters are: - -

- -

As with Parse(), the return value will be -1 if -the parsing succeeded, else an index to the location of the error. None of -the specified return values will be modified in case of error. - - - -

Specialized function objects

- -

The AddFunction() method can be used to add a new user-defined -function to the parser, its implementation being called through a C++ function -pointer. Sometimes this might not be enough, though. For example, one might -want to use boost::function or other similar specialized stateful -function objects instead of raw function pointers. This library provides a -mechanism to achieve this. - -

Creating and adding a specialized function object

- -

In order to create a specialized function object, create a class derived -from the FunctionParser::FunctionWrapper class. This class -declares a virtual function named callFunction that the derived -class must implement. For example: - -

-class MyFunctionWrapper:
-    public FunctionParser::FunctionWrapper
-{
- public:
-    virtual double callFunction(const double* values)
-    {
-        // Perform the actual function call here, like:
-        return someFunctionSomewhere(values);
-
-        // In principle the result could also be
-        // calculated here, like for example:
-        return values[0] * values[0];
-    }
-};
-
- -

You can then add an instance of this class to FunctionParser -using the AddFunctionWrapper() method, which works like -AddFunction(), but takes a wrapper object instead of a function -pointer as parameter. For example: - -

-MyFunctionWrapper wrapper;
-parser.AddFunctionWrapper("funcName", wrapper, 1);
-
- -

Note that FunctionParser will internally create a copy of -the wrapper object, managing the lifetime of this copy, and thus the object -given as parameter does not need to exist for as long as the -FunctionParser instance. Hence the above could also be written as: - -

-parser.AddFunctionWrapper("funcName", MyFunctionWrapper(), 1);
-
- -

Note that this also means that the wrapper class must have a working -copy constructor. - -

Also note that if the FunctionParser instance is copied, all -the copies will share the same function wrapper objects given to the original. - -

Retrieving specialized function objects

- -

As noted, the library will internally make a copy of the wrapper object, -and thus it will be separate from the one which was given as parameter to -AddFunctionWrapper(). In some cases it may be necessary to -retrieve this wrapper object (for example to read or change its state). -This can be done with the GetFunctionWrapper() method, which -takes the name of the function and returns a pointer to the wrapper object, -or null if no such object exists with that name. - -

Note that the returned pointer will be of type -FunctionParser::FunctionWrapper. In order to get a pointer to -the actual derived type, the calling code should perform a -dynamic_cast, for example like this: - -

-MyFunctionWrapper* wrapper =
-    dynamic_cast<MyFunctionWrapper*>
-    (parser.GetFunctionWrapper("funcName"));
-
-if(!wrapper) { /* oops, the retrieval failed */ }
-else ...
-
- -

(Using dynamic cast rather than a static cast adds safety because if you -accidentally try to downcast to the wrong type, the pointer will become null.) - -

The calling code is free to modify the object in any way it wants, but it -must not delete it (because FunctionParser itself handles this). - - - - -

FunctionParserBase

- -

All the different parser types are derived from a templated base class -named FunctionParserBase. In normal use it's not necessary to -directly refer to this base class in the calling code. However, if the calling -code also needs to be templated (with respect to the numerical type), then -using FunctionParserBase directly is the easiest way to achieve -this. - -

For example, if you want to make a function that handles more than one -type of parser, it can be done like this: - -

-template<typename Value_t>
-void someFunction(FunctionParserBase<Value_t>& parser)
-{
-    // do something with 'parser' here
-}
-
- -

Now it's convenient to call that function with more than one type of -parser, for example: - -

-FunctionParser realParser;
-FunctionParser_cd complexParser;
-
-someFunction(realParser);
-someFunction(complexParser);
-
- -

Another example is a class that inherits from FunctionParser -which also wants to support different numerical types. Such class can be -declared as: - -

-template<typename Value_t>
-class SpecializedParser: public FunctionParserBase<Value_t>
-{
-    ...
-};
-
- - - -

Syntax

- - -

Numeric literals

- -

A numeric literal is a fixed numerical value in the input function string - (either a floating point value or an integer value, depending on the parser - type). - -

An integer literal can consist solely of numerical digits (possibly with - a preceding unary minus). For example, "12345". - -

If the literal is preceded by the characters "0x", it - will be interpreted as a hexadecimal literal, where digits can also include - the letters from 'A' to 'F' (in either uppercase - or lowercase). For example, "0x89ABC" (which corresponds to the - value 563900). - -

A floating point literal (only supported by the floating point type parsers) - may additionally include a decimal point followed by the decimal part of the - value, such as for example "12.34", optionally followed by a - decimal exponent. - -

A decimal exponent consists of an 'E' or 'e', - followed by an optional plus or minus sign, followed by decimal digits, and - indicates multiplication by a power of 10. For example, "1.2e5" - (which is equivalent to the value 120000). - -

If a floating point literal is preceded by the characters "0x" - it will be interpreted in hexadecimal. A hexadecimal floating point - literal consists of a hexadecimal value, with an optional decimal point, - followed optionally by a binary exponent in base 10 (in other words, the - exponent is not in hexadecimal). - -

A binary exponent has the same format as a decimal exponent, except that - 'P' or 'p' is used. A binary exponent indicates - multiplication by a power of 2. For example, "0xA.Bp10" - (which is equivalent to the value 10944). - -

With the complex versions of the library, the imaginary part of a numeric - literal is written as a regular numeric literal with an 'i' - appended, for example "5i". Note that when also specifying - the real part of a complex literal, parentheses should be used to avoid - precedence problems. (For example, "(2+5i) * x" - is not the same thing as "2+5i * x". The latter - would be equivalent to "2 + (5i * x)".) - - -

Identifier names

- -

An identifier is the name of a function (internal or user-defined), - variable, constant or unit. New identifiers can be specified with the - functions described in the earlier subsections in this document. - -

The name of an identifier can use any alphanumeric characters, the - underscore character and any UTF8-encoded unicode character, excluding - those denoting whitespace. - The first character of the name cannot be a numeric digit, though. - -

All functions, variables, constants and units must use unique names. - It's not possible to add two different identifiers with the same name. - - - - -

The function string syntax

- -

The function string understood by the class is very similar (but not -completely identical in all aspects) to mathematical expressions in the -C/C++ languages. -Arithmetic float expressions can be created from float literals, variables -or functions using the following operators in this order of precedence: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
()expressions in parentheses first
A unita unit multiplier (if one has been added)
A^Bexponentiation (A raised to the power B)
-Aunary minus
!Aunary logical not (result is 1 if int(A) is 0, else 0)
A*B A/B A%Bmultiplication, division and modulo
A+B A-Baddition and subtraction
A=B A<B A<=B
A!=B A>B A>=B
comparison between A and B (result is either 0 or 1)
A&Bresult is 1 if int(A) and int(B) differ from - 0, else 0.
- Note: Regardless of the values, both operands are always - evaluated. However, if the expression is optimized, it may - be changed such that only one of the operands is evaluated, - according to standard shortcut logical operation semantics.
A|Bresult is 1 if int(A) or int(B) differ from 0, - else 0.
- Note: Regardless of the values, both operands are always - evaluated. However, if the expression is optimized, it may - be changed such that only one of the operands is evaluated, - according to standard shortcut logical operation semantics.
- -

(Note that currently the exponentiation operator is not supported for - FunctionParser_li nor FunctionParser_gmpint. - With the former the result would very easily overflow, making its - usefulness questionable. With the latter it could be easily abused to - make the program run out of memory; think of a function like - "10^10^10^100000".) - -

Since the unary minus has higher precedence than any other operator, for - example the following expression is valid: x*-y - -

The comparison operators use an epsilon value, so expressions which may -differ in very least-significant digits should work correctly. For example, -"0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 1" should always -return 1, and the same comparison done with ">" or -"<" should always return 0. (The epsilon value can be -configured in the fpconfig.hh file.) -Without epsilon this comparison probably returns the wrong value. - -

The class supports these functions: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
abs(A)Absolute value (magnitude) of A. - With real numbers, if A is negative, returns -A otherwise returns A. - With complex numbers, equivalent to hypot(real(x),imag(x)).
acos(A)Arc-cosine of A. Returns the angle, measured in radians, whose cosine is A.
acosh(A)Same as acos() but for hyperbolic cosine.
arg(A)Phase angle of complex number A. Equivalent to atan2(imag(x),real(x)).
asin(A)Arc-sine of A. Returns the angle, measured in radians, whose sine is A.
asinh(A)Same as asin() but for hyperbolic sine.
atan(A)Arc-tangent of (A). Returns the angle, measured in radians, - whose tangent is A.
atan2(A,B)Principal arc-tangent of A/B, using the signs of the - two arguments to determine the quadrant of the result. - Returns the solution to the two expressions - hypot(A,B)*sin(x)=A, hypot(A,B)*cos(x)=B. - The return value is in range -pi to pi, inclusive.
atanh(A)Same as atan() but for hyperbolic tangent.
cbrt(A)Cube root of A. Returns a solution to expression pow(x,3)=A.
conj(A)Complex conjugate of A. Equivalent to real(x) - 1i*imag(x) or polar(abs(x),-arg(x)).
ceil(A)Ceiling of A. Returns the smallest integer not smaller than A. - Rounds up to the next higher integer. E.g. -2.9, -2.5 and -2.1 are - rounded to -2.0, and 2.9, 2.5 and 2.1 are rounded to 3.0.
cos(A)Cosine of A. Returns the cosine of the angle A, where A is - measured in radians.
cosh(A)Same as cos() but for hyperbolic cosine.
cot(A)Cotangent of A. Equivalent to 1/tan(A).
csc(A)Cosecant of A. Equivalent to 1/sin(A).
eval(...)This a recursive call to the function to be evaluated. The - number of parameters must be the same as the number of parameters - taken by the function. Must be called inside if() to avoid - infinite recursion.
exp(A)Exponential of A. Returns the value of e raised to the power - A where e is the base of the natural logarithm, i.e. the - non-repeating value approximately equal to 2.71828182846.
exp2(A)Base 2 exponential of A. Equivalent to pow(2,A).
floor(A)Floor of A. Returns the largest integer not greater than A. Rounds - down to the next lower integer. - E.g. -2.9, -2.5 and -2.1 are rounded to -3.0, - and 2.9, 2.5 and 2.1 are rounded to 2.0.
hypot(A,B)Euclidean distance function. Equivalent to sqrt(A^2+B^2).
if(A,B,C)If int(A) differs from 0, the return value of this function is B, - else C. Only the parameter which needs to be evaluated is - evaluated, the other parameter is skipped; this makes it safe to - use eval() in them.
imag(A)Return the imaginary part of complex number A. Equivalent to abs(A)*sin(arg(A)).
int(A)Rounds A to the closest integer. Equidistant values are rounded away from - zero. E.g. -2.9 and -2.5 are rounded to -3.0; -2.1 is rounded to -2.0, - and 2.9 and 2.5 are rounded to 3.0; 2.1 is rounded to 2.0.
log(A)Natural (base e) logarithm of A. Returns the solution to expression exp(x)=A.
log2(A)Base 2 logarithm of A. Equivalent to log(A)/log(2).
log10(A)Base 10 logarithm of A.
max(A,B)If A>B, the result is A, else B.
min(A,B)If A<B, the result is A, else B.
polar(A,B)Returns a complex number from magnitude A, phase angle B (in radians). - Equivalent to real(A)*(cos(real(B))+1i*sin(real(B))).
pow(A,B)Exponentiation (A raised to the power B).
real(A)Return the real part of complex number A. Equivalent to abs(A)*cos(arg(A)).
sec(A)Secant of A. Equivalent to 1/cos(A).
sin(A)Sine of A. Returns the sine of the angle A, where A is - measured in radians.
sinh(A)Same as sin() but for hyperbolic sine.
sqrt(A)Square root of A. Returns a solution to expression pow(x,2)=A.
tan(A)Tangent of A. Returns the tangent of the angle A, where A - is measured in radians.
tanh(A)Same as tan() but for hyperbolic tangent.
trunc(A)Truncated value of A. Returns an integer corresponding to the value - of A without its fractional part. - E.g. -2.9, -2.5 and -2.1 are rounded to -2.0, - and 2.9, 2.5 and 2.1 are rounded to 2.0.
- -

(Note that for FunctionParser_li and - FunctionParser_gmpint only the functions - abs(), eval(), if(), - min() and max() are supported.) - -

Examples of function string understood by the class: - -

"1+2"
-"x-1"
-"-sin(sqrt(x^2+y^2))"
-"sqrt(XCoord*XCoord + YCoord*YCoord)"
- -

An example of a recursive function is the factorial function: - -"if(n>1, n*eval(n-1), 1)" - -

Note that a recursive call has some overhead, which makes it a bit slower - than any other operation. It may be a good idea to avoid recursive functions - in very time-critical applications. Recursion also takes some memory, so - extremely deep recursions should be avoided (eg. millions of nested recursive - calls). - -

Also note that even though the maximum recursion level of -eval() is limited, it is possible to write functions which -never reach that level but still take enormous amounts of time to evaluate. -This can sometimes be undesirable because it is prone to exploitation, -which is why eval() is disabled by default. It can be enabled -in the fpconfig.hh file. - - - - -

Inline variables

- -

The function syntax supports defining new variables inside the function -string itself. This can be done with the following syntax: - -

"<variable name> := <expression>; <function>" - -

For example: - -

"length := sqrt(x*x+y*y); 2*length*sin(length)" - -

(Spaces around the ':=' operator are optional.) - -

The obvious benefit of this is that if a long expression needs to be -used in the function several times, this allows writing it only once and -using a named variable from that point forward. - -

The variable name must be an unused identifier (in other words, not an -existing function, variable or unit name). - -

The <function> part can have further inline variable -definitions, and thus it's possible to have any amount of them, for example: - -

"A := x^2; B := y^2; C := z^2; sqrt(A+B+C)" - -

The expressions in subsequent inline variable definitions can use any -of the previous inline variables. It is also possible to redefine an inline -variable. For example: - -

"A := x^2; A := 2*A; sqrt(A)" - - - - -

Whitespace

- -

Arbitrary amounts of whitespace can optionally be included between - elements in the function string. - The following unicode characters are interpreted as whitespace: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Character numberCharacter nameUTF-8 byte sequence
U+0009HORIZONTAL TABULATION 09
U+000ALINE FEED 0A
U+000BVERTICAL TABULATION 0B
U+000DCARRIAGE RETURN 0D
U+0020SPACE 20
U+00A0NO-BREAK SPACE C2 A0
U+2000EN QUAD E2 80 80
U+2001EM QUAD E2 80 81
U+2002EN SPACE E2 80 82
U+2003EM SPACE E2 80 83
U+2004THREE-PER-EM SPACE E2 80 84
U+2005FOUR-PER-EM SPACE E2 80 85
U+2006SIX-PER-EM SPACE E2 80 86
U+2007FIGURE SPACE E2 80 87
U+2008PUNCTUATION SPACE E2 80 88
U+2009THIN SPACE E2 80 89
U+200AHAIR SPACE E2 80 8A
U+200BZERO WIDTH SPACE E2 80 8B
U+202FNARROW NO-BREAK SPACE E2 80 AF
U+205FMEDIUM MATHEMATICAL SPACEE2 81 9F
U+3000IDEOGRAPHIC SPACE E3 80 80
- - -

Miscellaneous

- - -

About floating point accuracy

- -

Note that if you are using FunctionParser_ld or -FunctionParser_cld and you want calculations to be as accurate -as the long double type allows, you should pay special attention -to floating point literals in your own code. For example, this is a very -typical mistake: - -

FunctionParser_ld parser;
-parser.AddConstant("pi", 3.14159265358979323846);
- -

The mistake might not be immediately apparent. The mistake is that a -literal of type double is passed to the AddConstant() -function even though it expects a value of type long double. -In most systems the latter has more bits of precision than the former, which -means that the value will have its least-significant bits clipped, -introducing a rounding error. The proper way of making the above calls is: - -

FunctionParser_ld parser;
-parser.AddConstant("pi", 3.14159265358979323846L);
- -

The same principle should be used everywhere in your own code, if you are -using the long double type. - -

This is especially important if you are using the MpfrFloat -type (in which case its string-parsing constructor or its -ParseValue() or parseString() member functions -should be used instead of using numerical literals). - - -

About evaluation-time checks

- -

FunctionParser::Eval() will perform certain sanity -checks before performing certain operations. For example, before calling the -sqrt function, it will check if the parameter is negative, and -if so, it will set the proper error code instead of calling the function. -These checks include: - -

- -

However, the library can not guarantee that it will catch all -possible floating point errors before performing them, because this is -impossible to do with standard C++. For example, dividing a very large -value by a value which is very close to zero, or calculating the logarithm -of a very small value may overflow the result, as well as multiplying two -very large values. Raising a negative number to a non-integral power may -cause a NaN result, etc. - -

As a rule of thumb, the library will (by default) detect invalid operations -if they are invalid for a range of values. For example, square root is undefined -for all negative values, and arc sine is undefined only values outside the range -[-1, 1]. In general, operations which are invalid for only one single value -(rather than a contiguous range of values) will not be detected (division by -the exact value of zero is an exception to this rule) nor will -overflow/underflow situations. - -

The library cannot guarantee that floating point -errors will never happen during evaluation. This can make the library to -return the floating point values inf and NaN. Moreover, -if floating point errors cause an interrupt in the target computer -architecture and/or when using certain compiler settings, this library -cannot guarantee that it will never happen. - -

Note that the optimizer never performs any sanity checks. - - - - -

About thread safety

- -

None of the member functions of the FunctionParser class are thread-safe. -Most prominently, the Eval() function is not thread-safe. -(In other words, the Eval() function of a single FunctionParser -instance cannot be safely called simultaneously by two threads.) - -

There are ways to use this library in a thread-safe way, though. If each -thread uses its own FunctionParser instance, no problems will obviously -happen. Note, however, that if these instances need to be a copy of a given -FunctionParser instance (eg. one where the user has entered a function), -a deep copy of this instance has to be performed for each thread. By -default FunctionParser uses shallow-copying (copy-on-write), which means -that a simple assignment of copy construction will not copy the data itself. -To force a deep copy you can all the ForceDeepCopy() function on -each of the instances of each thread after the assignment or copying has been -done. - -

Another possibility is to compile the FunctionParser library so that -its Eval() function will be thread-safe. (This can be done by -defining the FP_USE_THREAD_SAFE_EVAL or the -FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA -precompiler constant.) As long as only one thread calls the other functions -of FunctionParser, the other threads can safely call the Eval() -of this one instance. - -

Note, however, that compiling the library like this can make -Eval() slightly slower. (The alloca version, if -supported by the compiler, will not be as slow.) - -

Also note that the MPFR and GMP versions of the library cannot be - made thread-safe, and thus this setting has no effect on them. - - - - -

Tips and tricks

- -

Add constants automatically to all parser objects

- -

Often the same constants (such as pi and e) and other -user-defined identifiers (such as units) are always used in all the -FunctionParser objects throughout the program. It would be -troublesome to always have to manually add these constants every time a -new parser object is created. - -

There is, however, a simple way to always add these user-defined identifiers -to all instances. Write a class like this: - -

-    class ParserWithConsts: public FunctionParser
-    {
-     public:
-        ParserWithConsts()
-        {
-            AddConstant("pi", 3.14159265358979323846);
-            AddConstant("e", 2.71828182845904523536);
-        }
-    };
-
- -

Now instead of using FunctionParser, always use -ParserWithConsts. It will behave identically except that the -constants (and possibly other user-defined identifiers) will always be -automatically defined. (Objects of this type even survive -slicing, so -they are completely safe to use anywhere.) - - - - -

Contacting the author

- -

Any comments, bug reports, etc. should be sent to warp@iki.fi - - - - - - - - -

Usage license

- -

Copyright © 2003-2011 Juha Nieminen, Joel Yliluoma - -

This Library is distributed under the - Lesser General Public - License (LGPL) version 3. - - - diff --git a/deal.II/contrib/functionparser/docs/gpl.txt b/deal.II/contrib/functionparser/docs/gpl.txt deleted file mode 100644 index 94a9ed024d..0000000000 --- a/deal.II/contrib/functionparser/docs/gpl.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/deal.II/contrib/functionparser/docs/lgpl.txt b/deal.II/contrib/functionparser/docs/lgpl.txt deleted file mode 100644 index cca7fc278f..0000000000 --- a/deal.II/contrib/functionparser/docs/lgpl.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/deal.II/contrib/functionparser/docs/style.css b/deal.II/contrib/functionparser/docs/style.css deleted file mode 100644 index d5141d3ae6..0000000000 --- a/deal.II/contrib/functionparser/docs/style.css +++ /dev/null @@ -1,80 +0,0 @@ -html -{ - background-color: #E0E0E0; -} - -body -{ - background-color: white; - margin-left: 7%; - margin-top: 16px; - margin-right: 7%; - padding-top: 2em; - padding-left: 7%; - padding-right: 7%; - padding-bottom: 2%; - border-color: black; - border: solid; - border-width: 1px; -} - -h1 -{ - text-align: center; - background-color: #FFEEBB; - padding-bottom: 0.2em; - padding-top: 0.1em; -} - -h2 -{ - background-color: #FFFFCC; - padding-left: 0.5em; -} - -h3 -{ - background-color: #FFFFEE; -} - -blockquote -{ - padding-left: 2em; - padding-right: 2em; - font-style: italic; - background-color: #FFFAF0; -} - -li -{ - padding-top: 0.3em; -} - -pre -{ - background-color: #E8E8E8; - padding-left: 1em; - padding-top: 0.5em; - padding-bottom: 0.5em; -} - -code -{ - font-family: monospace; - color: #900040; -} - -.small -{ - font-size: 80%; -} - -.codecomment -{ - color: green; -} - -.highlight -{ - background: #C0D0FF; -} diff --git a/deal.II/contrib/functionparser/examples/example.cc b/deal.II/contrib/functionparser/examples/example.cc deleted file mode 100644 index b4ab5f45c8..0000000000 --- a/deal.II/contrib/functionparser/examples/example.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Simple example file for the function parser -// =========================================== - -/* When running the program, try for example with these values: - -f(x) = x^2 -min x: -5 -max x: 5 -step: 1 - -*/ - -#include "../fparser.hh" - -#include -#include - -int main() -{ - std::string function; - double minx, maxx, step; - FunctionParser fparser; - - fparser.AddConstant("pi", 3.1415926535897932); - - while(true) - { - std::cout << "f(x) = "; - std::getline(std::cin, function); - if(std::cin.fail()) return 0; - - int res = fparser.Parse(function, "x"); - if(res < 0) break; - - std::cout << std::string(res+7, ' ') << "^\n" - << fparser.ErrorMsg() << "\n\n"; - } - - std::cout << "min x: "; - std::cin >> minx; - std::cout << "max x: "; - std::cin >> maxx; - std::cout << "step: "; - std::cin >> step; - if(std::cin.fail()) return 0; - - double vals[] = { 0 }; - for(vals[0] = minx; vals[0] <= maxx; vals[0] += step) - { - std::cout << "f(" << vals[0] << ") = " << fparser.Eval(vals) - << std::endl; - } - - return 0; -} diff --git a/deal.II/contrib/functionparser/examples/example2.cc b/deal.II/contrib/functionparser/examples/example2.cc deleted file mode 100644 index 958b9a1e6c..0000000000 --- a/deal.II/contrib/functionparser/examples/example2.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Simple example file for the function parser -// =========================================== -/* Note that the library has to be compiled with - FP_SUPPORT_FLOAT_TYPE, FP_SUPPORT_LONG_DOUBLE_TYPE and - FP_SUPPORT_LONG_INT_TYPE - preprocessor macros defined for this example to work. - - Try with these input values with the different floating point parser - types to see the difference in accuracy: - -f(x) = x + 1.234567890123456789 -min x: 0 -max x: 2 -step: 1 -*/ - -#include "../fparser.hh" - -#include -#include -#include - -template -void runExample(const char* valueTypeName) -{ - typedef typename Parser::value_type Value_t; - - std::cout << "Using " << valueTypeName << " parser." << std::endl; - - Parser fparser; - std::string function; - Value_t minx, maxx, step; - - fparser.AddConstant("pi", Value_t(3.1415926535897932)); - - std::cin.ignore(); - while(true) - { - std::cout << "f(x) = "; - std::getline(std::cin, function); - if(std::cin.fail()) return; - - int res = fparser.Parse(function, "x"); - if(res < 0) break; - - std::cout << std::string(res+7, ' ') << "^\n" - << fparser.ErrorMsg() << "\n\n"; - } - - std::cout << "min x: "; - std::cin >> minx; - std::cout << "max x: "; - std::cin >> maxx; - std::cout << "step: "; - std::cin >> step; - if(std::cin.fail()) return; - - Value_t vals[] = { 0 }; - for(vals[0] = minx; vals[0] <= maxx; vals[0] += step) - { - std::cout << std::setprecision(20); - std::cout << "f(" << vals[0] << ") = " << fparser.Eval(vals) - << std::endl; - } -} - -int main() -{ - int choice = 0; - do - { - std::cout << "1 = double, 2 = float, 3 = long double, 4 = long int: "; - std::cin >> choice; - } while(choice < 1 || choice > 4); - - switch(choice) - { - case 1: runExample("double"); break; - case 2: runExample("float"); break; - case 3: runExample("long double"); break; - case 4: runExample("long int"); break; - } - - return 0; -} diff --git a/deal.II/contrib/functionparser/extrasrc/fp_identifier_parser.inc b/deal.II/contrib/functionparser/extrasrc/fp_identifier_parser.inc deleted file mode 100644 index 00d5081a7f..0000000000 --- a/deal.II/contrib/functionparser/extrasrc/fp_identifier_parser.inc +++ /dev/null @@ -1,379 +0,0 @@ -/* NOTE: - Do not include this file in your project. The fparser.cc 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). - - 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 -to be modified by hand. -*/ - - unsigned nameLength = 0; - const unsigned maximumNameLength = 0x80000000U-8; - /* - Due to the manner the identifier lengths are returned from - the readOpcode() function, the maximum supported length for - identifiers is 0x7FFFFFFF bytes. We minus 8 here to add some - buffer, because of the multibyteness of UTF-8. - Function names are limited to 0xFFFF bytes instead, but because - function names that long just are not defined, the point is moot. - */ - const unsigned char* const uptr = (const unsigned char*) input; - typedef signed char schar; - while(likely(nameLength < maximumNameLength)) - { - unsigned char byte = uptr[nameLength+0]; - /* Handle the common case of A-Za-z first */ - if(byte >= 0x40) - { - if(byte < 0x80) // 0x40..0x7F - most common case - { - // Valid characters in 40..7F: A-Za-z_ - // Valid bitmask for 40..5F: 01111111111111111111111111100001 - // Valid bitmask for 60..7F: 01111111111111111111111111100000 - if(sizeof(unsigned long) == 8) - { - const unsigned n = sizeof(unsigned long)*8-32; - // ^ avoids compiler warning when not 64-bit - unsigned long masklow6bits = 1UL << (byte & 0x3F); - if(masklow6bits & ~((1UL << 0) | (0x0FUL << (0x1B )) - | (1UL << n) | (0x1FUL << (0x1B+n)))) - { ++nameLength; continue; } - } - else - { - unsigned masklow5bits = 1 << (byte & 0x1F); - if((masklow5bits & ~(1 | (0x1F << 0x1B))) || byte == '_') - { ++nameLength; continue; } - } - break; - } - if(byte < 0xF0) - { - if(byte < 0xE0) - { - if(byte < 0xC2) break; // 0x80..0xC1 - if(byte == 0xC2 && uptr[nameLength+1]==0xA0) break; // skip nbsp - // C2-DF - next common case when >= 0x40 - // Valid sequence: C2-DF 80-BF - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - nameLength += 2; - continue; - } - if(byte == 0xE0) // E0 - { - // Valid sequence: E0 A0-BF 80-BF - if((unsigned char)(uptr[nameLength+1] - 0xA0) > (0xBF-0xA0)) break; - } - else - { - if(byte == 0xED) break; // ED is invalid - // Valid sequence: E1-EC 80-BF 80-BF - // And: EE-EF 80-BF 80-BF - if(byte == 0xE2) - { - // break on various space characters - if(uptr[nameLength+1] == 0x80 - && (schar(uptr[nameLength+2]) <= schar(0x8B) - || (uptr[nameLength+2] == 0xAF))) break; - if(uptr[nameLength+1] == 0x81 - && uptr[nameLength+2] == 0x9F) break; - } else - if(byte == 0xE3 && uptr[nameLength+1] == 0x80 - && uptr[nameLength+2] == 0x80) break; // this too - - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - } - if(schar(uptr[nameLength+2]) > schar(0xBF)) break; - nameLength += 3; - continue; - } - if(byte == 0xF0) // F0 - { - // Valid sequence: F0 90-BF 80-BF 80-BF - if((unsigned char)(uptr[nameLength+1] - 0x90) > (0xBF-0x90)) break; - } - else - { - if(byte > 0xF4) break; // F5-FF are invalid - if(byte == 0xF4) // F4 - { - // Valid sequence: F4 80-8F - if(schar(uptr[nameLength+1]) > schar(0x8F)) break; - } - else - { - // F1-F3 - // Valid sequence: F1-F3 80-BF 80-BF 80-BF - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - } - } - if(schar(uptr[nameLength+2]) > schar(0xBF)) break; - if(schar(uptr[nameLength+3]) > schar(0xBF)) break; - nameLength += 4; - continue; - } - if(nameLength > 0) - { - if(sizeof(unsigned long) == 8) - { - // Valid bitmask for 00..1F: 00000000000000000000000000000000 - // Valid bitmask for 20..3F: 00000000000000001111111111000000 - const unsigned n = sizeof(unsigned long)*8-32; - // ^ avoids compiler warning when not 64-bit - unsigned long masklow6bits = 1UL << byte; - if(masklow6bits & (((1UL << 10)-1UL) << (16+n))) - { ++nameLength; continue; } - } - else - { - if(byte >= '0' && byte <= '9') - { ++nameLength; continue; } - } - } - break; - } - - /* This function generated with make_function_name_parser.cc */ -#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 l1 3]={ -#define lH case -#define lG 0x80000005U; -#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;}lH -#define l6 <<16)| -#define l5 ==uptr[ -#define l4 lJ l0 3; -#define l3 0x80000004U;l0 4; -#define l2 lD 1,tmp, -#define l1 static const char tmp[ -#define l0 return -lN -nameLength){lH -2:lL -0]&&'f'l5 -1])l0(cIf -l6 -0x80000002U;l0 -2;lH -3 -lA -0]){lH -l9'b':if('s'l5 -2])l0(cAbs -l6 -lM'r':if('g'l5 -2])l0(cArg -l6 -l4 -lE'c'lB'o'lA -2]){lH's':l0(cCos -l6 -lJ -lH't':l0(cCot -l6 -lJ -lE's':if('c'l5 -2])l0(cCsc -l6 -l4 -lE'e':if('x'l5 -1]&&'p'l5 -2])l0(cExp -l6 -lM'i':if(lK -1]&&'t'l5 -2])l0(cInt -l6 -lM'l':if('o'l5 -1]&&'g'l5 -2])l0(cLog -l6 -lM'm'lB'a':if('x'l5 -2])l0(cMax -l6 -lM'i':if(lK -2])l0(cMin -l6 -l4 -lE'p':if('o'l5 -1]&&'w'l5 -2])l0(cPow -l6 -lM's'lB'e':if('c'l5 -2])l0(cSec -l6 -lM'i':if(lK -2])l0(cSin -l6 -l4 -lE't':if('a'l5 -1]&&lK -2])l0(cTan -l6 -l4 -lE -4 -lA -0]){lH -l9'c':if('o'l5 -2]&&'s'l5 -3])l0(cAcos -l6 -lO's':lL -2]&&lK -3])l0(cAsin -l6 -lO't':if('a'l5 -2]&&lK -3])l0(cAtan -l6 -l3 -l8 -4;} -lH'c'lB'b':if('r'l5 -2]&&'t'l5 -3])l0(cCbrt -l6 -lO'e':lL -2]&&'l'l5 -3])l0(cCeil -l6 -lO'o'lA -2]){lH'n':if('j'l5 -3])l0(cConj -l6 -lO's':if('h'l5 -3])l0(cCosh -l6 -l3 -l8 -4;} -l8 -4;} -lH'e':{lI'x','p','2'} -;if(lC -cExp2 -l6 -l3} -lH'i':{lI'm','a','g'} -;if(lC -cImag -l6 -l3} -lH'l':{lI'o','g','2'} -;if(lC -cLog2 -l6 -l3} -lH'r':{lI'e','a','l'} -;if(lC -cReal -l6 -l3} -lH's'lB'i':if(lK -2]&&'h'l5 -3])l0(cSinh -l6 -lO'q':if('r'l5 -2]&&'t'l5 -3])l0(cSqrt -l6 -l3 -l8 -4;} -lH't':{lI'a','n','h'} -;if(lC -cTanh -l6 -l3} -l8 -4;} -lH -5 -lA -0]){lH -l9'c':{lI'o','s','h'} -;if(lD -2,tmp,3 -lF -cAcosh -l6 -l7's':{lI'i','n','h'} -;if(lD -2,tmp,3 -lF -cAsinh -l6 -l7't':if('a'l5 -2]){if(lK -3]){lN -uptr[4]){lH'2':l0(cAtan2 -l6 -lG -lH'h':l0(cAtanh -l6 -lG -l8 -5;} -} -l0 -5;} -l0 -5;l8 -5;} -lH'f':{l1 -4]={'l','o','o','r'} -;if(l2 -4 -lF -cFloor -l6 -l7'h':{l1 -4]={'y','p','o','t'} -;if(l2 -4 -lF -cHypot -l6 -l7'l':{l1 -4]={'o','g','1','0'} -;if(l2 -4 -lF -cLog10 -l6 -l7'p':{l1 -4]={'o','l','a','r'} -;if(l2 -4 -lF -cPolar -l6 -l7't':{l1 -4]={'r','u','n','c'} -;if(l2 -4 -lF -cTrunc -l6 -lG -l0 -5;} -l8 -5;} -default:break;} -l0 -nameLength; \ No newline at end of file diff --git a/deal.II/contrib/functionparser/extrasrc/fp_opcode_add.inc b/deal.II/contrib/functionparser/extrasrc/fp_opcode_add.inc deleted file mode 100644 index cb7280ca44..0000000000 --- a/deal.II/contrib/functionparser/extrasrc/fp_opcode_add.inc +++ /dev/null @@ -1,7748 +0,0 @@ -/* Function Parser for C++ v4.5 - - NOTE: - Do not include this file in your project. The fparser.cc 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 contains generated code and is thus not intended to be to -be modified by hand. It was generated by util/bytecoderules_parser, which -is available in the development package. -*/ -#define HasInvalidRangesOpcode HasInvalidRangesOpcode::result> -#define FP_TRACE_BYTECODE_OPTIMIZATION(srcline,from,to,with) \ - /*std::cout << "Changing \"" from "\"\t(line " #srcline ")\n" \ - " into \"" to "\"\n" with << std::flush*/ -#define FP_TRACE_OPCODENAME(op) \ - (op < VarBegin \ - ? FP_GetOpcodeName(OPCODE(op)) \ - : findName(mData->mNamePtrs,op,NameData::VARIABLE)) -#define FP_TRACE_BYTECODE_ADD(opcode) \ - /*std::cout << "Adding opcode: " << FP_TRACE_OPCODENAME(opcode) \ - << ", bytecode length " << data->ByteCode.size() \ - << ", pointer is " << (void*)ByteCodePtr \ - << ", code is " << (data->ByteCode.empty() \ - ? (void*)0 \ - : (void*)&data->ByteCode[0]) \ - << std::endl*/ -#define q81 "cNeg" -#define q71 <<","aP -#define q61 wA","aP -#define q51 <<","aQ -#define q41 ", "wU<<"," -#define q31 wA","aE -#define q21 "B[IsVarOpcode(B)]"m7 -#define q11 );qW q6 -#define q01 "cSqrt" -#define mZ "cSqr " -#define mY ){hD wB -#define mX "cSec" -#define mW "cCeil" -#define mV "A "a3 -#define mU "cImag" -#define mT "cConj" -#define mS a4" "a6 -#define mR hO wB -#define mQ "cAbs" -#define mP qS w2 wB -#define mO "cFloor" -#define mN "cTan" -#define mM "cSin" -#define mL (y hX; -#define mK " "aS -#define mJ "[ y+x]" -#define mI hV 2 gC -#define mH "cExp" -#define mG "cNeg " -#define mF " cSub" -#define mE " cDup" -#define mD " cNeg" -#define mC "cDup " -#define mB "cLess" -#define mA "cLog" -#define m9 "cMin" -#define m8 "cMax" -#define m7 " cDiv" -#define m6 wH" " -#define m5 (x);gJ -#define m4 " "wU wM -#define m3 aU"x " -#define m2 gN wB -#define m1 g1 oG wB -#define m0 "B cSqr" -#define aZ "[y*x]" -#define aY oH dE wB -#define aX mQ" " -#define aW "cGreater" -#define aV " cAdd" -#define aU "y " -#define aT gY if(dO wB -#define aS "cInv" -#define aR mC aS -#define aQ " B"a0 -#define aP " "aO -#define aO "A"a0 -#define aN "cAbsNot" -#define aM "cLessOrEq" -#define aL "cAdd "q01 -#define aK "cCos" -#define aJ "cLog2" -#define aI "cCosh" -#define aH "cLog10" -#define aG "B[B==A]" -#define aF "cNotNot" -#define aE " "wG -#define aD "A[IsVarOpcode(A)]" -#define aC " "aD" " -#define aB " cNot" -#define aA " "a2 -#define a9 "cDup"aV -#define a8 "cGreaterOrEq" -#define a7 " cRDiv" -#define a6 "x"aV -#define a5 "cEqual" -#define a4 "cRSub" -#define a3 "[x]"wH -#define a2 " with"aP -#define a1 " cPow" -#define a0 " "wC -#define wZ "x[x!=Value_t()] " -#define wY " x"wH -#define wX "x[x==Value_t()]"wH -#define wW "cNEqual" -#define wV aD m7 -#define wU "x = "<Value_t(0)]" -#define wP "B[IsNeverNegativeValueOpcode(B)] " -#define wO "x[x==Value_t(1)] " -#define wN wA"\n" -#define wM <<"\n" -#define wL "x[x==Value_t(0)] " -#define wK "B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] "wD -#define wJ "A[IsNeverNegativeValueOpcode(A)] " -#define wI "A[IsVarOpcode(A)&&mData->mByteCode.size()>2] " -#define wH " cMul" -#define wG aU"= "<oP){ -#define dN mImmed -#define dM qE h3 gX -#define dL qK dJ w3 -#define dK cGreaterOrEq -#define dJ =q6; -#define dI qK dJ g6 -#define dH Value_t -#define dG q8 2 gH q4 -#define dF q0[0] -#define dE qK qR qX -#define dD qK qR IsLogicalOpcode(h2 -#define dC (qK== -#define dB hB oY -#define dA qY g8 oG -#define d9 pop_back() -#define d8 q6;q1 h3 gI -#define d7 q8 2 gC -#define d6 hR Lba; -#define d5 Default4 qU -#define d4 :if( -#define d3 qV hS d4 qL -#define d2 h3 gM if -#define d1 IsVarOpcode( -#define d0 mData-> -#define hZ ]qR w4 -#define hY gX Llq -#define hX ,x gX Lap -#define hW gT y+x;q8 -#define hV for qA -#define hU gQ cAbs: -#define hT unsigned -#define hS cAdd -#define hR ,y gX -#define hQ qL 3 hZ -#define hP y=q3-1]qR -#define hO y gO -#define hN qY if(dP -#define hM q6:qC -#define hL :if gF -#define hK qQ h9 hS hL -#define hJ 4 qZ mR(292,aU"cAdd B[IsVarOpcode(B)]"mF" "a6,mJ aV" B"mF,wA","aQ(B)<<","aE);q4 -#define hI cNeg: -#define hH :qS cDup: -#define hG hS hH hK h1 wB(310,a9" "a9,"[Value_t(4)]"wH,);q4 -#define hF (x!=g1 -#define hE qL 2] -#define hD B g4 w4 -#define hC B=hE qO B)){ -#define hB if hF 0)){ -#define hA gX Lng; -#define h9 qK qV -#define h8 }break; -#define h7 ()){ -#define h6 hR Lap; -#define h5 isEvenInteger( -#define h4 DegreesToRadians(x -#define h3 cMul -#define h2 A)){ -#define h1 ]==cDup){ -#define h0 hI wB(201,mG mQ,mQ,);q4 Lab qU qB -#define gZ 3 h1 wB(311,a9 m6 a9,"cMul [Value_t(4)]"wH,);q4 -#define gY qU hM -#define gX );q4 -#define gW y,x gX Lba; -#define gV IsUnaryOpcode( -#define gU g6 w5= -#define gT q3-1]= -#define gS gR qR IsAlwaysIntegerOpcode(h2 -#define gR ;oH dF -#define gQ )){qQ h9 -#define gP break gR qO A gQ -#define gO =q3-1]; -#define gN qJ hO -#define gM :qJ qC -#define gL d2(dO -#define gK ]=q6 q9 2 gH -#define gJ return; -#define gI );w5= -#define gH ;qI q5 -#define gG qL 2 gK q0-=2; -#define gF (qL 2 -#define gE y;hT B;hT -#define gD d0 mByteCode -#define gC ;qI q1 -#define gB q9 2 gC h3 gI -#define gA ){if gF -#define g9 oY h3 dV -#define g8 if(x==g1 -#define g7 default: -#define g6 q5 q0-=1; -#define g5 if(!q0){q2 -#define g4 =hE qR -#define g3 B g4 IsNeverNegativeValueOpcode(B)){ -#define g2 &&!HasInvalidRangesOpcode( -#define g1 dH( -#define g0 FP_ReDefinePointers(); -#define qZ ]==q6){ -#define qY if(q0[0 qZ qC -#define qX IsNeverNegativeValueOpcode(h2 -#define qW gD qD -#define qV ){case -#define qU ;case -#define qT }break qU -#define qS qQ dF qV -#define qR ;if( -#define qQ switch( -#define qP )&&gD oK> -#define qO qR d1 -#define qN dF w1 2){ -#define qM d0 dN.d9; -#define qL q0[- -#define qK qL 1] -#define qJ oY q6){ -#define qI tmp-->0;) -#define qH q4 Default0; -#define qG }}qH -#define qF d0 dN qD -#define qE AddFunctionOpcode( -#define qD .push_back( -#define qC x=q7; -#define qB hM wB(132,"x "mQ,"[fp_abs(x)]",wN);q4 Lac; -#define qA (hT tmp= -#define q9 ;hV -#define q8 d0 dN.d9 q9 -#define q7 q3 0] -#define q6 cImmed -#define q5 gD.d9; -#define q4 goto -#define q3 dW[ -#define q2 q4 Laa;}case -#define q1 q5 qE -#define q0 ByteCodePtr -hT*q0;dH*dW; -#define FP_ReDefinePointers() q0=!gD.empty()?&gD[0]+gD oK-1:0;dW=!d0 dN.empty()?&d0 dN[0]+d0 dN oK-1:0; -g0 -wE(opcode); -#if(!(FP_COMPLEX_VERSION) && !(FP_FLOAT_VERSION)) -dH -x;hT -A;dH -gE -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0 -oH -dF -qR -qX -wB(393,wJ -mQ,"A" -,aA(A)wM);gJ -qG -TailCall_cAdd:g5 -hG -Lad;qT -h3 -hL]==hS){if(qL -gZ -Lae;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -wY -aV,"[x+Value_t(1)]" -wH,wN);q4 -Laf;} -} -q4 -dX -oF -wB(199,q81 -aV,"cSub" -,);q4 -Lag -gY -hK -qZ -mR(127,aU"cAdd " -a6,"[y+x]" -aV,q31);q4 -Lah;qT -cRSub:qQ -hE -d3 -3 -qZ -mR(298,aU"cAdd " -mS,mJ -aV" " -a4,q31);q4 -Lai;qT -hI -wB(299,mG -mS,"[-x]" -aV" " -a4,wN);q4 -Laj -qU -q6:mR(297,aU -mS,mJ" " -a4,q31);q4 -Lak;qT -oA -Lal;qT -hI -wB(293,mG"B[IsVarOpcode(B)]" -mF" " -a6,"[-x]" -aV" B" -mF,wA"," -aQ(B)wM);q4 -Lam -qU -q6:mR(291,aU"B[IsVarOpcode(B)]" -mF" " -a6,mJ" B" -mF,wA"," -aQ(B)<<"," -aE);q4 -Lan;} -w9 -mR(105,aU -a6,"[y+x]" -,q31);q4 -Lao;} -g8)){wB(57,"x[x==Value_t()]" -aV,,wN);q4 -Lap;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x " -a4 -aC"cAdd" -,"[DO_STACKPLUS1] A [x]" -aV" " -a4,aA(A)<<"," -m4);incStackPtr();--mStackPtr;q4 -Laq;} -wB(295,a4 -aC"cAdd" -,"[DO_STACKPLUS1] A" -aV" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lba;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mC"cAnd" -,aF,);q4 -Lbb -gY -m2(117,m3"cAnd" -,"[fp_and(x,y)]" -,q31);q4 -Lbc;h8} -qH -TailCall_cDiv:g5 -cDiv -hH -wB(78,"cDup" -m7,"[Value_t()]" -m6"[Value_t(1)]" -aV,);q4 -w7 -if -hF -gQ -hI -wB(125,mG -wZ"cDiv" -,"[-x]" -m7,wN);q4 -Lbe -qU -q6:mR(103,aU -wZ"cDiv" -,"[y/x]" -,q31);q4 -Lbf;} -} -g8 -oG -wB(56,wO"cDiv" -,,wN);q4 -Lap;h8} -qH -TailCall_cEqual:g5 -w8:dA -A=dD -wB(421,"A[IsLogicalOpcode(A)] " -wO -a5,"A" -,q61(A)wM);q4 -Lap;} -} -m2(115,m3 -a5,"[fp_equal(y,x)]" -,q31);q4 -Lbg;} -g8 -0 -hU -wB(359,aX -wL -a5,"[x] " -a5,wN);q4 -Lbh -qU -cSqr:wB(361,mZ -wL -a5,"[x] " -a5,wN);q4 -Lbh;} -wB(411,wL -a5,"cNot" -,wN);q4 -Lbi;qG -TailCall_cGreater:g5 -o1:oL -hU -wB(413,aX -wL -aW,aF,wN);q4 -Lbj;aY(417,wJ -wL -aW,"A " -aF,q61(A)wM);q4 -Lbk;} -} -} -m2(113,m3 -aW,"[fp_less(x,y)]" -,q31);q4 -Lbl;qG -TailCall_cGreaterOrEq:g5 -dK:qY -g8 -1 -hU -wB(414,aX -wO -a8,aF,wN);q4 -Lbj;aY(418,wJ -wO -a8,"A " -aF,q61(A)wM);q4 -Lbk;} -} -} -m2(114,m3 -a8,"[fp_lessOrEq(x,y)]" -,q31);q4 -Lbm;qG -TailCall_cInv:g5 -cInv:qY -if -hF)){wB(101,wZ -aS,"[Value_t(1)/x]" -,wN);q4 -Lbn;qG -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mB,mV,q61(A)wM);oS;} -} -g8 -1 -hU -wB(415,aX -wO -mB,"cNot" -,wN);q4 -Lbp;aY(419,wJ -wO -mB,"A" -aB,q61(A)wM);q4 -Lbi;} -} -} -m2(111,m3 -mB,"[fp_less(y,x)]" -,q31);q4 -Lbq;qG -TailCall_cLessOrEq:g5 -cLessOrEq:oL -hU -wB(416,aX -wL -aM,"cNot" -,wN);q4 -Lbp;aY(420,wJ -wL -aM,"A" -aB,q61(A)wM);q4 -Lbi;} -} -} -m2(112,m3 -aM,"[fp_lessOrEq(y,x)]" -,q31);q4 -Lca;qG -TailCall_cMax:g5 -cMax -hH -wB(60,mC -m8,,);q4 -w6 -m2(141,m3 -m8,"[fp_max(x,y)]" -,q31);q4 -Lcc;} -gP -cDup:hD -wB(66,aG -mE -aC -m8,"B" -mE,aA(A)q51(B)wM);q4 -Lcb;qT -cMax:hD -wB(68,aG" " -m8 -aC -m8,"B " -m8,aA(A)q51(B)wM);q4 -Lcb;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mC -m9,,);q4 -w6 -m2(140,m3 -m9,"[fp_min(x,y)]" -,q31);q4 -Lcd;} -gP -cDup:hD -wB(65,aG -mE -aC -m9,"B" -mE,aA(A)q51(B)wM);q4 -Lcb;qT -cMin:hD -wB(67,aG" " -m9 -aC -m9,"B " -m9,aA(A)q51(B)wM);q4 -Lcb;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m2(104,aU -wZ"cMod" -,"[fp_mod(y,x)]" -,q31);q4 -Lce;} -qG -TailCall_cMul:g5 -h3 -hH -wB(202,"cDup" -wH,"cSqr" -,);q4 -Lcf -oF -qQ -h9 -cDup:wB(467,mC -q81 -wH,"cSqr" -mD,);q4 -Lcg;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aG -wH -aC -q81 -wH,m0 -m6 -q81,aA(A)q51(B)wM);q4 -Lch;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mC"x" -a1 -wH,"[x+Value_t(1)]" -a1,wN);q4 -Lci;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wT" " -wX,a3,q61(A)wM);q4 -Lcj;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mR(92,aU -wD,a3,q61(A)<<"," -aE);q4 -Lck;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mR(96,aU -wK,mV,q61(A)q51(B)<<"," -aE);q4 -Lcl;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lcm;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lcn;} -} -} -if(d1 -B)){wB(90,"B[IsVarOpcode(B)] " -wD,a3,q61(A)q51(B)wM);q4 -Lcj;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mV,q61(A)q51(B)wM);q4 -Lco;} -} -} -if(d1 -h2 -wB(88,aD" " -wX,"[x]" -,q61(A)wM);q4 -Lcp;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wX,a3,q61(A)wM);q4 -Lcq;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup:wB(317,a9 -wY,"[x+x]" -wH,wN);q4 -Lda -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,aD" y" -wH -aV -wY,a3" A " -aZ -wH -aV,wA", " -aU"= " -<mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Ldm;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:dA -A=dD -wB(422,"A[IsLogicalOpcode(A)] " -wO -wW,"A" -aB,q61(A)wM);q4 -Lbi;} -} -m2(116,m3 -wW,"[fp_nequal(y,x)]" -,q31);q4 -Ldn;} -g8 -0 -hU -wB(360,aX -wL -wW,"[x] " -wW,wN);q4 -Ldo -qU -cSqr:wB(362,mZ -wL -wW,"[x] " -wW,wN);q4 -Ldo;} -wB(412,wL -wW,aF,wN);q4 -Lbk;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -m6 -q81,"[-x]" -wH,wN);q4 -Ldp;qT -hI -wB(61,q81 -mD,,);q4 -w6 -wB(100,"x" -mD,"[-x]" -,wN);q4 -Ldq;} -qH -TailCall_cNot:g5 -cNot:qS -cAbs:wB(227,mQ -aB,"cNot" -,);q4 -Lea -qU -cAbsNot:A=dD -wB(389,"A[IsLogicalOpcode(A)] " -aN -aB,"A" -,aA(A)wM);q4 -Lcb;} -if(A!=q6){wB(390,"A[A!=cImmed] " -aN -aB,"A cAbsNotNot" -,aA(A)wM);q4 -Leb;} -q4 -o0 -qU -cAbsNotNot:wB(231,"cAbsNotNot" -aB,aN,);q4 -Lec -qU -hS -gM -wB(424,a6 -aB,"[-x] " -a5,wN);q4 -Led;} -q4 -o0 -qU -w8:wB(220,a5 -aB,wW,);q4 -Lee -qU -o1:wB(218,aW -aB,aM,);q4 -Lef -qU -dK:wB(219,a8 -aB,mB,);q4 -Leg -qU -cLess:wB(216,mB -aB,a8,);q4 -Leh -qU -cLessOrEq:wB(217,aM -aB,aW,);q4 -Lei -qU -cNEqual:wB(221,wW -aB,a5,);q4 -Lej -oF -wB(226,q81 -aB,"cNot" -,);q4 -Lea -qU -cNot:wB(229,"cNot" -aB,aF,);q4 -Lbb -qU -dS:wB(230,aF -aB,"cNot" -,);q4 -Lea -gY -wB(107,"x" -aB,"[fp_not(x)]" -,wN);q4 -Lek;g7 -o0:;A=dF -qR -qX -wB(391,wJ"cNot" -,"A " -aN,aA(A)wM);q4 -Lel;qG -TailCall_cNotNot:g5 -dS:qS -hS -gM -wB(423,a6" " -aF,"[-x] " -wW,wN);q4 -Lem;qT -cNot:wB(232,"cNot " -aF,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mC"cOr" -,aF,);q4 -Lbb -gY -m2(118,m3"cOr" -,"[fp_or(x,y)]" -,q31);q4 -Len;h8} -qH -TailCall_cRDiv:g5 -cRDiv:dA -wB(268,wO"cRDiv" -,aS,wN);q4 -Leo;qG -TailCall_cRSub:g5 -cRSub -d4 -q0[0 -h1 -wB(77,mC -a4,"[Value_t()]" -wH,);q4 -Lep;} -qH -TailCall_cSqr:g5 -cSqr:qS -cAbs:wB(204,aX"cSqr" -,"cSqr" -,);q4 -Leq -oF -wB(203,mG"cSqr" -,"cSqr" -,);q4 -Leq;} -qH -TailCall_cSub:g5 -cSub -hH -wB(76,mC"cSub" -,"[Value_t()]" -wH,);q4 -Lep -oF -wB(200,q81 -mF,"cAdd" -,);q4 -Lfa -gY -g8)){wB(58,"x[x==Value_t()]" -mF,,wN);q4 -Lap;} -m2(106,m3"cSub" -,"[y-x]" -,q31);q4 -Lfb;} -wB(51,"x" -mF,"[-x]" -aV,wN);q4 -Lfc -gR -w0 -oY -cRSub -dV -wB(289,"x " -a4 -aC"cSub" -,"A" -aV" [x] " -a4,aA(A)<<"," -m4);q4 -Lfd;} -wB(296,a4 -aC"cSub" -,"[DO_STACKPLUS1] A" -mF" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lfe;} -qG -g7 -Default0:;A=w5 -qR -IsComparisonOpcode(h2 -qY -hK -qZ -mR(364,aU"cAdd" -wF,"[x-y] A" -,aA(A)<mByteCode.size()>0]" -,"B" -mE,aA(A)q51(B)wM);q4 -Lfh;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mE,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Lfi;} -} -} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:oZ -4));gG -Lfj:w5=h3;Lfk:g0 -Lfl:wE(cMul);q4 -TailCall_cMul;Lae:hV -4 -dT -oZ -4)q11 -gX -Lfj;Laf:q7=x+g1 -1);gG -Lbo:w5=h3;q4 -Lfl;Lag:gU -cSub;Lfm:wE(cSub);q4 -TailCall_cSub;Lah:hW -2 -gH -Lfn:g0 -Lfo:wE(cAdd);q4 -TailCall_cAdd;Lai:hW -oR -Lfp:qE -hS);Lfq:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Laj:o9;qL -2 -gK -q4 -Lfp;Lak:hW -2 -gH -q4 -Lfq;Lal:hW -4 -gH -Lga:qE -hS);Lgb:qE -B);Lgc:w5=cSub;g0 -q4 -Lfm;Lam:o9;oC=q6 -q9 -oR -q4 -Lga;Lan:hW -oR -q4 -Lgb;Lao:gT -y+x;Lap:qM -Lcb:q5 -gJ -Laq:q8 -oV -o7 -x -q11 -gX -Lfp;Lba:mI -A -gX -Lfp;Lbb:gU -dS;Lgd:wE(cNotNot);q4 -TailCall_cNotNot;Lbc:gT -fp_and(x -h6 -Lbd:oZ));dF -dJ -qE -dU -oZ -1));Lge:qW -q6);Lgf:w5=hS;q4 -Lfn;Lbe:o9;dI -wE(cDiv);q4 -TailCall_cDiv;Lbf:gT -y/x;q4 -Lap;Lbg:gT -fp_equal -mL -Lbh:dI -Lgg:wE(cEqual);q4 -TailCall_cEqual;Lbi:qM -q5 -Lgh:w5=cNot;g0 -Lgi:wE(cNot);q4 -TailCall_cNot;Lbj:q8 -2 -gH -Lgj:w5=dS;g0 -q4 -Lgd;Lbk:qM -w3 -Lgj;Lbl:gT -fp_less(x -h6 -Lbm:gT -fp_lessOrEq(x -h6 -Lbn:q7=g1 -1)/x;gJ -Lbp:dG -Lgh;Lbq:gT -fp_less -mL -Lca:gT -fp_lessOrEq -mL -Lcc:gT -fp_max(x -h6 -Lcd:gT -fp_min(x -h6 -Lce:gT -fp_mod -mL -Lcf:gU -cSqr;Lgk:wE(cSqr);q4 -TailCall_cSqr;Lcg:mI -cSqr);Lgl:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lch:hV -3 -gC -cSqr);dM -Lgl;Lci:q7=x+g1 -1);hE=q6 -q9 -2 -gC -cPow);gJ -Lcj:gG -q4 -Lfl;Lck:gT -x;Lgm:dG -Lfk;Lcl:hV -2;qI -qM -Lgn:hV -4 -gH -Lgo:o6 -x);Lgp:qW -q6 -gX -Lfk;Lcm:qM -q4 -Lgn;Lcn:q8 -4 -gC -B -gX -Lgo;Lco:q8 -oR -q4 -Lgo;Lcp:qK -dJ -q4 -Lcb;Lcq:dI -q4 -Lfl;Lda:q7=x+x;q4 -Lcj;Ldb:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Lgf;Ldc:gT -x;d7 -dU -qF -y*x -gX -Lge;Ldd:q8 -4 -dT -qF -x+x -gX -Lgp;Lde:hV -2;qI -q8 -oR -gJ -Ldf:gT -y*x;q4 -Lgm;Ldg:o9;q4 -Lcq;Ldh:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Lgc;Ldi:gT -y*x;q4 -Lap;Ldj:qM -w3 -Lgl;Ldk:dF=cDup;dW-=1;qM -Lgq:w5=hS;q4 -Lfo;Ldl:hV -2 -gH -Lha:qE -cSqr -gX -Lfk;Ldm:hV -oR -q4 -Lha;Ldn:gT -fp_nequal -mL -Ldo:dI -Lhb:wE(cNEqual);q4 -TailCall_cNEqual;Ldp:o9;g6 -oS;Ldq:o9;gJ -Lea:g6 -q4 -Lgi;Leb:q1 -cAbsNotNot);gJ -Lec:q5 -Lel:qE -cAbsNot);gJ -Led:o9;Lej:gU -w8;q4 -Lgg;Lee:gU -cNEqual;q4 -Lhb;Lef:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Leg:gU -cLess;wE(cLess);q4 -TailCall_cLess;Leh:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Lei:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Lek:q7=fp_not -m5 -Lem:o9;q4 -Lee;Len:gT -fp_or(x -h6 -Leo:qM -q5 -w5=cInv;g0 -wE(cInv);q4 -TailCall_cInv;Lep:oZ));dF -dJ -q4 -Lfj;Leq:g6 -q4 -Lgk;Lfa:g6 -q4 -Lgq;Lfb:gT -y-x;q4 -Lap;Lfc:o9;q4 -Lgq;Lfd:q8 -oV -oJ -hS -o7 -x -q11 -gX -Lfq;Lfe:mI -A -oJ -cSub -gX -Lfq;Lff:gT -x-y;d7 -A);gJ -Lfg:o9;qK -dJ -q1 -OppositeComparisonOpcode(A));gJ -Lfh:qW -cDup);gJ -Lfi:dF=cDup;gJ -gJ -q4 -TailCall_cAnd;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cNeg;q4 -TailCall_cOr;q4 -TailCall_cRDiv;q4 -TailCall_cSub; -#endif -#if((FP_COMPLEX_VERSION) && !(FP_FLOAT_VERSION)) -dH -x;dH -gE -A;hT -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0} -qH -TailCall_cAdd:g5 -hG -Lad;qT -h3 -hL]==hS){if(qL -gZ -Lae;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -wY -aV,"[x+Value_t(1)]" -wH,wN);q4 -Laf;} -} -q4 -dX -oF -wB(199,q81 -aV,"cSub" -,);q4 -Lag -gY -hK -qZ -mR(127,aU"cAdd " -a6,"[y+x]" -aV,q31);q4 -Lah;qT -cRSub:qQ -hE -d3 -3 -qZ -mR(298,aU"cAdd " -mS,mJ -aV" " -a4,q31);q4 -Lai;qT -hI -wB(299,mG -mS,"[-x]" -aV" " -a4,wN);q4 -Laj -qU -q6:mR(297,aU -mS,mJ" " -a4,q31);q4 -Lak;qT -oA -Lal;qT -hI -wB(293,mG"B[IsVarOpcode(B)]" -mF" " -a6,"[-x]" -aV" B" -mF,wA"," -aQ(B)wM);q4 -Lam -qU -q6:mR(291,aU"B[IsVarOpcode(B)]" -mF" " -a6,mJ" B" -mF,wA"," -aQ(B)<<"," -aE);q4 -Lan;} -w9 -mR(105,aU -a6,"[y+x]" -,q31);q4 -Lao;} -g8)){wB(57,"x[x==Value_t()]" -aV,,wN);q4 -Lap;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x " -a4 -aC"cAdd" -,"[DO_STACKPLUS1] A [x]" -aV" " -a4,aA(A)<<"," -m4);incStackPtr();--mStackPtr;q4 -Laq;} -wB(295,a4 -aC"cAdd" -,"[DO_STACKPLUS1] A" -aV" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lba;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mC"cAnd" -,aF,);q4 -Lbb -gY -m2(117,m3"cAnd" -,"[fp_and(x,y)]" -,q31);q4 -Lbc;h8} -qH -TailCall_cConj:g5 -cConj:qS -cConj:wB(63,mT" " -mT,,);q4 -w7 -wB(193,"x " -mT,"[fp_conj(x)]" -,wN);q4 -Lbe;} -qH -TailCall_cDiv:g5 -cDiv -hH -wB(78,"cDup" -m7,"[Value_t()]" -m6"[Value_t(1)]" -aV,);q4 -Lbf -gY -if -hF -gQ -hI -wB(125,mG -wZ"cDiv" -,"[-x]" -m7,wN);q4 -Lbg -qU -q6:mR(103,aU -wZ"cDiv" -,"[y/x]" -,q31);q4 -Lbh;} -} -g8 -oG -wB(56,wO"cDiv" -,,wN);q4 -Lap;h8} -qH -TailCall_cEqual:g5 -w8:dA -A=dD -wB(421,"A[IsLogicalOpcode(A)] " -wO -a5,"A" -,q61(A)wM);q4 -Lap;} -} -m2(115,m3 -a5,"[fp_equal(y,x)]" -,q31);q4 -Lbi;} -g8 -0 -hU -wB(359,aX -wL -a5,"[x] " -a5,wN);q4 -Lbj -qU -cSqr:wB(361,mZ -wL -a5,"[x] " -a5,wN);q4 -Lbj;} -wB(411,wL -a5,"cNot" -,wN);q4 -Lbk;qG -TailCall_cGreater:g5 -o1:qY -m2(113,m3 -aW,"[fp_less(x,y)]" -,q31);q4 -Lbl;qG -TailCall_cGreaterOrEq:g5 -dK:qY -m2(114,m3 -a8,"[fp_lessOrEq(x,y)]" -,q31);q4 -Lbm;qG -TailCall_cImag:g5 -cImag:qS -cAbs:wB(81,aX -mU,"[Value_t()]" -wH,);q4 -Lbn -qU -cReal:wB(80,"cReal " -mU,"[Value_t()]" -wH,);q4 -Lbn -gY -wB(192,"x " -mU,"[fp_imag(x)]" -,wN);oS;} -qH -TailCall_cInv:g5 -cInv:qY -if -hF)){wB(101,wZ -aS,"[Value_t(1)/x]" -,wN);q4 -Lbp;qG -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mB,mV,q61(A)wM);q4 -Lbq;} -} -m2(111,m3 -mB,"[fp_less(y,x)]" -,q31);q4 -Lca;qG -TailCall_cLessOrEq:g5 -cLessOrEq:qY -m2(112,m3 -aM,"[fp_lessOrEq(y,x)]" -,q31);q4 -Lcb;qG -TailCall_cMax:g5 -cMax -hH -wB(60,mC -m8,,);q4 -w7 -m2(141,m3 -m8,"[fp_max(x,y)]" -,q31);q4 -Lcc;} -gP -cDup:hD -wB(66,aG -mE -aC -m8,"B" -mE,aA(A)q51(B)wM);q4 -Lbd;qT -cMax:hD -wB(68,aG" " -m8 -aC -m8,"B " -m8,aA(A)q51(B)wM);q4 -Lbd;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mC -m9,,);q4 -w7 -m2(140,m3 -m9,"[fp_min(x,y)]" -,q31);q4 -Lcd;} -gP -cDup:hD -wB(65,aG -mE -aC -m9,"B" -mE,aA(A)q51(B)wM);q4 -Lbd;qT -cMin:hD -wB(67,aG" " -m9 -aC -m9,"B " -m9,aA(A)q51(B)wM);q4 -Lbd;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m2(104,aU -wZ"cMod" -,"[fp_mod(y,x)]" -,q31);q4 -Lce;} -qG -TailCall_cMul:g5 -h3 -hH -wB(202,"cDup" -wH,"cSqr" -,);q4 -Lcf -oF -qQ -h9 -cDup:wB(467,mC -q81 -wH,"cSqr" -mD,);q4 -Lcg;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aG -wH -aC -q81 -wH,m0 -m6 -q81,aA(A)q51(B)wM);q4 -Lch;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mC"x" -a1 -wH,"[x+Value_t(1)]" -a1,wN);q4 -Lci;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wT" " -wX,a3,q61(A)wM);q4 -Lcj;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mR(92,aU -wD,a3,q61(A)<<"," -aE);q4 -Lck;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mR(96,aU -wK,mV,q61(A)q51(B)<<"," -aE);q4 -Lcl;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lcm;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lcn;} -} -} -if(d1 -B)){wB(90,"B[IsVarOpcode(B)] " -wD,a3,q61(A)q51(B)wM);q4 -Lcj;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mV,q61(A)q51(B)wM);q4 -Lco;} -} -} -if(d1 -h2 -wB(88,aD" " -wX,"[x]" -,q61(A)wM);q4 -Lcp;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wX,a3,q61(A)wM);q4 -Lcq;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup:wB(317,a9 -wY,"[x+x]" -wH,wN);q4 -Lda -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,aD" y" -wH -aV -wY,a3" A " -aZ -wH -aV,wA", " -aU"= " -<mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Ldm;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:dA -A=dD -wB(422,"A[IsLogicalOpcode(A)] " -wO -wW,"A" -aB,q61(A)wM);q4 -Lbk;} -} -m2(116,m3 -wW,"[fp_nequal(y,x)]" -,q31);q4 -Ldn;} -g8 -0 -hU -wB(360,aX -wL -wW,"[x] " -wW,wN);q4 -Ldo -qU -cSqr:wB(362,mZ -wL -wW,"[x] " -wW,wN);q4 -Ldo;} -wB(412,wL -wW,aF,wN);q4 -Ldp;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -m6 -q81,"[-x]" -wH,wN);q4 -Ldq;qT -hI -wB(61,q81 -mD,,);q4 -w7 -wB(100,"x" -mD,"[-x]" -,wN);q4 -Lea;} -qH -TailCall_cNot:g5 -cNot:qS -cAbsNotNot:wB(231,"cAbsNotNot" -aB,aN,);q4 -Leb -qU -hS -gM -wB(424,a6 -aB,"[-x] " -a5,wN);q4 -Lec;qT -w8:wB(220,a5 -aB,wW,);q4 -Led -qU -o1:wB(218,aW -aB,aM,);q4 -Lee -qU -dK:wB(219,a8 -aB,mB,);q4 -Lef -qU -cLess:wB(216,mB -aB,a8,);q4 -Leg -qU -cLessOrEq:wB(217,aM -aB,aW,);q4 -Leh -qU -cNEqual:wB(221,wW -aB,a5,);q4 -Lei -qU -cNot:wB(229,"cNot" -aB,aF,);q4 -Lbb -qU -dS:wB(230,aF -aB,"cNot" -,);q4 -Lej -gY -wB(107,"x" -aB,"[fp_not(x)]" -,wN);q4 -Lek;} -qH -TailCall_cNotNot:g5 -dS:qS -hS -gM -wB(423,a6" " -aF,"[-x] " -wW,wN);q4 -Lel;qT -cNot:wB(232,"cNot " -aF,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mC"cOr" -,aF,);q4 -Lbb -gY -m2(118,m3"cOr" -,"[fp_or(x,y)]" -,q31);q4 -Lem;h8} -qH -TailCall_cRDiv:g5 -cRDiv:dA -wB(268,wO"cRDiv" -,aS,wN);q4 -Len;qG -TailCall_cRSub:g5 -cRSub -d4 -q0[0 -h1 -wB(77,mC -a4,"[Value_t()]" -wH,);q4 -Lbn;} -qH -TailCall_cReal:g5 -cReal:qY -wB(191,"x cReal" -,"[fp_real(x)]" -,wN);q4 -Leo;} -qH -TailCall_cSqr:g5 -cSqr:qS -cAbs:wB(204,aX"cSqr" -,"cSqr" -,);q4 -Lep -oF -wB(203,mG"cSqr" -,"cSqr" -,);q4 -Lep;} -qH -TailCall_cSub:g5 -cSub -hH -wB(76,mC"cSub" -,"[Value_t()]" -wH,);q4 -Lbn -oF -wB(200,q81 -mF,"cAdd" -,);q4 -Leq -gY -g8)){wB(58,"x[x==Value_t()]" -mF,,wN);q4 -Lap;} -m2(106,m3"cSub" -,"[y-x]" -,q31);q4 -Lfa;} -wB(51,"x" -mF,"[-x]" -aV,wN);q4 -Lfb -gR -w0 -oY -cRSub -dV -wB(289,"x " -a4 -aC"cSub" -,"A" -aV" [x] " -a4,aA(A)<<"," -m4);q4 -Lfc;} -wB(296,a4 -aC"cSub" -,"[DO_STACKPLUS1] A" -mF" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lfd;} -qG -g7 -Default0:;A=w5 -w1 -0){B=q0[0 -hZ -wB(475,aG" A[IsVarOpcode(A)&&mData->mByteCode.size()>0]" -,"B" -mE,aA(A)q51(B)wM);q4 -Lfe;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mE,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Lff;} -} -} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:oZ -4));gG -Lfg:w5=h3;Lfh:g0 -Lfi:wE(cMul);q4 -TailCall_cMul;Lae:hV -4 -dT -oZ -4)q11 -gX -Lfg;Laf:q7=x+g1 -1);gG -Lbq:w5=h3;q4 -Lfi;Lag:gU -cSub;Lfj:wE(cSub);q4 -TailCall_cSub;Lah:hW -2 -gH -Lfk:g0 -Lfl:wE(cAdd);q4 -TailCall_cAdd;Lai:hW -oR -Lfm:qE -hS);Lfn:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Laj:o9;qL -2 -gK -q4 -Lfm;Lak:hW -2 -gH -q4 -Lfn;Lal:hW -4 -gH -Lfo:qE -hS);Lfp:qE -B);Lfq:w5=cSub;g0 -q4 -Lfj;Lam:o9;oC=q6 -q9 -oR -q4 -Lfo;Lan:hW -oR -q4 -Lfp;Lao:gT -y+x;Lap:qM -Lbd:q5 -gJ -Laq:q8 -oV -o7 -x -q11 -gX -Lfm;Lba:mI -A -gX -Lfm;Lbb:gU -dS;Lga:wE(cNotNot);q4 -TailCall_cNotNot;Lbc:gT -fp_and(x -h6 -Lbe:q7=fp_conj -m5 -Lbf:oZ));dF -dJ -qE -dU -oZ -1));Lgb:qW -q6);Lgc:w5=hS;q4 -Lfk;Lbg:o9;dI -wE(cDiv);q4 -TailCall_cDiv;Lbh:gT -y/x;q4 -Lap;Lbi:gT -fp_equal -mL -Lbj:dI -Lgd:wE(cEqual);q4 -TailCall_cEqual;Lbk:qM -q5 -w5=cNot;g0 -Lge:wE(cNot);q4 -TailCall_cNot;Lbl:gT -fp_less(x -h6 -Lbm:gT -fp_lessOrEq(x -h6 -Lbn:oZ));dF -dJ -q4 -Lfg;Lbo:q7=fp_imag -m5 -Lbp:q7=g1 -1)/x;gJ -Lca:gT -fp_less -mL -Lcb:gT -fp_lessOrEq -mL -Lcc:gT -fp_max(x -h6 -Lcd:gT -fp_min(x -h6 -Lce:gT -fp_mod -mL -Lcf:gU -cSqr;Lgf:wE(cSqr);q4 -TailCall_cSqr;Lcg:mI -cSqr);Lgg:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lch:hV -3 -gC -cSqr);dM -Lgg;Lci:q7=x+g1 -1);hE=q6 -q9 -2 -gC -cPow);gJ -Lcj:gG -q4 -Lfi;Lck:gT -x;Lgh:dG -Lfh;Lcl:hV -2;qI -qM -Lgi:hV -4 -gH -Lgj:o6 -x);Lgk:qW -q6 -gX -Lfh;Lcm:qM -q4 -Lgi;Lcn:q8 -4 -gC -B -gX -Lgj;Lco:q8 -oR -q4 -Lgj;Lcp:qK -dJ -q4 -Lbd;Lcq:dI -q4 -Lfi;Lda:q7=x+x;q4 -Lcj;Ldb:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Lgc;Ldc:gT -x;d7 -dU -qF -y*x -gX -Lgb;Ldd:q8 -4 -dT -qF -x+x -gX -Lgk;Lde:hV -2;qI -q8 -oR -gJ -Ldf:gT -y*x;q4 -Lgh;Ldg:o9;q4 -Lcq;Ldh:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Lfq;Ldi:gT -y*x;q4 -Lap;Ldj:qM -w3 -Lgg;Ldk:dF=cDup;dW-=1;qM -Lgl:w5=hS;q4 -Lfl;Ldl:hV -2 -gH -Lgm:qE -cSqr -gX -Lfh;Ldm:hV -oR -q4 -Lgm;Ldn:gT -fp_nequal -mL -Ldo:dI -Lgn:wE(cNEqual);q4 -TailCall_cNEqual;Ldp:qM -q5 -w5=dS;g0 -q4 -Lga;Ldq:o9;g6 -q4 -Lbq;Lea:o9;gJ -Leb:q1 -cAbsNot);gJ -Lec:o9;Lei:gU -w8;q4 -Lgd;Led:gU -cNEqual;q4 -Lgn;Lee:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Lef:gU -cLess;wE(cLess);q4 -TailCall_cLess;Leg:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Leh:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Lej:g6 -q4 -Lge;Lek:q7=fp_not -m5 -Lel:o9;q4 -Led;Lem:gT -fp_or(x -h6 -Len:qM -q5 -w5=cInv;g0 -wE(cInv);q4 -TailCall_cInv;Leo:q7=fp_real -m5 -Lep:g6 -q4 -Lgf;Leq:g6 -q4 -Lgl;Lfa:gT -y-x;q4 -Lap;Lfb:o9;q4 -Lgl;Lfc:q8 -oV -oJ -hS -o7 -x -q11 -gX -Lfn;Lfd:mI -A -oJ -cSub -gX -Lfn;Lfe:qW -cDup);gJ -Lff:dF=cDup;gJ -gJ -q4 -TailCall_cAnd;q4 -TailCall_cConj;q4 -TailCall_cImag;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cNeg;q4 -TailCall_cOr;q4 -TailCall_cRDiv;q4 -TailCall_cReal;q4 -TailCall_cSub; -#endif -#if((FP_FLOAT_VERSION) && !(FP_COMPLEX_VERSION)) -dH -x;hT -A;dH -gE -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0 -oH -dF -qR -qX -wB(393,wJ -mQ,"A" -,aA(A)wM);gJ -qG -TailCall_cAcos:g5 -cAcos:hN<=m1(148,"x[fp_abs(x)<=Value_t(1)] cAcos" -,"[fp_acos(x)]" -,wN);q4 -Lad;qG -TailCall_cAcosh:g5 -cAcosh:qY -if(x>=m1(145,"x[x>=Value_t(1)] cAcosh" -,"[fp_acosh(x)]" -,wN);q4 -Lae;qG -TailCall_cAdd:g5 -hG -Laf;qT -h3 -hL]==hS){if(qL -gZ -Lag;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -wY -aV,"[x+Value_t(1)]" -wH,wN);q4 -Lah;} -} -q4 -dX -oF -wB(199,q81 -aV,"cSub" -,);q4 -Lai -gY -hK -qZ -mR(127,aU"cAdd " -a6,"[y+x]" -aV,q31);q4 -Laj;qT -cRSub:qQ -hE -d3 -3 -qZ -mR(298,aU"cAdd " -mS,mJ -aV" " -a4,q31);q4 -Lak;qT -hI -wB(299,mG -mS,"[-x]" -aV" " -a4,wN);q4 -Lal -qU -q6:mR(297,aU -mS,mJ" " -a4,q31);q4 -Lam;qT -oA -Lan;qT -hI -wB(293,mG"B[IsVarOpcode(B)]" -mF" " -a6,"[-x]" -aV" B" -mF,wA"," -aQ(B)wM);q4 -Lao -qU -q6:mR(291,aU"B[IsVarOpcode(B)]" -mF" " -a6,mJ" B" -mF,wA"," -aQ(B)<<"," -aE);q4 -Lap;} -w9 -mR(105,aU -a6,"[y+x]" -,q31);q4 -Laq;} -g8)){wB(57,"x[x==Value_t()]" -aV,,wN);q4 -Lba;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x " -a4 -aC"cAdd" -,"[DO_STACKPLUS1] A [x]" -aV" " -a4,aA(A)<<"," -m4);incStackPtr();--mStackPtr;q4 -Lbb;} -wB(295,a4 -aC"cAdd" -,"[DO_STACKPLUS1] A" -aV" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lbc;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mC"cAnd" -,aF,);q4 -w7 -m2(117,m3"cAnd" -,"[fp_and(x,y)]" -,q31);q4 -Lbe;h8} -qH -TailCall_cAsin:g5 -cAsin:hN<=m1(149,"x[fp_abs(x)<=Value_t(1)] cAsin" -,"[fp_asin(x)]" -,wN);q4 -Lbf;qG -TailCall_cAsinh:g5 -cAsinh:qY -wB(146,"x cAsinh" -,"[fp_asinh(x)]" -,wN);q4 -Lbg;} -qH -TailCall_cAtan:g5 -cAtan:qY -wB(150,"x cAtan" -,"[fp_atan(x)]" -,wN);q4 -Lbh;} -qH -TailCall_cAtan2:g5 -cAtan2:qY -m2(139,m3"cAtan2" -,"[fp_atan2(y,x)]" -,q31);q4 -Lbi;qG -TailCall_cAtanh:g5 -cAtanh:hN()]" -m6 -wR,"cDeg" -,q31);q4 -Ldd;} -if((y/x)==fp_const_deg_to_rad -h7 -wB(322,"y[(y/x)==fp_const_deg_to_rad()]" -m6 -wR,"cRad" -,q31);q4 -Lde;} -wB(323,"y" -m6 -wR,"[y/x]" -wH,q31);q4 -Ldf;} -} -wB(325,wR,"[Value_t(1)/x]" -wH,wN);q4 -Ldg;} -gP -cDiv:hC -wB(271,q21" " -wV,"[DO_STACKPLUS1] B A" -m6"cDiv" -,aA(A)q51(B)wM);incStackPtr();--mStackPtr;q4 -Ldh;qT -cRDiv:qQ -hE -qV -hM -wB(266,"x" -a7" " -wV,"A" -m6"[x]" -a7,aA(A)<<"," -m4);q4 -Ldi;g7 -hC -wB(265,"B[IsVarOpcode(B)]" -a7" " -wV,"A" -m6"B" -a7,aA(A)q51(B)wM);q4 -Ldj;} -h8} -qG -TailCall_cEqual:g5 -w8:oL -hU -wB(359,aX -wL -a5,"[x] " -a5,wN);q4 -Ldk -qU -cSqr:wB(361,mZ -wL -a5,"[x] " -a5,wN);q4 -Ldk;} -} -m2(115,m3 -a5,"[fp_equal(y,x)]" -,q31);q4 -Ldl;qG -TailCall_cExp:g5 -w2 -qS -hS -gM -wB(404,a6" " -mH,mH" [fp_exp(x)]" -wH,wN);q4 -Ldm;qT -cLog:A=dE -wB(340,wJ -mA" " -mH,"A" -,aA(A)wM);q4 -oN -hM -wB(154,"x " -mH,"[fp_exp(x)]" -,wN);q4 -Ldo;} -qH -TailCall_cExp2:g5 -cExp2:qS -hS -gM -wB(405,a6" cExp2" -,"cExp2 [fp_exp2(x)]" -wH,wN);q4 -Ldp;qT -cLog2:A=dE -wB(341,wJ -aJ" cExp2" -,"A" -,aA(A)wM);q4 -oN -hM -wB(155,"x cExp2" -,"[fp_exp2(x)]" -,wN);q4 -Ldq;} -wB(479,"cExp2" -,"[DO_STACKPLUS1] [fp_log(Value_t(2))]" -m6 -mH,);incStackPtr();--mStackPtr;q4 -Lea;TailCall_cFloor:g5 -cFloor:qS -hI -wB(401,mG -mO,mW -mD,);q4 -Leb -gY -wB(136,"x " -mO,"[fp_floor(x)]" -,wN);q4 -Lec -gS -wB(395,"A[IsAlwaysIntegerOpcode(A)] " -mO,"A" -,aA(A)wM);gJ -qG -TailCall_cGreater:g5 -o1:qY -m2(113,m3 -aW,"[fp_less(x,y)]" -,q31);q4 -Led;} -g8-oO -wB(431,"x[x==Value_t(-0.5)] " -aW,mG -aN,wN);q4 -Lee;qG -TailCall_cGreaterOrEq:g5 -dK:qY -dB -cAbs){wB(427,aX"x[x!=Value_t(0)] " -a8,"[Value_t(0.5)/x]" -m6 -aF,wN);q4 -Lef;} -} -m2(114,m3 -a8,"[fp_lessOrEq(x,y)]" -,q31);q4 -Leg;} -g8 -oO -wB(430,"x[x==Value_t(0.5)] " -a8,"cAbsNotNot" -,wN);q4 -Leh;qG -TailCall_cHypot:g5 -cHypot -d4 -dF==cSinCos){wB(84,"cSinCos cHypot" -,"[Value_t()]" -m6"[Value_t(1)]" -aV,);q4 -Lci;} -qH -TailCall_cInt:g5 -cInt:qS -hM -wB(137,"x cInt" -,"[fp_int(x)]" -,wN);q4 -Lei -gS -wB(397,"A[IsAlwaysIntegerOpcode(A)] cInt" -,"A" -,aA(A)wM);gJ -qG -TailCall_cInv:g5 -cInv:qS -cCos:wB(256,aK -mK,mX,);q4 -Lej -qU -cCot:wB(260,"cCot" -mK,mN,);q4 -Lcp -qU -cCsc:wB(258,"cCsc" -mK,mM,);q4 -Lek -qU -cInv:wB(62,aS -mK,,);q4 -Ldn -qU -cPow:wB(355,"cPow" -mK,q81 -a1,);q4 -Lel -qU -cSec:wB(259,mX -mK,aK,);q4 -Lem -qU -cSin:wB(255,mM -mK,"cCsc" -,);q4 -Len -qU -cSqrt:wB(206,q01 -mK,"cRSqrt" -,);q4 -Leo -qU -cTan:wB(257,mN -mK,"cCot" -,);q4 -Lep -gY -if -hF)){wB(101,wZ -aS,"[Value_t(1)/x]" -,wN);q4 -Leq;h8} -qH -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mB,mV,q61(A)wM);q4 -Lfa;} -} -dB -cAbs){wB(426,aX"x[x!=Value_t(0)] " -mB,"[Value_t(0.5)/x]" -wH -aB,wN);q4 -Lfb;} -} -m2(111,m3 -mB,"[fp_less(y,x)]" -,q31);q4 -Lfc;} -g8 -oO -wB(429,"x[x==Value_t(0.5)] " -mB,aN,wN);q4 -Lfd;qG -TailCall_cLessOrEq:g5 -cLessOrEq:qY -m2(112,m3 -aM,"[fp_lessOrEq(y,x)]" -,q31);q4 -Lfe;} -g8-oO -wB(432,"x[x==Value_t(-0.5)] " -aM,mG"cAbsNotNot" -,wN);q4 -Lff;qG -TailCall_cLog:g5 -cLog:mP(343,mH" " -mA,,);q4 -Ldn -qU -gL -wB(491,wQ -m6 -mA,mA" [fp_log(x)]" -aV,wN);q4 -Lfg;} -o2 -wB(303,mZ -mA,aX -mA" " -a9,);q4 -Lfh -aT(156,wQ" " -mA,"[fp_log(x)]" -,wN);q4 -Lfi;h8} -qH -TailCall_cLog10:g5 -cLog10:mP(481,mH" " -aH,"[DO_STACKPLUS1] [fp_log10(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfj -qU -gL -wB(492,wQ -m6 -aH,aH" [fp_log10(x)]" -aV,wN);q4 -Lfk;} -o2 -wB(305,mZ -aH,aX -aH" " -a9,);q4 -Lfl -aT(157,wQ" " -aH,"[fp_log10(x)]" -,wN);q4 -Lfm;h8} -qH -TailCall_cLog2:g5 -cLog2:mP(480,mH" " -aJ,"[DO_STACKPLUS1] [fp_log2(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfn -qU -cExp2:wB(344,"cExp2 " -aJ,,);q4 -Ldn -qU -gL -wB(490,wQ -m6 -aJ,aJ" [fp_log2(x)]" -aV,wN);q4 -Lfo;} -o2 -wB(304,mZ -aJ,aX -aJ" " -a9,);q4 -Lfp -aT(158,wQ" " -aJ,"[fp_log2(x)]" -,wN);q4 -Lfq;h8} -qH -TailCall_cMax:g5 -cMax -hH -wB(60,mC -m8,,);q4 -Ldn -gY -m2(141,m3 -m8,"[fp_max(x,y)]" -,q31);q4 -Lga;} -gP -cDup:hD -wB(66,aG -mE -aC -m8,"B" -mE,aA(A)q51(B)wM);q4 -oN -cMax:hD -wB(68,aG" " -m8 -aC -m8,"B " -m8,aA(A)q51(B)wM);q4 -Ldn;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mC -m9,,);q4 -Ldn -gY -m2(140,m3 -m9,"[fp_min(x,y)]" -,q31);q4 -Lgb;} -gP -cDup:hD -wB(65,aG -mE -aC -m9,"B" -mE,aA(A)q51(B)wM);q4 -oN -cMin:hD -wB(67,aG" " -m9 -aC -m9,"B " -m9,aA(A)q51(B)wM);q4 -Ldn;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m2(104,aU -wZ"cMod" -,"[fp_mod(y,x)]" -,q31);q4 -Lgc;} -qG -TailCall_cMul:g5 -h3:qS -cCsc:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(508,aG" " -aK" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cCsc" -wH,"B cCot" -,aA(A)q51(B)wM);q4 -Lgd;} -} -} -q4 -dY -qU -cDup:wB(202,"cDup" -wH,"cSqr" -,);q4 -Lge -qU -cInv:wB(214,aS -wH,"cDiv" -,);q4 -Lgf -oF -qQ -h9 -cDup:wB(467,mC -q81 -wH,"cSqr" -mD,);q4 -Lgg;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aG -wH -aC -q81 -wH,m0 -m6 -q81,aA(A)q51(B)wM);q4 -Lgh;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mC"x" -a1 -wH,"[x+Value_t(1)]" -a1,wN);q4 -Lgi;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wT" " -wX,a3,q61(A)wM);q4 -Lgj;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mR(92,aU -wD,a3,q61(A)<<"," -aE);q4 -Lgk;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mR(96,aU -wK,mV,q61(A)q51(B)<<"," -aE);q4 -Lgl;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lgm;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lgn;} -} -} -if(d1 -B)){wB(90,"B[IsVarOpcode(B)] " -wD,a3,q61(A)q51(B)wM);q4 -Lgj;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mV,q61(A)q51(B)wM);q4 -Lgo;} -} -} -if(d1 -h2 -wB(88,aD" " -wX,"[x]" -,q61(A)wM);q4 -Lgp;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wX,a3,q61(A)wM);q4 -Lgq;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup -d4 -x+oU -wB(316,"cDup[x+x==Value_t(1)]" -aV -wY,,wN);q4 -Lha;} -wB(317,a9 -wY,"[x+x]" -wH,wN);q4 -Lhb -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,aD" y" -wH -aV -wY,a3" A " -aZ -wH -aV,wA", " -aU"= " -<()]" -wH -wY,"cDeg" -,q31);q4 -Ldd;} -if((y*x)==fp_const_deg_to_rad -h7 -wB(308,"y[(y*x)==fp_const_deg_to_rad()]" -wH -wY,"cRad" -,q31);q4 -Lde;} -wB(128,"y" -wH -wY,aZ -wH,q31);q4 -Lhl;qT -hI -wB(122,q81 -wY,"[-x]" -wH,wN);q4 -Lhm -qU -cRDiv:qQ -hE -qV -o5 -3 -qZ -mR(285,"y" -wH -a7 -wY,aZ -wH -a7,q31);q4 -Lhn;qT -hI -wB(286,q81 -a7 -wY,"[-x]" -wH -a7,wN);q4 -Lho -qU -q6:mR(284,"y" -a7 -wY,aZ -a7,q31);q4 -Lhp;qT -cRad:wB(210,"cRad" -wY,"[DegreesToRadians(x)]" -wH,wN);q4 -Lhq -qU -cSub -hL -oM -if(qL -3 -qZ -hO -A=qL -4]w0 -wB(387,aD" y" -m6"cSub" -wY,a3" A " -aZ -m6"cSub" -,wA", " -aU"= " -<()]" -wH,"cDeg" -,wN);q4 -Lie;} -if(x==fp_const_deg_to_rad -h7 -wB(208,"x[x==fp_const_deg_to_rad()]" -wH,"cRad" -,wN);q4 -Lif;h8 -g7 -dY:;A=dF -qO -A -gQ -cDiv:hC -wB(274,q21" " -wT,"[DO_STACKPLUS1] A" -m6"B" -m7,aA(A)q51(B)wM);incStackPtr();--mStackPtr;q4 -Lig;} -q4 -d5 -h3:qQ -hE -qV -hI -B=hQ -wB(470,aG -mD -m6 -wT,m0 -m6 -q81,aA(A)q51(B)wM);q4 -Lgh;} -q4 -dZ;g7 -dZ:;hD -wB(461,aG -m6 -wT,m0 -wH,aA(A)q51(B)wM);q4 -Lih;} -} -q4 -d5 -hI -hD -wB(464,aG -mD" " -wT,m0 -mD,aA(A)q51(B)wM);q4 -Lgg;} -q4 -d5 -cRDiv -hL -qZ -qC -wB(267,"x" -a7" " -wT,"[DO_STACKPLUS1] " -mV -a7,aA(A)<<"," -m4);incStackPtr();--mStackPtr;q4 -Lii;} -wB(281,"cRDiv " -wT,"[DO_STACKPLUS1] A" -wH -a7,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lij;g7 -Default4:;B=qK -qR -w4 -wB(458,aG" " -wT,m0,aA(A)q51(B)wM);q4 -Lge;} -} -} -if(gV -h2 -B=qK -qO -B -qP -1 -gA -oM -C=oC -qR -C==A){D=qL -4]qR -D==B){wB(477,"D[D==B] C[C==A]" -m6"B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Lik;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:oL -hU -wB(360,aX -wL -wW,"[x] " -wW,wN);q4 -Lil -qU -cSqr:wB(362,mZ -wL -wW,"[x] " -wW,wN);q4 -Lil;} -} -m2(116,m3 -wW,"[fp_nequal(y,x)]" -,q31);q4 -Lim;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -m6 -q81,"[-x]" -wH,wN);q4 -Lin;qT -hI -wB(61,q81 -mD,,);q4 -Ldn -qU -cSin:g9 -wB(244,"x" -m6 -mM -mD,"[-x]" -m6 -mM,wN);q4 -Lio;} -qT -oQ -g9 -wB(245,"x" -m6"cSinh" -mD,"[-x]" -m6"cSinh" -,wN);q4 -Lip;} -qT -cTan:g9 -wB(246,"x" -m6 -mN -mD,"[-x]" -m6 -mN,wN);q4 -Liq;} -qT -cTanh:g9 -wB(247,"x" -m6"cTanh" -mD,"[-x]" -m6"cTanh" -,wN);q4 -Lja;} -qT -hM -wB(100,"x" -mD,"[-x]" -,wN);q4 -Ljb;} -qH -TailCall_cNot:g5 -cNot:qS -cAbs:wB(227,mQ -aB,"cNot" -,);q4 -Ljc -qU -cAbsNot:A=dD -wB(389,"A[IsLogicalOpcode(A)] " -aN -aB,"A" -,aA(A)wM);q4 -Ldn;} -if(A!=q6){wB(390,"A[A!=cImmed] " -aN -aB,"A cAbsNotNot" -,aA(A)wM);q4 -Ljd;} -q4 -o0 -qU -cAbsNotNot:wB(231,"cAbsNotNot" -aB,aN,);q4 -Lje -qU -w8:wB(220,a5 -aB,wW,);q4 -Ljf -qU -o1:wB(218,aW -aB,aM,);q4 -Ljg -qU -dK:wB(219,a8 -aB,mB,);q4 -Ljh -qU -cLess:wB(216,mB -aB,a8,);q4 -Lji -qU -cLessOrEq:wB(217,aM -aB,aW,);q4 -Ljj -qU -cNEqual:wB(221,wW -aB,a5,);q4 -Ljk -oF -wB(226,q81 -aB,"cNot" -,);q4 -Ljc -qU -cNot:wB(229,"cNot" -aB,aF,);q4 -Lbd -qU -dS:wB(230,aF -aB,"cNot" -,);q4 -Ljc -gY -wB(107,"x" -aB,"[fp_not(x)]" -,wN);q4 -Ljl;g7 -o0:;A=dF -qR -qX -wB(391,wJ"cNot" -,"A " -aN,aA(A)wM);q4 -Ljm;qG -TailCall_cNotNot:g5 -dS -d4 -dF==cNot){wB(232,"cNot " -aF,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mC"cOr" -,aF,);q4 -w7 -m2(118,m3"cOr" -,"[fp_or(x,y)]" -,q31);q4 -Ljn;h8} -qH -TailCall_cPow:g5 -cPow:qY -if(!h5 -x+x)){oY -cSqr){wB(22,mZ"x[!isEvenInteger(x+x)]" -a1,aX"[x+x]" -a1,wN);q4 -Ljo;} -} -if(isInteger(x -gQ -w2 -wB(43,mH" " -wS,a3" " -mH,wN);q4 -Ljp -qU -cExp2:wB(44,"cExp2 " -wS,a3" cExp2" -,wN);q4 -Ljq -qU -cPow -hL -qZ -hP!isInteger(y)){wB(42,"y[!isInteger(y)]" -a1" " -wS,aZ -a1,q31);q4 -Lka;} -} -wB(45,"cPow " -wS,a3 -a1,wN);q4 -Lkb;} -} -if(h5 -x -hU -wB(434,aX"x[isEvenInteger(x)]" -a1,"[x]" -a1,wN);q4 -Lkc -qU -h3 -hL]==cAbs){wB(435,mQ -m6"x[isEvenInteger(x)]" -a1,"cMul [x]" -a1,wN);q4 -Lkd;h8} -} -g8)){wB(83,"x[x==Value_t()]" -a1,"[Value_t()]" -m6"[Value_t(1)]" -aV,wN);q4 -Lke;} -g8 -oO -wB(332,"x[x==Value_t(0.5)]" -a1,q01,wN);q4 -Lkf;} -g8 -1)/g1 -3)){wB(333,"x[x==Value_t(1)/Value_t(3)]" -a1,"cCbrt" -,wN);q4 -Lkg;} -g8 -1)/g1-3)){wB(334,"x[x==Value_t(1)/Value_t(-3)]" -a1,"cCbrt" -mK,wN);q4 -Lkh;} -g8-oO -wB(335,"x[x==Value_t(-0.5)]" -a1,"cRSqrt" -,wN);q4 -Lki;} -g8-oG -wB(336,"x[x==Value_t(-1)]" -a1,aS,wN);q4 -Lkj;} -qQ -h9 -cPow -hL -qZ -hP -h5 -y)&&!h5 -x*y)){wB(21,"y[isEvenInteger(y)&&!isEvenInteger(x*y)]" -a1" x" -a1,aX -aZ -a1,q31);q4 -Lkk;} -wB(330,"y" -a1" x" -a1,aZ -a1,q31);q4 -Lka;o2 -wB(46,mZ"x" -a1,"[x+x]" -a1,wN);q4 -Lkl -qU -q6:hP -y!=oP||x>=oP){wB(165,"y[y!=Value_t(0)||x>=Value_t(0)] x" -a1,"[fp_pow(y,x)]" -,q31);q4 -Lkm;h8} -wB(455,"x" -a1,"[DO_POWI]" -,wN)qR -TryCompilePowi(x))gJ} -qH -TailCall_cRDiv:g5 -cRDiv:qS -cSinCos:wB(503,"cSinCos" -a7,"cCot" -,);q4 -Lep -qU -cSinhCosh:wB(510,"cSinhCosh" -a7,"cTanh" -mK,);q4 -Lkn -gY -g8 -oG -wB(268,wO"cRDiv" -,aS,wN);q4 -Lkj;h8} -qH -TailCall_cRSub:g5 -cRSub -d4 -q0[0 -h1 -wB(77,mC -a4,"[Value_t()]" -wH,);q4 -Lko;} -qH -TailCall_cRad:g5 -cRad:qS -h3 -gM -wB(211,"x" -m6"cRad" -,"[DegreesToRadians(x)]" -wH,wN);q4 -Lkp;qT -hM -wB(134,"x cRad" -,"[DegreesToRadians(x)]" -,wN);q4 -Lkq;} -qH -TailCall_cSec:g5 -cSec:A=qN -qQ -h9 -cCos:hD -wB(497,aG" " -aK" " -wI -mX,"B " -aK" " -aR,aA(A)q51(B)wM);q4 -Lbp;qT -cSin:hD -wB(495,aG" " -mM" " -wI -mX,"B cSinCos" -mK,aA(A)q51(B)wM);q4 -Lla;h8 -qG -TailCall_cSin:g5 -cSin:qS -hI -wB(240,mG -mM,mM -mD,);q4 -Llb -gY -wB(159,"x " -mM,"[fp_sin(x)]" -,wN);q4 -Llc;oH -qN -oY -cCsc -mY(499,aG" cCsc " -wI -mM,"B cCsc " -aR,aA(A)q51(B)wM);q4 -Lbp;} -} -qG -TailCall_cSinh:g5 -oQ -qS -cAcosh:wB(437,"cAcosh cSinh" -,"[DO_STACKPLUS1] " -mZ"[Value_t(-1)] " -aL,);incStackPtr();--mStackPtr;q4 -Lld -qU -cAsinh:wB(349,"cAsinh cSinh" -,,);q4 -Ldn -oF -wB(241,mG"cSinh" -,"cSinh" -mD,);q4 -Lle -gY -wB(160,"x cSinh" -,"[fp_sinh(x)]" -,wN);q4 -Llf;} -qH -TailCall_cSqr:g5 -cSqr:qS -cAbs:wB(204,aX"cSqr" -,"cSqr" -,);q4 -Llg -oF -wB(203,mG"cSqr" -,"cSqr" -,);q4 -Llg -qU -cSqrt:A=dE -wB(338,wJ -q01" cSqr" -,"A" -,aA(A)wM);q4 -Ldn;h8} -qH -TailCall_cSqrt:g5 -cSqrt:qS -hS -d4 -qK -o3 -A=hE -w0 -if(oC -o3 -wB(512,"cSqr" -aC -mZ -aL,"A cHypot" -,aA(A)wM);q4 -Llh;} -} -B -g4 -gV -B)){A=oC -w0 -if(qL -4]o3 -wB(513,"cSqr" -aC"B[IsUnaryOpcode(B)] " -mZ -aL,"A B cHypot" -," with" -aQ(B)q71(A)wM);q4 -Lli;} -} -} -o2 -wB(23,mZ -q01,mQ,);q4 -Llj -gY -if(x>=oP){wB(161,"x[x>=Value_t(0)] " -q01,"[fp_sqrt(x)]" -,wN);q4 -Llk;h8} -qH -TailCall_cSub:g5 -cSub -hH -wB(76,mC"cSub" -,"[Value_t()]" -wH,);q4 -Lko -oF -wB(200,q81 -mF,"cAdd" -,);q4 -Lll -gY -g8)){wB(58,"x[x==Value_t()]" -mF,,wN);q4 -Lba;} -m2(106,m3"cSub" -,"[y-x]" -,q31);q4 -Llm;} -wB(51,"x" -mF,"[-x]" -aV,wN);q4 -Lln -gR -w0 -oY -cRSub -dV -wB(289,"x " -a4 -aC"cSub" -,"A" -aV" [x] " -a4,aA(A)<<"," -m4);q4 -Llo;} -wB(296,a4 -aC"cSub" -,"[DO_STACKPLUS1] A" -mF" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Llp;} -qG -TailCall_cTan:g5 -cTan:qS -cAtan2:wB(354,"cAtan2 " -mN,"cDiv" -,);q4 -Lgf -oF -wB(242,mG -mN,mN -mD,);q4 -Llq -gY -wB(163,"x " -mN,"[fp_tan(x)]" -,wN);q4 -Lma;oH -qN -oY -cCot -mY(501,aG" cCot " -wI -mN,"B cCot " -aR,aA(A)q51(B)wM);q4 -Lbp;} -} -qG -TailCall_cTanh:g5 -cTanh:qS -hI -wB(243,mG"cTanh" -,"cTanh" -mD,);q4 -Lmb -gY -wB(164,"x cTanh" -,"[fp_tanh(x)]" -,wN);q4 -Lmc;} -qH -TailCall_cTrunc:g5 -cTrunc:qS -hM -wB(138,"x cTrunc" -,"[fp_trunc(x)]" -,wN);q4 -Lmd -gS -wB(394,"A[IsAlwaysIntegerOpcode(A)] cTrunc" -,"A" -,aA(A)wM);gJ -qG -g7 -Default0:;A=w5 -qR -IsComparisonOpcode(h2 -qY -hK -qZ -mR(364,aU"cAdd" -wF,"[x-y] A" -,aA(A)<()*g1 -oO -wB(380,"cAtan[fp_abs(x)()*Value_t(0.5)]" -wF,"[fp_tan(x)] A" -,aA(A)<<"," -m4);q4 -Lmf;qT -cExp -d4 -dO -wB(370,"cExp[x>Value_t(0)]" -wF,"[fp_log(x)] A" -,aA(A)<<"," -m4);q4 -Lmg;qT -cExp2 -d4 -dO -wB(371,"cExp2[x>Value_t(0)]" -wF,"[fp_log2(x)] A" -,aA(A)<<"," -m4);q4 -Lmh;qT -cLog:g3 -wB(373,wP -mA -wF,"B [fp_exp(x)] A" -,aA(A)<oP){wB(366,"y[y>Value_t(0)]" -wH -wF,"[x/y] A" -,aA(A)<oP -gA -qZ -hP -y>oP){wB(368,"y[y>Value_t(0)] cPow[x>Value_t(0)]" -wF,"[fp_pow(x,Value_t(1)/y)] A" -,aA(A)<Value_t(0)]" -wF,aX"[fp_sqrt(x)] A" -,aA(A)<<"," -m4);q4 -Lmq;qT -cTanh -d4 -dPmByteCode.size()>0]" -,"B" -mE,aA(A)q51(B)wM);q4 -Lnb;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mE,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Lnc;} -} -} -} -C=w5 -qR -IsCommutativeOrParamSwappableBinaryOpcode(C)){qS -cSin:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(505,aG" " -aK" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] " -mM" C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinCos {GetParamSwappedBinaryOpcode(C)}" -," with C" -a0(C)q71(A)q51(B)wM);q4 -Lnd;} -} -qT -oQ -A=qK -w1 -3 -gA]==cCosh){B=hQ -wB(506,aG" " -aI" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cSinh C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinhCosh {GetParamSwappedBinaryOpcode(C)}" -," with C" -a0(C)q71(A)q51(B)wM);q4 -Lne;} -} -h8} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -Lnf:wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:q7=fp_acos -m5 -Lae:q7=fp_acosh -m5 -Laf:oZ -4));gG -Lng:w5=h3;Lnh:g0 -Lni:wE(cMul);q4 -TailCall_cMul;Lag:hV -4 -dT -oZ -4));Lnj:qW -q6 -hA -Lah:q7=x+g1 -1);gG -Lfa:w5=h3;q4 -Lni;Lai:gU -cSub;Lnk:wE(cSub);q4 -TailCall_cSub;Laj:hW -2 -gH -Lnl:g0 -Lnm:wE(cAdd);q4 -TailCall_cAdd;Lak:hW -oR -Lnn:qE -hS);Lno:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Lal:o9;qL -2 -gK -q4 -Lnn;Lam:hW -2 -gH -q4 -Lno;Lan:hW -4 -gH -Lnp:qE -hS);Lnq:qE -B);Loa:w5=cSub;g0 -q4 -Lnk;Lao:o9;oC=q6 -q9 -oR -q4 -Lnp;Lap:hW -oR -q4 -Lnq;Laq:gT -y+x;Lba:qM -Ldn:q5 -gJ -Lbb:q8 -oV -o7 -x -q11 -gX -Lnn;Lbc:mI -A -gX -Lnn;Lbd:gU -dS;Lob:wE(cNotNot);q4 -TailCall_cNotNot;Lbe:gT -fp_and(x -d6 -Lbf:q7=fp_asin -m5 -Lbg:q7=fp_asinh -m5 -Lbh:q7=fp_atan -m5 -Lbi:gT -fp_atan2(gW -Lbj:q7=fp_atanh -m5 -Lbk:q7=fp_cbrt -m5 -Lbl:q1 -cFloor);Loc:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lbm:q7=fp_ceil -m5 -Lbn:g6 -Lod:wE(cCos);q4 -TailCall_cCos;Lbo:q7=fp_cos -m5 -Lbp:dF=cDup;w5=cInv;Loe:wE(cInv);q4 -TailCall_cInv;Lbq:mI -cSinCos);gJ -Lca:g6 -wE(cCosh);q4 -TailCall_cCosh;Lcb:q1 -cSqr -o7 -g1 -1));Lof:qW -q6 -oJ -hS);Log:w5=cSqrt;g0 -wE(cSqrt);q4 -TailCall_cSqrt;Lcc:q7=fp_cosh -m5 -Lcd:mI -cSinhCosh);gJ -Lce:q7=RadiansToDegrees -m5 -Lcf:q1 -cSec -hA -Lcg:q1 -cTan -hA -Lch:q1 -cSin -hA -Lci:oZ));dF -dJ -Loh:qE -dU -oZ -1));Loi:qW -q6);Loj:w5=hS;q4 -Lnl;Lcj:q1 -cNeg -oJ -cExp -hA -Lck:q1 -cNeg -oJ -cExp2 -hA -Lcl:g6 -q4 -Lfa;Lcm:q1 -cNeg -oJ -cPow -hA -Lcn:q1 -cCos -hA -Lco:q1 -cCsc -hA -Lcp:gU -cTan;Lok:wE(cTan);q4 -TailCall_cTan;Lcq:gU -cTanh;Lol:wE(cTanh);q4 -TailCall_cTanh;Lda:q1 -cCot -hA -Ldb:o9;dI -Lom:wE(cDiv);q4 -TailCall_cDiv;Ldc:gT -y/x;q4 -Lba;Ldd:hV -2;qI -q8 -oR -Lon:w5=cDeg;g0 -wE(cDeg);q4 -TailCall_cDeg;Lde:hV -2;qI -q8 -oR -Loo:w5=cRad;g0 -wE(cRad);q4 -TailCall_cRad;Ldf:gT -y/x;dG -Lng;Ldg:q7=g1 -1)/x;q4 -Lfa;Ldh:mI -oI -Lop:g0 -q4 -Lom;Ldi:q8 -3 -gC -oI -qF -x -q11);Loq:w5=cRDiv;g0 -wE(cRDiv);q4 -TailCall_cRDiv;Ldj:hV -3 -gC -oI -qE -B -gX -Loq;Ldk:dI -Lpa:wE(cEqual);q4 -TailCall_cEqual;Ldl:gT -fp_equal(gW -Ldm:d7 -cExp -o7 -fp_exp(x)gX -Lnj;Ldo:q7=fp_exp -m5 -Ldp:d7 -cExp2 -o7 -fp_exp2(x)gX -Lnj;Ldq:q7=fp_exp2 -m5 -Lea:qF -oW -g1 -2))q11);Lpb:qE -h3 -gI -cExp;g0 -wE(cExp);q4 -TailCall_cExp;Leb:q1 -cCeil -gX -Loc;Lec:q7=fp_floor -m5 -Led:gT -fp_less(x -d6 -Lee:qM -q1 -cNeg);Ljm:qE -cAbsNot);gJ -Lef:q7=g1 -0.5)/x;qK=d8 -dS;g0 -q4 -Lob;Leg:gT -fp_lessOrEq(x -d6 -Leh:qM -Ljd:q5 -Lpc:qE -cAbsNotNot);gJ -Lei:q7=fp_int -m5 -Lej:gU -cSec;wE(cSec);q4 -TailCall_cSec;Lek:gU -cSin;Lpd:wE(cSin);q4 -TailCall_cSin;Lel:q1 -cNeg -gI -cPow;Lpe:g0 -Lpf:wE(cPow);q4 -TailCall_cPow;Lem:gU -cCos;q4 -Lod;Len:gU -cCsc;wE(cCsc);q4 -TailCall_cCsc;Leo:q1 -cRSqrt);gJ -Lep:g6 -Lpg:w5=cCot;wE(cCot);q4 -TailCall_cCot;Leq:q7=g1 -1)/x;gJ -Lfb:q7=g1 -0.5)/x;qK=d8 -cNot;g0 -Lph:wE(cNot);q4 -TailCall_cNot;Lfc:gT -fp_less(gW -Lfd:qM -Lje:w3 -Ljm;Lfe:gT -fp_lessOrEq(gW -Lff:qM -q1 -cNeg -gX -Lpc;Lfg:d7 -cLog -o7 -oW -x)o8 -Lfh:q1 -dQ -qE -cLog);Lpi:qW -cDup -gX -Loj;Lfi:q7=oW -x);gJ -Lfj:qF -dR -fp_const_e()));Lpj:dF -dJ -q4 -Lng;Lfk:d7 -cLog10 -o7 -dR -x)o8 -Lfl:q1 -dQ -qE -cLog10 -gX -Lpi;Lfm:q7=dR -x);gJ -Lfn:qF -o4 -fp_const_e())gX -Lpj;Lfo:d7 -cLog2 -o7 -o4 -x)o8 -Lfp:q1 -dQ -qE -cLog2 -gX -Lpi;Lfq:q7=o4 -x);gJ -Lga:gT -fp_max(x -d6 -Lgb:gT -fp_min(x -d6 -Lgc:gT -fp_mod(gW -Lgd:hV -oR -q0-=3;q4 -Lpg;Lge:gU -cSqr;Lpk:wE(cSqr);q4 -TailCall_cSqr;Lgf:gU -cDiv;q4 -Lom;Lgg:mI -cSqr -gX -Loc;Lgh:hV -3 -gC -cSqr);dM -Loc;Lgi:q7=x+g1 -1);gG -w5=cPow;q4 -Lpf;Lgj:gG -q4 -Lni;Lgk:gT -x;Lpl:dG -Lnh;Lgl:hV -2;qI -qM -Lpm:hV -4 -gH -Lpn:o6 -x);Lpo:qW -q6 -gX -Lnh;Lgm:qM -q4 -Lpm;Lgn:q8 -4 -gC -B -gX -Lpn;Lgo:q8 -oR -q4 -Lpn;Lgp:qK -dJ -q4 -Ldn;Lgq:dI -q4 -Lni;Lha:qM -Lpp:hV -oR -gJ -Lhb:q7=x+x;q4 -Lgj;Lhc:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Loj;Lhd:gT -x;d7 -dU -qF -y*x -o8 -Lhe:q7=RadiansToDegrees(x -gX -Lgq;Lhf:gT -y*x;q8 -4 -gH -Lpq:qE -dU -Lqa:qE -B -gI -cDiv;q4 -Lop;Lhg:o9;oC=q6 -q9 -oR -q4 -Lpq;Lhh:gT -y*x;q8 -oR -q4 -Lqa;Lhi:q8 -4 -gH -q4 -Lnh;Lhj:q8 -4 -dT -qF -x+x -gX -Lpo;Lhk:hV -2;qI -qM -q4 -Lpp;Lhl:gT -y*x;q4 -Lpl;Lhm:o9;q4 -Lgq;Lhn:gT -y*x;q8 -oR -Lqb:dM -Loq;Lho:o9;qL -2 -gK -q4 -Lqb;Lhp:gT -y*x;dG -Loq;Lhq:q7=h4 -gX -Lgq;Lia:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Loa;Lib:gT -y*x;q4 -Lba;Lic:qM -w3 -Loc;Lid:dF=cDup;dW-=1;qM -Lqc:w5=hS;q4 -Lnm;Lie:qM -w3 -Lon;Lif:qM -w3 -Loo;Lig:hV -oV -gX -Lpq;Lih:hV -2 -gH -Lqd:qE -cSqr -gX -Lnh;Lii:q8 -oV -o7 -x -q11 -gX -Lqb;Lij:mI -A -gX -Lqb;Lik:hV -oR -q4 -Lqd;Lil:dI -Lqe:wE(cNEqual);q4 -TailCall_cNEqual;Lim:gT -fp_nequal(gW -Lin:o9;q4 -Lcl;Lio:o9 -gB -cSin;g0 -q4 -Lpd;Lip:o9 -gB -cSinh;g0 -wE(cSinh);q4 -TailCall_cSinh;Liq:o9 -gB -cTan;g0 -q4 -Lok;Lja:o9 -gB -cTanh;g0 -q4 -Lol;Ljb:o9;gJ -Ljc:g6 -q4 -Lph;Ljf:gU -cNEqual;q4 -Lqe;Ljg:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Ljh:gU -cLess;wE(cLess);q4 -TailCall_cLess;Lji:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Ljj:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Ljk:gU -w8;q4 -Lpa;Ljl:q7=fp_not -m5 -Ljn:gT -fp_or(x -d6 -Ljo:d7 -dQ -qF -x+x);Lqf:qW -q6 -gX -Lpe;Ljp:dL -Lpb;Ljq:qK=d8 -cExp2;g0 -wE(cExp2);q4 -TailCall_cExp2;Lka:gT -y*x;dG -Lpe;Lkb:qK -dJ -q1 -h3 -gX -Lpe;Lkc:dI -q4 -Lpf;Lkd:q8 -3 -dT -qF -x -gX -Lqf;Lke:q7=g1 -gX -Loh;Lkf:qM -w3 -Log;Lkg:qM -q5 -w5=cCbrt;g0 -wE(cCbrt);q4 -TailCall_cCbrt;Lkh:qM -q1 -cCbrt);Lqg:w5=cInv;g0 -q4 -Loe;Lki:qM -q4 -Leo;Lkj:qM -w3 -Lqg;Lkk:hV -2;qI -q8 -3 -gC -dQ -qF -y*x -gX -Lqf;Lkl:q7=x+x;q4 -Lkc;Lkm:gT -oX -gW -Lkn:q1 -cTanh -gX -Lqg;Lko:oZ)gX -Lpj;Lkp:q7=h4 -gX -Lcl;Lkq:q7=h4);gJ -Lla:mI -cSinCos -gX -Lqg;Llb:q1 -cSin -gX -Loc;Llc:q7=fp_sin -m5 -Lld:q1 -cSqr -o7 -g1-1)gX -Lof;Lle:q1 -cSinh -gX -Loc;Llf:q7=fp_sinh -m5 -Llg:g6 -q4 -Lpk;Llh:hV -4 -gC -A);Lqh:w5=cHypot;g0 -wE(cHypot);q4 -TailCall_cHypot;Lli:hV -5 -gC -A -oJ -B -gX -Lqh;Llj:gU -cAbs;q4 -Lnf;Llk:q7=fp_sqrt -m5 -Lll:g6 -q4 -Lqc;Llm:gT -y-x;q4 -Lba;Lln:o9;q4 -Lqc;Llo:q8 -oV -oJ -hS -o7 -x -q11 -gX -Lno;Llp:mI -A -oJ -cSub -gX -Lno;Llq:q1 -cTan -gX -Loc;Lma:q7=fp_tan -m5 -Lmb:q1 -cTanh -gX -Loc;Lmc:q7=fp_tanh -m5 -Lmd:q7=fp_trunc -m5 -Lme:gT -x-y;Lqi:q8 -2 -gH -Lqj:qE -A);gJ -Lmf:q7=fp_tan(x);Lqk:dL -Lqj;Lmg:q7=oW -x -gX -Lqk;Lmh:q7=o4 -x -gX -Lqk;Lmi:q7=fp_exp(x -gX -Lqk;Lmj:q7=oX -g1 -10),x -gX -Lqk;Lmk:q7=fp_exp2(x -gX -Lqk;Lml:gT -x/y;q4 -Lqi;Lmm:gT -x/y;q8 -2 -gH -Lql:qE -OppositeComparisonOpcode(A));gJ -Lmn:o9;dL -Lql;Lmo:gT -oX -x,g1 -1)/y -gX -Lqi;Lmp:q7=fp_asinh(x -gX -Lqk;Lmq:d7 -dQ -qF -fp_sqrt(x)q11 -gX -Lqj;Lna:q7=fp_atanh(x -gX -Lqk;Lnb:qW -cDup);gJ -Lnc:dF=cDup;gJ -Lnd:hV -3 -gC -cSinCos);Lqm:qE -GetParamSwappedBinaryOpcode(C));gJ -Lne:hV -3 -gC -cSinhCosh -gX -Lqm;gJ -q4 -TailCall_cAcos;q4 -TailCall_cAcosh;q4 -TailCall_cAnd;q4 -TailCall_cAsin;q4 -TailCall_cAsinh;q4 -TailCall_cAtan;q4 -TailCall_cAtan2;q4 -TailCall_cAtanh;q4 -TailCall_cCeil;q4 -TailCall_cFloor;q4 -TailCall_cInt;q4 -TailCall_cLog;q4 -TailCall_cLog10;q4 -TailCall_cLog2;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cOr;q4 -TailCall_cRDiv;q4 -TailCall_cRad;q4 -TailCall_cSec;q4 -TailCall_cSin;q4 -TailCall_cSinh;q4 -TailCall_cSqrt;q4 -TailCall_cSub;q4 -TailCall_cTan;q4 -TailCall_cTanh;q4 -TailCall_cTrunc; -#endif -#if((FP_COMPLEX_VERSION) && (FP_FLOAT_VERSION)) -dH -x;dH -gE -A;hT -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0} -qH -TailCall_cAcos:g5 -cAcos:qY -wB(172,"x cAcos" -,"[fp_acos(x)]" -,wN);q4 -Lad;} -qH -TailCall_cAcosh:g5 -cAcosh:qY -wB(169,"x cAcosh" -,"[fp_acosh(x)]" -,wN);q4 -Lae;} -qH -TailCall_cAdd:g5 -hG -Laf;qT -h3 -hL]==hS){if(qL -gZ -Lag;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -wY -aV,"[x+Value_t(1)]" -wH,wN);q4 -Lah;} -} -q4 -dX -oF -wB(199,q81 -aV,"cSub" -,);q4 -Lai -gY -hK -qZ -mR(127,aU"cAdd " -a6,"[y+x]" -aV,q31);q4 -Laj;qT -cRSub:qQ -hE -d3 -3 -qZ -mR(298,aU"cAdd " -mS,mJ -aV" " -a4,q31);q4 -Lak;qT -hI -wB(299,mG -mS,"[-x]" -aV" " -a4,wN);q4 -Lal -qU -q6:mR(297,aU -mS,mJ" " -a4,q31);q4 -Lam;qT -oA -Lan;qT -hI -wB(293,mG"B[IsVarOpcode(B)]" -mF" " -a6,"[-x]" -aV" B" -mF,wA"," -aQ(B)wM);q4 -Lao -qU -q6:mR(291,aU"B[IsVarOpcode(B)]" -mF" " -a6,mJ" B" -mF,wA"," -aQ(B)<<"," -aE);q4 -Lap;} -w9 -mR(105,aU -a6,"[y+x]" -,q31);q4 -Laq;} -g8)){wB(57,"x[x==Value_t()]" -aV,,wN);q4 -Lba;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x " -a4 -aC"cAdd" -,"[DO_STACKPLUS1] A [x]" -aV" " -a4,aA(A)<<"," -m4);incStackPtr();--mStackPtr;q4 -Lbb;} -wB(295,a4 -aC"cAdd" -,"[DO_STACKPLUS1] A" -aV" " -a4,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lbc;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mC"cAnd" -,aF,);q4 -w7 -m2(117,m3"cAnd" -,"[fp_and(x,y)]" -,q31);q4 -Lbe;h8} -qH -TailCall_cArg:g5 -cArg:qY -wB(190,"x cArg" -,"[fp_arg(x)]" -,wN);q4 -Lbf;} -qH -TailCall_cAsin:g5 -cAsin:qY -wB(173,"x cAsin" -,"[fp_asin(x)]" -,wN);q4 -Lbg;} -qH -TailCall_cAsinh:g5 -cAsinh:qY -wB(170,"x cAsinh" -,"[fp_asinh(x)]" -,wN);q4 -Lbh;} -qH -TailCall_cAtan:g5 -cAtan:qY -if(g1 -x.real(),fp_abs(x.imag()))!=g1 -0,oG -wB(174,"x[Value_t(x.real(),fp_abs(x.imag()))!=Value_t(0,1)] cAtan" -,"[fp_atan(x)]" -,wN);q4 -Lbi;qG -TailCall_cAtan2:g5 -cAtan2:qY -m2(139,m3"cAtan2" -,"[fp_atan2(y,x)]" -,q31);q4 -Lbj;qG -TailCall_cAtanh:g5 -cAtanh:qY -if(g1 -fp_abs(x.real()),x.imag())!=g1 -1,0)){wB(171,"x[Value_t(fp_abs(x.real()),x.imag())!=Value_t(1,0)] cAtanh" -,"[fp_atanh(x)]" -,wN);q4 -Lbk;qG -TailCall_cCbrt:g5 -cCbrt:qY -wB(175,"x cCbrt" -,"[fp_cbrt(x)]" -,wN);q4 -Lbl;} -qH -TailCall_cCeil:g5 -cCeil:qS -hI -wB(402,mG -mW,mO -mD,);q4 -Lbm -gY -wB(135,"x " -mW,"[fp_ceil(x)]" -,wN);q4 -Lbn -gS -wB(396,"A[IsAlwaysIntegerOpcode(A)] " -mW,"A" -,aA(A)wM);gJ -qG -TailCall_cConj:g5 -cConj:qS -cConj:wB(63,mT" " -mT,,);oS -gY -wB(193,"x " -mT,"[fp_conj(x)]" -,wN);q4 -Lbp;} -qH -TailCall_cCos:g5 -cCos:qS -cAcos:wB(346,"cAcos " -aK,,);q4 -oE -wB(238,mG -aK,aK,);q4 -Lbq -gY -wB(176,"x " -aK,"[fp_cos(x)]" -,wN);q4 -Lca;oH -qN -qQ -h9 -cSec:hD -wB(500,aG" " -mX" " -wI -aK,"B " -mX" " -aR,aA(A)q51(B)wM);q4 -Lcb;qT -cSin:hD -wB(494,aG" " -mM" " -wI -aK,"B cSinCos" -,aA(A)q51(B)wM);q4 -Lcc;h8} -qG -TailCall_cCosh:g5 -cCosh:qS -cAsinh:wB(450,"cAsinh " -aI,"[DO_STACKPLUS1] " -mZ"[Value_t(1)] " -aL,);incStackPtr();--mStackPtr;q4 -Lcd -oF -wB(239,mG -aI,aI,);q4 -Lce -gY -wB(177,"x " -aI,"[fp_cosh(x)]" -,wN);q4 -Lcf;oH -qN -oY -cSinh -mY(507,aG" cSinh " -wI -aI,"B cSinhCosh" -,aA(A)q51(B)wM);q4 -Lcg;} -} -qG -TailCall_cCot:g5 -cCot:A=qN -oY -cTan -mY(498,aG" " -mN" " -wI"cCot" -,"B " -mN" " -aR,aA(A)q51(B)wM);q4 -Lcb;} -qG -TailCall_cCsc:g5 -cCsc:A=qN -oY -cSin -mY(496,aG" " -mM" " -wI"cCsc" -,"B " -mM" " -aR,aA(A)q51(B)wM);q4 -Lcb;} -qG -TailCall_cDeg:g5 -cDeg:qY -wB(133,"x cDeg" -,"[RadiansToDegrees(x)]" -,wN);q4 -Lch;} -qH -TailCall_cDiv:g5 -cDiv:qS -cCos:wB(250,aK -m7,mX -wH,);q4 -Lci -qU -cCot:wB(254,"cCot" -m7,mN -wH,);q4 -Lcj -qU -cCsc:wB(252,"cCsc" -m7,mM -wH,);q4 -Lck -qU -cDup:wB(78,"cDup" -m7,"[Value_t()]" -m6"[Value_t(1)]" -aV,);q4 -Lcl -qU -w2 -wB(408,mH -m7,mG -mH -wH,);q4 -Lcm -qU -cExp2:wB(409,"cExp2" -m7,mG"cExp2" -wH,);q4 -Lcn -qU -cInv:wB(213,aS -m7,"cMul" -,);q4 -Lco -qU -cPow:wB(407,"cPow" -m7,q81 -a1 -wH,);q4 -Lcp -qU -cSec:wB(253,mX -m7,aK -wH,);q4 -Lcq -qU -cSin:wB(249,mM -m7,"cCsc" -wH,);q4 -Lda -qU -cSinCos:wB(502,"cSinCos" -m7,mN,);q4 -Ldb -qU -cSinhCosh:wB(509,"cSinhCosh" -m7,"cTanh" -,);q4 -Ldc -qU -cTan:wB(251,mN -m7,"cCot" -wH,);q4 -Ldd -gY -if -hF -gQ -hI -wB(125,mG -wZ"cDiv" -,"[-x]" -m7,wN);q4 -Lde -qU -q6:mR(103,aU -wZ"cDiv" -,"[y/x]" -,q31);q4 -Ldf;} -} -g8 -oG -wB(56,wO"cDiv" -,,wN);q4 -Lba;} -dB -h3 -gA -qZ -hP(y/x)==fp_const_rad_to_deg -h7 -wB(321,"y[(y/x)==fp_const_rad_to_deg()]" -m6 -wR,"cDeg" -,q31);q4 -Ldg;} -if((y/x)==fp_const_deg_to_rad -h7 -wB(322,"y[(y/x)==fp_const_deg_to_rad()]" -m6 -wR,"cRad" -,q31);q4 -Ldh;} -wB(323,"y" -m6 -wR,"[y/x]" -wH,q31);q4 -Ldi;} -} -wB(325,wR,"[Value_t(1)/x]" -wH,wN);q4 -Ldj;} -gP -cDiv:hC -wB(271,q21" " -wV,"[DO_STACKPLUS1] B A" -m6"cDiv" -,aA(A)q51(B)wM);incStackPtr();--mStackPtr;q4 -Ldk;qT -cRDiv:qQ -hE -qV -hM -wB(266,"x" -a7" " -wV,"A" -m6"[x]" -a7,aA(A)<<"," -m4);q4 -Ldl;g7 -hC -wB(265,"B[IsVarOpcode(B)]" -a7" " -wV,"A" -m6"B" -a7,aA(A)q51(B)wM);q4 -Ldm;} -h8} -qG -TailCall_cEqual:g5 -w8:oL -hU -wB(359,aX -wL -a5,"[x] " -a5,wN);q4 -Ldn -qU -cSqr:wB(361,mZ -wL -a5,"[x] " -a5,wN);q4 -Ldn;} -} -m2(115,m3 -a5,"[fp_equal(y,x)]" -,q31);q4 -Ldo;qG -TailCall_cExp:g5 -w2 -qS -hS -gM -wB(404,a6" " -mH,mH" [fp_exp(x)]" -wH,wN);q4 -Ldp;qT -cLog:A=dE -wB(340,wJ -mA" " -mH,"A" -,aA(A)wM);oS;qT -hM -wB(178,"x " -mH,"[fp_exp(x)]" -,wN);q4 -Ldq;} -qH -TailCall_cExp2:g5 -cExp2:qS -hS -gM -wB(405,a6" cExp2" -,"cExp2 [fp_exp2(x)]" -wH,wN);q4 -Lea;qT -cLog2:A=dE -wB(341,wJ -aJ" cExp2" -,"A" -,aA(A)wM);oS;qT -hM -wB(179,"x cExp2" -,"[fp_exp2(x)]" -,wN);q4 -Leb;} -wB(479,"cExp2" -,"[DO_STACKPLUS1] [fp_log(Value_t(2))]" -m6 -mH,);incStackPtr();--mStackPtr;q4 -Lec;TailCall_cFloor:g5 -cFloor:qS -hI -wB(401,mG -mO,mW -mD,);q4 -Led -gY -wB(136,"x " -mO,"[fp_floor(x)]" -,wN);q4 -Lee -gS -wB(395,"A[IsAlwaysIntegerOpcode(A)] " -mO,"A" -,aA(A)wM);gJ -qG -TailCall_cGreater:g5 -o1:qY -m2(113,m3 -aW,"[fp_less(x,y)]" -,q31);q4 -Lef;qG -TailCall_cGreaterOrEq:g5 -dK:qY -m2(114,m3 -a8,"[fp_lessOrEq(x,y)]" -,q31);q4 -Leg;qG -TailCall_cHypot:g5 -cHypot -d4 -dF==cSinCos){wB(84,"cSinCos cHypot" -,"[Value_t()]" -m6"[Value_t(1)]" -aV,);q4 -Lcl;} -qH -TailCall_cImag:g5 -cImag:qS -cAbs:wB(81,aX -mU,"[Value_t()]" -wH,);q4 -Leh -qU -cReal:wB(80,"cReal " -mU,"[Value_t()]" -wH,);q4 -Leh -gY -wB(192,"x " -mU,"[fp_imag(x)]" -,wN);q4 -Lei;} -qH -TailCall_cInt:g5 -cInt:qS -hM -wB(137,"x cInt" -,"[fp_int(x)]" -,wN);q4 -Lej -gS -wB(397,"A[IsAlwaysIntegerOpcode(A)] cInt" -,"A" -,aA(A)wM);gJ -qG -TailCall_cInv:g5 -cInv:qS -cCos:wB(256,aK -mK,mX,);q4 -Lek -qU -cCot:wB(260,"cCot" -mK,mN,);q4 -Ldb -qU -cCsc:wB(258,"cCsc" -mK,mM,);q4 -Lel -qU -cInv:wB(62,aS -mK,,);oS -qU -cPow:wB(355,"cPow" -mK,q81 -a1,);q4 -Lem -qU -cSec:wB(259,mX -mK,aK,);q4 -Len -qU -cSin:wB(255,mM -mK,"cCsc" -,);q4 -Leo -qU -cSqrt:wB(206,q01 -mK,"cRSqrt" -,);q4 -Lep -qU -cTan:wB(257,mN -mK,"cCot" -,);q4 -Leq -gY -if -hF)){wB(101,wZ -aS,"[Value_t(1)/x]" -,wN);q4 -Lfa;h8} -qH -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mB,mV,q61(A)wM);q4 -Lfb;} -} -m2(111,m3 -mB,"[fp_less(y,x)]" -,q31);q4 -Lfc;qG -TailCall_cLessOrEq:g5 -cLessOrEq:qY -m2(112,m3 -aM,"[fp_lessOrEq(y,x)]" -,q31);q4 -Lfd;qG -TailCall_cLog:g5 -cLog:mP(343,mH" " -mA,,);oS -qU -gL -wB(491,wQ -m6 -mA,mA" [fp_log(x)]" -aV,wN);q4 -Lfe;} -oD -wB(180,"x[x!=Value_t(0)] " -mA,"[fp_log(x)]" -,wN);q4 -Lff;h8} -qH -TailCall_cLog10:g5 -cLog10:mP(481,mH" " -aH,"[DO_STACKPLUS1] [fp_log10(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfg -qU -gL -wB(492,wQ -m6 -aH,aH" [fp_log10(x)]" -aV,wN);q4 -Lfh;} -oD -wB(181,"x[x!=Value_t(0)] " -aH,"[fp_log10(x)]" -,wN);q4 -Lfi;h8} -qH -TailCall_cLog2:g5 -cLog2:mP(480,mH" " -aJ,"[DO_STACKPLUS1] [fp_log2(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfj -qU -cExp2:wB(344,"cExp2 " -aJ,,);oS -qU -gL -wB(490,wQ -m6 -aJ,aJ" [fp_log2(x)]" -aV,wN);q4 -Lfk;} -oD -wB(182,"x[x!=Value_t(0)] " -aJ,"[fp_log2(x)]" -,wN);q4 -Lfl;h8} -qH -TailCall_cMax:g5 -cMax -hH -wB(60,mC -m8,,);oS -gY -m2(141,m3 -m8,"[fp_max(x,y)]" -,q31);q4 -Lfm;} -gP -cDup:hD -wB(66,aG -mE -aC -m8,"B" -mE,aA(A)q51(B)wM);oS;qT -cMax:hD -wB(68,aG" " -m8 -aC -m8,"B " -m8,aA(A)q51(B)wM);oS;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mC -m9,,);oS -gY -m2(140,m3 -m9,"[fp_min(x,y)]" -,q31);q4 -Lfn;} -gP -cDup:hD -wB(65,aG -mE -aC -m9,"B" -mE,aA(A)q51(B)wM);oS;qT -cMin:hD -wB(67,aG" " -m9 -aC -m9,"B " -m9,aA(A)q51(B)wM);oS;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m2(104,aU -wZ"cMod" -,"[fp_mod(y,x)]" -,q31);q4 -Lfo;} -qG -TailCall_cMul:g5 -h3:qS -cCsc:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(508,aG" " -aK" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cCsc" -wH,"B cCot" -,aA(A)q51(B)wM);q4 -Lfp;} -} -} -q4 -dY -qU -cDup:wB(202,"cDup" -wH,"cSqr" -,);q4 -Lfq -qU -cInv:wB(214,aS -wH,"cDiv" -,);q4 -Lga -oF -qQ -h9 -cDup:wB(467,mC -q81 -wH,"cSqr" -mD,);q4 -Lgb;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aG -wH -aC -q81 -wH,m0 -m6 -q81,aA(A)q51(B)wM);q4 -Lgc;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mC"x" -a1 -wH,"[x+Value_t(1)]" -a1,wN);q4 -Lgd;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wT" " -wX,a3,q61(A)wM);q4 -Lge;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mR(92,aU -wD,a3,q61(A)<<"," -aE);q4 -Lgf;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mR(96,aU -wK,mV,q61(A)q51(B)<<"," -aE);q4 -Lgg;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lgh;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mV,q61(A)q51(B)<<", C" -a0(C)wM);q4 -Lgi;} -} -} -if(d1 -B)){wB(90,"B[IsVarOpcode(B)] " -wD,a3,q61(A)q51(B)wM);q4 -Lge;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mV,q61(A)q51(B)wM);q4 -Lgj;} -} -} -if(d1 -h2 -wB(88,aD" " -wX,"[x]" -,q61(A)wM);q4 -Lgk;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wX,a3,q61(A)wM);q4 -Lgl;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup -d4 -x+oU -wB(316,"cDup[x+x==Value_t(1)]" -aV -wY,,wN);q4 -Lgm;} -wB(317,a9 -wY,"[x+x]" -wH,wN);q4 -Lgn -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,aD" y" -wH -aV -wY,a3" A " -aZ -wH -aV,wA", " -aU"= " -<()]" -wH -wY,"cDeg" -,q31);q4 -Ldg;} -if((y*x)==fp_const_deg_to_rad -h7 -wB(308,"y[(y*x)==fp_const_deg_to_rad()]" -wH -wY,"cRad" -,q31);q4 -Ldh;} -wB(128,"y" -wH -wY,aZ -wH,q31);q4 -Lhg;qT -hI -wB(122,q81 -wY,"[-x]" -wH,wN);q4 -Lhh -qU -cRDiv:qQ -hE -qV -o5 -3 -qZ -mR(285,"y" -wH -a7 -wY,aZ -wH -a7,q31);q4 -Lhi;qT -hI -wB(286,q81 -a7 -wY,"[-x]" -wH -a7,wN);q4 -Lhj -qU -q6:mR(284,"y" -a7 -wY,aZ -a7,q31);q4 -Lhk;qT -cRad:wB(210,"cRad" -wY,"[DegreesToRadians(x)]" -wH,wN);q4 -Lhl -qU -cSub -hL -oM -if(qL -3 -qZ -hO -A=qL -4]w0 -wB(387,aD" y" -m6"cSub" -wY,a3" A " -aZ -m6"cSub" -,wA", " -aU"= " -<()]" -wH,"cDeg" -,wN);q4 -Lhq;} -if(x==fp_const_deg_to_rad -h7 -wB(208,"x[x==fp_const_deg_to_rad()]" -wH,"cRad" -,wN);q4 -Lia;h8 -g7 -dY:;A=dF -qO -A -gQ -cDiv:hC -wB(274,q21" " -wT,"[DO_STACKPLUS1] A" -m6"B" -m7,aA(A)q51(B)wM);incStackPtr();--mStackPtr;q4 -Lib;} -q4 -d5 -h3:qQ -hE -qV -hI -B=hQ -wB(470,aG -mD -m6 -wT,m0 -m6 -q81,aA(A)q51(B)wM);q4 -Lgc;} -q4 -dZ;g7 -dZ:;hD -wB(461,aG -m6 -wT,m0 -wH,aA(A)q51(B)wM);q4 -Lic;} -} -q4 -d5 -hI -hD -wB(464,aG -mD" " -wT,m0 -mD,aA(A)q51(B)wM);q4 -Lgb;} -q4 -d5 -cRDiv -hL -qZ -qC -wB(267,"x" -a7" " -wT,"[DO_STACKPLUS1] " -mV -a7,aA(A)<<"," -m4);incStackPtr();--mStackPtr;q4 -Lid;} -wB(281,"cRDiv " -wT,"[DO_STACKPLUS1] A" -wH -a7,aA(A)wM);incStackPtr();--mStackPtr;q4 -Lie;g7 -Default4:;B=qK -qR -w4 -wB(458,aG" " -wT,m0,aA(A)q51(B)wM);q4 -Lfq;} -} -} -if(gV -h2 -B=qK -qO -B -qP -1 -gA -oM -C=oC -qR -C==A){D=qL -4]qR -D==B){wB(477,"D[D==B] C[C==A]" -m6"B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Lif;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:oL -hU -wB(360,aX -wL -wW,"[x] " -wW,wN);q4 -Lig -qU -cSqr:wB(362,mZ -wL -wW,"[x] " -wW,wN);q4 -Lig;} -} -m2(116,m3 -wW,"[fp_nequal(y,x)]" -,q31);q4 -Lih;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -m6 -q81,"[-x]" -wH,wN);q4 -Lii;qT -hI -wB(61,q81 -mD,,);oS -qU -cSin:g9 -wB(244,"x" -m6 -mM -mD,"[-x]" -m6 -mM,wN);q4 -Lij;} -qT -oQ -g9 -wB(245,"x" -m6"cSinh" -mD,"[-x]" -m6"cSinh" -,wN);q4 -Lik;} -qT -cTan:g9 -wB(246,"x" -m6 -mN -mD,"[-x]" -m6 -mN,wN);q4 -Lil;} -qT -cTanh:g9 -wB(247,"x" -m6"cTanh" -mD,"[-x]" -m6"cTanh" -,wN);q4 -Lim;} -qT -hM -wB(100,"x" -mD,"[-x]" -,wN);q4 -Lin;} -qH -TailCall_cNot:g5 -cNot:qS -cAbsNotNot:wB(231,"cAbsNotNot" -aB,aN,);q4 -Lio -qU -w8:wB(220,a5 -aB,wW,);q4 -Lip -qU -o1:wB(218,aW -aB,aM,);q4 -Liq -qU -dK:wB(219,a8 -aB,mB,);q4 -Lja -qU -cLess:wB(216,mB -aB,a8,);q4 -Ljb -qU -cLessOrEq:wB(217,aM -aB,aW,);q4 -Ljc -qU -cNEqual:wB(221,wW -aB,a5,);q4 -Ljd -qU -cNot:wB(229,"cNot" -aB,aF,);q4 -Lbd -qU -dS:wB(230,aF -aB,"cNot" -,);q4 -Lje -gY -wB(107,"x" -aB,"[fp_not(x)]" -,wN);q4 -Ljf;} -qH -TailCall_cNotNot:g5 -dS -d4 -dF==cNot){wB(232,"cNot " -aF,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mC"cOr" -,aF,);q4 -w7 -m2(118,m3"cOr" -,"[fp_or(x,y)]" -,q31);q4 -Ljg;h8} -qH -TailCall_cPolar:g5 -cPolar -d4 -q0[0 -qZ -y=q7;qJ -x -gO -wB(194,"x " -aU"cPolar" -,"[fp_polar(x,y)]" -," with " -aU"= " -<mByteCode.size()>0]" -,"B" -mE,aA(A)q51(B)wM);q4 -Lll;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mE,aA(A)q51(B)<<", C" -a0(C)<<", D" -a0(D)wM);q4 -Llm;} -} -} -} -C=w5 -qR -IsCommutativeOrParamSwappableBinaryOpcode(C)){qS -cSin:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(505,aG" " -aK" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] " -mM" C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinCos {GetParamSwappedBinaryOpcode(C)}" -," with C" -a0(C)q71(A)q51(B)wM);q4 -Lln;} -} -qT -oQ -A=qK -w1 -3 -gA]==cCosh){B=hQ -wB(506,aG" " -aI" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cSinh C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinhCosh {GetParamSwappedBinaryOpcode(C)}" -," with C" -a0(C)q71(A)q51(B)wM);q4 -Llo;} -} -h8} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -Llp:wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:q7=fp_acos -m5 -Lae:q7=fp_acosh -m5 -Laf:oZ -4));gG -Llq:w5=h3;Lma:g0 -Lmb:wE(cMul);q4 -TailCall_cMul;Lag:hV -4 -dT -oZ -4));Lmc:qW -q6 -hY;Lah:q7=x+g1 -1);gG -Lfb:w5=h3;q4 -Lmb;Lai:gU -cSub;Lmd:wE(cSub);q4 -TailCall_cSub;Laj:hW -2 -gH -Lme:g0 -Lmf:wE(cAdd);q4 -TailCall_cAdd;Lak:hW -oR -Lmg:qE -hS);Lmh:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Lal:o9;qL -2 -gK -q4 -Lmg;Lam:hW -2 -gH -q4 -Lmh;Lan:hW -4 -gH -Lmi:qE -hS);Lmj:qE -B);Lmk:w5=cSub;g0 -q4 -Lmd;Lao:o9;oC=q6 -q9 -oR -q4 -Lmi;Lap:hW -oR -q4 -Lmj;Laq:gT -y+x;Lba:qM -Lbo:q5 -gJ -Lbb:q8 -oV -o7 -x -q11 -gX -Lmg;Lbc:mI -A -gX -Lmg;Lbd:gU -dS;wE(cNotNot);q4 -TailCall_cNotNot;Lbe:gT -fp_and(x -d6 -Lbf:q7=fp_arg -m5 -Lbg:q7=fp_asin -m5 -Lbh:q7=fp_asinh -m5 -Lbi:q7=fp_atan -m5 -Lbj:gT -fp_atan2(gW -Lbk:q7=fp_atanh -m5 -Lbl:q7=fp_cbrt -m5 -Lbm:q1 -cFloor);Lml:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lbn:q7=fp_ceil -m5 -Lbp:q7=fp_conj -m5 -Lbq:g6 -Lmm:wE(cCos);q4 -TailCall_cCos;Lca:q7=fp_cos -m5 -Lcb:dF=cDup;w5=cInv;Lmn:wE(cInv);q4 -TailCall_cInv;Lcc:mI -cSinCos);gJ -Lcd:q1 -cSqr -o7 -g1 -1));Lmo:qW -q6 -oJ -hS);Lmp:w5=cSqrt;g0 -wE(cSqrt);q4 -TailCall_cSqrt;Lce:g6 -wE(cCosh);q4 -TailCall_cCosh;Lcf:q7=fp_cosh -m5 -Lcg:mI -cSinhCosh);gJ -Lch:q7=RadiansToDegrees -m5 -Lci:q1 -cSec -hY;Lcj:q1 -cTan -hY;Lck:q1 -cSin -hY;Lcl:oZ));dF -dJ -Lmq:qE -dU -oZ -1));Lna:qW -q6);Lnb:w5=hS;q4 -Lme;Lcm:q1 -cNeg -oJ -cExp -hY;Lcn:q1 -cNeg -oJ -cExp2 -hY;Lco:g6 -q4 -Lfb;Lcp:q1 -cNeg -oJ -cPow -hY;Lcq:q1 -cCos -hY;Lda:q1 -cCsc -hY;Ldb:gU -cTan;Lnc:wE(cTan);q4 -TailCall_cTan;Ldc:gU -cTanh;Lnd:wE(cTanh);q4 -TailCall_cTanh;Ldd:q1 -cCot -hY;Lde:o9;dI -Lne:wE(cDiv);q4 -TailCall_cDiv;Ldf:gT -y/x;q4 -Lba;Ldg:hV -2;qI -q8 -oR -Lnf:w5=cDeg;g0 -wE(cDeg);q4 -TailCall_cDeg;Ldh:hV -2;qI -q8 -oR -Lng:w5=cRad;g0 -wE(cRad);q4 -TailCall_cRad;Ldi:gT -y/x;dG -Llq;Ldj:q7=g1 -1)/x;q4 -Lfb;Ldk:mI -oI -Lnh:g0 -q4 -Lne;Ldl:q8 -3 -gC -oI -qF -x -q11);Lni:w5=cRDiv;g0 -wE(cRDiv);q4 -TailCall_cRDiv;Ldm:hV -3 -gC -oI -qE -B -gX -Lni;Ldn:dI -Lnj:wE(cEqual);q4 -TailCall_cEqual;Ldo:gT -fp_equal(gW -Ldp:d7 -cExp -o7 -fp_exp(x)gX -Lmc;Ldq:q7=fp_exp -m5 -Lea:d7 -cExp2 -o7 -fp_exp2(x)gX -Lmc;Leb:q7=fp_exp2 -m5 -Lec:qF -oW -g1 -2))q11);Lnk:qE -h3 -gI -cExp;g0 -wE(cExp);q4 -TailCall_cExp;Led:q1 -cCeil -oT -Lee:q7=fp_floor -m5 -Lef:gT -fp_less(x -d6 -Leg:gT -fp_lessOrEq(x -d6 -Leh:oZ));Lnl:dF -dJ -q4 -Llq;Lei:q7=fp_imag -m5 -Lej:q7=fp_int -m5 -Lek:gU -cSec;wE(cSec);q4 -TailCall_cSec;Lel:gU -cSin;Lnm:wE(cSin);q4 -TailCall_cSin;Lem:q1 -cNeg -gI -cPow;Lnn:g0 -Lno:wE(cPow);q4 -TailCall_cPow;Len:gU -cCos;q4 -Lmm;Leo:gU -cCsc;wE(cCsc);q4 -TailCall_cCsc;Lep:q1 -cRSqrt);gJ -Leq:g6 -Lnp:w5=cCot;wE(cCot);q4 -TailCall_cCot;Lfa:q7=g1 -1)/x;gJ -Lfc:gT -fp_less(gW -Lfd:gT -fp_lessOrEq(gW -Lfe:d7 -cLog -o7 -oW -x)gX -Lna;Lff:q7=oW -x);gJ -Lfg:qF -dR -fp_const_e())gX -Lnl;Lfh:d7 -cLog10 -o7 -dR -x)gX -Lna;Lfi:q7=dR -x);gJ -Lfj:qF -o4 -fp_const_e())gX -Lnl;Lfk:d7 -cLog2 -o7 -o4 -x)gX -Lna;Lfl:q7=o4 -x);gJ -Lfm:gT -fp_max(x -d6 -Lfn:gT -fp_min(x -d6 -Lfo:gT -fp_mod(gW -Lfp:hV -oR -q0-=3;q4 -Lnp;Lfq:gU -cSqr;Lnq:wE(cSqr);q4 -TailCall_cSqr;Lga:gU -cDiv;q4 -Lne;Lgb:mI -cSqr -oT -Lgc:hV -3 -gC -cSqr);dM -Lml;Lgd:q7=x+g1 -1);gG -w5=cPow;q4 -Lno;Lge:gG -q4 -Lmb;Lgf:gT -x;Loa:dG -Lma;Lgg:hV -2;qI -qM -Lob:hV -4 -gH -Loc:o6 -x);Lod:qW -q6 -gX -Lma;Lgh:qM -q4 -Lob;Lgi:q8 -4 -gC -B -gX -Loc;Lgj:q8 -oR -q4 -Loc;Lgk:qK -dJ -oS;Lgl:dI -q4 -Lmb;Lgm:qM -Loe:hV -oR -gJ -Lgn:q7=x+x;q4 -Lge;Lgo:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Lnb;Lgp:gT -x;d7 -dU -qF -y*x -gX -Lna;Lgq:q7=RadiansToDegrees(x -gX -Lgl;Lha:gT -y*x;q8 -4 -gH -Lof:qE -dU -Log:qE -B -gI -cDiv;q4 -Lnh;Lhb:o9;oC=q6 -q9 -oR -q4 -Lof;Lhc:gT -y*x;q8 -oR -q4 -Log;Lhd:q8 -4 -gH -q4 -Lma;Lhe:q8 -4 -dT -qF -x+x -gX -Lod;Lhf:hV -2;qI -qM -q4 -Loe;Lhg:gT -y*x;q4 -Loa;Lhh:o9;q4 -Lgl;Lhi:gT -y*x;q8 -oR -Loh:dM -Lni;Lhj:o9;qL -2 -gK -q4 -Loh;Lhk:gT -y*x;dG -Lni;Lhl:q7=h4 -gX -Lgl;Lhm:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q11);dM -Lmk;Lhn:gT -y*x;q4 -Lba;Lho:qM -w3 -Lml;Lhp:dF=cDup;dW-=1;qM -Loi:w5=hS;q4 -Lmf;Lhq:qM -w3 -Lnf;Lia:qM -w3 -Lng;Lib:hV -oV -gX -Lof;Lic:hV -2 -gH -Loj:qE -cSqr -gX -Lma;Lid:q8 -oV -o7 -x -q11 -gX -Loh;Lie:mI -A -gX -Loh;Lif:hV -oR -q4 -Loj;Lig:dI -Lok:wE(cNEqual);q4 -TailCall_cNEqual;Lih:gT -fp_nequal(gW -Lii:o9;q4 -Lco;Lij:o9 -gB -cSin;g0 -q4 -Lnm;Lik:o9 -gB -cSinh;g0 -wE(cSinh);q4 -TailCall_cSinh;Lil:o9 -gB -cTan;g0 -q4 -Lnc;Lim:o9 -gB -cTanh;g0 -q4 -Lnd;Lin:o9;gJ -Lio:q1 -cAbsNot);gJ -Lip:gU -cNEqual;q4 -Lok;Liq:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Lja:gU -cLess;wE(cLess);q4 -TailCall_cLess;Ljb:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Ljc:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Ljd:gU -w8;q4 -Lnj;Lje:g6 -wE(cNot);q4 -TailCall_cNot;Ljf:q7=fp_not -m5 -Ljg:gT -fp_or(x -d6 -Ljh:gT -fp_polar(x -d6 -Lji:dL -Lnk;Ljj:qK=d8 -cExp2;g0 -wE(cExp2);q4 -TailCall_cExp2;Ljk:gT -y*x;dG -Lnn;Ljl:qK -dJ -q1 -h3 -gX -Lnn;Ljm:q7=g1 -gX -Lmq;Ljn:qM -w3 -Lmp;Ljo:qM -q5 -w5=cCbrt;g0 -wE(cCbrt);q4 -TailCall_cCbrt;Ljp:qM -q1 -cCbrt);Lol:w5=cInv;g0 -q4 -Lmn;Ljq:qM -q4 -Lep;Lka:qM -w3 -Lol;Lkb:q7=x+x;dI -q4 -Lno;Lkc:gT -oX -gW -Lkd:q1 -cTanh -gX -Lol;Lke:q7=h4 -gX -Lco;Lkf:q7=h4);gJ -Lkg:q7=fp_real -m5 -Lkh:mI -cSinCos -gX -Lol;Lki:q1 -cSin -oT -Lkj:q7=fp_sin -m5 -Lkk:q1 -cSqr -o7 -g1-1)gX -Lmo;Lkl:q1 -cSinh -oT -Lkm:q7=fp_sinh -m5 -Lkn:g6 -q4 -Lnq;Lko:hV -4 -gC -A);Lom:w5=cHypot;g0 -wE(cHypot);q4 -TailCall_cHypot;Lkp:hV -5 -gC -A -oJ -B -gX -Lom;Lkq:gU -cAbs;q4 -Llp;Lla:q7=fp_sqrt -m5 -Llb:g6 -q4 -Loi;Llc:gT -y-x;q4 -Lba;Lld:o9;q4 -Loi;Lle:q8 -oV -oJ -hS -o7 -x -q11 -gX -Lmh;Llf:mI -A -oJ -cSub -gX -Lmh;Llg:q1 -cTan -oT -Llh:q7=fp_tan -m5 -Lli:q1 -cTanh -oT -Llj:q7=fp_tanh -m5 -Llk:q7=fp_trunc -m5 -Lll:qW -cDup);gJ -Llm:dF=cDup;gJ -Lln:hV -3 -gC -cSinCos);Lon:qE -GetParamSwappedBinaryOpcode(C));gJ -Llo:hV -3 -gC -cSinhCosh -gX -Lon;gJ -q4 -TailCall_cAcos;q4 -TailCall_cAcosh;q4 -TailCall_cAnd;q4 -TailCall_cArg;q4 -TailCall_cAsin;q4 -TailCall_cAsinh;q4 -TailCall_cAtan;q4 -TailCall_cAtan2;q4 -TailCall_cAtanh;q4 -TailCall_cCeil;q4 -TailCall_cConj;q4 -TailCall_cFloor;q4 -TailCall_cImag;q4 -TailCall_cInt;q4 -TailCall_cLog;q4 -TailCall_cLog10;q4 -TailCall_cLog2;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cOr;q4 -TailCall_cPolar;q4 -TailCall_cRDiv;q4 -TailCall_cRad;q4 -TailCall_cReal;q4 -TailCall_cSec;q4 -TailCall_cSin;q4 -TailCall_cSinh;q4 -TailCall_cSqrt;q4 -TailCall_cSub;q4 -TailCall_cTan;q4 -TailCall_cTanh;q4 -TailCall_cTrunc; -#endif -#undef FP_ReDefinePointers -#undef FP_TRACE_BYTECODE_OPTIMIZATION -#undef FP_TRACE_OPCODENAME diff --git a/deal.II/contrib/functionparser/extrasrc/fpaux.hh b/deal.II/contrib/functionparser/extrasrc/fpaux.hh deleted file mode 100644 index 2ce6da2944..0000000000 --- a/deal.II/contrib/functionparser/extrasrc/fpaux.hh +++ /dev/null @@ -1,1295 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -// NOTE: -// This file contains only internal types for the function parser library. -// You don't need to include this file in your code. Include "fparser.hh" -// only. - -#ifndef ONCE_FPARSER_AUX_H_ -#define ONCE_FPARSER_AUX_H_ - -#include "fptypes.hh" - -#include - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -#include "mpfr/MpfrFloat.hh" -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -#include "mpfr/GmpInt.hh" -#endif - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS -#include -#endif - -#ifdef ONCE_FPARSER_H_ -namespace FUNCTIONPARSERTYPES -{ - template - struct IsIntType - { - enum { result = false }; - }; - template<> - struct IsIntType - { - enum { result = true }; - }; -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - struct IsIntType - { - enum { result = true }; - }; -#endif - - template - struct IsComplexType - { - enum { result = false }; - }; -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template - struct IsComplexType > - { - enum { result = true }; - }; -#endif - - -//========================================================================== -// Constants -//========================================================================== - template - inline Value_t fp_const_pi() // CONSTANT_PI - { - return Value_t(3.1415926535897932384626433832795028841971693993751L); - } - - template - inline Value_t fp_const_e() // CONSTANT_E - { - return Value_t(2.7182818284590452353602874713526624977572L); - } - template - inline Value_t fp_const_einv() // CONSTANT_EI - { - return Value_t(0.367879441171442321595523770161460867445811131L); - } - template - inline Value_t fp_const_log2() // CONSTANT_L2, CONSTANT_L2EI - { - return Value_t(0.69314718055994530941723212145817656807550013436025525412L); - } - template - inline Value_t fp_const_log10() // CONSTANT_L10, CONSTANT_L10EI - { - return Value_t(2.302585092994045684017991454684364207601101488628772976L); - } - template - inline Value_t fp_const_log2inv() // CONSTANT_L2I, CONSTANT_L2E - { - return Value_t(1.442695040888963407359924681001892137426645954L); - } - template - inline Value_t fp_const_log10inv() // CONSTANT_L10I, CONSTANT_L10E - { - return Value_t(0.434294481903251827651128918916605082294397L); - } - - template - inline const Value_t& fp_const_deg_to_rad() // CONSTANT_DR - { - static const Value_t factor = fp_const_pi() / Value_t(180); // to rad from deg - return factor; - } - - template - inline const Value_t& fp_const_rad_to_deg() // CONSTANT_RD - { - static const Value_t factor = Value_t(180) / fp_const_pi(); // to deg from rad - return factor; - } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline MpfrFloat fp_const_pi() { return MpfrFloat::const_pi(); } - - template<> - inline MpfrFloat fp_const_e() { return MpfrFloat::const_e(); } - - template<> - inline MpfrFloat fp_const_einv() { return MpfrFloat(1) / MpfrFloat::const_e(); } - - template<> - inline MpfrFloat fp_const_log2() { return MpfrFloat::const_log2(); } - - /* - template<> - inline MpfrFloat fp_const_log10() { return fp_log(MpfrFloat(10)); } - - template<> - inline MpfrFloat fp_const_log2inv() { return MpfrFloat(1) / MpfrFloat::const_log2(); } - - template<> - inline MpfrFloat fp_const_log10inv() { return fp_log10(MpfrFloat::const_e()); } - */ -#endif - - -//========================================================================== -// Generic math functions -//========================================================================== - template - inline Value_t fp_abs(const Value_t& x) { return std::fabs(x); } - - template - inline Value_t fp_acos(const Value_t& x) { return std::acos(x); } - - template - inline Value_t fp_asin(const Value_t& x) { return std::asin(x); } - - template - inline Value_t fp_atan(const Value_t& x) { return std::atan(x); } - - template - inline Value_t fp_atan2(const Value_t& x, const Value_t& y) - { return std::atan2(x, y); } - - template - inline Value_t fp_ceil(const Value_t& x) { return std::ceil(x); } - - template - inline Value_t fp_cos(const Value_t& x) { return std::cos(x); } - - template - inline Value_t fp_cosh(const Value_t& x) { return std::cosh(x); } - - template - inline Value_t fp_exp(const Value_t& x) { return std::exp(x); } - - template - inline Value_t fp_floor(const Value_t& x) { return std::floor(x); } - - template - inline Value_t fp_log(const Value_t& x) { return std::log(x); } - - template - inline Value_t fp_mod(const Value_t& x, const Value_t& y) - { return std::fmod(x, y); } - - template - inline Value_t fp_sin(const Value_t& x) { return std::sin(x); } - - template - inline Value_t fp_sinh(const Value_t& x) { return std::sinh(x); } - - template - inline Value_t fp_sqrt(const Value_t& x) { return std::sqrt(x); } - - template - inline Value_t fp_tan(const Value_t& x) { return std::tan(x); } - - template - inline Value_t fp_tanh(const Value_t& x) { return std::tanh(x); } - -#if __cplusplus > 201100 - template - inline Value_t fp_asinh(const Value_t& x) { return std::asinh(x); } - - template - inline Value_t fp_acosh(const Value_t& x) { return std::acosh(x); } - - template - inline Value_t fp_atanh(const Value_t& x) { return std::atanh(x); } -#else - template - inline Value_t fp_asinh(const Value_t& x) - { return fp_log(x + fp_sqrt(x*x + Value_t(1))); } - - template - inline Value_t fp_acosh(const Value_t& x) - { return fp_log(x + fp_sqrt(x*x - Value_t(1))); } - - template - inline Value_t fp_atanh(const Value_t& x) - { - return fp_log( (Value_t(1)+x) / (Value_t(1)-x)) * Value_t(0.5); - // Note: x = +1 causes division by zero - // x = -1 causes log(0) - // Thus, x must not be +-1 - } -#endif // FP_SUPPORT_ASINH - -#if __cplusplus > 201100 - template - inline Value_t fp_hypot(const Value_t& x, const Value_t& y) - { return std::hypot(x,y); } -#else - template - inline Value_t fp_hypot(const Value_t& x, const Value_t& y) - { return fp_sqrt(x*x + y*y); } -#endif - - template - inline Value_t fp_pow_base(const Value_t& x, const Value_t& y) - { return std::pow(x, y); } - -#if __cplusplus > 201100 - template - inline Value_t fp_log2(const Value_t& x) { return std::log2(x); } -#else - template - inline Value_t fp_log2(const Value_t& x) - { - return fp_log(x) * fp_const_log2inv(); - } -#endif // FP_SUPPORT_LOG2 - - template - inline Value_t fp_log10(const Value_t& x) - { - return fp_log(x) * fp_const_log10inv(); - } - - template - inline Value_t fp_trunc(const Value_t& x) - { - return x < Value_t() ? fp_ceil(x) : fp_floor(x); - } - - template - inline Value_t fp_int(const Value_t& x) - { - return x < Value_t() ? - fp_ceil(x - Value_t(0.5)) : fp_floor(x + Value_t(0.5)); - } - - template - inline void fp_sinCos(Value_t& sinvalue, Value_t& cosvalue, - const Value_t& param) - { - // Assuming that "cosvalue" and "param" do not - // overlap, but "sinvalue" and "param" may. - cosvalue = fp_cos(param); - sinvalue = fp_sin(param); - } - - template - inline void fp_sinhCosh(Value_t& sinhvalue, Value_t& coshvalue, - const Value_t& param) - { - const Value_t ex(fp_exp(param)), emx(fp_exp(-param)); - sinhvalue = Value_t(0.5)*(ex-emx); - coshvalue = Value_t(0.5)*(ex+emx); - } - - template - inline Value_t fp_epsilon() - { - return FunctionParserBase::epsilon(); - } - - -#ifdef _GNU_SOURCE - inline void fp_sinCos(double& sin, double& cos, const double& a) - { - sincos(a, &sin, &cos); - } - inline void fp_sinCos(float& sin, float& cos, const float& a) - { - sincosf(a, &sin, &cos); - } - inline void fp_sinCos(long double& sin, long double& cos, - const long double& a) - { - sincosl(a, &sin, &cos); - } -#endif - - -// ------------------------------------------------------------------------- -// Long int -// ------------------------------------------------------------------------- - inline long fp_abs(const long& x) { return x < 0 ? -x : x; } - inline long fp_acos(const long&) { return 0; } - inline long fp_asin(const long&) { return 0; } - inline long fp_atan(const long&) { return 0; } - inline long fp_atan2(const long&, const long&) { return 0; } - inline long fp_cbrt(const long&) { return 0; } - inline long fp_ceil(const long& x) { return x; } - inline long fp_cos(const long&) { return 0; } - inline long fp_cosh(const long&) { return 0; } - inline long fp_exp(const long&) { return 0; } - inline long fp_exp2(const long&) { return 0; } - inline long fp_floor(const long& x) { return x; } - inline long fp_log(const long&) { return 0; } - inline long fp_log2(const long&) { return 0; } - inline long fp_log10(const long&) { return 0; } - inline long fp_mod(const long& x, const long& y) { return x % y; } - inline long fp_pow(const long&, const long&) { return 0; } - inline long fp_sin(const long&) { return 0; } - inline long fp_sinh(const long&) { return 0; } - inline long fp_sqrt(const long&) { return 1; } - inline long fp_tan(const long&) { return 0; } - inline long fp_tanh(const long&) { return 0; } - inline long fp_asinh(const long&) { return 0; } - inline long fp_acosh(const long&) { return 0; } - inline long fp_atanh(const long&) { return 0; } - inline long fp_pow_base(const long&, const long&) { return 0; } - inline void fp_sinCos(long&, long&, const long&) {} - inline void fp_sinhCosh(long&, long&, const long&) {} - - template<> inline long fp_epsilon() { return 0; } - - -// ------------------------------------------------------------------------- -// MpfrFloat -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - inline MpfrFloat fp_abs(const MpfrFloat& x) { return MpfrFloat::abs(x); } - inline MpfrFloat fp_acos(const MpfrFloat& x) { return MpfrFloat::acos(x); } - inline MpfrFloat fp_acosh(const MpfrFloat& x) { return MpfrFloat::acosh(x); } - inline MpfrFloat fp_asin(const MpfrFloat& x) { return MpfrFloat::asin(x); } - inline MpfrFloat fp_asinh(const MpfrFloat& x) { return MpfrFloat::asinh(x); } - inline MpfrFloat fp_atan(const MpfrFloat& x) { return MpfrFloat::atan(x); } - inline MpfrFloat fp_atan2(const MpfrFloat& x, const MpfrFloat& y) - { return MpfrFloat::atan2(x, y); } - inline MpfrFloat fp_atanh(const MpfrFloat& x) { return MpfrFloat::atanh(x); } - inline MpfrFloat fp_cbrt(const MpfrFloat& x) { return MpfrFloat::cbrt(x); } - inline MpfrFloat fp_ceil(const MpfrFloat& x) { return MpfrFloat::ceil(x); } - inline MpfrFloat fp_cos(const MpfrFloat& x) { return MpfrFloat::cos(x); } - inline MpfrFloat fp_cosh(const MpfrFloat& x) { return MpfrFloat::cosh(x); } - inline MpfrFloat fp_exp(const MpfrFloat& x) { return MpfrFloat::exp(x); } - inline MpfrFloat fp_exp2(const MpfrFloat& x) { return MpfrFloat::exp2(x); } - inline MpfrFloat fp_floor(const MpfrFloat& x) { return MpfrFloat::floor(x); } - inline MpfrFloat fp_hypot(const MpfrFloat& x, const MpfrFloat& y) - { return MpfrFloat::hypot(x, y); } - inline MpfrFloat fp_int(const MpfrFloat& x) { return MpfrFloat::round(x); } - inline MpfrFloat fp_log(const MpfrFloat& x) { return MpfrFloat::log(x); } - inline MpfrFloat fp_log2(const MpfrFloat& x) { return MpfrFloat::log2(x); } - inline MpfrFloat fp_log10(const MpfrFloat& x) { return MpfrFloat::log10(x); } - inline MpfrFloat fp_mod(const MpfrFloat& x, const MpfrFloat& y) { return x % y; } - inline MpfrFloat fp_sin(const MpfrFloat& x) { return MpfrFloat::sin(x); } - inline MpfrFloat fp_sinh(const MpfrFloat& x) { return MpfrFloat::sinh(x); } - inline MpfrFloat fp_sqrt(const MpfrFloat& x) { return MpfrFloat::sqrt(x); } - inline MpfrFloat fp_tan(const MpfrFloat& x) { return MpfrFloat::tan(x); } - inline MpfrFloat fp_tanh(const MpfrFloat& x) { return MpfrFloat::tanh(x); } - inline MpfrFloat fp_trunc(const MpfrFloat& x) { return MpfrFloat::trunc(x); } - - inline MpfrFloat fp_pow(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); } - inline MpfrFloat fp_pow_base(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); } - - - inline void fp_sinCos(MpfrFloat& sin, MpfrFloat& cos, const MpfrFloat& a) - { - MpfrFloat::sincos(a, sin, cos); - } - - inline void fp_sinhCosh(MpfrFloat& sinhvalue, MpfrFloat& coshvalue, - const MpfrFloat& param) - { - const MpfrFloat paramCopy = param; - sinhvalue = fp_sinh(paramCopy); - coshvalue = fp_cosh(paramCopy); - } - - template<> - inline MpfrFloat fp_epsilon() { return MpfrFloat::someEpsilon(); } -#endif // FP_SUPPORT_MPFR_FLOAT_TYPE - - -// ------------------------------------------------------------------------- -// GMP int -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_GMP_INT_TYPE - inline GmpInt fp_abs(const GmpInt& x) { return GmpInt::abs(x); } - inline GmpInt fp_acos(const GmpInt&) { return 0; } - inline GmpInt fp_acosh(const GmpInt&) { return 0; } - inline GmpInt fp_asin(const GmpInt&) { return 0; } - inline GmpInt fp_asinh(const GmpInt&) { return 0; } - inline GmpInt fp_atan(const GmpInt&) { return 0; } - inline GmpInt fp_atan2(const GmpInt&, const GmpInt&) { return 0; } - inline GmpInt fp_atanh(const GmpInt&) { return 0; } - inline GmpInt fp_cbrt(const GmpInt&) { return 0; } - inline GmpInt fp_ceil(const GmpInt& x) { return x; } - inline GmpInt fp_cos(const GmpInt&) { return 0; } - inline GmpInt fp_cosh(const GmpInt&) { return 0; } - inline GmpInt fp_exp(const GmpInt&) { return 0; } - inline GmpInt fp_exp2(const GmpInt&) { return 0; } - inline GmpInt fp_floor(const GmpInt& x) { return x; } - inline GmpInt fp_hypot(const GmpInt&, const GmpInt&) { return 0; } - inline GmpInt fp_int(const GmpInt& x) { return x; } - inline GmpInt fp_log(const GmpInt&) { return 0; } - inline GmpInt fp_log2(const GmpInt&) { return 0; } - inline GmpInt fp_log10(const GmpInt&) { return 0; } - inline GmpInt fp_mod(const GmpInt& x, const GmpInt& y) { return x % y; } - inline GmpInt fp_pow(const GmpInt&, const GmpInt&) { return 0; } - inline GmpInt fp_sin(const GmpInt&) { return 0; } - inline GmpInt fp_sinh(const GmpInt&) { return 0; } - inline GmpInt fp_sqrt(const GmpInt&) { return 0; } - inline GmpInt fp_tan(const GmpInt&) { return 0; } - inline GmpInt fp_tanh(const GmpInt&) { return 0; } - inline GmpInt fp_trunc(const GmpInt& x) { return x; } - inline GmpInt fp_pow_base(const GmpInt&, const GmpInt&) { return 0; } - inline void fp_sinCos(GmpInt&, GmpInt&, const GmpInt&) {} - inline void fp_sinhCosh(GmpInt&, GmpInt&, const GmpInt&) {} - - template<> - inline GmpInt fp_epsilon() { return 0; } -#endif // FP_SUPPORT_GMP_INT_TYPE - - -#if __cplusplus > 201100 - template - inline Value_t fp_cbrt(const Value_t& x) { return std::cbrt(x); } -#else - template - 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 -// ------------------------------------------------------------------------- - template inline Value_t fp_arg(const Value_t& x); - template inline Value_t fp_exp2(const Value_t& x); - template inline Value_t fp_int(const Value_t& x); - template inline Value_t fp_trunc(const Value_t& x); - template - inline void fp_sinCos(Value_t& , Value_t& , const Value_t& ); - template - inline void fp_sinhCosh(Value_t& , Value_t& , const Value_t& ); - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - /* NOTE: Complex multiplication of a and b can be done with: - tmp = b.real * (a.real + a.imag) - result.real = tmp - a.imag * (b.real + b.imag) - result.imag = tmp + a.real * (b.imag - b.real) - This has fewer multiplications than the standard - algorithm. Take note, if you support mpfr complex one day. - */ - - template - struct FP_ProbablyHasFastLibcComplex - { enum { result = false }; }; - /* The generic sqrt() etc. implementations in libstdc++ - * are very plain and non-optimized; however, it contains - * callbacks to libc complex math functions where possible, - * and I suspect that those may actually be well optimized. - * So we use std:: functions when we suspect they may be fast, - * and otherwise we use our own optimized implementations. - */ -#ifdef __GNUC__ - template<> struct FP_ProbablyHasFastLibcComplex - { enum { result = true }; }; - template<> struct FP_ProbablyHasFastLibcComplex - { enum { result = true }; }; - template<> struct FP_ProbablyHasFastLibcComplex - { enum { result = true }; }; -#endif - - template - inline const std::complex fp_make_imag(const std::complex& v) - { - return std::complex ( T(), v.real() ); - } - - template - inline std::complex fp_real(const std::complex& x) - { - return x.real(); - } - template - inline std::complex fp_imag(const std::complex& x) - { - return x.imag(); - } - template - inline std::complex fp_arg(const std::complex& x) - { - return std::arg(x); - } - template - inline std::complex fp_conj(const std::complex& x) - { - return std::conj(x); - } - template - inline std::complex fp_polar(const T& x, const T& y) - { - T si, co; fp_sinCos(si, co, y); - return std::complex (x*co, x*si); - } - template - inline std::complex fp_polar(const std::complex& x, const std::complex& y) - { - // x * cos(y) + i * x * sin(y) -- arguments are supposed to be REAL numbers - return fp_polar (x.real(), y.real()); - //return std::polar(x.real(), y.real()); - //return x * (fp_cos(y) + (std::complex(0,1) * fp_sin(y)); - } - - // These provide fallbacks in case there's no library function - template - inline std::complex fp_floor(const std::complex& x) - { - return std::complex (fp_floor(x.real()), fp_floor(x.imag())); - } - template - inline std::complex fp_trunc(const std::complex& x) - { - return std::complex (fp_trunc(x.real()), fp_trunc(x.imag())); - } - template - inline std::complex fp_int(const std::complex& x) - { - return std::complex (fp_int(x.real()), fp_int(x.imag())); - } - template - inline std::complex fp_ceil(const std::complex& x) - { - return std::complex (fp_ceil(x.real()), fp_ceil(x.imag())); - } - template - inline std::complex fp_abs(const std::complex& x) - { - return std::abs(x); - //T extent = fp_max(fp_abs(x.real()), fp_abs(x.imag())); - //if(extent == T()) return x; - //return extent * fp_hypot(x.real() / extent, x.imag() / extent); - } - template - inline std::complex fp_exp(const std::complex& x) - { - if(FP_ProbablyHasFastLibcComplex::result) - return std::exp(x); - return fp_polar(fp_exp(x.real()), x.imag()); - } - template - inline std::complex fp_log(const std::complex& x) - { - if(FP_ProbablyHasFastLibcComplex::result) - return std::log(x); - // log(abs(x)) + i*arg(x) - // log(Xr^2+Xi^2)*0.5 + i*arg(x) - if(x.imag()==T()) - return std::complex( fp_log(fp_abs(x.real())), - fp_arg(x.real()) ); // Note: Uses real-value fp_arg() here! - return std::complex( - fp_log(std::norm(x)) * T(0.5), - fp_arg(x).real() ); - } - template - inline std::complex fp_sqrt(const std::complex& x) - { - if(FP_ProbablyHasFastLibcComplex::result) - return std::sqrt(x); - return fp_polar (fp_sqrt(fp_abs(x).real()), - T(0.5)*fp_arg(x).real()); - } - template - inline std::complex fp_acos(const std::complex& x) - { - // -i * log(x + i * sqrt(1 - x^2)) - const std::complex i (T(), T(1)); - return -i * fp_log(x + i * fp_sqrt(T(1) - x*x)); - // Note: Real version of acos() cannot handle |x| > 1, - // because it would cause sqrt(negative value). - } - template - inline std::complex fp_asin(const std::complex& x) - { - // -i * log(i*x + sqrt(1 - x^2)) - const std::complex i (T(), T(1)); - return -i * fp_log(i*x + fp_sqrt(T(1) - x*x)); - // Note: Real version of asin() cannot handle |x| > 1, - // because it would cause sqrt(negative value). - } - template - inline std::complex fp_atan(const std::complex& x) - { - // 0.5i * (log(1-i*x) - log(1+i*x)) - // -0.5i * log( (1+i*x) / (1-i*x) ) - const std::complex i (T(), T(1)); - return (T(-0.5)*i) * fp_log( (T(1)+i*x) / (T(1)-i*x) ); - // Note: x = -1i causes division by zero - // x = +1i causes log(0) - // Thus, x must not be +-1i - } - template - inline std::complex fp_cos(const std::complex& x) - { - return std::cos(x); - // // (exp(i*x) + exp(-i*x)) / (2) - // //const std::complex i (T(), T(1)); - // //return (fp_exp(i*x) + fp_exp(-i*x)) * T(0.5); - // // Also: cos(Xr)*cosh(Xi) - i*sin(Xr)*sinh(Xi) - // return std::complex ( - // fp_cos(x.real())*fp_cosh(x.imag()), - // -fp_sin(x.real())*fp_sinh(x.imag())); - } - template - inline std::complex fp_sin(const std::complex& x) - { - return std::sin(x); - // // (exp(i*x) - exp(-i*x)) / (2i) - // //const std::complex i (T(), T(1)); - // //return (fp_exp(i*x) - fp_exp(-i*x)) * (T(-0.5)*i); - // // Also: sin(Xr)*cosh(Xi) + cos(Xr)*sinh(Xi) - // return std::complex ( - // fp_sin(x.real())*fp_cosh(x.imag()), - // fp_cos(x.real())*fp_sinh(x.imag())); - } - template - inline void fp_sinCos( - std::complex& sinvalue, - std::complex& cosvalue, - const std::complex& x) - { - //const std::complex i (T(), T(1)), expix(fp_exp(i*x)), expmix(fp_exp((-i)*x)); - //cosvalue = (expix + expmix) * T(0.5); - //sinvalue = (expix - expmix) * (i*T(-0.5)); - // The above expands to the following: - T srx, crx; fp_sinCos(srx, crx, x.real()); - T six, cix; fp_sinhCosh(six, cix, x.imag()); - sinvalue = std::complex(srx*cix, crx*six); - cosvalue = std::complex(crx*cix, -srx*six); - } - template - inline void fp_sinhCosh( - std::complex& sinhvalue, - std::complex& coshvalue, - const std::complex& x) - { - T srx, crx; fp_sinhCosh(srx, crx, x.real()); - T six, cix; fp_sinCos(six, cix, x.imag()); - sinhvalue = std::complex(srx*cix, crx*six); - coshvalue = std::complex(crx*cix, srx*six); - } - template - inline std::complex fp_tan(const std::complex& x) - { - return std::tan(x); - //std::complex si, co; - //fp_sinCos(si, co, x); - //return si/co; - // // (i-i*exp(2i*x)) / (exp(2i*x)+1) - // const std::complex i (T(), T(1)), exp2ix=fp_exp((2*i)*x); - // return (i-i*exp2ix) / (exp2ix+T(1)); - // // Also: sin(x)/cos(y) - // // return fp_sin(x)/fp_cos(x); - } - template - inline std::complex fp_cosh(const std::complex& x) - { - return std::cosh(x); - // // (exp(x) + exp(-x)) * 0.5 - // // Also: cosh(Xr)*cos(Xi) + i*sinh(Xr)*sin(Xi) - // return std::complex ( - // fp_cosh(x.real())*fp_cos(x.imag()), - // fp_sinh(x.real())*fp_sin(x.imag())); - } - template - inline std::complex fp_sinh(const std::complex& x) - { - return std::sinh(x); - // // (exp(x) - exp(-x)) * 0.5 - // // Also: sinh(Xr)*cos(Xi) + i*cosh(Xr)*sin(Xi) - // return std::complex ( - // fp_sinh(x.real())*fp_cos(x.imag()), - // fp_cosh(x.real())*fp_sin(x.imag())); - } - template - inline std::complex fp_tanh(const std::complex& x) - { - return std::tanh(x); - //std::complex si, co; - //fp_sinhCosh(si, co, x); - //return si/co; - // // (exp(2*x)-1) / (exp(2*x)+1) - // // Also: sinh(x)/tanh(x) - // const std::complex exp2x=fp_exp(x+x); - // return (exp2x-T(1)) / (exp2x+T(1)); - } - -#if __cplusplus > 201100 - template - inline std::complex fp_acosh(const std::complex& x) - { return fp_log(x + fp_sqrt(x*x - std::complex(1))); } - template - inline std::complex fp_asinh(const std::complex& x) - { return fp_log(x + fp_sqrt(x*x + std::complex(1))); } - template - inline std::complex fp_atanh(const std::complex& x) - { return fp_log( (std::complex(1)+x) / (std::complex(1)-x)) - * std::complex(0.5); } -#endif - template - inline std::complex fp_pow(const std::complex& x, const std::complex& y) - { - // return std::pow(x,y); - - // With complex numbers, pow(x,y) can be solved with - // the general formula: exp(y*log(x)). It handles - // all special cases gracefully. - // It expands to the following: - // A) - // t1 = log(x) - // t2 = y * t1 - // res = exp(t2) - // B) - // t1.r = log(x.r * x.r + x.i * x.i) * 0.5 \ fp_log() - // t1.i = atan2(x.i, x.r) / - // t2.r = y.r*t1.r - y.i*t1.i \ multiplication - // t2.i = y.r*t1.i + y.i*t1.r / - // rho = exp(t2.r) \ fp_exp() - // theta = t2.i / - // res.r = rho * cos(theta) \ fp_polar(), called from - // res.i = rho * sin(theta) / fp_exp(). Uses sincos(). - // Aside from the common "norm" calculation in atan2() - // and in the log parameter, both of which are part of fp_log(), - // there does not seem to be any incentive to break this - // function down further; it would not help optimizing it. - // However, we do handle the following special cases: - // - // When x is real (positive or negative): - // t1.r = log(abs(x.r)) - // t1.i = x.r<0 ? -pi : 0 - // When y is real: - // t2.r = y.r * t1.r - // t2.i = y.r * t1.i - const std::complex t = - (x.imag() != T()) - ? fp_log(x) - : std::complex (fp_log(fp_abs(x.real())), - fp_arg(x.real())); // Note: Uses real-value fp_arg() here! - return y.imag() != T() - ? fp_exp(y * t) - : fp_polar (fp_exp(y.real()*t.real()), y.real()*t.imag()); - } - template - inline std::complex fp_cbrt(const std::complex& x) - { - // For real numbers, prefer giving a real solution - // rather than a complex solution. - // For example, cbrt(-3) has the following three solutions: - // A) 0.7211247966535 + 1.2490247864016i - // B) 0.7211247966535 - 1.2490247864016i - // C) -1.442249593307 - // exp(log(x)/3) gives A, but we prefer to give C. - if(x.imag() == T()) return fp_cbrt(x.real()); - const std::complex t(fp_log(x)); - return fp_polar (fp_exp(t.real() / T(3)), t.imag() / T(3)); - } - - template - inline std::complex fp_exp2(const std::complex& x) - { - // pow(2, x) - // polar(2^Xr, Xi*log(2)) - return fp_polar (fp_exp2(x.real()), x.imag()*fp_const_log2()); - } - template - inline std::complex fp_mod(const std::complex& x, const std::complex& y) - { - // Modulo function is probably not defined for complex numbers. - // But we do our best to calculate it the same way as it is done - // with real numbers, so that at least it is in some way "consistent". - if(y.imag() == 0) return fp_mod(x.real(), y.real()); // optimization - std::complex n = fp_trunc(x / y); - return x - n * y; - } - - /* libstdc++ already defines a streaming operator for complex values, - * but we redefine our own that it is compatible with the input - * accepted by fparser. I.e. instead of (5,3) we now get (5+3i), - * and instead of (-4,0) we now get -4. - */ - template - inline std::ostream& operator<<(std::ostream& os, const std::complex& value) - { - if(value.imag() == T()) return os << value.real(); - if(value.real() == T()) return os << value.imag() << 'i'; - if(value.imag() < T()) - return os << '(' << value.real() << "-" << -value.imag() << "i)"; - else - return os << '(' << value.real() << "+" << value.imag() << "i)"; - } - - /* Less-than or greater-than operators are not technically defined - * for Complex types. However, in fparser and its tool set, these - * operators are widely required to be present. - * Our implementation here is based on converting the complex number - * into a scalar and the doing a scalar comparison on the value. - * The means by which the number is changed into a scalar is based - * on the following principles: - * - Does not introduce unjustified amounts of extra inaccuracy - * - Is transparent to purely real values - * (this disqualifies something like x.real() + x.imag()) - * - Does not ignore the imaginary value completely - * (this may be relevant especially in testbed) - * - Is not so complicated that it would slow down a great deal - * - * Basically our formula here is the same as std::abs(), - * except that it keeps the sign of the original real number, - * and it does not do a sqrt() calculation that is not really - * needed because we are only interested in the relative magnitudes. - * - * Equality and nonequality operators must not need to be overloaded. - * They are already implemented in standard, and we must - * not introduce flawed equality assumptions. - */ - template - inline T fp_complexScalarize(const std::complex& x) - { - T res(std::norm(x)); - if(x.real() < T()) res = -res; - return res; - } - template - inline T fp_realComplexScalarize(const T& x) - { - T res(x*x); - if(x < T()) res = -res; - return res; - } - // { return x.real() * (T(1.0) + fp_abs(x.imag())); } - #define d(op) \ - template \ - inline bool operator op (const std::complex& x, T y) \ - { return fp_complexScalarize(x) op fp_realComplexScalarize(y); } \ - template \ - inline bool operator op (const std::complex& x, const std::complex& y) \ - { return fp_complexScalarize(x) op \ - fp_complexScalarize(y); } \ - template \ - inline bool operator op (T x, const std::complex& y) \ - { return fp_realComplexScalarize(x) op fp_complexScalarize(y); } - d( < ) d( <= ) d( > ) d( >= ) - #undef d -#endif - - template - inline Value_t fp_real(const Value_t& x) { return x; } - template - inline Value_t fp_imag(const Value_t& ) { return Value_t(); } - template - inline Value_t fp_arg(const Value_t& x) - { return x < Value_t() ? -fp_const_pi() : Value_t(); } - template - inline Value_t fp_conj(const Value_t& x) { return x; } - template - inline Value_t fp_polar(const Value_t& x, const Value_t& y) - { return x * fp_cos(y); } // This is of course a meaningless function. - - template - inline std::complex fp_atan2(const std::complex& y, - const std::complex& x) - { - if(y == Value_t()) return fp_arg(x); - if(x == Value_t()) return fp_const_pi() * Value_t(-0.5); - // 2*atan(y / (sqrt(x^2+y^2) + x) ) - // 2*atan( (sqrt(x^2+y^2) - x) / y) - std::complex res( fp_atan(y / (fp_hypot(x,y) + x)) ); - return res+res; - } - -// ------------------------------------------------------------------------- -// Comparison -// ------------------------------------------------------------------------- - template - inline bool fp_equal(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x == y) - : (fp_abs(x - y) <= fp_epsilon()); } - - template - inline bool fp_nequal(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x != y) - : (fp_abs(x - y) > fp_epsilon()); } - - template - inline bool fp_less(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x < y) - : (x < y - fp_epsilon()); } - - template - inline bool fp_lessOrEq(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x <= y) - : (x <= y + fp_epsilon()); } - - - template - inline bool fp_greater(const Value_t& x, const Value_t& y) - { return fp_less(y, x); } - - template - inline bool fp_greaterOrEq(const Value_t& x, const Value_t& y) - { return fp_lessOrEq(y, x); } - - template - inline bool fp_truth(const Value_t& d) - { - return IsIntType::result - ? d != Value_t() - : fp_abs(d) >= Value_t(0.5); - } - - template - inline bool fp_absTruth(const Value_t& abs_d) - { - return IsIntType::result - ? abs_d > Value_t() - : abs_d >= Value_t(0.5); - } - - template - inline const Value_t& fp_min(const Value_t& d1, const Value_t& d2) - { return d1 - inline const Value_t& fp_max(const Value_t& d1, const Value_t& d2) - { return d1>d2 ? d1 : d2; } - - template - inline const Value_t fp_not(const Value_t& b) - { return Value_t(!fp_truth(b)); } - - template - inline const Value_t fp_notNot(const Value_t& b) - { return Value_t(fp_truth(b)); } - - template - inline const Value_t fp_absNot(const Value_t& b) - { return Value_t(!fp_absTruth(b)); } - - template - inline const Value_t fp_absNotNot(const Value_t& b) - { return Value_t(fp_absTruth(b)); } - - template - inline const Value_t fp_and(const Value_t& a, const Value_t& b) - { return Value_t(fp_truth(a) && fp_truth(b)); } - - template - inline const Value_t fp_or(const Value_t& a, const Value_t& b) - { return Value_t(fp_truth(a) || fp_truth(b)); } - - template - inline const Value_t fp_absAnd(const Value_t& a, const Value_t& b) - { return Value_t(fp_absTruth(a) && fp_absTruth(b)); } - - template - inline const Value_t fp_absOr(const Value_t& a, const Value_t& b) - { return Value_t(fp_absTruth(a) || fp_absTruth(b)); } - - template - inline const Value_t fp_make_imag(const Value_t& ) // Imaginary 1. In real mode, always zero. - { - return Value_t(); - } - - ///////////// - /* 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 - */ - bool IsLogicalOpcode(unsigned op); - bool IsComparisonOpcode(unsigned op); - unsigned OppositeComparisonOpcode(unsigned op); - bool IsNeverNegativeValueOpcode(unsigned op); - bool IsAlwaysIntegerOpcode(unsigned op); - bool IsUnaryOpcode(unsigned op); - bool IsBinaryOpcode(unsigned op); - bool IsVarOpcode(unsigned op); - bool IsCommutativeOrParamSwappableBinaryOpcode(unsigned op); - unsigned GetParamSwappedBinaryOpcode(unsigned op); - - template - bool HasInvalidRangesOpcode(unsigned op); - - template - inline Value_t DegreesToRadians(const Value_t& degrees) - { - return degrees * fp_const_deg_to_rad(); - } - - template - inline Value_t RadiansToDegrees(const Value_t& radians) - { - return radians * fp_const_rad_to_deg(); - } - - template - inline long makeLongInteger(const Value_t& value) - { - return (long) fp_int(value); - } - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template - inline long makeLongInteger(const std::complex& value) - { - return (long) fp_int( std::abs(value) ); - } -#endif - - // Is value an integer that fits in "long" datatype? - template - inline bool isLongInteger(const Value_t& value) - { - return value == Value_t( makeLongInteger(value) ); - } - - template - 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)); - } - - template - inline bool isEvenInteger(const Value_t& value) - { - const Value_t halfValue = value * Value_t(0.5); - return fp_equal(halfValue, fp_floor(halfValue)); - } - - template - 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) - { - return value%2 == 0; - } - - template<> - inline bool isInteger(const long&) { return true; } - - template<> - inline bool isLongInteger(const long&) { return true; } - - template<> - inline long makeLongInteger(const long& value) - { - return value; - } -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline bool isInteger(const MpfrFloat& value) { return value.isInteger(); } - - template<> - inline bool isEvenInteger(const MpfrFloat& value) - { - return isInteger(value) && value%2 == 0; - } - - template<> - inline long makeLongInteger(const MpfrFloat& value) - { - return (long) value.toInt(); - } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool isEvenInteger(const GmpInt& value) - { - return value%2 == 0; - } - - template<> - inline bool isInteger(const GmpInt&) { return true; } - - template<> - inline long makeLongInteger(const GmpInt& value) - { - return (long) value.toInt(); - } -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE - template<> - inline bool isOddInteger(const long& value) - { - return value%2 != 0; - } -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline bool isOddInteger(const MpfrFloat& value) - { - return value.isInteger() && value%2 != 0; - } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool isOddInteger(const GmpInt& value) - { - return value%2 != 0; - } -#endif - - -// ------------------------------------------------------------------------- -// fp_pow -// ------------------------------------------------------------------------- - // Commented versions in fparser.cc - template - inline Value_t fp_pow_with_exp_log(const Value_t& x, const Value_t& y) - { - return fp_exp(fp_log(x) * y); - } - - template - 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 - 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 - inline Value_t fp_exp2(const Value_t& x) - { - return fp_pow(Value_t(2), x); - } -} // namespace FUNCTIONPARSERTYPES - -#endif // ONCE_FPARSER_H_ - - -#ifndef FP_DISABLE_DOUBLE_TYPE -# define FUNCTIONPARSER_INSTANTIATE_D(g) g(double) -#else -# define FUNCTIONPARSER_INSTANTIATE_D(g) -#endif - -#ifdef FP_SUPPORT_FLOAT_TYPE -# define FUNCTIONPARSER_INSTANTIATE_F(g) g(float) -#else -# define FUNCTIONPARSER_INSTANTIATE_F(g) -#endif - -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -# define FUNCTIONPARSER_INSTANTIATE_LD(g) g(long double) -#else -# define FUNCTIONPARSER_INSTANTIATE_LD(g) -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE -# define FUNCTIONPARSER_INSTANTIATE_LI(g) g(long) -#else -# define FUNCTIONPARSER_INSTANTIATE_LI(g) -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -# define FUNCTIONPARSER_INSTANTIATE_MF(g) g(MpfrFloat) -#else -# define FUNCTIONPARSER_INSTANTIATE_MF(g) -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -# define FUNCTIONPARSER_INSTANTIATE_GI(g) g(GmpInt) -#else -# define FUNCTIONPARSER_INSTANTIATE_GI(g) -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE -# define FUNCTIONPARSER_INSTANTIATE_CD(cd) cd(std::complex) -#else -# define FUNCTIONPARSER_INSTANTIATE_CD(cd) -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE -# define FUNCTIONPARSER_INSTANTIATE_CF(cd) cd(std::complex) -#else -# define FUNCTIONPARSER_INSTANTIATE_CF(cd) -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE -# define FUNCTIONPARSER_INSTANTIATE_CLD(cd) cd(std::complex) -#else -# define FUNCTIONPARSER_INSTANTIATE_CLD(cd) -#endif - -/* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cc files - containing FunctionParserBase implementations. - */ -#define FUNCTIONPARSER_INSTANTIATE_BASE(type) \ - template class FunctionParserBase; - -#define FUNCTIONPARSER_INSTANTIATE_TYPES \ - FUNCTIONPARSER_INSTANTIATE_D(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_F(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_LD(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_LI(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_MF(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_GI(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_CD(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_CF(FUNCTIONPARSER_INSTANTIATE_BASE) \ - FUNCTIONPARSER_INSTANTIATE_CLD(FUNCTIONPARSER_INSTANTIATE_BASE) - -#endif // ONCE_FPARSER_AUX_H_ diff --git a/deal.II/contrib/functionparser/extrasrc/fptypes.hh b/deal.II/contrib/functionparser/extrasrc/fptypes.hh deleted file mode 100644 index 4023c8b95f..0000000000 --- a/deal.II/contrib/functionparser/extrasrc/fptypes.hh +++ /dev/null @@ -1,288 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -// NOTE: -// This file contains only internal types for the function parser library. -// You don't need to include this file in your code. Include "fparser.hh" -// only. - -#ifndef ONCE_FPARSER_TYPES_H_ -#define ONCE_FPARSER_TYPES_H_ - -#include "../fpconfig.hh" -#include - -#ifdef ONCE_FPARSER_H_ -#include -#endif - -namespace FUNCTIONPARSERTYPES -{ - enum OPCODE - { -// The order of opcodes in the function list must -// match that which is in the Functions[] array. - cAbs, - cAcos, cAcosh, - cArg, /* get the phase angle of a complex value */ - cAsin, cAsinh, - cAtan, cAtan2, cAtanh, - cCbrt, cCeil, - cConj, /* get the complex conjugate of a complex value */ - cCos, cCosh, cCot, cCsc, - cExp, cExp2, cFloor, cHypot, - cIf, - cImag, /* get imaginary part of a complex value */ - cInt, cLog, cLog10, cLog2, cMax, cMin, - cPolar, /* create a complex number from polar coordinates */ - cPow, - cReal, /* get real part of a complex value */ - cSec, cSin, cSinh, cSqrt, cTan, cTanh, - cTrunc, - -// These do not need any ordering: -// Except that if you change the order of {eq,neq,lt,le,gt,ge}, you -// must also change the order in ConstantFolding_ComparisonOperations(). - cImmed, cJump, - cNeg, cAdd, cSub, cMul, cDiv, cMod, - cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq, - cNot, cAnd, cOr, - cNotNot, /* Protects the double-not sequence from optimizations */ - - cDeg, cRad, /* Multiplication and division by 180 / pi */ - - cFCall, cPCall, - -#ifdef FP_SUPPORT_OPTIMIZER - cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything - * above [x]. Used for disposing of temporaries. - */ - cLog2by, /* log2by(x,y) = log2(x) * y */ - cNop, /* Used by fpoptimizer internally; should not occur in bytecode */ -#endif - cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */ - cSinhCosh, /* hyperbolic equivalent of sincos */ - cAbsAnd, /* As cAnd, but assume both operands are absolute values */ - cAbsOr, /* As cOr, but assume both operands are absolute values */ - cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */ - cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */ - cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */ - - cDup, /* Duplicates the last value in the stack: Push [Stacktop] */ - cFetch, /* Same as Dup, except with absolute index - * (next value is index) */ - cInv, /* Inverts the last value in the stack (x = 1/x) */ - cSqr, /* squares the last operand in the stack, no push/pop */ - cRDiv, /* reverse division (not x/y, but y/x) */ - cRSub, /* reverse subtraction (not x-y, but y-x) */ - cRSqrt, /* inverse square-root (1/sqrt(x)) */ - - VarBegin - }; - -#ifdef ONCE_FPARSER_H_ - struct FuncDefinition - { - enum FunctionFlags - { - Enabled = 0x01, - AngleIn = 0x02, - AngleOut = 0x04, - OkForInt = 0x08, - ComplexOnly = 0x10 - }; - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING - const char name[8]; -#else - struct name { } name; -#endif - unsigned params : 8; - unsigned flags : 8; - - inline bool okForInt() const { return (flags & OkForInt) != 0; } - inline bool complexOnly() const { return (flags & ComplexOnly) != 0; } - }; - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -# define FP_FNAME(n) n -#else -# define FP_FNAME(n) {} -#endif -// This list must be in the same order as that in OPCODE enum, -// because the opcode value is used to index this array, and -// the pointer to array element is used for generating the opcode. - const FuncDefinition Functions[]= - { - /*cAbs */ { FP_FNAME("abs"), 1, FuncDefinition::OkForInt }, - /*cAcos */ { FP_FNAME("acos"), 1, FuncDefinition::AngleOut }, - /*cAcosh*/ { FP_FNAME("acosh"), 1, FuncDefinition::AngleOut }, - /*cArg */ { FP_FNAME("arg"), 1, FuncDefinition::AngleOut | FuncDefinition::ComplexOnly }, - /*cAsin */ { FP_FNAME("asin"), 1, FuncDefinition::AngleOut }, - /*cAsinh*/ { FP_FNAME("asinh"), 1, FuncDefinition::AngleOut }, - /*cAtan */ { FP_FNAME("atan"), 1, FuncDefinition::AngleOut }, - /*cAtan2*/ { FP_FNAME("atan2"), 2, FuncDefinition::AngleOut }, - /*cAtanh*/ { FP_FNAME("atanh"), 1, 0 }, - /*cCbrt */ { FP_FNAME("cbrt"), 1, 0 }, - /*cCeil */ { FP_FNAME("ceil"), 1, 0 }, - /*cConj */ { FP_FNAME("conj"), 1, FuncDefinition::ComplexOnly }, - /*cCos */ { FP_FNAME("cos"), 1, FuncDefinition::AngleIn }, - /*cCosh */ { FP_FNAME("cosh"), 1, FuncDefinition::AngleIn }, - /*cCot */ { FP_FNAME("cot"), 1, FuncDefinition::AngleIn }, - /*cCsc */ { FP_FNAME("csc"), 1, FuncDefinition::AngleIn }, - /*cExp */ { FP_FNAME("exp"), 1, 0 }, - /*cExp2 */ { FP_FNAME("exp2"), 1, 0 }, - /*cFloor*/ { FP_FNAME("floor"), 1, 0 }, - /*cHypot*/ { FP_FNAME("hypot"), 2, 0 }, - /*cIf */ { FP_FNAME("if"), 0, FuncDefinition::OkForInt }, - /*cImag */ { FP_FNAME("imag"), 1, FuncDefinition::ComplexOnly }, - /*cInt */ { FP_FNAME("int"), 1, 0 }, - /*cLog */ { FP_FNAME("log"), 1, 0 }, - /*cLog10*/ { FP_FNAME("log10"), 1, 0 }, - /*cLog2 */ { FP_FNAME("log2"), 1, 0 }, - /*cMax */ { FP_FNAME("max"), 2, FuncDefinition::OkForInt }, - /*cMin */ { FP_FNAME("min"), 2, FuncDefinition::OkForInt }, - /*cPolar */{ FP_FNAME("polar"), 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn }, - /*cPow */ { FP_FNAME("pow"), 2, 0 }, - /*cReal */ { FP_FNAME("real"), 1, FuncDefinition::ComplexOnly }, - /*cSec */ { FP_FNAME("sec"), 1, FuncDefinition::AngleIn }, - /*cSin */ { FP_FNAME("sin"), 1, FuncDefinition::AngleIn }, - /*cSinh */ { FP_FNAME("sinh"), 1, FuncDefinition::AngleIn }, - /*cSqrt */ { FP_FNAME("sqrt"), 1, 0 }, - /*cTan */ { FP_FNAME("tan"), 1, FuncDefinition::AngleIn }, - /*cTanh */ { FP_FNAME("tanh"), 1, FuncDefinition::AngleIn }, - /*cTrunc*/ { FP_FNAME("trunc"), 1, 0 } - }; -#undef FP_FNAME - - struct NamePtr - { - const char* name; - unsigned nameLength; - - NamePtr(const char* n, unsigned l): name(n), nameLength(l) {} - - inline bool operator==(const NamePtr& rhs) const - { - return nameLength == rhs.nameLength - && std::memcmp(name, rhs.name, nameLength) == 0; - } - inline bool operator<(const NamePtr& rhs) const - { - for(unsigned i = 0; i < nameLength; ++i) - { - if(i == rhs.nameLength) return false; - const char c1 = name[i], c2 = rhs.name[i]; - if(c1 < c2) return true; - if(c2 < c1) return false; - } - return nameLength < rhs.nameLength; - } - }; - - template - struct NameData - { - enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE }; - DataType type; - unsigned index; - Value_t value; - - NameData(DataType t, unsigned v) : type(t), index(v), value() { } - NameData(DataType t, Value_t v) : type(t), index(), value(v) { } - NameData() { } - }; - - template - class NamePtrsMap: public - std::map > - { - }; - - const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]); -#endif // ONCE_FPARSER_H_ -} - -#ifdef ONCE_FPARSER_H_ -#include - -template -struct FunctionParserBase::Data -{ - unsigned mReferenceCounter; - - char mDelimiterChar; - ParseErrorType mParseErrorType; - int mEvalErrorType; - bool mUseDegreeConversion; - bool mHasByteCodeFlags; - const char* mErrorLocation; - - unsigned mVariablesAmount; - std::string mVariablesString; - FUNCTIONPARSERTYPES::NamePtrsMap mNamePtrs; - - struct InlineVariable - { - FUNCTIONPARSERTYPES::NamePtr mName; - unsigned mFetchIndex; - }; - - typedef std::vector InlineVarNamesContainer; - InlineVarNamesContainer mInlineVarNames; - - struct FuncWrapperPtrData - { - /* Only one of the pointers will point to a function, the other - will be null. (The raw function pointer could be implemented - as a FunctionWrapper specialization, but it's done like this - for efficiency.) */ - FunctionPtr mRawFuncPtr; - FunctionWrapper* mFuncWrapperPtr; - unsigned mParams; - - FuncWrapperPtrData(); - ~FuncWrapperPtrData(); - FuncWrapperPtrData(const FuncWrapperPtrData&); - FuncWrapperPtrData& operator=(const FuncWrapperPtrData&); - }; - - struct FuncParserPtrData - { - FunctionParserBase* mParserPtr; - unsigned mParams; - }; - - std::vector mFuncPtrs; - std::vector mFuncParsers; - - std::vector mByteCode; - std::vector mImmed; - -#if !defined(FP_USE_THREAD_SAFE_EVAL) && \ - !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) - std::vector mStack; - // Note: When mStack exists, - // mStack.size() and mStackSize are mutually redundant. -#endif - - unsigned mStackSize; - - Data(); - Data(const Data&); - Data& operator=(const Data&); // not implemented on purpose - ~Data(); -}; -#endif - -//#include "fpaux.hh" - -#endif diff --git a/deal.II/contrib/functionparser/fparser.cc b/deal.II/contrib/functionparser/fparser.cc deleted file mode 100644 index 77ffc69079..0000000000 --- a/deal.II/contrib/functionparser/fparser.cc +++ /dev/null @@ -1,3785 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -#include "fpconfig.hh" -#include "fparser.hh" - -#include -#include -#include -#include -#include -#include -#include - -#include "extrasrc/fptypes.hh" -#include "extrasrc/fpaux.hh" -using namespace FUNCTIONPARSERTYPES; - -#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA -#ifndef FP_USE_THREAD_SAFE_EVAL -#define FP_USE_THREAD_SAFE_EVAL -#endif -#endif - -#ifdef __GNUC__ -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -#else -# define likely(x) (x) -# define unlikely(x) (x) -#endif - -//========================================================================= -// Opcode analysis functions -//========================================================================= -// These functions are used by the Parse() bytecode optimizer (mostly from -// code in fp_opcode_add.inc). - -bool FUNCTIONPARSERTYPES::IsLogicalOpcode(unsigned op) -{ - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - return true; - default: break; - } - return false; -} - -bool FUNCTIONPARSERTYPES::IsComparisonOpcode(unsigned op) -{ - switch(op) - { - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - return true; - default: break; - } - return false; -} - -unsigned FUNCTIONPARSERTYPES::OppositeComparisonOpcode(unsigned op) -{ - switch(op) - { - case cLess: return cGreater; - case cGreater: return cLess; - case cLessOrEq: return cGreaterOrEq; - case cGreaterOrEq: return cLessOrEq; - } - return op; -} - -bool FUNCTIONPARSERTYPES::IsNeverNegativeValueOpcode(unsigned op) -{ - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - case cSqrt: case cRSqrt: case cSqr: - case cHypot: - case cAbs: - case cAcos: case cCosh: - return true; - default: break; - } - return false; -} - -bool FUNCTIONPARSERTYPES::IsAlwaysIntegerOpcode(unsigned op) -{ - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - case cInt: case cFloor: case cCeil: case cTrunc: - return true; - default: break; - } - return false; -} - -bool FUNCTIONPARSERTYPES::IsUnaryOpcode(unsigned op) -{ - switch(op) - { - case cInv: case cNeg: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cSqr: case cRSqrt: - case cDeg: case cRad: - return true; - } - return (op < FUNC_AMOUNT && Functions[op].params == 1); -} - -bool FUNCTIONPARSERTYPES::IsBinaryOpcode(unsigned op) -{ - switch(op) - { - case cAdd: case cSub: case cRSub: - case cMul: case cDiv: case cRDiv: - case cMod: - case cEqual: case cNEqual: case cLess: - case cLessOrEq: case cGreater: case cGreaterOrEq: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - return true; - } - return (op < FUNC_AMOUNT && Functions[op].params == 2); -} - -bool FUNCTIONPARSERTYPES::IsVarOpcode(unsigned op) -{ - // See comment in declaration of FP_ParamGuardMask - return int(op) >= VarBegin; -} - -bool FUNCTIONPARSERTYPES::IsCommutativeOrParamSwappableBinaryOpcode(unsigned op) -{ - switch(op) - { - case cAdd: - case cMul: - case cEqual: case cNEqual: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cMin: case cMax: case cHypot: - return true; - case cDiv: case cSub: case cRDiv: case cRSub: - return true; - case cLess: case cGreater: - case cLessOrEq: case cGreaterOrEq: return true; - } - return false; -} - -unsigned FUNCTIONPARSERTYPES::GetParamSwappedBinaryOpcode(unsigned op) -{ - switch(op) - { - case cAdd: - case cMul: - case cEqual: case cNEqual: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cMin: case cMax: case cHypot: - return op; - case cDiv: return cRDiv; - case cSub: return cRSub; - case cRDiv: return cDiv; - case cRSub: return cSub; - case cLess: return cGreater; - case cGreater: return cLess; - case cLessOrEq: return cGreaterOrEq; - case cGreaterOrEq: return cLessOrEq; - } - return op; // Error -} - -template -bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op) -{ - // Returns true, if the given opcode has a range of - // input values that gives an error. - if(ComplexType) - { - // COMPLEX: - switch(op) - { - case cAtan: // allowed range: x != +-1i - case cAtanh: // allowed range: x != +-1 - //case cCot: // allowed range: tan(x) != 0 - //case cCsc: // allowed range: sin(x) != 0 - case cLog: // allowed range: x != 0 - case cLog2: // allowed range: x != 0 - case cLog10: // allowed range: x != 0 - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by:// allowed range: x != 0 - #endif - //case cPow: // allowed when: x != 0 or y != 0 - //case cSec: // allowed range: cos(x) != 0 - //case cTan: // allowed range: cos(x) != 0 --> x != +-(pi/2) - //case cTanh: // allowed range: log(x) != -1 --> x != +-(pi/2)i - case cRSqrt: // allowed range: x != 0 - //case cDiv: // allowed range: y != 0 - //case cRDiv: // allowed range: x != 0 - //case cInv: // allowed range: x != 0 - return true; - } - } - else - { - // REAL: - switch(op) - { - case cAcos: // allowed range: |x| <= 1 - case cAsin: // allowed range: |x| <= 1 - case cAcosh: // allowed range: x >= 1 - case cAtanh: // allowed range: |x| < 1 - //case cCot: // allowed range: tan(x) != 0 - //case cCsc: // allowed range: sin(x) != 0 - case cLog: // allowed range: x > 0 - case cLog2: // allowed range: x > 0 - case cLog10: // allowed range: x > 0 - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by:// allowed range: x > 0 - #endif - //case cPow: // allowed when: x > 0 or (x = 0 and y != 0) or (x<0) - // Technically, when (x<0 and y is not integer), - // it is not allowed, but we allow it anyway - // in order to make nontrivial roots work. - //case cSec: // allowed range: cos(x) != 0 - case cSqrt: // allowed range: x >= 0 - case cRSqrt: // allowed range: x > 0 - //case cTan: // allowed range: cos(x) != 0 --> x != +-(pi/2) - //case cDiv: // allowed range: y != 0 - //case cRDiv: // allowed range: x != 0 - //case cInv: // allowed range: x != 0 - return true; - } - } - return false; -} - -template bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op); -template bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op); - - -#if(0) // Implementation moved to fpaux.hh due to linker problems -//========================================================================= -// Mathematical template functions -//========================================================================= -/* fp_pow() is a wrapper for std::pow() - * that produces an identical value for - * exp(1) ^ 2.0 (0x4000000000000000) - * as exp(2.0) (0x4000000000000000) - * - std::pow() on x86_64 - * produces 2.0 (0x3FFFFFFFFFFFFFFF) instead! - * See comments below for other special traits. - */ -namespace -{ - template - inline ValueT fp_pow_with_exp_log(const ValueT& x, const ValueT& y) - { - // Exponentiation using exp(log(x)*y). - // See http://en.wikipedia.org/wiki/Exponentiation#Real_powers - // Requirements: x > 0. - return fp_exp(fp_log(x) * y); - } - - template - inline ValueT fp_powi(ValueT x, unsigned long y) - { - // Fast binary exponentiation algorithm - // See http://en.wikipedia.org/wiki/Exponentiation_by_squaring - // Requirements: y is non-negative integer. - ValueT result(1); - while(y != 0) - { - if(y & 1) { result *= x; y -= 1; } - else { x *= x; y /= 2; } - } - return result; - } -} - -template -ValueT FUNCTIONPARSERTYPES::fp_pow(const ValueT& x, const ValueT& y) -{ - if(x == ValueT(1)) return ValueT(1); - // y is now zero or positive - if(isLongInteger(y)) - { - // Use fast binary exponentiation algorithm - if(y >= ValueT(0)) - return fp_powi(x, makeLongInteger(y)); - else - return ValueT(1) / fp_powi(x, -makeLongInteger(y)); - } - if(y >= ValueT(0)) - { - // y is now positive. Calculate using exp(log(x)*y). - if(x > ValueT(0)) return fp_pow_with_exp_log(x, y); - if(x == ValueT(0)) return ValueT(0); - // At this point, y > 0.0 and x is known to be < 0.0, - // because positive and zero cases are already handled. - if(!isInteger(y*ValueT(16))) - return -fp_pow_with_exp_log(-x, y); - // ^This is not technically correct, but it allows - // functions such as cbrt(x^5), that is, x^(5/3), - // to be evaluated when x is negative. - // It is too complicated (and slow) to test whether y - // is a formed from a ratio of an integer to an odd integer. - // (And due to floating point inaccuracy, pointless too.) - // For example, x^1.30769230769... is - // actually x^(17/13), i.e. (x^17) ^ (1/13). - // (-5)^(17/13) gives us now -8.204227562330453. - // To see whether the result is right, we can test the given - // root: (-8.204227562330453)^13 gives us the value of (-5)^17, - // which proves that the expression was correct. - // - // The y*16 check prevents e.g. (-4)^(3/2) from being calculated, - // as it would confuse functioninfo when pow() returns no error - // but sqrt() does when the formula is converted into sqrt(x)*x. - // - // The errors in this approach are: - // (-2)^sqrt(2) should produce NaN - // or actually sqrt(2)I + 2^sqrt(2), - // produces -(2^sqrt(2)) instead. - // (Impact: Neglible) - // Thus, at worst, we're changing a NaN (or complex) - // result into a negative real number result. - } - else - { - // y is negative. Utilize the x^y = 1/(x^-y) identity. - if(x > ValueT(0)) return fp_pow_with_exp_log(ValueT(1) / x, -y); - if(x < ValueT(0)) - { - if(!isInteger(y*ValueT(-16))) - return -fp_pow_with_exp_log(ValueT(-1) / x, -y); - // ^ See comment above. - } - // Remaining case: 0.0 ^ negative number - } - // This is reached when: - // x=0, and y<0 - // x<0, and y*16 is either positive or negative integer - // It is used for producing error values and as a safe fallback. - return fp_pow_base(x, y); -} -#endif - - -//========================================================================= -// Elementary (atom) parsing functions -//========================================================================= -namespace -{ - const unsigned FP_ParamGuardMask = 1U << (sizeof(unsigned) * 8u - 1u); - // ^ This mask is used to prevent cFetch/other opcode's parameters - // from being confused into opcodes or variable indices within the - // bytecode optimizer. Because the way it is tested in bytecoderules.dat - // for speed reasons, it must also be the sign-bit of the "int" datatype. - // Perhaps an "assert(IsVarOpcode(X | FP_ParamGuardMask) == false)" - // might be justified to put somewhere in the code, just in case? - - - /* Reads an UTF8-encoded sequence which forms a valid identifier name from - the given input string and returns its length. If bit 31 is set, the - return value also contains the internal function opcode (defined in - fptypes.hh) that matches the name. - */ - unsigned readIdentifierCommon(const char* input) - { - /* Assuming unsigned = 32 bits: - 76543210 76543210 76543210 76543210 - Return value if built-in function: - 1PPPPPPP PPPPPPPP LLLLLLLL LLLLLLLL - P = function opcode (15 bits) - L = function name length (16 bits) - Return value if not built-in function: - 0LLLLLLL LLLLLLLL LLLLLLLL LLLLLLLL - L = identifier length (31 bits) - If unsigned has more than 32 bits, the other - higher order bits are to be assumed zero. - */ -#include "extrasrc/fp_identifier_parser.inc" - return 0; - } - - template - inline unsigned readIdentifier(const char* input) - { - const unsigned value = readIdentifierCommon(input); - if( (value & 0x80000000U) != 0) // Function? - { - // Verify that the function actually exists for this datatype - if(IsIntType::result - && !Functions[(value >> 16) & 0x7FFF].okForInt()) - { - // If it does not exist, return it as an identifier instead - return value & 0xFFFFu; - } - if(!IsComplexType::result - && Functions[(value >> 16) & 0x7FFF].complexOnly()) - { - // If it does not exist, return it as an identifier instead - return value & 0xFFFFu; - } - } - return value; - } - - // Returns true if the entire string is a valid identifier - template - bool containsOnlyValidIdentifierChars(const std::string& name) - { - if(name.empty()) return false; - return readIdentifier(name.c_str()) == (unsigned) name.size(); - } - - - // ----------------------------------------------------------------------- - // Wrappers for strto... functions - // ----------------------------------------------------------------------- - template - inline Value_t fp_parseLiteral(const char* str, char** endptr) - { - return std::strtod(str, endptr); - } - -#if defined(FP_USE_STRTOLD) || __cplusplus > 201100 - template<> - inline long double fp_parseLiteral(const char* str, - char** endptr) - { - using namespace std; // Just in case strtold() is not inside std:: - return strtold(str, endptr); - } -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE - template<> - inline long fp_parseLiteral(const char* str, char** endptr) - { - return std::strtol(str, endptr, 10); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template - inline std::complex fp_parseComplexLiteral(const char* str, - char** endptr) - { - T result = fp_parseLiteral (str,endptr); - const char* end = *endptr; - if( (*end == 'i' || *end == 'I') - && !std::isalnum(end[1]) ) - { - ++*endptr; - return std::complex (T(), result); - } - return std::complex (result, T()); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE - template<> - inline std::complex fp_parseLiteral > - (const char* str, char** endptr) - { - return fp_parseComplexLiteral (str,endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE - template<> - inline std::complex fp_parseLiteral > - (const char* str, char** endptr) - { - return fp_parseComplexLiteral (str,endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE - template<> - inline std::complex fp_parseLiteral > - (const char* str, char** endptr) - { - return fp_parseComplexLiteral (str,endptr); - } -#endif - - // ----------------------------------------------------------------------- - // Hexadecimal floating point literal parsing - // ----------------------------------------------------------------------- - inline int testXdigit(unsigned c) - { - if((c-'0') < 10u) return c&15; // 0..9 - if(((c|0x20)-'a') < 6u) return 9+(c&15); // A..F or a..f - return -1; // Not a hex digit - } - - template - inline void addXdigit(elem_t* buffer, unsigned nibble) - { - for(unsigned p=0; p> (elem_t)(limb_bits-4) ); - buffer[p] = (buffer[p] << 4) | nibble; - nibble = carry; - } - } - - template - Value_t parseHexLiteral(const char* str, char** endptr) - { - const unsigned bits_per_char = 8; - - const int MantissaBits = - std::numeric_limits::radix == 2 - ? std::numeric_limits::digits - : (((sizeof(Value_t) * bits_per_char) &~ 3) - 4); - - typedef unsigned long elem_t; - const int ExtraMantissaBits = 4 + ((MantissaBits+3)&~3); // Store one digit more for correct rounding - const unsigned limb_bits = sizeof(elem_t) * bits_per_char; - const unsigned n_limbs = (ExtraMantissaBits + limb_bits-1) / limb_bits; - elem_t mantissa_buffer[n_limbs] = { 0 }; - - int n_mantissa_bits = 0; // Track the number of bits - int exponent = 0; // The exponent that will be used to multiply the mantissa - // Read integer portion - while(true) - { - int xdigit = testXdigit(*str); - if(xdigit < 0) break; - addXdigit (mantissa_buffer, xdigit); - ++str; - - n_mantissa_bits += 4; - if(n_mantissa_bits >= ExtraMantissaBits) - { - // Exhausted the precision. Parse the rest (until exponent) - // normally but ignore the actual digits. - for(; testXdigit(*str) >= 0; ++str) - exponent += 4; - // Read but ignore decimals - if(*str == '.') - for(++str; testXdigit(*str) >= 0; ++str) - {} - goto read_exponent; - } - } - // Read decimals - if(*str == '.') - for(++str; ; ) - { - int xdigit = testXdigit(*str); - if(xdigit < 0) break; - addXdigit (mantissa_buffer, xdigit); - ++str; - - exponent -= 4; - n_mantissa_bits += 4; - if(n_mantissa_bits >= ExtraMantissaBits) - { - // Exhausted the precision. Skip the rest - // of the decimals, until the exponent. - while(testXdigit(*str) >= 0) - ++str; - break; - } - } - - // Read exponent - read_exponent: - if(*str == 'p' || *str == 'P') - { - const char* str2 = str+1; - long p_exponent = strtol(str2, const_cast (&str2), 10); - if(str2 != str+1 && p_exponent == (long)(int)p_exponent) - { - exponent += (int)p_exponent; - str = str2; - } - } - - if(endptr) *endptr = const_cast (str); - - Value_t result = std::ldexp(Value_t(mantissa_buffer[0]), exponent); - for(unsigned p=1; p - long parseHexLiteral(const char* str, char** endptr) - { - return std::strtol(str, endptr, 16); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE - template<> - std::complex - parseHexLiteral >(const char* str, char** endptr) - { - return parseHexLiteral (str, endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE - template<> - std::complex - parseHexLiteral >(const char* str, char** endptr) - { - return parseHexLiteral (str, endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE - template<> - std::complex - parseHexLiteral >(const char* str, char** endptr) - { - return parseHexLiteral (str, endptr); - } -#endif -} - -//========================================================================= -// Utility functions -//========================================================================= -namespace -{ - // ----------------------------------------------------------------------- - // Add a new identifier to the specified identifier map - // ----------------------------------------------------------------------- - // Return value will be false if the name already existed - template - bool addNewNameData(NamePtrsMap& namePtrs, - std::pair >& newName, - bool isVar) - { - typename NamePtrsMap::iterator nameIter = - namePtrs.lower_bound(newName.first); - - if(nameIter != namePtrs.end() && newName.first == nameIter->first) - { - // redefining a var is not allowed. - if(isVar) return false; - - // redefining other tokens is allowed, if the type stays the same. - if(nameIter->second.type != newName.second.type) - return false; - - // update the data - nameIter->second = newName.second; - return true; - } - - if(!isVar) - { - // Allocate a copy of the name (pointer stored in the map key) - // However, for VARIABLEs, the pointer points to VariableString, - // which is managed separately. Thusly, only done when !IsVar. - char* namebuf = new char[newName.first.nameLength]; - memcpy(namebuf, newName.first.name, newName.first.nameLength); - newName.first.name = namebuf; - } - - namePtrs.insert(nameIter, newName); - return true; - } -} - - -//========================================================================= -// Data struct implementation -//========================================================================= -template -FunctionParserBase::Data::Data(): - mReferenceCounter(1), - mDelimiterChar(0), - mParseErrorType(NO_FUNCTION_PARSED_YET), - mEvalErrorType(0), - mUseDegreeConversion(false), - mErrorLocation(0), - mVariablesAmount(0), - mStackSize(0) -{} - -template -FunctionParserBase::Data::Data(const Data& rhs): - mReferenceCounter(0), - mDelimiterChar(rhs.mDelimiterChar), - mParseErrorType(rhs.mParseErrorType), - mEvalErrorType(rhs.mEvalErrorType), - mUseDegreeConversion(rhs.mUseDegreeConversion), - mErrorLocation(rhs.mErrorLocation), - mVariablesAmount(rhs.mVariablesAmount), - mVariablesString(rhs.mVariablesString), - mNamePtrs(), - mFuncPtrs(rhs.mFuncPtrs), - mFuncParsers(rhs.mFuncParsers), - mByteCode(rhs.mByteCode), - mImmed(rhs.mImmed), -#ifndef FP_USE_THREAD_SAFE_EVAL - mStack(rhs.mStackSize), -#endif - mStackSize(rhs.mStackSize) -{ - for(typename NamePtrsMap::const_iterator i = rhs.mNamePtrs.begin(); - i != rhs.mNamePtrs.end(); - ++i) - { - if(i->second.type == NameData::VARIABLE) - { - const std::size_t variableStringOffset = - i->first.name - rhs.mVariablesString.c_str(); - std::pair > tmp - (NamePtr(&mVariablesString[variableStringOffset], - i->first.nameLength), - i->second); - mNamePtrs.insert(mNamePtrs.end(), tmp); - } - else - { - std::pair > tmp - (NamePtr(new char[i->first.nameLength], i->first.nameLength), - i->second ); - memcpy(const_cast(tmp.first.name), i->first.name, - tmp.first.nameLength); - mNamePtrs.insert(mNamePtrs.end(), tmp); - } - } -} - -template -FunctionParserBase::Data::~Data() -{ - for(typename NamePtrsMap::iterator i = mNamePtrs.begin(); - i != mNamePtrs.end(); - ++i) - { - if(i->second.type != NameData::VARIABLE) - delete[] i->first.name; - } -} - -template -void FunctionParserBase::incFuncWrapperRefCount -(FunctionWrapper* wrapper) -{ - ++wrapper->mReferenceCount; -} - -template -unsigned FunctionParserBase::decFuncWrapperRefCount -(FunctionWrapper* wrapper) -{ - return --wrapper->mReferenceCount; -} - -template -FunctionParserBase::Data::FuncWrapperPtrData::FuncWrapperPtrData(): - mRawFuncPtr(0), mFuncWrapperPtr(0), mParams(0) -{} - -template -FunctionParserBase::Data::FuncWrapperPtrData::~FuncWrapperPtrData() -{ - if(mFuncWrapperPtr && - FunctionParserBase::decFuncWrapperRefCount(mFuncWrapperPtr) == 0) - delete mFuncWrapperPtr; -} - -template -FunctionParserBase::Data::FuncWrapperPtrData::FuncWrapperPtrData -(const FuncWrapperPtrData& rhs): - mRawFuncPtr(rhs.mRawFuncPtr), - mFuncWrapperPtr(rhs.mFuncWrapperPtr), - mParams(rhs.mParams) -{ - if(mFuncWrapperPtr) - FunctionParserBase::incFuncWrapperRefCount(mFuncWrapperPtr); -} - -template -typename FunctionParserBase::Data::FuncWrapperPtrData& -FunctionParserBase::Data::FuncWrapperPtrData::operator= -(const FuncWrapperPtrData& rhs) -{ - if(&rhs != this) - { - if(mFuncWrapperPtr && - FunctionParserBase::decFuncWrapperRefCount(mFuncWrapperPtr) == 0) - delete mFuncWrapperPtr; - mRawFuncPtr = rhs.mRawFuncPtr; - mFuncWrapperPtr = rhs.mFuncWrapperPtr; - mParams = rhs.mParams; - if(mFuncWrapperPtr) - FunctionParserBase::incFuncWrapperRefCount(mFuncWrapperPtr); - } - return *this; -} - - -//========================================================================= -// FunctionParser constructors, destructor and assignment -//========================================================================= -template -FunctionParserBase::FunctionParserBase(): - mData(new Data), - mStackPtr(0) -{ -} - -template -FunctionParserBase::~FunctionParserBase() -{ - if(--(mData->mReferenceCounter) == 0) - delete mData; -} - -template -FunctionParserBase::FunctionParserBase(const FunctionParserBase& cpy): - mData(cpy.mData), - mStackPtr(0) -{ - ++(mData->mReferenceCounter); -} - -template -FunctionParserBase& -FunctionParserBase::operator=(const FunctionParserBase& cpy) -{ - if(mData != cpy.mData) - { - if(--(mData->mReferenceCounter) == 0) delete mData; - - mData = cpy.mData; - ++(mData->mReferenceCounter); - } - return *this; -} - -template -typename FunctionParserBase::Data* -FunctionParserBase::getParserData() -{ - return mData; -} - -template -void FunctionParserBase::setDelimiterChar(char c) -{ - mData->mDelimiterChar = c; -} - - -//--------------------------------------------------------------------------- -// Copy-on-write method -//--------------------------------------------------------------------------- -template -void FunctionParserBase::CopyOnWrite() -{ - if(mData->mReferenceCounter > 1) - { - Data* oldData = mData; - mData = new Data(*oldData); - --(oldData->mReferenceCounter); - mData->mReferenceCounter = 1; - } -} - -template -void FunctionParserBase::ForceDeepCopy() -{ - CopyOnWrite(); -} - - -//========================================================================= -// Epsilon -//========================================================================= -template<> double FunctionParserBase::sEpsilon = 1E-12; -template<> float FunctionParserBase::sEpsilon = 1E-5F; -template<> long double FunctionParserBase::sEpsilon = 1E-14L; -template<> long FunctionParserBase::sEpsilon = 0; - -template<> std::complex -FunctionParserBase >::sEpsilon = 1E-12; - -template<> std::complex -FunctionParserBase >::sEpsilon = 1E-5F; - -template<> std::complex -FunctionParserBase >::sEpsilon = 1E-14L; - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -template<> MpfrFloat -FunctionParserBase::sEpsilon(MpfrFloat::someEpsilon()); -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> GmpInt FunctionParserBase::sEpsilon = 0; -#endif - -template -Value_t FunctionParserBase::epsilon() -{ - return sEpsilon; -} - -template -void FunctionParserBase::setEpsilon(Value_t value) -{ - sEpsilon = value; -} - - -//========================================================================= -// User-defined identifier addition functions -//========================================================================= -template -bool FunctionParserBase::AddConstant(const std::string& name, - Value_t value) -{ - if(!containsOnlyValidIdentifierChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::CONSTANT, value)); - - return addNewNameData(mData->mNamePtrs, newName, false); -} - -template -bool FunctionParserBase::AddUnit(const std::string& name, - Value_t value) -{ - if(!containsOnlyValidIdentifierChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::UNIT, value)); - return addNewNameData(mData->mNamePtrs, newName, false); -} - -template -bool FunctionParserBase::AddFunction -(const std::string& name, FunctionPtr ptr, unsigned paramsAmount) -{ - if(!containsOnlyValidIdentifierChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::FUNC_PTR, - unsigned(mData->mFuncPtrs.size()))); - - const bool success = addNewNameData(mData->mNamePtrs, newName, false); - if(success) - { - mData->mFuncPtrs.push_back(typename Data::FuncWrapperPtrData()); - mData->mFuncPtrs.back().mRawFuncPtr = ptr; - mData->mFuncPtrs.back().mParams = paramsAmount; - } - return success; -} - -template -bool FunctionParserBase::addFunctionWrapperPtr -(const std::string& name, FunctionWrapper* wrapper, unsigned paramsAmount) -{ - if(!AddFunction(name, FunctionPtr(0), paramsAmount)) return false; - mData->mFuncPtrs.back().mFuncWrapperPtr = wrapper; - return true; -} - -template -typename FunctionParserBase::FunctionWrapper* -FunctionParserBase::GetFunctionWrapper(const std::string& name) -{ - CopyOnWrite(); - NamePtr namePtr(name.data(), unsigned(name.size())); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(namePtr); - - if(nameIter != mData->mNamePtrs.end() && - nameIter->second.type == NameData::FUNC_PTR) - { - return mData->mFuncPtrs[nameIter->second.index].mFuncWrapperPtr; - } - return 0; -} - -template -bool FunctionParserBase::CheckRecursiveLinking -(const FunctionParserBase* fp) const -{ - if(fp == this) return true; - for(unsigned i = 0; i < fp->mData->mFuncParsers.size(); ++i) - if(CheckRecursiveLinking(fp->mData->mFuncParsers[i].mParserPtr)) - return true; - return false; -} - -template -bool FunctionParserBase::AddFunction(const std::string& name, - FunctionParserBase& fp) -{ - if(!containsOnlyValidIdentifierChars(name) || - CheckRecursiveLinking(&fp)) - return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::PARSER_PTR, - unsigned(mData->mFuncParsers.size()))); - - const bool success = addNewNameData(mData->mNamePtrs, newName, false); - if(success) - { - mData->mFuncParsers.push_back(typename Data::FuncParserPtrData()); - mData->mFuncParsers.back().mParserPtr = &fp; - mData->mFuncParsers.back().mParams = fp.mData->mVariablesAmount; - } - return success; -} - -template -bool FunctionParserBase::RemoveIdentifier(const std::string& name) -{ - CopyOnWrite(); - - NamePtr namePtr(name.data(), unsigned(name.size())); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(namePtr); - - if(nameIter != mData->mNamePtrs.end()) - { - if(nameIter->second.type == NameData::VARIABLE) - { - // Illegal attempt to delete variables - return false; - } - delete[] nameIter->first.name; - mData->mNamePtrs.erase(nameIter); - return true; - } - return false; -} - - -//========================================================================= -// Function parsing -//========================================================================= -namespace -{ - // Error messages returned by ErrorMsg(): - const char* const ParseErrorMessage[]= - { - "Syntax error", // 0 - "Mismatched parenthesis", // 1 - "Missing ')'", // 2 - "Empty parentheses", // 3 - "Syntax error: Operator expected", // 4 - "Not enough memory", // 5 - "An unexpected error occurred. Please make a full bug report " - "to the author", // 6 - "Syntax error in parameter 'Vars' given to " - "FunctionParser::Parse()", // 7 - "Illegal number of parameters to function", // 8 - "Syntax error: Premature end of string", // 9 - "Syntax error: Expecting ( after function", // 10 - "Syntax error: Unknown identifier", // 11 - "(No function has been parsed yet)", - "" - }; - - template - inline typename FunctionParserBase::ParseErrorType - noCommaError(char c) - { - return c == ')' ? - FunctionParserBase::ILL_PARAMS_AMOUNT : - FunctionParserBase::SYNTAX_ERROR; - } - - template - inline typename FunctionParserBase::ParseErrorType - noParenthError(char c) - { - return c == ',' ? - FunctionParserBase::ILL_PARAMS_AMOUNT : - FunctionParserBase::MISSING_PARENTH; - } - - template - struct IntLiteralMask - { - enum { mask = - // ( 1UL << ('-'-offset)) | - (0x3FFUL << ('0'-offset)) }; /* 0x3FF = 10 bits worth "1" */ - // Note: If you change fparser to support negative numbers parsing - // (as opposed to parsing them as cNeg followed by literal), - // enable the '-' line above, and change the offset value - // in BeginsLiteral() to '-' instead of '.'. - }; - - template - struct LiteralMask - { - enum { mask = - ( 1UL << ('.'-offset)) | - IntLiteralMask::mask }; - }; -#ifdef FP_SUPPORT_LONG_INT_TYPE - template - struct LiteralMask: public IntLiteralMask - { - }; -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE - template - struct LiteralMask: public IntLiteralMask - { - }; -#endif - - template - struct SimpleSpaceMask - { - enum { mask = - (1UL << ('\r'-offset)) | - (1UL << ('\n'-offset)) | - (1UL << ('\v'-offset)) | - (1UL << ('\t'-offset)) | - (1UL << (' ' -offset)) }; - }; - - template - inline bool BeginsLiteral(unsigned byte) - { - enum { n = sizeof(unsigned long)>=8 ? 0 : '.' }; - byte -= n; - if(byte > (unsigned char)('9'-n)) return false; - unsigned long shifted = 1UL << byte; - const unsigned long mask = LiteralMask::mask; - return (mask & shifted) != 0; - } - - template - inline void SkipSpace(CharPtr& function) - { -/* - Space characters in unicode: -U+0020 SPACE Depends on font, often adjusted (see below) -U+00A0 NO-BREAK SPACE As a space, but often not adjusted -U+2000 EN QUAD 1 en (= 1/2 em) -U+2001 EM QUAD 1 em (nominally, the height of the font) -U+2002 EN SPACE 1 en (= 1/2 em) -U+2003 EM SPACE 1 em -U+2004 THREE-PER-EM SPACE 1/3 em -U+2005 FOUR-PER-EM SPACE 1/4 em -U+2006 SIX-PER-EM SPACE 1/6 em -U+2007 FIGURE SPACE Tabular width, the width of digits -U+2008 PUNCTUATION SPACE The width of a period . -U+2009 THIN SPACE 1/5 em (or sometimes 1/6 em) -U+200A HAIR SPACE Narrower than THIN SPACE -U+200B ZERO WIDTH SPACE Nominally no width, but may expand -U+202F NARROW NO-BREAK SPACE Narrower than NO-BREAK SPACE (or SPACE) -U+205F MEDIUM MATHEMATICAL SPACE 4/18 em -U+3000 IDEOGRAPHIC SPACE The width of ideographic (CJK) characters. - Also: -U+000A \n -U+000D \r -U+0009 \t -U+000B \v - As UTF-8 sequences: - 09 - 0A - 0B - 0D - 20 - C2 A0 - E2 80 80-8B - E2 80 AF - E2 81 9F - E3 80 80 -*/ - while(true) - { - enum { n = sizeof(unsigned long)>=8 ? 0 : '\t' }; - typedef signed char schar; - unsigned byte = (unsigned char)*function; - byte -= n; - // ^Note: values smaller than n intentionally become - // big values here due to integer wrap. The - // comparison below thus excludes them, making - // the effective range 0x09..0x20 (32-bit) - // or 0x00..0x20 (64-bit) within the if-clause. - if(byte <= (unsigned char)(' '-n)) - { - unsigned long shifted = 1UL << byte; - const unsigned long mask = SimpleSpaceMask::mask; - if(mask & shifted) - { ++function; continue; } // \r, \n, \t, \v and space - break; - } - if(likely(byte < 0xC2-n)) break; - - if(byte == 0xC2-n && function[1] == char(0xA0)) - { function += 2; continue; } // U+00A0 - if(byte == 0xE3-n && - function[1] == char(0x80) && function[2] == char(0x80)) - { function += 3; continue; } // U+3000 - if(byte == 0xE2-n) - { - if(function[1] == char(0x81)) - { - if(function[2] != char(0x9F)) break; - function += 3; // U+205F - continue; - } - if(function[1] == char(0x80)) - if(function[2] == char(0xAF) || // U+202F - schar(function[2]) <= schar(0x8B) // U+2000..U+200B - ) - { - function += 3; - continue; - } - } - break; - } // while(true) - } // SkipSpace(CharPtr& function) -} - -// --------------------------------------------------------------------------- -// Return parse error message -// --------------------------------------------------------------------------- -template -const char* FunctionParserBase::ErrorMsg() const -{ - return ParseErrorMessage[mData->mParseErrorType]; -} - -template -typename FunctionParserBase::ParseErrorType -FunctionParserBase::GetParseErrorType() const -{ - return mData->mParseErrorType; -} - -template -int FunctionParserBase::EvalError() const -{ - return mData->mEvalErrorType; -} - - -// --------------------------------------------------------------------------- -// Parse variables -// --------------------------------------------------------------------------- -template -bool FunctionParserBase::ParseVariables -(const std::string& inputVarString) -{ - if(mData->mVariablesString == inputVarString) return true; - - /* Delete existing variables from mNamePtrs */ - for(typename NamePtrsMap::iterator i = - mData->mNamePtrs.begin(); - i != mData->mNamePtrs.end(); ) - { - if(i->second.type == NameData::VARIABLE) - { - typename NamePtrsMap::iterator j (i); - ++i; - mData->mNamePtrs.erase(j); - } - else ++i; - } - mData->mVariablesString = inputVarString; - - const std::string& vars = mData->mVariablesString; - const unsigned len = unsigned(vars.size()); - - unsigned varNumber = VarBegin; - - const char* beginPtr = vars.c_str(); - const char* finalPtr = beginPtr + len; - while(beginPtr < finalPtr) - { - SkipSpace(beginPtr); - unsigned nameLength = readIdentifier(beginPtr); - if(nameLength == 0 || (nameLength & 0x80000000U)) return false; - const char* endPtr = beginPtr + nameLength; - SkipSpace(endPtr); - if(endPtr != finalPtr && *endPtr != ',') return false; - - std::pair > newName - (NamePtr(beginPtr, nameLength), - NameData(NameData::VARIABLE, varNumber++)); - - if(!addNewNameData(mData->mNamePtrs, newName, true)) - { - return false; - } - - beginPtr = endPtr + 1; - } - - mData->mVariablesAmount = varNumber - VarBegin; - return true; -} - -// --------------------------------------------------------------------------- -// Parse() public interface functions -// --------------------------------------------------------------------------- -template -int FunctionParserBase::Parse(const char* Function, - const std::string& Vars, - bool useDegrees) -{ - CopyOnWrite(); - - if(!ParseVariables(Vars)) - { - mData->mParseErrorType = INVALID_VARS; - return int(strlen(Function)); - } - - return ParseFunction(Function, useDegrees); -} - -template -int FunctionParserBase::Parse(const std::string& Function, - const std::string& Vars, - bool useDegrees) -{ - CopyOnWrite(); - - if(!ParseVariables(Vars)) - { - mData->mParseErrorType = INVALID_VARS; - return int(Function.size()); - } - - return ParseFunction(Function.c_str(), useDegrees); -} - - -// --------------------------------------------------------------------------- -// Main parsing function -// --------------------------------------------------------------------------- -template -int FunctionParserBase::ParseFunction(const char* function, - bool useDegrees) -{ - mData->mUseDegreeConversion = useDegrees; - mData->mParseErrorType = FP_NO_ERROR; - - mData->mInlineVarNames.clear(); - mData->mByteCode.clear(); mData->mByteCode.reserve(128); - mData->mImmed.clear(); mData->mImmed.reserve(128); - mData->mStackSize = mStackPtr = 0; - - mData->mHasByteCodeFlags = false; - - const char* ptr = Compile(function); - mData->mInlineVarNames.clear(); - - if(mData->mHasByteCodeFlags) - { - for(unsigned i = unsigned(mData->mByteCode.size()); i-- > 0; ) - mData->mByteCode[i] &= ~FP_ParamGuardMask; - } - - if(mData->mParseErrorType != FP_NO_ERROR) - return int(mData->mErrorLocation - function); - - assert(ptr); // Should never be null at this point. It's a bug otherwise. - if(*ptr) - { - if(mData->mDelimiterChar == 0 || *ptr != mData->mDelimiterChar) - mData->mParseErrorType = EXPECT_OPERATOR; - return int(ptr - function); - } - -#ifndef FP_USE_THREAD_SAFE_EVAL - mData->mStack.resize(mData->mStackSize); -#endif - - return -1; -} - - -//========================================================================= -// Parsing and bytecode compiling functions -//========================================================================= -template -inline const char* FunctionParserBase::SetErrorType(ParseErrorType t, - const char* pos) -{ - mData->mParseErrorType = t; - mData->mErrorLocation = pos; - return 0; -} - -template -inline void FunctionParserBase::incStackPtr() -{ - if(++mStackPtr > mData->mStackSize) ++(mData->mStackSize); -} - -namespace -{ - const unsigned char powi_factor_table[128] = - { - 0,1,0,0,0,0,0,0, 0, 0,0,0,0,0,0,3,/* 0 - 15 */ - 0,0,0,0,0,0,0,0, 0, 5,0,3,0,0,3,0,/* 16 - 31 */ - 0,0,0,0,0,0,0,3, 0, 0,0,0,0,5,0,0,/* 32 - 47 */ - 0,0,5,3,0,0,3,5, 0, 3,0,0,3,0,0,3,/* 48 - 63 */ - 0,0,0,0,0,0,0,0, 0, 0,0,3,0,0,3,0,/* 64 - 79 */ - 0,9,0,0,0,5,0,3, 0, 0,5,7,0,0,0,5,/* 80 - 95 */ - 0,0,0,3,5,0,3,0, 0, 3,0,0,3,0,5,3,/* 96 - 111 */ - 0,0,3,5,0,9,0,7, 3,11,0,3,0,5,3,0,/* 112 - 127 */ - }; - - inline int get_powi_factor(long abs_int_exponent) - { - if(abs_int_exponent >= int(sizeof(powi_factor_table))) return 0; - return powi_factor_table[abs_int_exponent]; - } - -#if 0 - int EstimatePowiComplexity(int abs_int_exponent) - { - int cost = 0; - while(abs_int_exponent > 1) - { - int factor = get_powi_factor(abs_int_exponent); - if(factor) - { - cost += EstimatePowiComplexity(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - cost += 3; // sqr - } - else - { - cost += 4; // dup+mul - abs_int_exponent -= 1; - } - } - return cost; - } -#endif - - bool IsEligibleIntPowiExponent(long int_exponent) - { - if(int_exponent == 0) return false; - long abs_int_exponent = int_exponent; - #if 0 - int cost = 0; - - if(abs_int_exponent < 0) - { - cost += 11; - abs_int_exponent = -abs_int_exponent; - } - - cost += EstimatePowiComplexity(abs_int_exponent); - - return cost < (10*3 + 4*4); - #else - if(abs_int_exponent < 0) abs_int_exponent = -abs_int_exponent; - - return (abs_int_exponent >= 1) - && (abs_int_exponent <= 46 || - (abs_int_exponent <= 1024 && - (abs_int_exponent & (abs_int_exponent - 1)) == 0)); - #endif - } - - /* Needed by fp_opcode_add.inc if tracing is enabled */ - template - std::string findName(const NamePtrsMap& nameMap, - unsigned index, - typename NameData::DataType type) - { - for(typename NamePtrsMap::const_iterator - iter = nameMap.begin(); - iter != nameMap.end(); - ++iter) - { - if(iter->second.type == type && iter->second.index == index) - return std::string(iter->first.name, - iter->first.name + iter->first.nameLength); - } - return "?"; - } -} - -template -inline void FunctionParserBase::AddImmedOpcode(Value_t value) -{ - mData->mImmed.push_back(value); - mData->mByteCode.push_back(cImmed); -} - -template -inline void FunctionParserBase::CompilePowi(long abs_int_exponent) -{ - int num_muls=0; - while(abs_int_exponent > 1) - { - long factor = get_powi_factor(abs_int_exponent); - if(factor) - { - CompilePowi(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - mData->mByteCode.push_back(cSqr); - // ^ Don't put AddFunctionOpcode here, - // it would slow down a great deal. - } - else - { - mData->mByteCode.push_back(cDup); - incStackPtr(); - abs_int_exponent -= 1; - ++num_muls; - } - } - if(num_muls > 0) - { - mData->mByteCode.resize(mData->mByteCode.size()+num_muls, cMul); - mStackPtr -= num_muls; - } -} - -template -inline bool FunctionParserBase::TryCompilePowi(Value_t original_immed) -{ - Value_t changed_immed = original_immed; - for(int sqrt_count=0; /**/; ++sqrt_count) - { - long int_exponent = makeLongInteger(changed_immed); - if(isLongInteger(changed_immed) && - IsEligibleIntPowiExponent(int_exponent)) - { - long abs_int_exponent = int_exponent; - if(abs_int_exponent < 0) - abs_int_exponent = -abs_int_exponent; - - mData->mImmed.pop_back(); mData->mByteCode.pop_back(); - --mStackPtr; - // ^Though the above is accounted for by the procedure - // that generates cPow, we need it for correct cFetch - // indexes in CompilePowi(). - - while(sqrt_count > 0) - { - int opcode = cSqrt; - if(sqrt_count == 1 && int_exponent < 0) - { - opcode = cRSqrt; - int_exponent = -int_exponent; - } - mData->mByteCode.push_back(opcode); - --sqrt_count; - } - if((abs_int_exponent & 1) == 0) - { - // This special rule fixes the optimization - // shortcoming of (-x)^2 with minimal overhead. - AddFunctionOpcode(cSqr); - abs_int_exponent >>= 1; - } - CompilePowi(abs_int_exponent); - if(int_exponent < 0) mData->mByteCode.push_back(cInv); - ++mStackPtr; // Needed because cPow adding will assume this. - return true; - } - if(sqrt_count >= 4) break; - changed_immed += changed_immed; - } - - // When we don't know whether x >= 0, we still know that - // x^y can be safely converted into exp(y * log(x)) - // when y is _not_ integer, because we know that x >= 0. - // Otherwise either expression will give a NaN. - if(/*!isInteger(original_immed) ||*/ - IsNeverNegativeValueOpcode(mData->mByteCode[mData->mByteCode.size()-2])) - { - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - //--mStackPtr; - accounted for by the procedure that generates cPow - AddFunctionOpcode(cLog); - AddImmedOpcode(original_immed); - //incStackPtr(); - this and the next are redundant because... - AddFunctionOpcode(cMul); - //--mStackPtr; - ...because the cImmed was popped earlier. - AddFunctionOpcode(cExp); - return true; - } - return false; -} - -//#include "fpoptimizer/opcodename.hh" -// ^ needed only if FP_TRACE_BYTECODE_OPTIMIZATION() is used - -template -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 0 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} - -#ifdef FP_SUPPORT_LONG_INT_TYPE -template<> -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ - typedef long Value_t; -#define FP_FLOAT_VERSION 0 -#define FP_COMPLEX_VERSION 0 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ - typedef GmpInt Value_t; -#define FP_FLOAT_VERSION 0 -#define FP_COMPLEX_VERSION 0 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE -template<> -inline void FunctionParserBase >::AddFunctionOpcode(unsigned opcode) -{ - typedef std::complex Value_t; -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 1 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE -template<> -inline void FunctionParserBase >::AddFunctionOpcode(unsigned opcode) -{ - typedef std::complex Value_t; -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 1 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE -template<> -inline void FunctionParserBase >::AddFunctionOpcode(unsigned opcode) -{ - typedef std::complex Value_t; -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 1 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -template -unsigned -FunctionParserBase::ParseIdentifier(const char* function) -{ - return readIdentifier(function); -} - -template -std::pair -FunctionParserBase::ParseLiteral(const char* function) -{ - char* endptr; -#if 0 /* Profile the hex literal parser */ - if(function[0]=='0' && function[1]=='x') - { - // Parse hexadecimal literal if fp_parseLiteral didn't already - Value_t val = parseHexLiteral(function+2, &endptr); - if(endptr == function+2) - return std::pair (function, Value_t()); - return std::pair (endptr, val); - } -#endif - Value_t val = fp_parseLiteral(function, &endptr); - - if(endptr == function+1 && function[0] == '0' && function[1] == 'x') - { - // Parse hexadecimal literal if fp_parseLiteral didn't already - val = parseHexLiteral(function+2, &endptr); - if(endptr == function+2) - return std::pair (function, Value_t()); - } - else if(endptr == function) - return std::pair (function, Value_t()); - - return std::pair (endptr, val); -} - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -template<> -std::pair -FunctionParserBase::ParseLiteral(const char* function) -{ - char* endPtr; - const MpfrFloat val = MpfrFloat::parseString(function, &endPtr); - if(endPtr == function) - return std::pair (function, MpfrFloat()); - return std::pair (endPtr, val); -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -std::pair -FunctionParserBase::ParseLiteral(const char* function) -{ - char* endPtr; - const GmpInt val = GmpInt::parseString(function, &endPtr); - if(endPtr == function) - return std::pair (function, GmpInt()); - return std::pair (endPtr, val); -} -#endif - - -template -inline const char* -FunctionParserBase::CompileLiteral(const char* function) -{ - std::pair result = ParseLiteral(function); - - if(result.first == function) - return SetErrorType(SYNTAX_ERROR, result.first); - - AddImmedOpcode(result.second); - incStackPtr(); - SkipSpace(result.first); - return result.first; -} - -template -const char* FunctionParserBase::CompileIf(const char* function) -{ - if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function); - - function = CompileExpression(function+1); - if(!function) return 0; - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - OPCODE opcode = cIf; - if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back(); - if(IsNeverNegativeValueOpcode(mData->mByteCode.back())) - { - // If we know that the condition to be tested is always - // a positive value (such as when produced by "x= 0.5, - // cAbsIf simply tests whether cond >= 0.5. - opcode = cAbsIf; - } - - mData->mByteCode.push_back(opcode); - const unsigned curByteCodeSize = unsigned(mData->mByteCode.size()); - PushOpcodeParam(0); // Jump index; to be set later - PushOpcodeParam (0); // Immed jump index; to be set later - - --mStackPtr; - - function = CompileExpression(function + 1); - if(!function) return 0; - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - mData->mByteCode.push_back(cJump); - const unsigned curByteCodeSize2 = unsigned(mData->mByteCode.size()); - const unsigned curImmedSize2 = unsigned(mData->mImmed.size()); - PushOpcodeParam(0); // Jump index; to be set later - PushOpcodeParam (0); // Immed jump index; to be set later - - --mStackPtr; - - function = CompileExpression(function + 1); - if(!function) return 0; - if(*function != ')') - return SetErrorType(noParenthError(*function), function); - - PutOpcodeParamAt ( mData->mByteCode.back(), unsigned(mData->mByteCode.size()-1) ); - // ^Necessary for guarding against if(x,1,2)+1 being changed - // into if(x,1,3) by fp_opcode_add.inc - - // Set jump indices - PutOpcodeParamAt( curByteCodeSize2+1, curByteCodeSize ); - PutOpcodeParamAt( curImmedSize2, curByteCodeSize+1 ); - PutOpcodeParamAt( unsigned(mData->mByteCode.size())-1, curByteCodeSize2); - PutOpcodeParamAt( unsigned(mData->mImmed.size()), curByteCodeSize2+1); - - ++function; - SkipSpace(function); - return function; -} - -template -const char* FunctionParserBase::CompileFunctionParams -(const char* function, unsigned requiredParams) -{ - if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function); - - if(requiredParams > 0) - { - const char* function_end = CompileExpression(function+1); - if(!function_end) - { - // If an error occurred, verify whether it was caused by () - ++function; - SkipSpace(function); - if(*function == ')') - return SetErrorType(ILL_PARAMS_AMOUNT, function); - // Not caused by (), use the error message given by CompileExpression() - return 0; - } - function = function_end; - - for(unsigned i = 1; i < requiredParams; ++i) - { - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - function = CompileExpression(function+1); - if(!function) return 0; - } - // No need for incStackPtr() because each parse parameter calls it - mStackPtr -= requiredParams-1; - } - else - { - incStackPtr(); // return value of function is pushed onto the stack - ++function; - SkipSpace(function); - } - - if(*function != ')') - return SetErrorType(noParenthError(*function), function); - ++function; - SkipSpace(function); - return function; -} - -template -const char* FunctionParserBase::CompileElement(const char* function) -{ - if(BeginsLiteral( (unsigned char) *function)) - return CompileLiteral(function); - - unsigned nameLength = readIdentifier(function); - if(nameLength == 0) - { - // No identifier found - if(*function == '(') return CompileParenthesis(function); - if(*function == ')') return SetErrorType(MISM_PARENTH, function); - return SetErrorType(SYNTAX_ERROR, function); - } - - // Function, variable or constant - if(nameLength & 0x80000000U) // Function - { - OPCODE func_opcode = OPCODE( (nameLength >> 16) & 0x7FFF ); - return CompileFunction(function + (nameLength & 0xFFFF), func_opcode); - } - - NamePtr name(function, nameLength); - const char* endPtr = function + nameLength; - SkipSpace(endPtr); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(name); - if(nameIter == mData->mNamePtrs.end()) - { - // Check if it's an inline variable: - for(typename Data::InlineVarNamesContainer::reverse_iterator iter = - mData->mInlineVarNames.rbegin(); - iter != mData->mInlineVarNames.rend(); - ++iter) - { - if(name == iter->mName) - { - if( iter->mFetchIndex+1 == mStackPtr) - { - mData->mByteCode.push_back(cDup); - } - else - { - mData->mByteCode.push_back(cFetch); - PushOpcodeParam(iter->mFetchIndex); - } - incStackPtr(); - return endPtr; - } - } - - return SetErrorType(UNKNOWN_IDENTIFIER, function); - } - - const NameData* nameData = &nameIter->second; - switch(nameData->type) - { - case NameData::VARIABLE: // is variable - if(unlikely(!mData->mByteCode.empty() && - mData->mByteCode.back() == nameData->index)) - mData->mByteCode.push_back(cDup); - else - mData->mByteCode.push_back(nameData->index); - incStackPtr(); - return endPtr; - - case NameData::CONSTANT: // is constant - AddImmedOpcode(nameData->value); - incStackPtr(); - return endPtr; - - case NameData::UNIT: // is unit (error if appears here) - break; - - case NameData::FUNC_PTR: // is C++ function - function = CompileFunctionParams - (endPtr, mData->mFuncPtrs[nameData->index].mParams); - //if(!function) return 0; - mData->mByteCode.push_back(cFCall); - PushOpcodeParam(nameData->index); - return function; - - case NameData::PARSER_PTR: // is FunctionParser - function = CompileFunctionParams - (endPtr, mData->mFuncParsers[nameData->index].mParams); - //if(!function) return 0; - mData->mByteCode.push_back(cPCall); - PushOpcodeParam(nameData->index); - return function; - } - - // When it's an unit (or unrecognized type): - return SetErrorType(SYNTAX_ERROR, function); -} - -template -inline const char* FunctionParserBase::CompileFunction -(const char* function, unsigned func_opcode) -{ - SkipSpace(function); - const FuncDefinition& funcDef = Functions[func_opcode]; - - if(func_opcode == cIf) // "if" is a special case - return CompileIf(function); - - unsigned requiredParams = funcDef.params; - - function = CompileFunctionParams(function, requiredParams); - if(!function) return 0; - - if(mData->mUseDegreeConversion) - { - if(funcDef.flags & FuncDefinition::AngleIn) - AddFunctionOpcode(cRad); - - AddFunctionOpcode(func_opcode); - - if(funcDef.flags & FuncDefinition::AngleOut) - AddFunctionOpcode(cDeg); - } - else - { - AddFunctionOpcode(func_opcode); - } - return function; -} - -template -inline const char* -FunctionParserBase::CompileParenthesis(const char* function) -{ - ++function; // Skip '(' - - SkipSpace(function); - if(*function == ')') return SetErrorType(EMPTY_PARENTH, function); - function = CompileExpression(function); - if(!function) return 0; - - if(*function != ')') return SetErrorType(MISSING_PARENTH, function); - ++function; // Skip ')' - - SkipSpace(function); - return function; -} - -template -const char* -FunctionParserBase::CompilePossibleUnit(const char* function) -{ - unsigned nameLength = readIdentifier(function); - if(nameLength & 0x80000000U) return function; // built-in function name - if(nameLength != 0) - { - NamePtr name(function, nameLength); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(name); - if(nameIter != mData->mNamePtrs.end()) - { - const NameData* nameData = &nameIter->second; - if(nameData->type == NameData::UNIT) - { - AddImmedOpcode(nameData->value); - incStackPtr(); - AddFunctionOpcode(cMul); - --mStackPtr; - - const char* endPtr = function + nameLength; - SkipSpace(endPtr); - return endPtr; - } - } - } - - return function; -} - -template -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - function = CompilePossibleUnit(function); - - if(*function == '^') - { - ++function; - SkipSpace(function); - - unsigned op = cPow; - if(mData->mByteCode.back() == cImmed) - { - if(mData->mImmed.back() == fp_const_e()) - { op = cExp; mData->mByteCode.pop_back(); - mData->mImmed.pop_back(); --mStackPtr; } - else if(mData->mImmed.back() == Value_t(2)) - { op = cExp2; mData->mByteCode.pop_back(); - mData->mImmed.pop_back(); --mStackPtr; } - } - - function = CompileUnaryMinus(function); - if(!function) return 0; - - // add opcode - AddFunctionOpcode(op); - - if(op == cPow) --mStackPtr; - } - return function; -} - -/* Currently the power operator is skipped for integral types because its - usefulness with them is questionable, and in the case of GmpInt, for safety - reasons: - - With long int almost any power, except for very small ones, would - overflow the result, so the usefulness of this is rather questionable. - - With GmpInt the power operator could be easily abused to make the program - run out of memory (think of a function like "10^10^10^10^1000000"). -*/ -#ifdef FP_SUPPORT_LONG_INT_TYPE -template<> -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - return CompilePossibleUnit(function); -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - return CompilePossibleUnit(function); -} -#endif - -template -inline const char* -FunctionParserBase::CompileUnaryMinus(const char* function) -{ - char op = *function; - switch(op) - { - case '-': - case '!': - ++function; - SkipSpace(function); - - function = CompileUnaryMinus(function); - if(!function) return 0; - - AddFunctionOpcode(op=='-' ? cNeg : cNot); - - return function; - default: break; - } - return CompilePow(function); -} - -template -inline const char* -FunctionParserBase::CompileMult(const char* function) -{ - function = CompileUnaryMinus(function); - if(!function) return 0; - - Value_t pending_immed(1); - #define FP_FlushImmed(do_reset) \ - if(pending_immed != Value_t(1)) \ - { \ - unsigned op = cMul; \ - if(!IsIntType::result && mData->mByteCode.back() == cInv) \ - { \ - /* (...) cInv 5 cMul -> (...) 5 cRDiv */ \ - /* ^ ^ | */ \ - mData->mByteCode.pop_back(); \ - op = cRDiv; \ - } \ - AddImmedOpcode(pending_immed); \ - incStackPtr(); \ - AddFunctionOpcode(op); \ - --mStackPtr; \ - if(do_reset) pending_immed = Value_t(1); \ - } - while(true) - { - char c = *function; - if(c == '%') - { - FP_FlushImmed(true); - ++function; - SkipSpace(function); - function = CompileUnaryMinus(function); - if(!function) return 0; - AddFunctionOpcode(cMod); - --mStackPtr; - continue; - } - if(c != '*' && c != '/') break; - - bool safe_cumulation = (c == '*' || !IsIntType::result); - if(!safe_cumulation) - { - FP_FlushImmed(true); - } - - ++function; - SkipSpace(function); - if(mData->mByteCode.back() == cImmed - && (safe_cumulation - || mData->mImmed.back() == Value_t(1))) - { - // 5 (...) cMul --> (...) ||| 5 cMul - // 5 (...) cDiv --> (...) cInv ||| 5 cMul - // ^ | ^ - pending_immed *= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - --mStackPtr; - function = CompileUnaryMinus(function); - if(!function) return 0; - if(c == '/') - AddFunctionOpcode(cInv); - continue; - } - if(safe_cumulation - && mData->mByteCode.back() == cMul - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) 5 cMul (...) cMul -> (:::) (...) cMul ||| 5 cMul - // (:::) 5 cMul (...) cDiv -> (:::) (...) cDiv ||| 5 cMul - // ^ ^ - pending_immed *= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - // cDiv is not tested here because the bytecode - // optimizer will convert this kind of cDivs into cMuls. - bool lhs_inverted = false; - if(!IsIntType::result && c == '*' - && mData->mByteCode.back() == cInv) - { - // (:::) cInv (...) cMul -> (:::) (...) cRDiv - // (:::) cInv (...) cDiv -> (:::) (...) cMul cInv - // ^ ^ | - mData->mByteCode.pop_back(); - lhs_inverted = true; - } - function = CompileUnaryMinus(function); - if(!function) return 0; - if(safe_cumulation - && mData->mByteCode.back() == cMul - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cMul cMul -> (:::) (...) cMul ||| 5 Mul - // (:::) (...) 5 cMul cDiv -> (:::) (...) cDiv ||| /5 Mul - // ^ ^ - if(c == '*') - pending_immed *= mData->mImmed.back(); - else - pending_immed /= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - else - if(safe_cumulation - && mData->mByteCode.back() == cRDiv - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cRDiv cMul -> (:::) (...) cDiv ||| 5 cMul - // (:::) (...) 5 cRDiv cDiv -> (:::) (...) cMul ||| /5 cMul - // ^ ^ - if(c == '*') - { c = '/'; pending_immed *= mData->mImmed.back(); } - else - { c = '*'; pending_immed /= mData->mImmed.back(); } - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - if(!lhs_inverted) // if (/x/y) was changed to /(x*y), add missing cInv - { - AddFunctionOpcode(c == '*' ? cMul : cDiv); - --mStackPtr; - } - else if(c == '*') // (/x)*y -> rdiv(x,y) - { - AddFunctionOpcode(cRDiv); - --mStackPtr; - } - else // (/x)/y -> /(x*y) - { - AddFunctionOpcode(cMul); - --mStackPtr; - AddFunctionOpcode(cInv); - } - } - FP_FlushImmed(false); - #undef FP_FlushImmed - return function; -} - -template -inline const char* -FunctionParserBase::CompileAddition(const char* function) -{ - function = CompileMult(function); - if(!function) return 0; - - Value_t pending_immed(0); - #define FP_FlushImmed(do_reset) \ - if(pending_immed != Value_t(0)) \ - { \ - unsigned op = cAdd; \ - if(mData->mByteCode.back() == cNeg) \ - { \ - /* (...) cNeg 5 cAdd -> (...) 5 cRSub */ \ - /* ^ ^ | */ \ - mData->mByteCode.pop_back(); \ - op = cRSub; \ - } \ - AddImmedOpcode(pending_immed); \ - incStackPtr(); \ - AddFunctionOpcode(op); \ - --mStackPtr; \ - if(do_reset) pending_immed = Value_t(0); \ - } - while(true) - { - char c = *function; - if(c != '+' && c != '-') break; - ++function; - SkipSpace(function); - if(mData->mByteCode.back() == cImmed) - { - // 5 (...) cAdd --> (...) ||| 5 cAdd - // 5 (...) cSub --> (...) cNeg ||| 5 cAdd - // ^ | ^ - pending_immed += mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - --mStackPtr; - function = CompileMult(function); - if(!function) return 0; - if(c == '-') - AddFunctionOpcode(cNeg); - continue; - } - if(mData->mByteCode.back() == cAdd - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) 5 cAdd (...) cAdd -> (:::) (...) cAdd ||| 5 cAdd - // (:::) 5 cAdd (...) cSub -> (:::) (...) cSub ||| 5 cAdd - // ^ ^ - pending_immed += mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - // cSub is not tested here because the bytecode - // optimizer will convert this kind of cSubs into cAdds. - bool lhs_negated = false; - if(mData->mByteCode.back() == cNeg) - { - // (:::) cNeg (...) cAdd -> (:::) (...) cRSub - // (:::) cNeg (...) cSub -> (:::) (...) cAdd cNeg - // ^ ^ | - mData->mByteCode.pop_back(); - lhs_negated = true; - } - function = CompileMult(function); - if(!function) return 0; - if(mData->mByteCode.back() == cAdd - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cAdd cAdd -> (:::) (...) cAdd ||| 5 Add - // (:::) (...) 5 cAdd cSub -> (:::) (...) cSub ||| -5 Add - // ^ ^ - if(c == '+') - pending_immed += mData->mImmed.back(); - else - pending_immed -= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - else - if(mData->mByteCode.back() == cRSub - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cRSub cAdd -> (:::) (...) cSub ||| 5 cAdd - // (:::) (...) 5 cRSub cSub -> (:::) (...) cAdd ||| -5 cAdd - // ^ ^ - if(c == '+') - { c = '-'; pending_immed += mData->mImmed.back(); } - else - { c = '+'; pending_immed -= mData->mImmed.back(); } - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - if(!lhs_negated) // if (-x-y) was changed to -(x+y), add missing cNeg - { - AddFunctionOpcode(c == '+' ? cAdd : cSub); - --mStackPtr; - } - else if(c == '+') // (-x)+y -> rsub(x,y) - { - AddFunctionOpcode(cRSub); - --mStackPtr; - } - else // (-x)-y -> -(x+y) - { - AddFunctionOpcode(cAdd); - --mStackPtr; - AddFunctionOpcode(cNeg); - } - } - FP_FlushImmed(false); - #undef FP_FlushImmed - return function; -} - -template -inline const char* -FunctionParserBase::CompileComparison(const char* function) -{ - unsigned op=0; - while(true) - { - function = CompileAddition(function); - if(!function) return 0; - - if(op) - { - AddFunctionOpcode(op); - --mStackPtr; - } - switch(*function) - { - case '=': - ++function; op = cEqual; break; - case '!': - if(function[1] == '=') - { function += 2; op = cNEqual; break; } - // If '=' does not follow '!', a syntax error will - // be generated at the outermost parsing level - return function; - case '<': - if(function[1] == '=') - { function += 2; op = cLessOrEq; break; } - ++function; op = cLess; break; - case '>': - if(function[1] == '=') - { function += 2; op = cGreaterOrEq; break; } - ++function; op = cGreater; break; - default: return function; - } - SkipSpace(function); - } - return function; -} - -template -inline const char* FunctionParserBase::CompileAnd(const char* function) -{ - std::size_t param0end=0; - while(true) - { - function = CompileComparison(function); - if(!function) return 0; - - if(param0end) - { - if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back(); - - AddFunctionOpcode(cAnd); - --mStackPtr; - } - if(*function != '&') break; - ++function; - SkipSpace(function); - param0end = mData->mByteCode.size(); - } - return function; -} - -template -const char* FunctionParserBase::CompileExpression(const char* function) -{ - std::size_t param0end=0; - while(true) - { - SkipSpace(function); - function = CompileAnd(function); - if(!function) return 0; - - if(param0end) - { - if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back(); - - AddFunctionOpcode(cOr); - --mStackPtr; - } - if(*function != '|') break; - ++function; - param0end = mData->mByteCode.size(); - } - return function; -} - -template -const char* FunctionParserBase::Compile(const char* function) -{ - while(true) - { - // Check if an identifier appears as first token: - SkipSpace(function); - unsigned nameLength = readIdentifier(function); - if(nameLength > 0 && !(nameLength & 0x80000000U)) - { - typename Data::InlineVariable inlineVar = - { NamePtr(function, nameLength), 0 }; - - // Check if it's an unknown identifier: - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(inlineVar.mName); - if(nameIter == mData->mNamePtrs.end()) - { - const char* function2 = function + nameLength; - SkipSpace(function2); - - // Check if ":=" follows the unknown identifier: - if(function2[0] == ':' && function2[1] == '=') - { - // Parse the expression that follows and create the - // inline variable: - function2 = CompileExpression(function2 + 2); - if(!function2) return 0; - if(*function2 != ';') return function2; - - inlineVar.mFetchIndex = mStackPtr - 1; - mData->mInlineVarNames.push_back(inlineVar); - - // Continue with the expression after the ';': - function = function2 + 1; - continue; - } - } - } - break; - } - - return CompileExpression(function); -} - -template template -inline void FunctionParserBase::PushOpcodeParam - (unsigned value) -{ - mData->mByteCode.push_back(value | (PutFlag ? FP_ParamGuardMask : 0u)); - if(PutFlag) mData->mHasByteCodeFlags = true; -} - -template template -inline void FunctionParserBase::PutOpcodeParamAt - (unsigned value, unsigned offset) -{ - mData->mByteCode[offset] = value | (PutFlag ? FP_ParamGuardMask : 0u); - if(PutFlag) mData->mHasByteCodeFlags = true; -} - -//=========================================================================== -// Function evaluation -//=========================================================================== -template -Value_t FunctionParserBase::Eval(const Value_t* Vars) -{ - if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0); - - const unsigned* const byteCode = &(mData->mByteCode[0]); - const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]); - const unsigned byteCodeSize = unsigned(mData->mByteCode.size()); - unsigned IP, DP=0; - int SP=-1; - -#ifdef FP_USE_THREAD_SAFE_EVAL - /* If Eval() may be called by multiple threads simultaneously, - * then Eval() must allocate its own stack. - */ -#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA - /* alloca() allocates room from the hardware stack. - * It is automatically freed when the function returns. - */ - Value_t* const Stack = (Value_t*)alloca(mData->mStackSize*sizeof(Value_t)); -#else - /* Allocate from the heap. Ensure that it is freed - * automatically no matter which exit path is taken. - */ - struct AutoDealloc - { - Value_t* ptr; - ~AutoDealloc() { delete[] ptr; } - } AutoDeallocStack = { new Value_t[mData->mStackSize] }; - Value_t*& Stack = AutoDeallocStack.ptr; -#endif -#else - /* No thread safety, so use a global stack. */ - std::vector& Stack = mData->mStack; -#endif - - for(IP=0; IP::result == false - && (Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_acos(Stack[SP]); break; - - case cAcosh: - if(IsComplexType::result == false - && Stack[SP] < Value_t(1)) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_acosh(Stack[SP]); break; - - case cAsin: - if(IsComplexType::result == false - && (Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_asin(Stack[SP]); break; - - case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break; - - case cAtan: Stack[SP] = fp_atan(Stack[SP]); break; - - case cAtan2: Stack[SP-1] = fp_atan2(Stack[SP-1], Stack[SP]); - --SP; break; - - case cAtanh: - if(IsComplexType::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); } - Stack[SP] = fp_atanh(Stack[SP]); break; - - case cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break; - - case cCeil: Stack[SP] = fp_ceil(Stack[SP]); break; - - case cCos: Stack[SP] = fp_cos(Stack[SP]); break; - - case cCosh: Stack[SP] = fp_cosh(Stack[SP]); break; - - case cCot: - { - const Value_t t = fp_tan(Stack[SP]); - if(t == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/t; break; - } - - case cCsc: - { - const Value_t s = fp_sin(Stack[SP]); - if(s == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/s; break; - } - - - case cExp: Stack[SP] = fp_exp(Stack[SP]); break; - - case cExp2: Stack[SP] = fp_exp2(Stack[SP]); break; - - case cFloor: Stack[SP] = fp_floor(Stack[SP]); break; - - case cHypot: - Stack[SP-1] = fp_hypot(Stack[SP-1], Stack[SP]); - --SP; break; - - case cIf: - if(fp_truth(Stack[SP--])) - IP += 2; - else - { - const unsigned* buf = &byteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - } - break; - - case cInt: Stack[SP] = fp_int(Stack[SP]); break; - - case cLog: - if(IsComplexType::result - ? Stack[SP] == Value_t(0) - : !(Stack[SP] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP] = fp_log(Stack[SP]); break; - - case cLog10: - if(IsComplexType::result - ? Stack[SP] == Value_t(0) - : !(Stack[SP] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP] = fp_log10(Stack[SP]); - break; - - case cLog2: - if(IsComplexType::result - ? Stack[SP] == Value_t(0) - : !(Stack[SP] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP] = fp_log2(Stack[SP]); - break; - - case cMax: Stack[SP-1] = fp_max(Stack[SP-1], Stack[SP]); - --SP; break; - - case cMin: Stack[SP-1] = fp_min(Stack[SP-1], Stack[SP]); - --SP; break; - - case cPow: - // x:Negative ^ y:NonInteger is failure, - // except when the reciprocal of y forms an integer - /*if(IsComplexType::result == false - && Stack[SP-1] < Value_t(0) && - !isInteger(Stack[SP]) && - !isInteger(1.0 / Stack[SP])) - { mEvalErrorType=3; return Value_t(0); }*/ - // x:0 ^ y:negative is failure - if(Stack[SP-1] == Value_t(0) && - Stack[SP] < Value_t(0)) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]); - --SP; break; - - case cTrunc: Stack[SP] = fp_trunc(Stack[SP]); break; - - case cSec: - { - const Value_t c = fp_cos(Stack[SP]); - if(c == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/c; break; - } - - case cSin: Stack[SP] = fp_sin(Stack[SP]); break; - - case cSinh: Stack[SP] = fp_sinh(Stack[SP]); break; - - case cSqrt: - if(IsComplexType::result == false && - Stack[SP] < Value_t(0)) - { mData->mEvalErrorType=2; return Value_t(0); } - Stack[SP] = fp_sqrt(Stack[SP]); break; - - case cTan: Stack[SP] = fp_tan(Stack[SP]); break; - - case cTanh: Stack[SP] = fp_tanh(Stack[SP]); break; - - -// Misc: - case cImmed: Stack[++SP] = immed[DP++]; break; - - case cJump: - { - const unsigned* buf = &byteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - break; - } - -// Operators: - case cNeg: Stack[SP] = -Stack[SP]; break; - case cAdd: Stack[SP-1] += Stack[SP]; --SP; break; - case cSub: Stack[SP-1] -= Stack[SP]; --SP; break; - case cMul: Stack[SP-1] *= Stack[SP]; --SP; break; - - case cDiv: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP-1] /= Stack[SP]; --SP; break; - - case cMod: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP-1] = fp_mod(Stack[SP-1], Stack[SP]); - --SP; break; - - case cEqual: - Stack[SP-1] = fp_equal(Stack[SP-1], Stack[SP]); - --SP; break; - - case cNEqual: - Stack[SP-1] = fp_nequal(Stack[SP-1], Stack[SP]); - --SP; break; - - case cLess: - Stack[SP-1] = fp_less(Stack[SP-1], Stack[SP]); - --SP; break; - - case cLessOrEq: - Stack[SP-1] = fp_lessOrEq(Stack[SP-1], Stack[SP]); - --SP; break; - - case cGreater: - Stack[SP-1] = fp_less(Stack[SP], Stack[SP-1]); - --SP; break; - - case cGreaterOrEq: - Stack[SP-1] = fp_lessOrEq(Stack[SP], Stack[SP-1]); - --SP; break; - - case cNot: Stack[SP] = fp_not(Stack[SP]); break; - - case cNotNot: Stack[SP] = fp_notNot(Stack[SP]); break; - - case cAnd: - Stack[SP-1] = fp_and(Stack[SP-1], Stack[SP]); - --SP; break; - - case cOr: - Stack[SP-1] = fp_or(Stack[SP-1], Stack[SP]); - --SP; break; - -// Degrees-radians conversion: - case cDeg: Stack[SP] = RadiansToDegrees(Stack[SP]); break; - case cRad: Stack[SP] = DegreesToRadians(Stack[SP]); break; - -// User-defined function calls: - case cFCall: - { - const unsigned index = byteCode[++IP]; - const unsigned params = mData->mFuncPtrs[index].mParams; - const Value_t retVal = - mData->mFuncPtrs[index].mRawFuncPtr ? - mData->mFuncPtrs[index].mRawFuncPtr(&Stack[SP-params+1]) : - mData->mFuncPtrs[index].mFuncWrapperPtr->callFunction - (&Stack[SP-params+1]); - SP -= int(params)-1; - Stack[SP] = retVal; - break; - } - - case cPCall: - { - unsigned index = byteCode[++IP]; - unsigned params = mData->mFuncParsers[index].mParams; - Value_t retVal = - mData->mFuncParsers[index].mParserPtr->Eval - (&Stack[SP-params+1]); - SP -= int(params)-1; - Stack[SP] = retVal; - const int error = - mData->mFuncParsers[index].mParserPtr->EvalError(); - if(error) - { - mData->mEvalErrorType = error; - return 0; - } - break; - } - - - case cFetch: - { - unsigned stackOffs = byteCode[++IP]; - Stack[SP+1] = Stack[stackOffs]; ++SP; - break; - } - -#ifdef FP_SUPPORT_OPTIMIZER - case cPopNMov: - { - unsigned stackOffs_target = byteCode[++IP]; - unsigned stackOffs_source = byteCode[++IP]; - Stack[stackOffs_target] = Stack[stackOffs_source]; - SP = stackOffs_target; - break; - } - - case cLog2by: - if(IsComplexType::result - ? Stack[SP-1] == Value_t(0) - : !(Stack[SP-1] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP]; - --SP; - break; - - case cNop: break; -#endif // FP_SUPPORT_OPTIMIZER - - case cSinCos: - fp_sinCos(Stack[SP], Stack[SP+1], Stack[SP]); - ++SP; - break; - case cSinhCosh: - fp_sinhCosh(Stack[SP], Stack[SP+1], Stack[SP]); - ++SP; - break; - - case cAbsNot: - Stack[SP] = fp_absNot(Stack[SP]); break; - case cAbsNotNot: - Stack[SP] = fp_absNotNot(Stack[SP]); break; - case cAbsAnd: - Stack[SP-1] = fp_absAnd(Stack[SP-1], Stack[SP]); - --SP; break; - case cAbsOr: - Stack[SP-1] = fp_absOr(Stack[SP-1], Stack[SP]); - --SP; break; - case cAbsIf: - if(fp_absTruth(Stack[SP--])) - IP += 2; - else - { - const unsigned* buf = &byteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - } - break; - - case cDup: Stack[SP+1] = Stack[SP]; ++SP; break; - - case cInv: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/Stack[SP]; - break; - - case cSqr: - Stack[SP] = Stack[SP]*Stack[SP]; - break; - - case cRDiv: - if(Stack[SP-1] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break; - - case cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break; - - case cRSqrt: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1) / fp_sqrt(Stack[SP]); break; - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - case cReal: Stack[SP] = fp_real(Stack[SP]); break; - case cImag: Stack[SP] = fp_imag(Stack[SP]); break; - case cArg: Stack[SP] = fp_arg(Stack[SP]); break; - case cConj: Stack[SP] = fp_conj(Stack[SP]); break; - case cPolar: - Stack[SP-1] = fp_polar(Stack[SP-1], Stack[SP]); - --SP; break; -#endif - - -// Variables: - default: - Stack[++SP] = Vars[byteCode[IP]-VarBegin]; - } - } - - mData->mEvalErrorType=0; - return Stack[SP]; -} - - -//=========================================================================== -// Variable deduction -//=========================================================================== -namespace -{ - template - int deduceVariables(FunctionParserBase& fParser, - const char* funcStr, - std::string& destVarString, - int* amountOfVariablesFound, - std::vector* destVarNames, - bool useDegrees) - { - typedef std::set StrSet; - StrSet varNames; - - int oldIndex = -1; - - while(true) - { - destVarString.clear(); - for(StrSet::iterator iter = varNames.begin(); - iter != varNames.end(); - ++iter) - { - if(iter != varNames.begin()) destVarString += ","; - destVarString += *iter; - } - - const int index = - fParser.Parse(funcStr, destVarString, useDegrees); - if(index < 0) break; - if(index == oldIndex) return index; - - unsigned nameLength = readIdentifier(funcStr + index); - if(nameLength & 0x80000000U) return index; - if(nameLength == 0) return index; - - varNames.insert(std::string(funcStr + index, nameLength)); - oldIndex = index; - } - - if(amountOfVariablesFound) - *amountOfVariablesFound = int(varNames.size()); - - if(destVarNames) - destVarNames->assign(varNames.begin(), varNames.end()); - - return -1; - } -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - int* amountOfVariablesFound, - bool useDegrees) -{ - std::string varString; - return deduceVariables(*this, function.c_str(), varString, - amountOfVariablesFound, 0, useDegrees); -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - std::string& resultVarString, - int* amountOfVariablesFound, - bool useDegrees) -{ - std::string varString; - const int index = - deduceVariables(*this, function.c_str(), varString, - amountOfVariablesFound, 0, useDegrees); - if(index < 0) resultVarString = varString; - return index; -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - std::vector& resultVars, - bool useDegrees) -{ - std::string varString; - std::vector vars; - const int index = - deduceVariables(*this, function.c_str(), varString, - 0, &vars, useDegrees); - if(index < 0) resultVars.swap(vars); - return index; -} - - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -//=========================================================================== -// Bytecode injection -//=========================================================================== -template -void FunctionParserBase::InjectRawByteCode -(const unsigned* bytecode, unsigned bytecodeAmount, - const Value_t* immed, unsigned immedAmount, unsigned stackSize) -{ - CopyOnWrite(); - - mData->mByteCode.assign(bytecode, bytecode + bytecodeAmount); - mData->mImmed.assign(immed, immed + immedAmount); - mData->mStackSize = stackSize; - -#ifndef FP_USE_THREAD_SAFE_EVAL - mData->mStack.resize(stackSize); -#endif -} - -//=========================================================================== -// Debug output -//=========================================================================== -#include -#include -namespace -{ - inline void printHex(std::ostream& dest, unsigned n) - { - std::ios::fmtflags flags = dest.flags(); - dest.width(4); dest.fill('0'); std::hex(dest); //uppercase(dest); - dest << n; - dest.flags(flags); - } - - void padLine(std::ostringstream& dest, unsigned destLength) - { - for(std::size_t currentLength = dest.str().length(); - currentLength < destLength; - ++currentLength) - { - dest << ' '; - } - } - - const struct PowiMuliType - { - unsigned opcode_square; - unsigned opcode_cumulate; - unsigned opcode_invert; - unsigned opcode_half; - unsigned opcode_invhalf; - } iseq_powi = {cSqr,cMul,cInv,cSqrt,cRSqrt}, - iseq_muli = {~unsigned(0), cAdd,cNeg, ~unsigned(0),~unsigned(0) }; - - template - Value_t ParsePowiMuli( - const PowiMuliType& opcodes, - const std::vector& ByteCode, unsigned& IP, - unsigned limit, - std::size_t factor_stack_base, - std::vector& stack, - bool IgnoreExcess) - { - Value_t result = Value_t(1); - while(IP < limit) - { - if(ByteCode[IP] == opcodes.opcode_square) - { - if(!isInteger(result)) break; - result *= Value_t(2); - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invert) - { - if(result < Value_t(0)) break; - result = -result; - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_half) - { - if(result > Value_t(0) && isEvenInteger(result)) - break; - if(isInteger(result * Value_t(0.5))) break; - result *= Value_t(0.5); - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invhalf) - { - if(result > Value_t(0) && isEvenInteger(result)) - break; - if(isInteger(result * Value_t(-0.5))) break; - result *= Value_t(-0.5); - ++IP; - continue; - } - - unsigned dup_fetch_pos = IP; - Value_t lhs = Value_t(1); - - if(ByteCode[IP] == cFetch) - { - unsigned index = ByteCode[++IP]; - if(index < factor_stack_base - || std::size_t(index-factor_stack_base) >= stack.size()) - { - // It wasn't a powi-fetch after all - IP = dup_fetch_pos; - break; - } - lhs = stack[index - factor_stack_base]; - // Note: ^This assumes that cFetch of recentmost - // is always converted into cDup. - goto dup_or_fetch; - } - - if(ByteCode[IP] == cDup) - { - lhs = result; - goto dup_or_fetch; - - dup_or_fetch: - stack.push_back(result); - ++IP; - Value_t subexponent = ParsePowiMuli - (opcodes, - ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - if(IP >= limit && IgnoreExcess) - return lhs*subexponent; - if(IP >= limit || ByteCode[IP] != opcodes.opcode_cumulate) - { - // It wasn't a powi-dup after all - IP = dup_fetch_pos; - break; - } - ++IP; // skip opcode_cumulate - stack.pop_back(); - result += lhs*subexponent; - continue; - } - break; - } - return result; - } - - template - Value_t ParsePowiSequence(const std::vector& ByteCode, - unsigned& IP, unsigned limit, - std::size_t factor_stack_base, - bool IgnoreExcess = false) - { - std::vector stack; - stack.push_back(Value_t(1)); - return ParsePowiMuli(iseq_powi, ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - } - - template - Value_t ParseMuliSequence(const std::vector& ByteCode, - unsigned& IP, unsigned limit, - std::size_t factor_stack_base, - bool IgnoreExcess = false) - { - std::vector stack; - stack.push_back(Value_t(1)); - return ParsePowiMuli(iseq_muli, ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - } - - struct IfInfo - { - std::pair condition; - std::pair thenbranch; - unsigned endif_location; - - IfInfo() : condition(), thenbranch(), endif_location() { } - }; -} - -template -void FunctionParserBase::PrintByteCode(std::ostream& dest, - bool showExpression) const -{ - dest << "Size of stack: " << mData->mStackSize << "\n"; - - std::ostringstream outputBuffer; - std::ostream& output = (showExpression ? outputBuffer : dest); - - const std::vector& ByteCode = mData->mByteCode; - const std::vector& Immed = mData->mImmed; - - std::vector > stack; - std::vector if_stack; - - for(unsigned IP = 0, DP = 0; IP <= ByteCode.size(); ++IP) - { - after_powi_or_muli:; - std::string n; - bool out_params = false; - unsigned params = 2, produces = 1, opcode = 0; - - if(showExpression && !if_stack.empty() && - ( // Normal If termination rule: - if_stack.back().endif_location == IP - // This rule matches when cJumps are threaded: - || (IP < ByteCode.size() && ByteCode[IP] == cJump - && !if_stack.back().thenbranch.second.empty()) - )) - { - printHex(output, IP); - if(if_stack.back().endif_location == IP) - output << ": ----- (phi)"; - else - output << ": ----- (phi+)"; - - stack.resize(stack.size()+2); - std::swap(stack[stack.size()-3], stack[stack.size()-1]); - std::swap(if_stack.back().condition, stack[stack.size()-3]); - std::swap(if_stack.back().thenbranch, stack[stack.size()-2]); - opcode = cIf; - params = 3; - --IP; - if_stack.pop_back(); - } - else - { - if(IP >= ByteCode.size()) break; - opcode = ByteCode[IP]; - - if(showExpression && ( - opcode == cSqr || opcode == cDup - || opcode == cInv - || opcode == cSqrt || opcode == cRSqrt - || opcode == cFetch - )) - { - unsigned changed_ip = IP; - Value_t exponent = - ParsePowiSequence - (ByteCode, changed_ip, - if_stack.empty() - ? (unsigned)ByteCode.size() - : if_stack.back().endif_location, - stack.size()-1); - std::string operation_prefix; - std::ostringstream operation_value; - int prio = 0; - if(exponent == Value_t(1.0)) - { - if(opcode != cDup) goto not_powi_or_muli; - Value_t factor = - ParseMuliSequence - (ByteCode, changed_ip, - if_stack.empty() - ? (unsigned)ByteCode.size() - : if_stack.back().endif_location, - stack.size()-1); - if(factor == Value_t(1) || factor == Value_t(-1)) - goto not_powi_or_muli; - operation_prefix = "*"; - operation_value << factor; - prio = 3; - } - else - { - prio = 2; - operation_prefix = "^"; - operation_value << exponent; - } - - //unsigned explanation_before = changed_ip-2; - unsigned explanation_before = changed_ip-1; - - const char* explanation_prefix = "_"; - for(const unsigned first_ip = IP; IP < changed_ip; ++IP) - { - printHex(output, IP); - output << ": "; - - const char* sep = "|"; - if(first_ip+1 == changed_ip) - { sep = "="; explanation_prefix = " "; } - else if(IP == first_ip) sep = "\\"; - else if(IP+1 == changed_ip) sep = "/"; - else explanation_prefix = "="; - - switch(ByteCode[IP]) - { - case cInv: output << "inv"; break; - case cNeg: output << "neg"; break; - case cDup: output << "dup"; break; - case cSqr: output << "sqr"; break; - case cMul: output << "mul"; break; - case cAdd: output << "add"; break; - case cCbrt: output << "cbrt"; break; - case cSqrt: output << "sqrt"; break; - case cRSqrt: output << "rsqrt"; break; - case cFetch: - { - unsigned index = ByteCode[++IP]; - output << "cFetch(" << index << ")"; - break; - } - default: break; - } - padLine(outputBuffer, 20); - output << sep; - if(IP >= explanation_before) - { - explanation_before = (unsigned)ByteCode.size(); - output << explanation_prefix - << '[' << (stack.size()-1) << ']'; - std::string last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - output << last; - output << operation_prefix; - output << operation_value.str(); - } - else - { - unsigned p = first_ip; - Value_t exp = operation_prefix=="^" ? - ParsePowiSequence - (ByteCode, p, IP+1, stack.size()-1, true) : - ParseMuliSequence - (ByteCode, p, IP+1, stack.size()-1, true); - std::string last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - output << " ..." << last; - output << operation_prefix; - output << exp; - } - dest << outputBuffer.str() << std::endl; - outputBuffer.str(""); - } - - std::string& last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - last += operation_prefix; - last += operation_value.str(); - stack.back().first = prio; - - goto after_powi_or_muli; - } - not_powi_or_muli:; - printHex(output, IP); - output << ": "; - - switch(opcode) - { - case cIf: - { - unsigned label = ByteCode[IP+1]+1; - output << "jz "; - printHex(output, label); - params = 1; - produces = 0; - IP += 2; - - if_stack.resize(if_stack.size() + 1); - std::swap( if_stack.back().condition, stack.back() ); - if_stack.back().endif_location = (unsigned) ByteCode.size(); - stack.pop_back(); - break; - } - case cAbsIf: - { - unsigned dp = ByteCode[IP+2]; - unsigned label = ByteCode[IP+1]+1; - output << "jz_abs " << dp << ","; - printHex(output, label); - params = 1; - produces = 0; - IP += 2; - - if_stack.resize(if_stack.size() + 1); - std::swap( if_stack.back().condition, stack.back() ); - if_stack.back().endif_location = (unsigned) ByteCode.size(); - stack.pop_back(); - break; - } - - case cJump: - { - unsigned dp = ByteCode[IP+2]; - unsigned label = ByteCode[IP+1]+1; - - if(!if_stack.empty() && !stack.empty()) - { - std::swap(if_stack.back().thenbranch, stack.back()); - if_stack.back().endif_location = label; - stack.pop_back(); - } - - output << "jump " << dp << ","; - printHex(output, label); - params = 0; - produces = 0; - IP += 2; - break; - } - case cImmed: - { - if(showExpression) - { - std::ostringstream buf; - buf.precision(8); - buf << Immed[DP]; - stack.push_back( std::make_pair(0, buf.str()) ); - } - output.precision(8); - output << "push " << Immed[DP]; - ++DP; - produces = 0; - break; - } - - case cFCall: - { - const unsigned index = ByteCode[++IP]; - params = mData->mFuncPtrs[index].mParams; - static std::string name; - name = "f:" + findName(mData->mNamePtrs, index, - NameData::FUNC_PTR); - n = name.c_str(); - out_params = true; - break; - } - - case cPCall: - { - const unsigned index = ByteCode[++IP]; - params = mData->mFuncParsers[index].mParams; - static std::string name; - name = "p:" + findName(mData->mNamePtrs, index, - NameData::PARSER_PTR); - n = name.c_str(); - out_params = true; - break; - } - - default: - if(IsVarOpcode(opcode)) - { - if(showExpression) - { - stack.push_back(std::make_pair(0, - (findName(mData->mNamePtrs, opcode, - NameData::VARIABLE)))); - } - output << "push Var" << opcode-VarBegin; - produces = 0; - } - else - { - switch(OPCODE(opcode)) - { - case cNeg: n = "neg"; params = 1; break; - case cAdd: n = "add"; break; - case cSub: n = "sub"; break; - case cMul: n = "mul"; break; - case cDiv: n = "div"; break; - case cMod: n = "mod"; break; - case cPow: n = "pow"; break; - case cEqual: n = "eq"; break; - case cNEqual: n = "neq"; break; - case cLess: n = "lt"; break; - case cLessOrEq: n = "le"; break; - case cGreater: n = "gt"; break; - case cGreaterOrEq: n = "ge"; break; - case cAnd: n = "and"; break; - case cOr: n = "or"; break; - case cNot: n = "not"; params = 1; break; - case cNotNot: n = "notnot"; params = 1; break; - case cDeg: n = "deg"; params = 1; break; - case cRad: n = "rad"; params = 1; break; - - case cFetch: - { - unsigned index = ByteCode[++IP]; - if(showExpression && index < stack.size()) - stack.push_back(stack[index]); - output << "cFetch(" << index << ")"; - produces = 0; - break; - } - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by: n = "log2by"; params = 2; out_params = 1; break; - case cPopNMov: - { - std::size_t a = ByteCode[++IP]; - std::size_t b = ByteCode[++IP]; - if(showExpression && b < stack.size()) - { - std::pair stacktop(0, "?"); - if(b < stack.size()) stacktop = stack[b]; - stack.resize(a); - stack.push_back(stacktop); - } - output << "cPopNMov(" << a << ", " << b << ")"; - produces = 0; - break; - } - case cNop: - output << "nop"; params = 0; produces = 0; - break; - #endif - case cSinCos: - { - if(showExpression) - { - std::pair sin = stack.back(); - std::pair cos( - 0, "cos(" + sin.second + ")"); - sin.first = 0; - sin.second = "sin(" + sin.second + ")"; - stack.back() = sin; - stack.push_back(cos); - } - output << "sincos"; - produces = 0; - break; - } - case cSinhCosh: - { - if(showExpression) - { - std::pair sinh = stack.back(); - std::pair cosh( - 0, "cosh(" + sinh.second + ")"); - sinh.first = 0; - sinh.second = "sinh(" + sinh.second + ")"; - stack.back() = sinh; - stack.push_back(cosh); - } - output << "sinhcosh"; - produces = 0; - break; - } - case cAbsAnd: n = "abs_and"; break; - case cAbsOr: n = "abs_or"; break; - case cAbsNot: n = "abs_not"; params = 1; break; - case cAbsNotNot: n = "abs_notnot"; params = 1; break; - case cDup: - { - if(showExpression) - stack.push_back(stack.back()); - output << "dup"; - produces = 0; - break; - } - case cInv: n = "inv"; params = 1; break; - case cSqr: n = "sqr"; params = 1; break; - case cRDiv: n = "rdiv"; break; - case cRSub: n = "rsub"; break; - case cRSqrt: n = "rsqrt"; params = 1; break; - - default: - n = Functions[opcode-cAbs].name; - params = Functions[opcode-cAbs].params; - out_params = params != 1; - } - } - } - } - if(produces) output << n; - if(out_params) output << " (" << params << ")"; - if(showExpression) - { - padLine(outputBuffer, 20); - - if(produces > 0) - { - std::ostringstream buf; - const char *paramsep = ",", *suff = ""; - int prio = 0; bool commutative = false; - switch(opcode) - { - case cIf: buf << "if("; suff = ")"; - break; - case cAbsIf: buf << "if("; suff = ")"; - break; - case cOr: prio = 6; paramsep = "|"; commutative = true; - break; - case cAnd: prio = 5; paramsep = "&"; commutative = true; - break; - case cAdd: prio = 4; paramsep = "+"; commutative = true; - break; - case cSub: prio = 4; paramsep = "-"; - break; - case cMul: prio = 3; paramsep = "*"; commutative = true; - break; - case cDiv: prio = 3; paramsep = "/"; - break; - case cPow: prio = 2; paramsep = "^"; - break; - case cAbsOr: prio = 6; paramsep = "|"; commutative = true; - break; - case cAbsAnd: prio = 5; paramsep = "&"; commutative = true; - break; - case cSqr: prio = 2; suff = "^2"; - break; - case cNeg: buf << "(-("; suff = "))"; - break; - case cNot: buf << "(!("; suff = "))"; - break; - default: buf << n << '('; suff = ")"; - } - - const char* sep = ""; - for(unsigned a=0; a& prev = - stack[stack.size() - params + a]; - if(prio > 0 && (prev.first > prio || - (prev.first==prio && !commutative))) - buf << '(' << prev.second << ')'; - else - buf << prev.second; - } - sep = paramsep; - } - if(stack.size() >= params) - stack.resize(stack.size() - params); - else - stack.clear(); - buf << suff; - stack.push_back(std::make_pair(prio, buf.str())); - //if(n.size() <= 4 && !out_params) padLine(outputBuffer, 20); - } - //padLine(outputBuffer, 20); - output << "= "; - if(((opcode == cIf || opcode == cAbsIf) && params != 3) - || opcode == cJump - #ifdef FP_SUPPORT_OPTIMIZER - || opcode == cNop - #endif - ) - output << "(void)"; - else if(stack.empty()) - output << "[?] ?"; - else - output << '[' << (stack.size()-1) << ']' - << stack.back().second; - } - - if(showExpression) - { - dest << outputBuffer.str() << std::endl; - outputBuffer.str(""); - } - else - output << std::endl; - } - dest << std::flush; -} -#endif - - -#ifndef FP_SUPPORT_OPTIMIZER -template -void FunctionParserBase::Optimize() -{ - // Do nothing if no optimizations are supported. -} -#endif - -FUNCTIONPARSER_INSTANTIATE_TYPES diff --git a/deal.II/contrib/functionparser/fparser.hh b/deal.II/contrib/functionparser/fparser.hh deleted file mode 100644 index b2959a81d3..0000000000 --- a/deal.II/contrib/functionparser/fparser.hh +++ /dev/null @@ -1,224 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_H_ -#define ONCE_FPARSER_H_ - -#include -#include - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -#include -#endif - -#ifdef _MSC_VER -// Visual Studio's warning about missing definitions for the explicit -// FunctionParserBase instantiations is irrelevant here. -#pragma warning(disable : 4661) -#endif - -namespace FPoptimizer_CodeTree { template class CodeTree; } - -template -class FunctionParserBase -{ - public: - enum ParseErrorType - { - SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH, - EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS, - ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC, - UNKNOWN_IDENTIFIER, - NO_FUNCTION_PARSED_YET, - FP_NO_ERROR - }; - - typedef Value_t value_type; - - - int Parse(const char* Function, const std::string& Vars, - bool useDegrees = false); - int Parse(const std::string& Function, const std::string& Vars, - bool useDegrees = false); - - void setDelimiterChar(char); - - static Value_t epsilon(); - static void setEpsilon(Value_t); - - const char* ErrorMsg() const; - ParseErrorType GetParseErrorType() const; - - Value_t Eval(const Value_t* Vars); - int EvalError() const; - - bool AddConstant(const std::string& name, Value_t value); - bool AddUnit(const std::string& name, Value_t value); - - typedef Value_t (*FunctionPtr)(const Value_t*); - - bool AddFunction(const std::string& name, - FunctionPtr, unsigned paramsAmount); - bool AddFunction(const std::string& name, FunctionParserBase&); - - class FunctionWrapper; - - template - bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&, - unsigned paramsAmount); - - FunctionWrapper* GetFunctionWrapper(const std::string& name); - - bool RemoveIdentifier(const std::string& name); - - void Optimize(); - - - int ParseAndDeduceVariables(const std::string& function, - int* amountOfVariablesFound = 0, - bool useDegrees = false); - int ParseAndDeduceVariables(const std::string& function, - std::string& resultVarString, - int* amountOfVariablesFound = 0, - bool useDegrees = false); - int ParseAndDeduceVariables(const std::string& function, - std::vector& resultVars, - bool useDegrees = false); - - - FunctionParserBase(); - ~FunctionParserBase(); - - // Copy constructor and assignment operator (implemented using the - // copy-on-write technique for efficiency): - FunctionParserBase(const FunctionParserBase&); - FunctionParserBase& operator=(const FunctionParserBase&); - - - void ForceDeepCopy(); - - - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING - // For debugging purposes only. - // Performs no sanity checks or anything. If the values are wrong, the - // library will crash. Do not use unless you know what you are doing. - void InjectRawByteCode(const unsigned* bytecode, unsigned bytecodeAmount, - const Value_t* immed, unsigned immedAmount, - unsigned stackSize); - - void PrintByteCode(std::ostream& dest, bool showExpression = true) const; -#endif - - - -//======================================================================== - protected: -//======================================================================== - // A derived class can implement its own evaluation logic by using - // the parser data (found in fptypes.hh). - struct Data; - Data* getParserData(); - - -//======================================================================== - private: -//======================================================================== - - friend class FPoptimizer_CodeTree::CodeTree; - -// Private data: -// ------------ - Data* mData; - unsigned mStackPtr; - static Value_t sEpsilon; - - -// Private methods: -// --------------- - void CopyOnWrite(); - bool CheckRecursiveLinking(const FunctionParserBase*) const; - bool NameExists(const char*, unsigned); - bool ParseVariables(const std::string&); - int ParseFunction(const char*, bool); - const char* SetErrorType(ParseErrorType, const char*); - - void AddFunctionOpcode(unsigned); - void AddImmedOpcode(Value_t v); - void incStackPtr(); - void CompilePowi(long); - bool TryCompilePowi(Value_t); - - const char* CompileIf(const char*); - const char* CompileFunctionParams(const char*, unsigned); - const char* CompileElement(const char*); - const char* CompilePossibleUnit(const char*); - const char* CompilePow(const char*); - const char* CompileUnaryMinus(const char*); - const char* CompileMult(const char*); - const char* CompileAddition(const char*); - const char* CompileComparison(const char*); - const char* CompileAnd(const char*); - const char* CompileExpression(const char*); - inline const char* CompileFunction(const char*, unsigned); - inline const char* CompileParenthesis(const char*); - inline const char* CompileLiteral(const char*); - template - inline void PushOpcodeParam(unsigned); - template - inline void PutOpcodeParamAt(unsigned, unsigned offset); - const char* Compile(const char*); - - bool addFunctionWrapperPtr(const std::string&, FunctionWrapper*, unsigned); - static void incFuncWrapperRefCount(FunctionWrapper*); - static unsigned decFuncWrapperRefCount(FunctionWrapper*); - -protected: - // Parsing utility functions - static std::pair ParseLiteral(const char*); - static unsigned ParseIdentifier(const char*); -}; - -class FunctionParser: public FunctionParserBase {}; -class FunctionParser_f: public FunctionParserBase {}; -class FunctionParser_ld: public FunctionParserBase {}; -class FunctionParser_li: public FunctionParserBase {}; - -#include -class FunctionParser_cd: public FunctionParserBase > {}; -class FunctionParser_cf: public FunctionParserBase > {}; -class FunctionParser_cld: public FunctionParserBase > {}; - - - -template -class FunctionParserBase::FunctionWrapper -{ - unsigned mReferenceCount; - friend class FunctionParserBase; - - public: - FunctionWrapper(): mReferenceCount(1) {} - FunctionWrapper(const FunctionWrapper&): mReferenceCount(1) {} - virtual ~FunctionWrapper() {} - FunctionWrapper& operator=(const FunctionWrapper&) { return *this; } - - virtual Value_t callFunction(const Value_t*) = 0; -}; - -template -template -bool FunctionParserBase::AddFunctionWrapper -(const std::string& name, const DerivedWrapper& wrapper, unsigned paramsAmount) -{ - return addFunctionWrapperPtr - (name, new DerivedWrapper(wrapper), paramsAmount); -} -#endif diff --git a/deal.II/contrib/functionparser/fparser_gmpint.hh b/deal.II/contrib/functionparser/fparser_gmpint.hh deleted file mode 100644 index fdb44502aa..0000000000 --- a/deal.II/contrib/functionparser/fparser_gmpint.hh +++ /dev/null @@ -1,15 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_GMPINT_H_ -#define ONCE_FPARSER_GMPINT_H_ - -#include "fparser.hh" -#include "mpfr/GmpInt.hh" - -class FunctionParser_gmpint: public FunctionParserBase {}; - -#endif diff --git a/deal.II/contrib/functionparser/fparser_mpfr.hh b/deal.II/contrib/functionparser/fparser_mpfr.hh deleted file mode 100644 index 443ec96113..0000000000 --- a/deal.II/contrib/functionparser/fparser_mpfr.hh +++ /dev/null @@ -1,15 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_MPFR_H_ -#define ONCE_FPARSER_MPFR_H_ - -#include "fparser.hh" -#include "mpfr/MpfrFloat.hh" - -class FunctionParser_mpfr: public FunctionParserBase {}; - -#endif diff --git a/deal.II/contrib/functionparser/fpconfig.hh b/deal.II/contrib/functionparser/fpconfig.hh deleted file mode 100644 index e729a12cc5..0000000000 --- a/deal.II/contrib/functionparser/fpconfig.hh +++ /dev/null @@ -1,82 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -// Configuration file -// ------------------ - -/* NOTE: - This file is for the internal use of the function parser only. - You don't need to include this file in your source files, just - include "fparser.hh". -*/ - - -/* Uncomment any of these lines or define them in your compiler settings - to enable the correspondent version of the parser. (These are disabled - by default because they rely on C99 functions, and non-standard libraries - in the case pf MPFR and GMP, and they make compiling needlessly slower - and the resulting binary needlessly larger if they are not used in the - program.) -*/ -//#define FP_SUPPORT_FLOAT_TYPE -//#define FP_SUPPORT_LONG_DOUBLE_TYPE -//#define FP_SUPPORT_LONG_INT_TYPE -//#define FP_SUPPORT_MPFR_FLOAT_TYPE -//#define FP_SUPPORT_GMP_INT_TYPE -//#define FP_SUPPORT_COMPLEX_DOUBLE_TYPE -//#define FP_SUPPORT_COMPLEX_FLOAT_TYPE -//#define FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE - -/* If you are using FunctionParser_ld or FunctionParser_cld and your compiler - supports the strtold() function, you should uncomment the following line. - */ -//#define FP_USE_STRTOLD - - -/* 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 - resulting binary smaller.) - */ -//#define FP_DISABLE_DOUBLE_TYPE - -/* - Whether to use shortcut evaluation for the & and | operators: -*/ -#ifndef FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION -#define FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION -#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. - If you are unsure, just leave it. It won't slow down the other parts of - the library. -*/ -#ifndef FP_NO_SUPPORT_OPTIMIZER -#define FP_SUPPORT_OPTIMIZER -#endif - -#if defined(FP_SUPPORT_COMPLEX_DOUBLE_TYPE) || defined(FP_SUPPORT_COMPLEX_FLOAT_TYPE) || defined(FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE) -#define FP_SUPPORT_COMPLEX_NUMBERS -#endif - - -/* - 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. - The second version requires that the compiler supports the alloca() function, - which is not standard, but is faster. - */ -//#define FP_USE_THREAD_SAFE_EVAL -//#define FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA diff --git a/deal.II/contrib/functionparser/fpoptimizer.cc b/deal.II/contrib/functionparser/fpoptimizer.cc deleted file mode 100644 index 7c41f511ca..0000000000 --- a/deal.II/contrib/functionparser/fpoptimizer.cc +++ /dev/null @@ -1,11763 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5 *| -|*-------------------------------------------------------------------------*| -|* Function optimizer *| -|*-------------------------------------------------------------------------*| -|* Copyright: Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -/* NOTE: - This file contains generated code (from the optimizer sources) and is - not intended to be modified by hand. If you want to modify the optimizer, - download the development version of the library. -*/ - -#include "fpconfig.hh" -#ifdef FP_SUPPORT_OPTIMIZER -#include "fparser.hh" -#include "extrasrc/fptypes.hh" -#include "extrasrc/fpaux.hh" -#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 );}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 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 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 xD data. -#define cP3 &Value){ -#define cO3 yH const -#define cN3 used[b] -#define cM3 sizeof( -#define cL3 cAbsIf, -#define cK3 cNotNot, -#define cJ3 18,2 eN1 -#define cI3 c22 iE, -#define cH3 450998, -#define cG3 cAtan2, -#define cF3 cExp2 nQ -#define cE3 lJ 2},0, -#define cD3 middle2 -#define cC3 ::string -#define cB3 fp_equal( -#define cA3 ;if(cB3 -#define c93 (iE2 l8 1)xC1 -#define c83 FP_GetOpcodeName( -#define c73 default: -#define c63 n31;case -#define c53 tG));nV -#define c43 range nJ3 -#define c33 range=x22 -#define tF2 .min.val -#define tE2 )?0:1))l7 -#define tD2 .n_int_sqrt -#define tC2 ;}else{x5=new -#define tB2 (half&63)-1; -#define tA2 ),0},{ -#define t92 ),Value -#define t82 data;data. -#define t72 MakeNEqual -#define t62 (exponent -#define t52 Dump(std:: -#define t42 isInteger( -#define t32 Comparison -#define t22 needs_flip -#define t12 value] -#define t02 ~size_t(0) -#define eZ2 xJ1 xS+1); -#define eY2 TopLevel) -#define eX2 -#define eU2 *)&*start_at; -#define eT2 Rule&rule, -#define eS2 >::res,b8< -#define eR2 continue;} -#define eQ2 c9 tree); -#define eP2 mul_item -#define eO2 innersub -#define eN2 cbrt_cost -#define eM2 best_cost -#define eL2 fp_min(yL -#define eK2 tree t31);} -#define eJ2 tree))cZ -#define eI2 condition -#define eH2 per_item -#define eG2 item_type -#define eF2 first2 -#define eE2 l4 18,1, -#define eD2 lJ 1},0, -#define eC2 Decision -#define eB2 not_tree -#define eA2 group_by -#define e92 exponent= -#define e82 ->second -#define e72 :xL iV2( -#define e62 eJ&tree) -#define e52 targetpos -#define e42 ParamSpec -#define e32 rhs.hash2;} -#define e22 rhs.hash1 -#define e12 struct -#define e02 Forget() -#define cZ2 &&cond e8)) -#define cY2 source_tree -#define cX2 nC==cLog2&& -#define cW2 ,eL1 0x1 nH -#define cV2 )lS 3*3* -#define cU2 (tK==eA3&& -#define cT2 );yF3 -#define cS2 ;iB.Remember( -#define cR2 -#define cQ2 );sim.nY 2, -#define cP2 )continue -#define cO2 CodeTree lW -#define cN2 p1_evenness -#define cM2 isNegative( -#define cL2 yN known&&( -#define cK2 neg_set -#define cJ2 cNop,cNop}} -#define cI2 cTanh,cNop, -#define cH2 NewHash -#define cG2 >e12 cA< -#define cF2 matches -#define cE2 .match_tree -#define cD2 cH1 void*)& -#define cC2 cSin iO -#define cB2 cTan nQ -#define cA2 ,cLog nQ -#define c92 cCos nQ -#define c82 long value -#define c72 (std::move( -#define c62 (xX l8 a)xF -#define c52 negated -#define c42 Specializer -#define c32 params -#define c22 18,2, -#define c12 coshtree -#define c02 sinhtree -#define yZ2 best_score -#define yY2 mulvalue -#define yX2 pow_item -#define yW2 subgroup -#define yV2 nC==cPow&&tO -#define yU2 PowiResult -#define yT2 ))y53 -#define yS2 0));c23 -#define yR2 maxValue -#define yQ2 minValue -#define yP2 div_tree -#define yO2 pow_tree -#define yN2 iV2 nT -#define yM2 preserve -#define yL2 PullResult() -#define yK2 dup_or_fetch -#define yJ2 nominator] -#define yI2 test_order -#define yH2 parampair -#define yG2 yH2, -#define yF2 .param_count -#define yE2 minimum_need -#define yD2 shift(index) -#define yC2 {std::cout<< -#define yB2 rulenumber -#define yA2 l2 16,2, -#define y92 cTanh nQ -#define y82 l14 l2 2,2, -#define y72 ,cPow iO -#define y62 cSinh nQ -#define y52 cIf,n91 3, -#define y42 cInv,lT 1, -#define y32 constraints= -#define y22 GetDepth() -#define y12 factor_immed -#define y02 changes -#define xZ2 c9 cond l8 -#define xY2 Become y91 -#define xX2 for(xK3 -#define xW2 exp_diff -#define xV2 ExponentInfo -#define xU2 lower_bound( -#define xT2 factor -#define xS2 is_logical -#define xR2 newrel_and -#define xQ2 )){data x7 lN -#define xP2 Suboptimal -#define xO2 eK[c eA -#define xN2 res_stackpos -#define xM2 half_pos -#define xL2 ifdata.ofs -#define xK2 i8 push_back( -#define xJ2 n31 true;} -#define xI2 >>1)):( -#define xH2 CodeTreeData -#define xG2 exponent) -#define xF2 yN known) -#define xE2 multiply( -#define xD2 )y3 cPow) -#define xC2 var_trees -#define xB2 nB OPCODE -#define xA2 CodeTree& -#define x92 parent_opcode -#define x82 GetParam(a eS -#define x72 {cW start_at; -#define x62 changed=true; -#define x52 log2_exponent -#define x42 iV2(2))); -#define x32 lR,tH)tH2 -#define x22 iV2(0.0)) -#define x12 dup_fetch_pos -#define x02 IsNever cL lC -#define nZ2 cSin nQ -#define nY2 Value_EvenInt -#define nX2 AddCollection -#define nW2 ConditionType -#define nV2 n31 Unknown;} -#define nU2 1 y7 i8 size( -#define nT2 (iF2 -#define nS2 iA|nT2) -#define nR2 SpecialOpcode -#define nQ2 =i e82. -#define nP2 yN known&&p -#define nO2 assimilated -#define nN2 denominator -#define nM2 fraction -#define nL2 DUP_BOTH(); -#define nK2 0x80000000u -#define nJ2 IsDescendantOf -#define nI2 TreeCounts -#define nH2 SetOpcode( -#define nG2 found_log2 -#define nF2 div_params -#define nE2 immed_sum -#define nD2 lE3++IP] -#define nC2 sim n92 -#define nB2 ;sim.Push( -#define nA2 ,cMul l3 -#define n92 .Eat(1, -#define n82 OPCODE(opcode) -#define n72 FactorStack xK -#define n62 Rehash(false); -#define n52 IsAlways cL lC -#define n42 cEqual, -#define n32 cNotNot nQ -#define n22 cNot nQ -#define n12 DumpHashesFrom -#define n02 replacing_slot -#define lZ2 RefParams -#define lY2 if_always[ -#define lX2 WhatDoWhenCase -#define lW2 exponent_immed -#define lV2 new_base_immed -#define lU2 base_immed -#define lT2 );std::cout<< -#define lS2 ||op1== -#define lR2 l8 0)); -#define lQ2 data[a tD3 -#define lP2 if(newrel_or== -#define lO2 .AddOperation( -#define lN2 DUP_ONE(apos); -#define lM2 flipped -#define lL2 .UseGetNeeded( -#define lK2 ,fp_max(yL); -#define lJ2 else if( -#define lI2 lJ2!nT3 -#define lH2 synth.PushImmed( -#define lG2 (*x5)[a].info -#define lF2 ,PowiCache&iB, -#define lE2 tree l8 -#define lD2 <(iV2(1), -#define t61 x22{xO -#define t51 (&*start_at){x5=( -#define t41 DelParam(a);} -#define t31 tK2 a -#define t21 a)i61) -#define t11 n82); -#define t01 0.5)xD2;lC -#define eZ1 std::cout<<"POP " -#define eY1 stack[iV1- -#define eX1 stack.push_back( -#define eW1 ,l0 2, -#define eV1 CollectionSet xK -#define eU1 xK())y3 cMul);lC -#define eT1 .Rehash(); -#define eS1 ParsePowiMuli -#define eR1 MaxChildDepth -#define eQ1 iF2 a -#define eP1 std::pair -#define eO1 cLess,l2 -#define eN1 ,n63 281856, -#define eM1 cNEqual, -#define eL1 cPow,lA -#define eK1 Sign_Negative -#define eJ1 Value_Logical -#define eI1 yD MakeFalse,{l5 -#define eH1 new_factor_immed -#define eG1 occurance_pos -#define eF1 exponent_hash -#define eE1 exponent_list -#define eD1 CollectMulGroup( -#define eC1 source_set -#define eB1 exponent,yT3 -#define eA1 operator -#define e91 FindAndDup(tree); -#define e81 ParamSpec_Extract -#define e71 retry_anyparams_3 -#define e61 retry_anyparams_2 -#define e51 needlist_cached_t -#define e41 lJ 2}lA2 -#define e31 lJ 1}lA2 -#define e21 CodeTreeImmed xK( -#define e11 by_float_exponent -#define e01 fp_equal t62 -#define cZ1 new_exp -#define cY1 end()&&i->first== -#define cX1 return BecomeZero; -#define cW1 return BecomeOne; -#define cV1 if(lQ.tF3<=n1) -#define cU1 addgroup -#define cT1 found_log2by -#define cS1 nC==cZ3) -#define cR1 if(keep_powi -#define cQ1 l22) -#define cP1 branch1_backup -#define cO1 branch2_backup -#define cN1 NeedList -#define cM1 tree.SetParam( -#define cL1 exponent_map -#define cK1 plain_set -#define cJ1 rangehalf -#define cI1 ;synth.StackTopIs( -#define cH1 (const -#define cG1 cH1 iV2& -#define cF1 eT1 tI3 op1);tree.DelParams() -#define cE1 .GetParamCount()== -#define cD1 LightWeight( -#define cC1 if(value -#define cB1 xW3 yX -#define cA1 xW3 static -#define c91 m yN set(fp_ceil);tV -#define c81 m yN val -#define c71 m yN known -#define c61 )yH2 tE3; -#define c51 ::MakeTrue -#define c41 should_regenerate=true; -#define c31 should_regenerate, -#define c21 Collection -#define c11 RelationshipResult -#define c01 Subdivide_Combine( -#define yZ1 e83 yR -#define yY1 rhs yZ1 hash1 -#define yX1 PositionalParams,0 -#define yW1 best_sep_factor -#define yV1 needlist_cached -#define yU1 inline iF2 -#define yT1 252421 nP 24830 -#define yS1 t83 bool pad -#define yR1 MakesInteger( -#define yQ1 mulgroup. -#define yP1 .AddParamMove( -#define yO1 =comp.AddItem(atree -#define yN1 tree i61 cL -#define yM1 ByteCodeSynth xK&synth) -#define yL1 lF3 FPoptimizer_Optimize -#define yK1 (long double) -#define yJ1 const iV2&value -#define yI1 best_sep_cost -#define yH1 AddParamMove(tree); -#define yG1 MultiplicationRange -#define yF1 pihalf_limits -#define yE1 n_stacked -#define yD1 cH2.hash1 -#define yC1 AnyParams_Rec -#define yB1 ):e2(),std xV3< -#define yA1 i13 cJ -#define y91 (lE2 -#define y81 Become(value l8 0)) -#define y71 always_sincostan -#define y61 Recheck_RefCount_Div -#define y51 Recheck_RefCount_Mul -#define y41 mulgroup;mulgroup xD -#define y31 MultiplyAndMakeLong( -#define y21 iV2(0) -#define y11 covers_plus1 -#define y01 if(synth.FindAndDup( -#define xZ1 SynthesizeParam( -#define xY1 grammar_func -#define xX1 cOr l3 16,1, -#define xW1 252180 nP 281854 -#define xV1 l2 0,2,165888 nP -#define xU1 l1 tV3 -#define xT1 Modulo_Radians}, -#define xS1 PositionType -#define xR1 CollectionResult -#define xQ1 ;m yN template set_if< -#define xP1 ByteCode,size_t&IP,size_t limit,size_t y1 -#define xO1 iT2))break;nT3*= -#define xN1 xW3 bool -#define xM1 const_offset -#define xL1 inline TriTruthValue -#define xK1 stacktop_desired -#define xJ1 SetStackTop( -#define xI1 }inline -#define xH1 FPoptimizer_ByteCode -#define xG1 1)?(poly^( -#define xF1 GetParamCount(); -#define xE1 public e2,public std xV3< -#define xD1 y21) -#define xC1 xF leaf2 l8 -#define xB1 c22 529654 nP -#define xA1 cond_type -#define x91 fphash_value_t -#define x81 Recheck_RefCount_RDiv -#define x71 cMul);tmp.nJ 0));tmp. -#define x61 SwapLastTwoInStack(); -#define x51 fPExponentIsTooLarge( -#define x41 CollectMulGroup_Item( -#define x31 pair -#define x21 nL xJ1 xS-1); -#define x11 covers_full_cycle -#define x01 AssembleSequence( -#define nZ1 <& -#define nR1 i31 xK3 -#define nQ1 has_good_balance_found -#define nP1 n_occurrences -#define nO1 found_log2_on_exponent -#define nN1 covers_minus1 -#define nM1 needs_resynth -#define nL1 immed_product -#define nK1 ,2,1 xN if(found[data. -#define nJ1 ;xW3 -#define nI1 yJ3 bitmask& -#define nH1 Sign_Positive -#define nG1 SetParamMove( -#define nF1 CodeTreeImmed(iV2( -#define nE1 changed_if -#define nD1 0,xG2;DelParam(1); -#define nC1 .GetImmed() -#define nB1 for iA1 a=0;a0;)if( -#define n31 ;return -#define n21 n31 xP2;} -#define n11 >::Optimize(){} -#define n01 n_as_tanh_param -#define lZ1 opposite= -#define lY1 x91( -#define lX1 MatchResultType -#define lW1 needs_sincos -#define lV1 resulting_exponent -#define lU1 val):Value(Value:: -#define lT1 Unknown:c73;} -#define lS1 GetParam(a) -#define lR1 inverse_nominator] -#define lQ1 cMul l3 0,1, -#define lP1 tree yP1 -#define lO1 AddFunctionOpcode( -#define lN1 SetParams(l02)); -#define lM1 o<<"("<){int mStackPtr=0; -#define l21 FPoptimizer_Grammar -#define l11 AddOperation(cInv,1,1 xN} -#define l01 GetPositivityInfo eZ3 -#define iZ ParamSpec_SubFunctionData -#define iY iA1 a=c8 a-->0;) -#define iX PositionalParams_Rec -#define iW yD MakeNotNotP1,l5:: -#define iV ,cMul x4 -#define iU eT1 tI3 iE2 nC);tree. -#define iT yD MakeNotNotP0,l5:: -#define iS lE3 xL2+ -#define iR DumpTreeWithIndent(*this); -#define iQ switch(type y33 cond_or: -#define iP ;if(eY2 tM3 SaveMatchedParamIndex( -#define iO ,l4 2,1, -#define iN CalculateResultBoundaries( -#define iM i31 iF2 Compare> -#define iL cE3 0x0},{{1, -#define iK edited_powgroup -#define iJ iA1 a=xF1 a -#define iI has_unknown_max -#define iH has_unknown_min -#define iG static const c23 -#define iF synthed_tree -#define iE 408964 nP 24963 -#define iD SelectedParams,0},0,0x0},{{ -#define iC collections -#define iB cache -#define iA ;xK2 nK2 -#define i9 )iA); -#define i8 ByteCode. -#define i7 ;pow xD cLog);tree tH3 -#define i6 goto ReplaceTreeWithOne;case -#define i5 ]);yE3 -#define i4 !=xB)return lY2 -#define i3 e11.data -#define i2 l53 xH2( -#define i1 needs_sinhcosh -#define i0 cAdd x4 -#define tZ cAdd l3 0, -#define tY tA2 iV2( -#define tX xW3 nA -#define tW int_exponent_t -#define tV return m;}case -#define tU MakeFalse,l5:: -#define tT lT2 std::endl;DumpHashes( -#define tS ,ByteCode,IP,limit,y1,stack); -#define tR matched_params -#define tQ [n1 tC3=true;lQ[n1 tD3 -#define tP l21::Grammar* -#define tO powgroup l8 -#define tN );p2 cK p2);tI3 l93 nC);cZ} -#define tM GetLogicalValue y91 -#define tL t02&&found[data. -#define tK valueType -#define tJ xE AnyParams, -#define tI =iN lE2 -#define tH eO3 nC1 -#define tG (tH) -#define tF nF1( -#define tE has_mulgroups_remaining -#define tD by_exponent -#define tC const iZ -#define tB MatchInfo xK& -#define tA Rehash();iA2.push_back( -#define t9 best_factor -#define t8 RootPowerTable xK::RootPowers[ -#define t7 MatchPositionSpec_AnyParams xK -#define t6 cLessOrEq,l2 -#define t5 lF3 FPoptimizer_CodeTree -#define t4 n_as_sinh_param -#define t3 n_as_cosh_param -#define t2 is_signed -#define t1 result_positivity -#define t0 yN known tO3 -#define eZ biggest_minimum -#define eY 142455 nP 141449, -#define eX cond_tree -#define eW else_tree -#define eV then_tree -#define eU sequencing -#define eT string c83 -#define eS );bool needs_cow=GetRefCount()>1; -#define eR nM iV2(-nR3 -#define eQ {AdoptChildrenWithSameOpcode(tree); -#define eP lJ3,l2 c22 -#define eO ;AddParamMove( -#define eN yN known&&p0 yN val<=fp_const_negativezero xK()) -#define eM tree.GetParamCount() -#define eL :goto ReplaceTreeWithZero;case -#define eK relationships -#define eJ CodeTree xK -#define eI ,2,122999 nP 139399, -#define eH std xV3 -#define eG if_stack -#define eF (l02));yQ1 Rehash(); -#define eE n_as_sin_param -#define eD n_as_cos_param -#define eC PowiResolver:: -#define eB cIf,tW3 -#define eA ].relationship -#define e9 PACKED_GRAMMAR_ATTRIBUTE; -#define e8 .BalanceGood -#define e7 AddParamMove(yW2 -#define e6 back().endif_location -#define e5 x91 key -#define e4 AddParamMove(mul); -#define e3 130,1, -#define e2 MatchPositionSpecBase -#define e1 l53 CodeTree( -#define e0 smallest_maximum -#define cZ goto redo; -#define cY ReplaceTreeWithParam0; -#define cX factor_needs_rehashing -#define cW MatchPositionSpecBaseP -#define cV xK3 tK1::yV3 -#define cU e81 xK(nN.param_list, -#define cT 243,244,245,246,249,250,251,253,255,256,257,258,259}};} -#define cS ];};extern"C"{ -#define cR 79,122,123,160,161,163,164,165,166,167,168,169,178,179,180,200,204,212,216,224,236,237,239,240, -#define cQ 27,28,29,30,31,32,33,35,36, -#define cP const ParamSpec_SubFunction -#define cO const ParamSpec_ParamHolder -#define cN otherhalf -#define cM StackState -#define cL )return false; -#define cK eT1 lP1 -#define cJ (tree lT2"\n"; -#define cI const SequenceOpCode xK -#define cH paramholder_matches[nZ] -#define cG MatchPositionSpec_PositionalParams xK -#define cF lC2 tree,std::ostream&o -#define cE paramholder_matches. -#define cD iV2(1.5)*fp_const_pi xK() -#define cC xB,l5::Never yD xB,l5::Never} -#define cB CalculatePowiFactorCost( -#define cA ImmedHashGenerator -#define c9 .AddParam( -#define c8 eM; -#define c7 ::map > -#define c6 ComparisonSetBase:: -#define c5 AddParamMove(comp.cK1[a].value); -#define c4 ,yA2 528503 nP 24713, -#define c3 T1,xK3 T2>inline iG2()( -#define c2 has_nonlogical_values -#define c1 from_logical_context) -#define c0 AnyParams,0 l91 -#define yZ for iA1 a=xX.xF1 a-->0;) -#define yY POWI_CACHE_SIZE -#define yX static inline eJ -#define yW ++IP;eR2 if(iT1==cS3. -#define yV .FoundChild -#define yU BalanceResultType -#define yT xM3(0),Opcode( -#define yS );void lO1 iF2 t83 c42< -#define yR {return -#define yQ const yR data-> -#define yP +=fp_const_twopi xK(); -#define yO fp_const_twopi xK()eY3 -#define yN .max. -#define yM eJ tmp,tmp2;tmp2 xD -#define yL fp_sin(min),fp_sin(max)) -#define yK m.min. -#define yJ lO2 GetOpcode(), -#define yI for iA1 a=0;aParams -#define xX branch1 -#define xW );eR2 if(list.first nC1==iV2( -#define xV nN yF2 -#define xU =fp_cosh nU3;c81=fp_cosh(c81); -#define xT {nI2.erase(i);eR2 -#define xS StackTop -#define xR FPOPT_autoptr -#define xQ +=nT3 n31 nT3;}xW3 inline iV2 -#define xP int_exponent -#define xO tree.ReplaceWithImmed( -#define xN )cI1*this)n31;} -#define xM GetStackTop()- -#define xL sim.AddConst( -#define xK -#define xJ .SetParam(0,l93 lR2 eJ p1;p1 xD -#define xI newnode -#define xH has_highlevel_opcodes -#define xG eD2 0x0},{{ -#define xF .IsIdenticalTo( -#define xE ,cAdd, -#define xD .nH2 -#define xC {if(needs_cow){l61 goto -#define xB Unchanged -#define xA cF=std::cout -#define x9 best_selected_sep -#define x8 i31>void FunctionParserBase< -#define x7 ->Recalculate_Hash_NoRecursion();} -#define x6 xF1++a)if(ApplyGrammar(tX2,t33, -#define x5 position -#define x4 l3 2,1, -#define x3 ;iE3 0));tmp xD cInv);tmp yP1 tmp2)n31 -#define x2 nB1{c23 -#define x1 std xV3 -#define x0 TestImmedConstraints y23 constraints,tree)cL -#define nZ paramholder_index -#define nY x61 tQ2 -#define nX )){tree.FixIncompleteHashes();} -#define nW );cR1){nC2 cInv cT2 xL-1 xD2;lC -#define nV return true;case -#define nU occurance_counts -#define nT >p tI a)eY3 p. -#define nS -->0;){lC2 powgroup=lS1;if(powgroup -#define nR lT3 i61 -#define nQ ,l0 1, -#define nP ,{2, -#define nO const FPoptimizer_CodeTree::eJ&tree -#define nN model_tree -#define nM return c23( -#define nL ){using lF3 FUNCTIONPARSERTYPES; -#define nK eH&lZ2 -#define nJ AddParam y91 -#define nI ConstantFolding_LogicCommon(tree,c6 -#define nH },{{2, -#define nG nR1 Ref>inline void xR:: -#define nF AnyParams,1},0,0x0},{{ -#define nE ):data(new xH2 xK( -#define nD goto do_return;} -#define nC .GetOpcode() -#define nB FUNCTIONPARSERTYPES:: -#define nA xH2 xK::xH2( -#define n9 b;}};i31>e12 Comp(iV2( -#define n2 DumpParams xK y23 data.param_list,yL3 data yF2,o); -#define n1 restholder_index -#define n0 eJ exponent;exponent xD cMul tF1 c9 -#define lZ lR eY3 fp_nequal(tmp,xD1){xO iV2(1)/tmp);nD}lC -#define lY :if(ParamComparer xK()(Params[1],Params[0])){std::swap(Params[0],Params[1]);Opcode= -#define lX -#define lW xK tmp;tmp xD cPow);tmp.nJ 0));tmp.yC iV2( -#define lV tR1,0x0}, -#define lU AddParamMove(pow l8 1));pow tK2 1);pow eT1 tree.nG1 0,pow);goto NowWeAreMulGroup;} -#define lT GroupFunction,0},lV{{ -#define lS tG1 1)/iV2( -#define lR lE2 0)nC1 -#define lQ restholder_matches -#define lP yD1|=key;x91 crc=(key>>10)|(key<<(64-10))lF1((~lY1 crc))*3)^1234567;}}; -#define lO nE1;nE1 iP2 nE1.AddParamMove y91 0));nE1 c9 xX l8 -#define lN xW3 eJ::CodeTree( -#define lM cM1 0,lE2 0)lR2 cM1 1,CodeTreeImmed( -#define lL lX void ByteCodeSynth xK::lO1 iF2 t83 c42< -#define lK cMul,lT 2, -#define lJ cMul,AnyParams, -#define lI y91 0)i61&&eO3 i61){xO -#define lH iN tmp i33 -#define lG :eM3=comp.AddRelationship(atree l8 0),atree l8 1),c6 -#define lF cPow,l0 2 -#define lE xK3 iV2>inline iG2()cG1 xN3 iV2&b)yR a -#define lD {c23 m tI 0)); -#define lC break;case -#define lB tZ1 eJ:: -#define lA yX1},0, -#define l9 l1 0x0 nH -#define l8 .GetParam( -#define l7 ;eJ nE1;nE1 iP2 nE1 iO3 tree.l02));nE1 eT1 tI3 -#define l6 SelectedParams,0},0,0x0 nH -#define l5 RangeComparisonData -#define l4 yX1 l91 -#define l3 ,AnyParams,0}}l44 -#define l2 yX1}}l44 -#define l1 cMul,SelectedParams,0},0, -#define l0 lA 0x0},{{ -#ifdef _MSC_VER -typedef -iF2 -int -iZ1; -#else -#include -typedef -uint_least32_t -iZ1; -#endif -lF3 -crc32{enum{startvalue=0xFFFFFFFFUL,poly=0xEDB88320UL} -;i31 -iZ1 -crc>e12 -b8{enum{b1=(crc&xG1 -crc -xI2 -crc>>1),b2=(b1&xG1 -b1 -xI2 -b1>>1),b3=(b2&xG1 -b2 -xI2 -b2>>1),b4=(b3&xG1 -b3 -xI2 -b3>>1),b5=(b4&xG1 -b4 -xI2 -b4>>1),b6=(b5&xG1 -b5 -xI2 -b5>>1),b7=(b6&xG1 -b6 -xI2 -b6>>1),res=(b7&xG1 -b7 -xI2 -b7>>1)} -;} -;inline -iZ1 -update(iZ1 -crc,iF2 -b){ -#define B4(n) b8::res -#define R(n) B4(n),B4(n+4),B4(n+8),B4(n+12) -static -const -iZ1 -table[256]={R(0x00),R(0x10),R(0x20),R(0x30),R(0x40),R(0x50),R(0x60),R(0x70),R(0x80),R(0x90),R(0xA0),R(0xB0),R(0xC0),R(0xD0),R(0xE0),R(0xF0)} -; -#undef R -#undef B4 -return((crc>>8))^table[(crc^b)&0xFF];xI1 -iZ1 -calc_upd(iZ1 -c,const -iF2 -char*buf,size_t -size){iZ1 -value=c;for -iA1 -p=0;pclass -xR{eX3 -xR():p(0){} -xR(Ref*b):p(b){xL3} -xR -cH1 -xR&b):p(b.p){xL3 -xI1 -Ref&eA1*(yZ1*p;xI1 -Ref*eA1->(yZ1 -p;} -xR&eA1=(Ref*b){Set(b)n31*this;} -xR&eA1=cH1 -xR&b){Set(b.p)n31*this;} -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -xR(xR&&b):p(b.p){b.p=0;} -xR&eA1=(xR&&b){if(p!=b.p){e02;p=b.p;b.p=0;} -return*this;} -#endif -~xR(){e02 -lL3 -UnsafeSetP(Ref*newp){p=newp -lL3 -swap(xR&b){Ref*tmp=p;p=b.p;b.p=tmp;} -private:inline -static -void -Have(Ref*p2);inline -void -e02;inline -void -xL3 -inline -void -Set(Ref*p2);private:Ref*p;} -;nG -e02{if(!p)return;p->xM3-=1;if(!p->xM3)delete -p;} -nG -Have(Ref*p2){if(p2)++(p2->xM3);} -nG -Birth(){Have(p);} -nG -Set(Ref*p2){Have(p2);e02;p=p2;} -#endif -#include -e12 -Compare2ndRev{nR1 -T>inline -iG2()cH1 -T&xN3 -T&b -yZ1 -a -tE3>b -tE3;} -} -;e12 -Compare1st{nR1 -c3 -const -nS1 -xN3 -nS1 -b -yZ1 -a.first -typedef -uint_fast64_t -x91; -#define FPHASH_CONST(x) x##ULL -#endif -lF3 -FUNCTIONPARSERTYPES{e12 -fphash_t{x91 -hash1,hash2;fphash_t():hash1(0),hash2(0){} -fphash_t -cH1 -x91&xN3 -x91&b):hash1(a),hash2(b){} -iG2==cH1 -fphash_t&yY1==e22&&hash2==e32 -iG2!=cH1 -fphash_t&yY1!=e22||hash2!=e32 -iG2 -#include -lF3 -l21{e12 -Grammar;} -lF3 -xH1{xW3 -class -ByteCodeSynth;} -t5{xW3 -class -CodeTree -nJ1 -e12 -xH2 -nJ1 -class -CodeTree{typedef -xRDataP;DataP -data;eX3 -CodeTree();~CodeTree();e12 -OpcodeTag{} -;e1 -xB2 -o,OpcodeTag);e12 -FuncOpcodeTag{} -;e1 -xB2 -o,iF2 -f,FuncOpcodeTag);e12 -xO3{} -;e1 -const -iV2&v,xO3); -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -e1 -iV2&&v,xO3); -#endif -e12 -VarTag{} -;e1 -iF2 -varno,VarTag);e12 -CloneTag{} -;e1 -lG3 -b,CloneTag);void -GenerateFrom -cH1 -xK3 -FunctionParserBase -xK::Data&data,bool -keep_powi=false);void -GenerateFrom -cH1 -xK3 -FunctionParserBase -xK::Data&data,const -x1&xC2,bool -keep_powi=false);void -SynthesizeByteCode(std -xV3&eI3,std -xV3 -xK&immed,size_t&stacktop_max);void -SynthesizeByteCode(xH1 -yG3&synth,bool -MustPopTemps=true -e83;size_t -SynthCommonSubExpressions(xH1::yM1 -const;void -SetParams -cH1 -x1&xP3 -SetParamsMove(x1&tA1 -CodeTree -GetUniqueRef(); -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -void -SetParams(x1&&tA1 -#endif -void -SetParam -iA1 -which,lG3 -b);void -nG1 -size_t -which,xA2 -b);void -AddParam -cH1 -xA2 -param);void -AddParamMove(xA2 -param);void -AddParams -cH1 -x1&xP3 -AddParamsMove(x1&xP3 -AddParamsMove(x1&lZ2,size_t -n02);void -DelParam -iA1 -index);void -DelParams();void -Become -cH1 -xA2 -b);inline -size_t -GetParamCount(yZ1 -l02).tF3;xI1 -xA2 -GetParam -iA1 -n)yR -l02)[n];xI1 -lG3 -GetParam -iA1 -n -yZ1 -l02)[n];xI1 -void -nH2 -xB2 -o)tN3 -Opcode=o;xI1 -xB2 -GetOpcode()yQ -Opcode;xI1 -nB -fphash_t -GetHash()yQ -Hash;xI1 -const -x1&l02 -yZ1 -xY;xI1 -x1&l02)yR -xY;xI1 -size_t -y22 -yQ -Depth;xI1 -const -iV2&GetImmed()yQ -Value;xI1 -iF2 -GetVar()yQ -l12 -xI1 -iF2 -GetFuncNo()yQ -l12 -xI1 -bool -IsDefined(yZ1 -GetOpcode()!=nB -cNop;xI1 -bool -IsImmed(yZ1 -GetOpcode()==nB -cImmed;xI1 -bool -IsVar(yZ1 -GetOpcode()==nB -l03;xI1 -iF2 -GetRefCount()yQ -xM3 -lL3 -ReplaceWithImmed -cG1 -i);void -Rehash(bool -constantfolding=true);void -Sort();inline -void -Mark_Incompletely_Hashed()tN3 -Depth=0;xI1 -bool -Is_Incompletely_Hashed()yQ -Depth==0;xI1 -const -tP -GetOptimizedUsing()yQ -l32;xI1 -void -SetOptimizedUsing -cH1 -tP -g)tN3 -l32=g;} -bool -RecreateInversionsAndNegations(bool -prefer_base2=false);void -FixIncompleteHashes();void -swap(xA2 -b){data.swap(b.data);} -bool -IsIdenticalTo -cH1 -xA2 -b -e83;void -l61} -nJ1 -e12 -xH2{int -xM3;xB2 -Opcode -iU2 -Value;iF2 -l12 -eH -Params;nB -fphash_t -Hash;size_t -Depth;const -tP -l32;xH2();xH2 -cH1 -xH2&b);i2 -xB2 -o);i2 -xB2 -o,iF2 -f);i2 -const -iV2&i); -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -i2 -iV2&&i);xH2(xH2&&b); -#endif -bool -IsIdenticalTo -cH1 -xH2&b -e83;void -Sort();void -Recalculate_Hash_NoRecursion();private:void -eA1=cH1 -xH2&b);} -nJ1 -yX -CodeTreeImmed -cG1 -i)yR -eJ(i -yA -xO3());} -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -cB1 -CodeTreeImmed(iV2&&i)yR -eJ -c72 -i)yA -xO3());} -#endif -cB1 -CodeTreeOp(xB2 -opcode)yR -eJ(opcode -yA -OpcodeTag());} -cB1 -CodeTreeFuncOp(xB2 -t83 -iF2 -f)yR -eJ(t83 -f -yA -FuncOpcodeTag());} -cB1 -CodeTreeVar -nT2 -varno)yR -eJ(varno -yA -VarTag());} -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -tZ1 -DumpHashes(xA)xR3 -DumpTree(xA)xR3 -DumpTreeWithIndent(xA,const -std -cC3&indent="\\" -); -#endif -} -#endif -#endif -#ifndef FPOptimizer_GrammarHH -#define FPOptimizer_GrammarHH -#include -t5{xW3 -class -CodeTree;} -lF3 -l21{enum -ImmedConstraint_Value{ValueMask=0x07,Value_AnyNum=0x0,nY2=0x1,Value_OddInt=0x2,tS1=0x3,Value_NonInteger=0x4,eJ1=0x5 -xF3 -ImmedConstraint_Sign{SignMask=0x18,Sign_AnySign=0x00,nH1=0x08,eK1=0x10,Sign_NoIdea=0x18 -xF3 -ImmedConstraint_Oneness{OnenessMask=0x60,Oneness_Any=0x00,Oneness_One=0x20,Oneness_NotOne=0x40 -xF3 -ImmedConstraint_Constness{ConstnessMask=0x180,Constness_Any=0x00,tR1=0x80,Constness_NotConst=0x100 -xF3 -Modulo_Mode{Modulo_None=0,Modulo_Radians=1 -xF3 -Situation_Flags{LogicalContextOnly=0x01,NotForIntegers=0x02,OnlyForIntegers=0x04,OnlyForComplex=0x08,NotForComplex=0x10 -xF3 -nR2{NumConstant,tG3,SubFunction -xF3 -ParamMatchingType{PositionalParams,SelectedParams,AnyParams,GroupFunction -xF3 -RuleType{ProduceNewTree,ReplaceParams} -; -#ifdef __GNUC__ -# define PACKED_GRAMMAR_ATTRIBUTE __attribute__((packed)) -#else -# define PACKED_GRAMMAR_ATTRIBUTE -#endif -typedef -std::paire42 -nJ1 -e42 -e81 -nT2 -paramlist,nA1)nJ1 -bool -ParamSpec_Compare -cH1 -void*xN3 -void*b,nR2 -type);iF2 -ParamSpec_GetDepCode -cH1 -e42&b);e12 -ParamSpec_ParamHolder{nA1:8;iF2 -constraints:9;iF2 -depcode:15;} -e9 -xW3 -e12 -ParamSpec_NumConstant{iV2 -constvalue;iF2 -modulo;} -;e12 -iZ{iF2 -param_count:2;iF2 -param_list:30;xB2 -subfunc_opcode:8;ParamMatchingType -match_type:3;iF2 -n1:5;} -e9 -e12 -ParamSpec_SubFunction{iZ -data;iF2 -constraints:9;iF2 -depcode:7;} -e9 -e12 -Rule{RuleType -ruletype:2;iF2 -situation_flags:5;iF2 -repl_param_count:2+9;iF2 -repl_param_list:30;iZ -match_tree;} -e9 -e12 -Grammar{iF2 -rule_count;iF2 -short -rule_list[999 -cS -extern -const -Rule -grammar_rules[];} -tZ1 -DumpParam -cH1 -e42&p,std::ostream&o=std::cout)xR3 -DumpParams -nT2 -paramlist,iF2 -count,std::ostream&o=std::cout);} -#endif -#ifndef M_PI -#define M_PI 3.1415926535897932384626433832795 -#endif -#define CONSTANT_POS_INF HUGE_VAL -#define CONSTANT_NEG_INF (-HUGE_VAL) -lF3 -FUNCTIONPARSERTYPES{xW3 -inline -iV2 -fp_const_pihalf()yR -fp_const_pi -xK()*iV2(0.5);} -xW3 -inline -iV2 -fp_const_twopi(tO2 -fp_const_pi -xK());lH3 -fp_const_twoe(tO2 -fp_const_e -xK());lH3 -fp_const_twoeinv(tO2 -fp_const_einv -xK());lH3 -fp_const_negativezero()yR-fp_epsilon -xK();} -} -#ifdef FP_SUPPORT_OPTIMIZER -#include -#include -#include -yL1{using -lF3 -l21;using -t5;using -lF3 -FUNCTIONPARSERTYPES -nJ1 -class -MatchInfo{eX3 -std -xV3 >lQ;eH -paramholder_matches;std -xV3tR;eX3 -MatchInfo():lQ(),paramholder_matches(),tR(){} -eX3 -bool -SaveOrTestRestHolder -nT2 -n1,iH2&iF1){cV1{lQ.t73 -n1+1);lQ -tQ=iF1 -xJ2 -if(lQ[n1 -tC3==false){lQ -tQ=iF1 -xJ2 -iH2&found=lQ[n1 -tD3;if(iF1.tF3!=found.tF3 -cL -for -iA1 -a=0;an1&&lQ[n1 -tC3==true;} -iH2&GetRestHolderValues -nT2 -n1 -e83{static -iH2 -empty_result;cV1 -return -empty_result -n31 -lQ[n1 -tD3;} -const -std -xV3&GetMatchedParamIndexes(yZ1 -tR -lL3 -swap(tB -b){lQ.swap(b.lQ);cE -swap(b.paramholder_matches);tR.swap(b.tR);} -tB -eA1=cH1 -tB -b){lQ=b.lQ;paramholder_matches=b.paramholder_matches;tR=b.tR -n31*this;} -} -;class -e2;typedef -xRcW;class -e2{eX3 -int -xM3;eX3 -e2():xM3(0){} -virtual~e2(){} -} -;e12 -lX1{bool -found;cW -specs;lX1(bool -f):found(f),specs(){} -lX1(bool -f,const -cW&s):found(f),specs(s){} -} -xR3 -SynthesizeRule -cH1 -eT2 -eJ&tree -tJ3)nJ1 -lX1 -TestParam -cH1 -e42&yG2 -lC2 -tree,const -cW&start_at -tJ3)nJ1 -lX1 -TestParams(tC&nN,lC2 -tree,const -cW&start_at -tJ3,bool -eY2 -nJ1 -bool -ApplyGrammar -cH1 -Grammar&tX2,FPoptimizer_CodeTree::eJ&tree,bool -from_logical_context=false)xR3 -ApplyGrammars(FPoptimizer_CodeTree::e62 -nJ1 -bool -IsLogisticallyPlausibleParamsMatch(tC&c32,lC2 -tree);} -lF3 -l21{tZ1 -DumpMatch -cH1 -eT2 -nO,const -FPoptimizer_Optimize::tB -info,bool -DidMatch,std::ostream&o=std::cout)xR3 -DumpMatch -cH1 -eT2 -nO,const -FPoptimizer_Optimize::tB -info,nH3 -i43,std::ostream&o=std::cout);} -#endif -#include -nI3 -l21::nR2 -yS1=false);nI3 -xB2 -yS1=false); -#include -#include -#include -#include -using -lF3 -l21;using -lF3 -FUNCTIONPARSERTYPES;nI3 -l21::nR2 -yS1){ -#if 1 -nH3 -p=0;switch(opcode -y33 -NumConstant:p="NumConstant" -;lC -tG3:p="ParamHolder" -;lC -SubFunction:p="SubFunction" -;yF3 -std::ostringstream -tmp;assert(p);tmp< -#include -#ifndef FP_GENERATING_POWI_TABLE -enum{MAX_POWI_BYTECODE_LENGTH=20} -; -#else -enum{MAX_POWI_BYTECODE_LENGTH=999} -; -#endif -enum{MAX_MULI_BYTECODE_LENGTH=3} -;lF3 -xH1{xW3 -class -ByteCodeSynth{eX3 -ByteCodeSynth():ByteCode(),Immed(),cM(),xS(0),StackMax(0){i8 -xS3 -64);Immed.xS3 -8);cM.xS3 -16 -lI3 -Pull(std -xV3&bc,std -xV3 -xK&imm,size_t&StackTop_max){for(eQ1=0;aoffset){cM -l62 -first=true;cM -l62 -second=tree;} -} -bool -IsStackTop(nO,int -offset=0 -yZ1(int)xS>offset&&cM -l62 -first&&cM -l62 -second -xF -tree);xI1 -void -EatNParams -nT2 -eat_count){xS-=eat_count -lL3 -ProducedNParams -nT2 -produce_count){xJ1 -xS+produce_count -lI3 -DoPopNMov -iA1 -e52,size_t -srcpos -nL -xK2 -cPopNMov)nS2 -e52)nS2 -srcpos);xJ1 -srcpos+1);cM[e52]=cM[srcpos];xJ1 -e52+1 -lI3 -DoDup -iA1 -xT3 -nL -if(xT3==xS-1){xK2 -cDup -t43{xK2 -cFetch)nS2 -xT3);} -eZ2 -cM[xS-1]=cM[xT3];} -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -i31 -int>void -Dump(){std::ostream&o=std::cout;o<<"Stack state now(" -<0;)if(cM[a -tC3&&cM[a -tD3 -xF -tree -nE3 -a -n31 -t02;} -bool -Find(nO -yZ1 -xU3 -tree)!=t02;} -bool -FindAndDup(nO){size_t -pos=xU3 -tree -eY3 -pos!=t02){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<lN3{StackMax=xS;cM.t73 -lN3;} -} -protected:std -xV3ByteCode;std -xV3 -xK -Immed;std -xV3 >cM;size_t -xS;size_t -StackMax;private:void -incStackPtr(){if(xS+2>lN3 -cM.t73 -StackMax=xS+2);} -i31 -bool -IsIntType,bool -IsComplexType>e12 -c42{} -;eX3 -void -AddOperation -nT2 -t83 -iF2 -eat_count,iF2 -produce_count=1){EatNParams(eat_count);lO1 -opcode);ProducedNParams(produce_count -lI3 -lO1 -iF2 -t83 -c42yS -false,true>yS -true,false>yS -true,true>);inline -void -lO1 -iF2 -opcode){lO1 -t83 -c42());} -} -nJ1 -e12 -SequenceOpCode -nJ1 -e12 -tN1{static -cI -AddSequence;static -cI -MulSequence;} -xR3 -x01 -long -count,cI&eU,yM1;} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;lF3 -xH1{xW3 -e12 -SequenceOpCode{iV2 -basevalue;iF2 -op_flip;iF2 -op_normal,op_normal_flip;iF2 -op_inverse,op_inverse_flip;} -nJ1 -cI -tN1 -xK::AddSequence={y21,cNeg -xE -cAdd,cSub,cRSub} -nJ1 -cI -tN1 -xK::MulSequence={iV2(1),cInv,cMul,cMul,cDiv,cRDiv} -; -#define findName(a,b,c) "var" -#define TryCompilePowi(o) false -#define mData this -#define mByteCode ByteCode -#define mImmed Immed -xY3 -false,false -l31 -# define FP_FLOAT_VERSION 1 -# define FP_COMPLEX_VERSION 0 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -xY3 -true,false -l31 -# define FP_FLOAT_VERSION 0 -# define FP_COMPLEX_VERSION 0 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -#ifdef FP_SUPPORT_COMPLEX_NUMBERS -xY3 -false,true -l31 -# define FP_FLOAT_VERSION 1 -# define FP_COMPLEX_VERSION 1 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -xY3 -true,true -l31 -# define FP_FLOAT_VERSION 0 -# define FP_COMPLEX_VERSION 1 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -#endif -#undef findName -#undef mImmed -#undef mByteCode -#undef mData -#undef TryCompilePowi -} -using -lF3 -xH1; -#define POWI_TABLE_SIZE 256 -#define POWI_WINDOW_SIZE 3 -lF3 -xH1{ -#ifndef FP_GENERATING_POWI_TABLE -extern -const -iF2 -char -powi_table[POWI_TABLE_SIZE];const -#endif -iF2 -char -powi_table[POWI_TABLE_SIZE]={0,1,1,1,2,1,2,1,y63 -4,1,2,y73 -2,1,y63 -8,eK3 -y83 -15,1,16,1,2,1,4,1,2,y73 -2,1,4,eK3 -1,16,1,25,y83 -27,5,8,3,2,1,30,1,31,3,32,1,2,1,y63 -8,1,2,y83 -39,1,16,137,2,1,4,eK3 -y73 -45,135,4,31,2,5,32,1,2,131,50,1,51,1,8,3,2,1,54,1,55,3,16,1,57,133,4,137,2,135,60,1,61,3,62,133,63,1,iG1 -131,iG1 -139,l82 -e3 -30,1,130,137,2,31,l82 -e3 -e3 -130,eK3 -1,e3 -e3 -2,1,130,133,iG1 -61,130,133,62,139,130,137,e3 -l82 -e3 -e3 -iG1 -131,e3 -e3 -130,131,2,133,l82 -130,141,e3 -130,eK3 -1,e3 -5,135,e3 -l82 -e3 -l82 -130,133,130,141,130,131,e3 -e3 -2,131} -;} -static -xC3 -yY=256; -#define FPO(x) -lF3{class -PowiCache{private:int -iB[yY];int -iH1[yY];eX3 -PowiCache():iB(),iH1(){iB[1]=1;} -bool -Plan_Add(c82,int -count){cC1>=yY -cL -iH1[t12+=count -n31 -iB[t12!=0 -lL3 -lO3 -c82){cC1=0){FPO(iM3(iR3,"* I found %ld from cache (%u,%d)\n",value,(unsigned)cache[value],iN3 value]))n31 -iB[t12;eW2-1 -lL3 -Remember(c82,size_t -l04){cC1>=yY)return;FPO(iM3(iR3,"* Remembering that %ld can be found at %u (%d uses remain)\n",value,(unsigned)l04,iN3 value]));iB[t12=(int)l04 -lL3 -DumpContents -e73 -FPO(for(int a=1;a=0||iN3 a]>0){iM3(iR3,"== cache: sp=%d, val=%d, needs=%d\n",cache[a],a,iN3 a]);})} -int -UseGetNeeded(c82){cC1>=0&&value32)throw -false; -#endif -if(iB.Plan_Add(value,need_count -nE3;long -yA3 -1;cC1cN||half<0)std::swap(half,cN);FPO(iM3(iR3,"value=%ld, half=%ld, otherhalf=%ld\n",value,half,otherhalf))lM3==cN){l41 -half,iB,2,l51+1 -t43{l41 -half -y93 -l41 -cN>0?cN:-cN -y93} -iB.lO3 -value);} -xW3 -size_t -y8 -c82 -lF2 -cI&eU,yM1{int -yB3=iB.Find(value -eY3 -yB3>=0)yR -yB3;} -long -yA3 -1;cC10||xM2!=tY1){iI1 -xM2)cS2 -half,tY1);} -x01 -value/half,eU,iS2 -size_t -l04=tY1 -cS2 -value,l04);iB.DumpContents()n31 -l04;} -lJ2 -half&64){yA3-tB2} -} -else -cC1&1)yA3 -value&((1<cN||half<0)std::swap(half,cN);FPO(iM3(iR3,"* I want %ld, my plan is %ld + %ld\n",value,half,value-half))lM3==cN){size_t -xM2=y8 -half -tX1 -c01 -xM2,half,xM2,half,iB,eU.op_normal,eU.op_normal_flip,iS2} -else{long -part1=half;long -part2=cN>0?cN:-cN;size_t -part1_pos=y8 -part1 -tX1 -size_t -part2_pos=y8 -part2 -tX1 -FPO(iM3(iR3,"Subdivide(%ld: %ld, %ld)\n",value,half,otherhalf));c01 -part1_pos,part1,part2_pos,part2,iB,cN>0?eU.op_normal:eU.op_inverse,cN>0?eU.op_normal_flip:eU.op_inverse_flip,iS2} -size_t -l04=tY1 -cS2 -value,l04);iB.DumpContents()n31 -l04;} -tZ1 -c01 -size_t -apos,long -aval,size_t -bpos,long -bval -lF2 -iF2 -cumulation_opcode,iF2 -cumulation_opcode_flip,yM1{int -a_needed=iB -lL2 -aval);int -yC3=iB -lL2 -bval);bool -lM2 -tO3 -#define DUP_BOTH() do{if(apos "iX3 iX3"op\n",(unsigned)apos,(unsigned)bpos));iI1 apos);iI1 apos==bpos?tY1:bpos);}while(0) -#define DUP_ONE(p) do{FPO(iM3(iR3,"-> "iX3"op\n",(unsigned)p));iI1 p);}while(0) -if(a_needed>0){if(yC3>0){nL2} -e63 -bpos!=tY1)nL2 -else{lN2 -lM2=!lM2;} -} -} -lJ2 -yC3>0){if(apos!=tY1)nL2 -else -DUP_ONE(bpos);} -e63 -apos==bpos&&apos==tY1)lN2 -iR2 -tY1&&bpos==yD3 -2){FPO(iM3(iR3,"-> op\n"));lM2=!lM2;} -iR2 -yD3 -2&&bpos==tY1)FPO(iM3(iR3,"-> op\n"));iR2 -tY1)DUP_ONE(bpos);lJ2 -bpos==tY1){lN2 -lM2=!lM2;} -else -nL2} -yE3 -lM2?cumulation_opcode_flip:cumulation_opcode,2);} -tZ1 -cD1 -long -count,cI&eU,yM1{while -eL3<256){int -yA3 -xH1::powi_table[count]lM3&128){half&=127;cD1 -half,eU,iS2 -count/=half;} -else -yF3 -if -eL3==1)return;if(!eL3&1)){yE3 -cSqr,1);cD1 -count/2,eU,iS2} -else{iI1 -tY1);cD1 -count-1,eU,iS2 -yE3 -cMul,2);} -} -} -lF3 -xH1{tZ1 -x01 -long -count,cI&eU,yM1{if -eL3==0)lH2 -eU.basevalue);else{bool -t22 -tO3 -if -eL3<0){t22=true;count=-count;} -if(false)cD1 -count,eU,iS2 -lJ2 -count>1){PowiCache -iB;l41 -count,iB,1);size_t -xK1=synth.GetStackTop();iB.Start(tY1);FPO(iM3(iR3,"Calculating result for %ld...\n",count));size_t -xN2=y8 -count -tX1 -size_t -n_excess=yD3 -xK1;if(n_excess>0||xN2!=xK1-1){synth.DoPopNMov(xK1-1,xN2);} -} -if(t22)yE3 -eU.op_flip,1);} -} -} -#endif -#ifndef FPOptimizer_ValueRangeHH -#define FPOptimizer_ValueRangeHH -t5{lF3 -lP3{iM -e12 -Comp{} -;i31>e12 -CompxZ3xZ3<=n9 -cGreater>xZ3>n9 -cGreaterOrEq>xZ3>=n9 -cEqual>xZ3==n9 -cNEqual>xZ3!=b;} -} -;} -xW3 -e12 -cJ1{iV2 -val;bool -known;cJ1():val(),known(false){} -cJ1 -cG1 -v):val(v),known(true){xI1 -void -set -cG1 -v){known=true;val=v -lL3 -set(iV2(iJ1(iV2),cJ1 -y9)val=iI2 -void -set(iV2(iJ1 -cG1),cJ1 -y9)val=iI2 -iM -void -set_if(iV2 -v -tG1 -iJ1(iV2),cJ1 -y9&&lP3::Comp()(val,v))val=iI2 -iM -void -set_if -cG1 -v -tG1 -iJ1 -cG1),cJ1 -y9&&lP3::Comp()(val,v))val=iI2} -nJ1 -e12 -range{cJ1 -xK -min,max;range():min(),max(){} -range(iV2 -mi,iV2 -ma):min(mi),max(ma){} -range(bool,iV2 -ma):min(),max(ma){} -range(iV2 -mi,bool):min(mi),max(){} -void -set_abs();void -set_neg();} -nJ1 -bool -IsLogicalTrueValue -cH1 -c23&p -tR2 -nJ1 -bool -IsLogicalFalseValue -cH1 -c23&p -tR2;} -#endif -#ifndef FPOptimizer_RangeEstimationHH -#define FPOptimizer_RangeEstimationHH -t5{enum -TriTruthValue{IsAlways,IsNever,Unknown} -nJ1 -c23 -iN -lC2 -tree)nJ1 -bool -IsLogicalValue -cH1 -e62 -nJ1 -TriTruthValue -GetIntegerInfo -cH1 -e62 -nJ1 -xL1 -GetEvennessInfo -cH1 -e62{if(!tree -i61)return -Unknown;yJ1=eC3;if(isEvenInteger(value -nF3 -isOddInteger(value -nG3 -xW3 -xL1 -GetPositivityInfo -cH1 -e62{c23 -p=iN -tree -eY3 -p -n51&&p -tF2>=iV2(nF3 -p -yN -known -lH1 -nG3 -xW3 -xL1 -GetLogicalValue -lQ3 -tree -tR2{c23 -p=iN -tree -eY3 -IsLogicalTrueValue(p,abs -nF3 -IsLogicalFalseValue(p,abs -nG3} -#endif -#ifndef FPOptimizer_ConstantFoldingHH -#define FPOptimizer_ConstantFoldingHH -t5{tZ1 -ConstantFolding(e62;} -#endif -lF3{using -lF3 -FUNCTIONPARSERTYPES;using -t5;e12 -ComparisonSetBase{enum{t93=0x1,Eq_Mask=0x2,Le_Mask=0x3,tA3=0x4,tB3=0x5,Ge_Mask=0x6} -;static -int -Swap_Mask(int -m)yR(m&Eq_Mask)|((m&t93)?tA3:0)|((m&tA3)?t93:0);} -enum -c11{Ok,BecomeZero,BecomeOne,xP2 -xF3 -nW2{cond_or,iK2,iL2,iM2} -;} -nJ1 -e12 -ComparisonSet:public -ComparisonSetBase{e12 -t32{eJ -a;eJ -b;int -relationship;t32():a(),b(),relationship(){} -} -;std -xV3eK;e12 -Item{eJ -value;bool -c52;Item():value(),c52(false){} -} -;std -xV3cK1;int -xM1;ComparisonSet():eK(),cK1(),xM1(0){} -c11 -AddItem -lQ3 -a,bool -c52,nW2 -type){for -iA1 -c=0;cbool -ConstantFolding_LogicCommon(eJ&tree,CondType -xA1,bool -xS2){bool -should_regenerate -tO3 -ComparisonSet -xK -comp;nB1{xK3 -c6 -c11 -eM3=c6 -Ok;lC2 -atree=t33;switch(atree -nC -y33 -cEqual -lG -Eq_Mask,xA1);lC -cNEqual -lG -tB3,xA1);lC -cLess -lG -t93,xA1);lC -cLessOrEq -lG -Le_Mask,xA1);lC -cGreater -lG -tA3,xA1);lC -cGreaterOrEq -lG -Ge_Mask,xA1);lC -cNot:eM3 -yO1 -l8 -0),true,xA1);lC -cNotNot:eM3 -yO1 -l8 -0),false,xA1);break;c73 -if(xS2||IsLogicalValue(atree))eM3 -yO1,false,xA1);l73 -eM3){ReplaceTreeWithZero:xO -0)n31 -true;ReplaceTreeWithOne:xO -1);nV -c6 -Ok:lC -c6 -BecomeZero -eL -c6 -BecomeOne:i6 -c6 -xP2:c41 -yF3} -if(should_regenerate){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Before ConstantFolding_LogicCommon: " -yA1 -#endif -if(xS2){tree.DelParams(t43{for -iY{lC2 -atree=lE2 -a -eY3 -IsLogicalValue(atree))eK2} -for -iA1 -a=0;a -#include -#include -lF3{using -lF3 -FUNCTIONPARSERTYPES;using -t5;e12 -CollectionSetBase{enum -xR1{Ok,xP2} -;} -nJ1 -e12 -CollectionSet:public -CollectionSetBase{e12 -c21{eJ -value;eJ -xT2;bool -cX;c21():value(),xT2(),cX(false){} -c21 -lQ3 -v,lC2 -f):value(v),xT2(f),cX(false){} -} -;std::multimapiC;typedef -xK3 -std::multimap::yV3 -xS1;CollectionSet():iC(){} -xS1 -FindIdenticalValueTo -lQ3 -value){fphash_t -hash=value.GetHash();for(xS1 -i=iC.xU2 -hash);i!=iC.cY1 -hash;++i){cC1 -xF -i -e82.value -nE3 -i;} -return -iC.end();} -bool -Found -cH1 -xS1&b)yR -b!=iC.end();} -xR1 -AddCollectionTo -lQ3 -xT2,const -xS1&into_which){c21&c=into_which -e82;if(c.cX)c.xT2 -c9 -xT2);else{eJ -add;add -xD -cAdd);add -yP1 -c.xT2);add -c9 -xT2);c.xT2.swap(add);c.cX=true;} -return -xP2;} -xR1 -nX2 -lQ3 -value,lC2 -xT2){const -fphash_t -hash=value.GetHash();xS1 -i=iC.xU2 -hash);for(;i!=iC.cY1 -hash;++i){if(i -e82.value -xF -value -nE3 -AddCollectionTo(xT2,i);} -iC.yR3,std::make_pair(hash,c21(value,xT2)))n31 -Ok;} -xR1 -nX2 -lQ3 -a)yR -nX2(a,nF1 -1)));} -} -nJ1 -e12 -ConstantExponentCollection{typedef -eH -yT3;typedef -std::x31 -xV2;std -xV3data;ConstantExponentCollection():data(){} -void -MoveToSet_Unique -cG1 -eB1&eC1){data.push_back(std::x31(eB1()));data.back()tE3.swap(eC1 -lI3 -MoveToSet_NonUnique -cG1 -eB1&eC1){xK3 -std -xV3::yV3 -i=std::xU2 -data.iN2 -data.end(),exponent,Compare1st()eY3 -i!=data.cY1 -xG2{i -e82.yR3 -e82.end(),eC1.iN2 -eC1.end()t43{data.yR3,std::x31 -t62,eC1));} -} -bool -Optimize(){bool -changed -tO3 -std::sort(data.iN2 -data.end(),Compare1st());redo:for -iA1 -a=0;a=fp_abs(exp_a))break -iU2 -exp_diff_still_probable_integer=xW2*iV2(16 -eY3 -t42 -exp_diff_still_probable_integer)&&!(t42 -exp_b)&&!t42 -xW2))){yT3&a_set=lQ2;yT3&b_set=data[b -tD3; -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Before ConstantExponentCollection iteration:\n" -;t52 -cout); -#endif -if(isEvenInteger(exp_b)&&!isEvenInteger(xW2+exp_a)){eJ -tmp2;tmp2 -tH3 -tmp2 -iO3 -b_set);tmp2 -eT1 -t81 -cAbs);tmp -yP1 -tmp2);tmp -eT1 -b_set.t73 -1);b_set[0].i72} -a_set.insert(a_set.end(),b_set.iN2 -b_set.end());yT3 -b_copy=b_set;data.erase(data.begin()+b);MoveToSet_NonUnique(xW2,b_copy);x62 -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"After ConstantExponentCollection iteration:\n" -;t52 -cout); -#endif -cZ} -eW2 -changed;} -#ifdef DEBUG_SUBSTITUTIONS -void -t52 -ostream&out){for -iA1 -a=0;a0)out<<'*'i13(lQ2[b],out);} -out<eE1;typedef -std::multimapcL1;cL1 -tD;xX2 -eV1::xS1 -j=mul.iC.yU3 -j!=mul.iC.end();++j){eJ&value=j -e82.value;eJ&e92 -j -e82.xT2;if(j -e82.cX)exponent -eT1 -const -fphash_t -eF1=exponent.GetHash();xK3 -cL1::yV3 -i=tD.xU2 -eF1);for(;i!=tD.cY1 -eF1;++i)if(i -e82.first -xF -xG2){if(!exponent -i61||!e01 -nC1 -tG1 -1)))c41 -i -e82 -tE3.push_back(value);goto -skip_b;} -tD.yR3,std::make_pair(eF1,std::make_pair -t62,eH -iA1(1),value))));skip_b:;} -#ifdef FP_MUL_COMBINE_EXPONENTS -ConstantExponentCollection -xK -e11;xX2 -cL1::yV3 -j,i=tD.yU3 -i!=tD.end();i=j){j=i;++j;eE1&list=i -e82;if(list.first -l71 -e92 -list.first -nC1;if(!t62==xD1)e11.MoveToSet_Unique -t62,list -iO2;tD.erase(i);} -} -if(e11.Optimize())c41 -#endif -if(should_regenerate){eJ -before=tree;before.l61 -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Before ConstantFolding_MulGrouping: " -i13(before -lT2"\n" -; -#endif -tree.DelParams();xX2 -cL1::yV3 -i=tD.yU3 -i!=tD.end();++i){eE1&list=i -e82; -#ifndef FP_MUL_COMBINE_EXPONENTS -if(list.first -l71 -e92 -list.first -nC1;if -t62==xD1 -continue;if(e01 -xE3 -tree.AddParamsMove(list -iO2;eR2} -#endif -eJ -mul;mul -tH3 -mul -iO3 -list -iO2;mul -eT1 -if(xH&&list.first -i51 -list.first -nC1==iV2(1)/iV2(3)){eJ -cbrt;cbrt -xD -cCbrt);cbrt.e4 -cbrt -cK -cbrt -xW -0.5)){eJ -sqrt;sqrt -xD -cSqrt);sqrt.e4 -sqrt -cK -sqrt -xW-0.5)){eJ -rsqrt;rsqrt -xD -cRSqrt);rsqrt.e4 -rsqrt -cK -rsqrt -xW-1)){eJ -inv;inv -xD -cInv);inv.e4 -inv -cK -inv);eR2} -eJ -pow;pow -xD -cPow);pow.e4 -pow -yP1 -list.first);pow -cK -pow);} -#ifdef FP_MUL_COMBINE_EXPONENTS -tD.clear()yM3 -0;a0){if(tE>1){std -xV3 >nU;std::multimapeG1;bool -lS3 -tO3 -nB1 -iC1{i81 -t33.tP3{lC2 -p=t33 -l8 -b);const -fphash_t -p_hash=p.GetHash();for(std::multimap::const_iterator -i=eG1.xU2 -p_hash);i!=eG1.cY1 -p_hash;++i){if(nU[i -e82 -tC3 -xF -p)){nU[i -e82 -tD3+=1;lS3=true;goto -found_mulgroup_item_dup;} -} -nU.push_back(std::make_pair(p,size_t(1)));eG1.insert(std::make_pair(p_hash,nU.tF3-1));found_mulgroup_item_dup:;} -} -if(lS3){eJ -eA2;{size_t -max=0;for -iA1 -p=0;pmax){eA2=nU[p -tC3;max=nU[p -tD3;} -} -} -eJ -group_add;group_add -xD -cAdd); -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Duplicate across some trees: " -i13(eA2 -lT2" in " -yA1 -#endif -nB1 -iC1 -i81 -t33.tP3 -if(eA2 -xF -t33 -l8 -b))){eJ -tmp -y91 -a)yA -CloneTag());tmp -tK2 -b);tmp -eT1 -group_add -yP1 -tmp);remaining[a]tO3 -yF3 -group_add -eT1 -eJ -group;group -tH3 -group -yP1 -eA2);group -yP1 -group_add);group -eT1 -add.nX2(group);c41} -} -nB1 -iC1{if(add.nX2 -y91 -a))==CollectionSetBase::xP2)c41} -} -if(should_regenerate){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Before ConstantFolding_AddGrouping: " -yA1 -#endif -tree.DelParams();xX2 -eV1::xS1 -j=add.iC.yU3 -j!=add.iC.end();++j){eJ&value=j -e82.value;eJ&coeff=j -e82.xT2;if(j -e82.cX)coeff -eT1 -if(coeff -i51 -cB3 -coeff -nC1,xD1 -cP2 -cA3 -coeff -nC1 -xE3 -lP1 -value);eR2} -eJ -mul;mul -tH3 -mul -yP1 -value);mul -yP1 -coeff);mul -cK -mul);} -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"After ConstantFolding_AddGrouping: " -yA1 -#endif -return -true;} -return -tR3} -lF3{using -lF3 -FUNCTIONPARSERTYPES;using -t5 -nJ1 -bool -ConstantFolding_IfOperations(iS3(tree.GetOpcode()==cIf||tree.GetOpcode()==cAbsIf);for(;;){lT3 -nC==cNot){tI3 -cIf);lE2 -0).xY2 -0)lR2 -eO3.swap -y91 -2)t43 -lT3 -cS1{tI3 -yW3;lE2 -0).xY2 -0)lR2 -eO3.swap -y91 -2)t43 -yJ3 -tM -0),i01==yW3)l92 -tree.xY2 -1));nV -lC3 -tree.xY2 -2));nV -lT1 -lT3 -nC==cIf||lE2 -0)nC==yW3{eJ -cond=lE2 -0);eJ -lU3;lU3 -t53==cIf?cNotNot:cAbsNotNot);lU3 -xZ2 -1));ConstantFolding(lU3);eJ -lV3;lV3 -t53==cIf?cNotNot:cAbsNotNot);lV3 -xZ2 -2));ConstantFolding(lV3 -eY3 -lU3 -i61||lV3 -i61){eJ -eV;eV -t53);eV -xZ2 -1));eV.nJ -1));eV.nJ -2));eV -eT1 -eJ -eW;eW -t53);eW -xZ2 -2));eW.nJ -1));eW.nJ -2));eW -eT1 -tree -t53);cM1 -0,cond -lR2 -tree.nG1 -1,eV);tree.nG1 -2,eW)xJ2} -if -y91 -1)nC==lE2 -2)nC&&y91 -1)nC==cIf||eO3 -nC==yW3){eJ&iE2=eO3;eJ&leaf2=lE2 -2 -eY3 -iE2 -l8 -0)xC1 -0))&&c93 -1))||iE2 -l8 -2)xC1 -2)))){eJ -eV;eV -iP2 -eV.nJ -0));eV -c9 -iE2 -l8 -1));eV -c9 -leaf2 -l8 -1));eV -eT1 -eJ -eW;eW -iP2 -eW.nJ -0));eW -c9 -iE2 -l8 -2));eW -c9 -leaf2 -l8 -2));eW -iU -SetParam(0,iE2 -lR2 -tree.nG1 -1,eV);tree.nG1 -2,eW)xJ2 -if -c93 -1))&&iE2 -l8 -2)xC1 -2))){eJ -eX;eX -iP2 -eX.AddParamMove -y91 -0));eX -c9 -iE2 -lR2 -eX -c9 -leaf2 -lR2 -eX -iU -nG1 -0,eX);cM1 -2,iE2 -l8 -2));cM1 -1,iE2 -l8 -1))xJ2 -if -c93 -2))&&iE2 -l8 -2)xC1 -1))){eJ -eB2;eB2 -xD -leaf2 -nC==cIf?cNot:cZ3);eB2 -c9 -leaf2 -lR2 -eB2 -eT1 -eJ -eX;eX -iP2 -eX.AddParamMove -y91 -0));eX -c9 -iE2 -lR2 -eX -yP1 -eB2);eX -iU -nG1 -0,eX);cM1 -2,iE2 -l8 -2));cM1 -1,iE2 -l8 -1))xJ2} -eJ&xX=eO3;eJ&y6=lE2 -2 -eY3 -xX -xF -y6)){tree.xY2 -1))xJ2 -const -OPCODE -op1=xX -nC;const -OPCODE -op2=y6 -nC;if -eN3 -op2){if(xX -cE1 -1){eJ -lO -0));lW3 -lR2 -tQ3 -n4 -if(xX -cE1 -2&&y6 -cE1 -2){if(xX -l8 -0)xF -y6 -l8 -0))){eJ -param0=xX -l8 -0);eJ -lO -1));lW3 -l8 -1));tQ3;lP1 -param0)n4 -if(xX -l8 -1)xF -y6 -l8 -1))){eJ -param1=xX -l8 -1);eJ -lO -0));lW3 -lR2 -tQ3;lP1 -nE1);lP1 -param1)xJ2} -if -eN3 -yZ3 -cMul -lS2 -cAnd -lS2 -cOr -lS2 -cAbsAnd -lS2 -cAbsOr -lS2 -cMin -lS2 -cMax){eH -lX3;yZ{for -iA1 -b=y6.xF1 -b-->0;){if -c62 -y6 -l8 -b))){if(lX3 -cT3){xX.l61 -y6.l61} -lX3.push_back(xX -x13 -y6 -tK2 -b);xX -t31 -cT2} -} -if(!lX3 -cT3){xX -eT1 -y6.Rehash()l7 -op1);tree -iO3 -lX3)n4} -} -if -eN3 -yZ3 -cMul||eN3 -cAnd -nT1 -y6))||eN3 -cOr -nT1 -y6))){yZ -if -c62 -y6)){xX.l61 -xX -t31);xX -eT1 -eJ -cO1=y6;y6=tF -op1==yZ3 -cOr -tE2 -op1);lP1 -cO1)n4} -if(eN3 -cAnd -lS2 -cOr)&&op2==cNotNot){eJ&lY3=y6 -l8 -0);yZ -if -c62 -lY3)){xX.l61 -xX -t31);xX -eT1 -eJ -cO1=lY3;y6=tF -op1 -yY3 -op1);lP1 -cO1)n4} -if(op2==cAdd||op2==cMul||(op2==cAnd -nT1 -xX))||(op2==cOr -nT1 -xX))){for -iA1 -a=y6 -n41 -y6 -l8 -a)xF -xX)){y6.l61 -y6 -t31);y6 -eT1 -eJ -cP1=xX;xX=tF -op2==cAdd||op2 -yY3 -op2);lP1 -cP1)n4} -if((op2==cAnd||op2==cOr)&&op1==cNotNot){eJ&lZ3=xX -l8 -0)yM3 -y6 -n41 -y6 -l8 -a)xF -lZ3)){y6.l61 -y6 -t31);y6 -eT1 -eJ -cP1=lZ3;xX=tF -op2 -yY3 -op2);lP1 -cP1)n4} -return -tR3} -#include -lF3{using -lF3 -FUNCTIONPARSERTYPES;using -t5 -nJ1 -int -maxFPExponent()yR -std::numeric_limits -xK::max_exponent;} -xN1 -x51 -iV2 -base,iV2 -xG2{if(base=iV2(maxFPExponent -xK())/fp_log2(base);} -xN1 -ConstantFolding_PowOperations(iS3(tree.GetOpcode()==cPow);nR&&eO3 -l71 -const_value -t03 -lR,tH);xO -const_value)n31 -tR3 -tM2 -cB3 -tH -xE3 -tree.xY2 -0))xJ2 -nR&&cB3 -lR -xE3 -xO -1)n31 -tR3 -nR&&eO3 -nC==cMul){bool -y02=false -iU2 -lU2=lR;eJ -mulgroup=eO3 -yM3 -mulgroup -n41 -mulgroup -l8 -a)l71 -imm=mulgroup -l8 -a)nC1;{if(x51 -lU2,imm))break -iU2 -lV2 -t03 -lU2,imm)cA3 -lV2,xD1)break;if(!y02){y02=true;yQ1 -l61} -lU2=lV2;yQ1 -DelParam(a -cT2} -if(y02){yQ1 -Rehash(); -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Before pow-mul change: " -yA1 -#endif -lE2 -0).Become(e21 -lU2));eO3.Become -lR3); -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"After pow-mul change: " -yA1 -#endif -} -} -tM2 -lE2 -0)nC==cMul -tJ2 -lW2=tH -iU2 -y12=1.0;bool -y02 -tO3 -eJ&mulgroup=lE2 -0)yM3 -mulgroup -n41 -mulgroup -l8 -a)l71 -imm=mulgroup -l8 -a)nC1;{if(x51 -imm,lW2))break -iU2 -eH1 -t03 -imm,lW2)cA3 -eH1,xD1)break;if(!y02){y02=true;yQ1 -l61} -y12*=eH1;yQ1 -DelParam(a -cT2} -if(y02){yQ1 -Rehash();eJ -eS3;eS3 -xD -cPow);eS3 -iO3 -tree.l02));eS3.n62 -tree -tH3 -lP1 -eS3);i83 -e21 -y12))xJ2} -lT3 -nC==cPow&&eO3 -i61&&lE2 -0)l8 -1)l71 -a=lE2 -0)l8 -1)nC1 -iU2 -b=tH -iU2 -c=a*b;if(isEvenInteger(a)&&!isEvenInteger(c)){eJ -n03;n03 -xD -cAbs);n03.nJ -0)lR2 -n03 -eT1 -tree.nG1 -0,n03 -t43 -cM1 -0,lE2 -0)lR2 -cM1 -1,e21 -c));} -return -tR3} -lF3{using -lF3 -FUNCTIONPARSERTYPES;using -t5;e12 -l5{enum -eC2{MakeFalse=0,MakeTrue=1,t72=2,n23=3,MakeNotNotP0=4,MakeNotNotP1=5,MakeNotP0=6,MakeNotP1=7,xB=8 -xF3 -lX2{Never=0,Eq0=1,Eq1=2,c03=3,c13=4} -;eC2 -if_identical;eC2 -lY2 -4];e12{eC2 -what:4;lX2 -when:4;} -iK1,iL1,iM1,iN1 -nJ1 -eC2 -Analyze -lQ3 -a,lC2 -b -e83{if(a -xF -b -nE3 -if_identical;c23 -p0=iN -a);c23 -p1=iN -b);eR3 -known&&p1 -n51){eR3 -valp1 -yN -val&&lY2 -2]i4 -2];if(p0 -tF2>=p1 -yN -val&&lY2 -3]i4 -3];} -if(IsLogicalValue(a)){if(iK1 -tP2 -iK1.when,p1 -nE3 -iK1.what;if(iM1 -tP2 -iM1.when,p1 -nE3 -iM1.what;} -if(IsLogicalValue(b)){if(iL1 -tP2 -iL1.when,p0 -nE3 -iL1.what;if(iN1 -tP2 -iN1.when,p0 -nE3 -iN1.what;} -return -xB;} -cA1 -bool -TestCase(lX2 -when,const -c23&p){if(!p -n51||!p -yN -known -cL -switch(when -y33 -Eq0 -nV1==iV2(0.0)&&e13==p -tF2;case -Eq1 -nV1==iV2(1.0)&&e13==e13;case -c03 -nV1>y21&&e13<=iV2(1);case -c13 -nV1>=y21 -lH1 -1);c73;} -return -tR3} -;lF3 -RangeComparisonsData{static -const -l5 -Data[6]={{l5 -c51,{l5::tU -xB,l5::tU -xB -iT -Eq1 -iW -Eq1 -nX1 -Eq0 -nY1 -Eq0} -eI1 -c51,l5::xB,l5 -c51,l5::xB -iT -Eq0 -iW -Eq0 -nX1 -Eq1 -nY1 -Eq1} -eI1 -c51,l5::t72,l5::tU -MakeFalse -nX1 -c03 -iW -c13 -yD -cC -yD -n13{l5::xB,l5 -c51,l5::tU -n23 -nX1 -c13 -iW -c03 -yD -cC -eI1::tU -tU -n13 -l5::t72 -iT -c13 -nY1 -c03 -yD -cC -yD -n13{l5::tU -n23,l5::xB,l5 -c51 -iT -c03 -nY1 -c13 -yD -cC} -} -;} -xN1 -ConstantFolding_Comparison(e62{using -lF3 -RangeComparisonsData;assert(tree.GetOpcode()>=cEqual&&tree.GetOpcode()<=cGreaterOrEq);switch(Data[i01-cEqual].Analyze -y91 -0),eO3)y33 -l5::MakeFalse:xO -0);nV -l5 -c51:xO -1)yN3 -n23:tI3 -cEqual)yN3 -t72:tI3 -cNEqual)yN3 -MakeNotNotP0:tI3 -cNotNot)yO3 -1)yN3 -MakeNotNotP1:tI3 -cNotNot)yO3 -0)yN3 -MakeNotP0:tI3 -cNot)yO3 -1)yN3 -MakeNotP1:tI3 -cNot)yO3 -0)yN3 -xB:;} -if -y91 -1)i61)switch -y91 -0)nC -y33 -cAsin:lM -fp_sin -c53 -cAcos:lM -fp_cos -tG));tI3 -i01==cLess?cGreater:i01==cLessOrEq?cGreaterOrEq:i01==cGreater?cLess:i01==cGreaterOrEq?cLessOrEq:i01);nV -cAtan:lM -fp_tan -c53 -cLog:lM -fp_exp -c53 -cSinh:lM -fp_asinh -c53 -cTanh:if(fp_less(fp_abs -tG -xE3 -lM -fp_atanh -tG))xJ2 -break;c73 -yF3 -return -tR3} -#include -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;lF3{ -#ifdef DEBUG_SUBSTITUTIONS -yE -double -d){union{double -d;uint_least64_t -h;} -t82 -d=d;lM1 -h -nZ1 -#ifdef FP_SUPPORT_FLOAT_TYPE -yE -float -f){union{float -f;uint_least32_t -h;} -t82 -f=f;lM1 -h -nZ1 -#endif -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -yE -long -double -ld){union{long -double -ld;e12{uint_least64_t -a;iF2 -short -b;} -s;} -t82 -ld=ld;lM1 -s.b<IsIdenticalTo(*b.data);} -xN1 -xH2 -xK::IsIdenticalTo -cH1 -xH2 -xK&b -e83{if(Hash!=b.Hash -cL -if(Opcode!=tK3 -cL -switch(Opcode -y33 -cImmed:return -cB3 -Value,tL3;case -l03:return -l22==b.l12 -case -cFCall:case -cPCall:if(l22!=b.l22 -cL -break;c73 -yF3 -if(xX3!=b.xX3 -cL -for -iA1 -a=0;a1)data=new -xH2 -xK(*data);} -xW3 -eJ -eJ::GetUniqueRef(){if(GetRefCount()>1)return -eJ(*this,CloneTag())n31*this;} -tX):yT -cNop -t92(),n8 -tX -const -xH2&b):yT -tK3 -t92(tL3,l22(b.cQ1,Params(b.Params),Hash(b.Hash),Depth(b.Depth),tP1 -b.l32){} -tX -const -iV2&i):yT -cImmed -t92(i),n8 -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -tX -xH2 -xK&&b):yT -tK3 -t92 -c72 -tL3),l22(b.cQ1,Params -c72 -b.Params)),Hash(b.Hash),Depth(b.Depth),tP1 -b.l32){} -tX -iV2&&i):yT -cImmed -t92 -c72 -i)),n8 -#endif -tX -xB2 -o):yT -o -t92(),n8 -tX -xB2 -o,iF2 -f):yT -o -t92(),l22(f),Params(),Hash(),Depth(1),tP1 -0){} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -#include -#include -#include -#include -#include -using -lF3 -FUNCTIONPARSERTYPES; -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -lF3{tZ1 -n12(nO,std -c7&done,std::ostream&o){nB1 -n12 -l64 -done,o);std::ostringstream -buf -i13(tree,buf);done[tree.GetHash()].insert(buf.str());} -} -#endif -t5{ -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -tZ1 -DumpHashes(cF){std -c7 -done;n12(tree,done,o);for(std -c7::const_iterator -i=done.yU3 -i!=done.end();++i){const -std::set&flist=i -e82;if(flist.tF3!=1)o<<"ERROR - HASH COLLISION?\n" -;for(std::set::const_iterator -j=flist.yU3 -j!=flist.end();++j){o<<'['<first.hash1<<','<first.hash2<<']'<0)o<<' 'i13 -l64 -o -eY3 -a+1 -lF3 -l21{iF2 -ParamSpec_GetDepCode -cH1 -e42&b -y13 -b.first -y33 -tG3:{cO*s=(cO*)b -tE3 -n31 -s->depcode;} -case -SubFunction:{cP*s=(cP*)b -tE3 -n31 -s->depcode;} -c73 -yF3 -return -0;} -tZ1 -DumpParam -cH1 -e42&yG2 -std::ostream&o){static -const -char -ParamHolderNames[][2]={"%" -,"&" -,"x" -,"y" -,"z" -,"a" -,"b" -,"c" -} -;iF2 -y32 -0;switch(yH2.first -y33 -NumConstant:{const -ParamSpec_NumConstant -xK -yK3 -cH1 -ParamSpec_NumConstant -xK*c61 -using -lF3 -FUNCTIONPARSERTYPES;o.precision(12);o<';yF -PositionalParams)o<<"]" -;yF -SelectedParams)o<<"}" -;o<<')';} -yF3 -l73 -ImmedConstraint_Value(constraints&ValueMask)y33 -ValueMask:lC -Value_AnyNum:lC -nY2:o<<"@E" -;lC -Value_OddInt:o<<"@O" -;lC -tS1:o<<"@I" -;lC -Value_NonInteger:o<<"@F" -;lC -eJ1:o<<"@L" -;yJ3 -ImmedConstraint_Sign(constraints&SignMask)y33 -SignMask:lC -Sign_AnySign:lC -nH1:o<<"@P" -;lC -eK1:o<<"@N" -;yJ3 -ImmedConstraint_Oneness(constraints&OnenessMask)y33 -OnenessMask:lC -Oneness_Any:lC -Oneness_One:o<<"@1" -;lC -Oneness_NotOne:o<<"@M" -;yJ3 -ImmedConstraint_Constness(constraints&ConstnessMask)y33 -ConstnessMask:lC -tR1:if(yH2.first==tG3){cO -yK3(cO*c61 -if -y23 -index<2)yF3 -o<<"@C" -;lC -Constness_NotConst:o<<"@V" -;lC -Oneness_Any:yF3} -tZ1 -DumpParams -nT2 -paramlist,iF2 -count,std::ostream&o){for(eQ1=0;a0)o<<' ';const -e42¶m=e81 -xK(paramlist,a);DumpParam -xK(param,o);iF2 -depcode=ParamSpec_GetDepCode(param -eY3 -depcode!=0)o<<"@D" -< -using -lF3 -l21;using -lF3 -FUNCTIONPARSERTYPES;lF3{cO -plist_p[37]={{2,0,0x0} -nP -0,0x4} -nP -nH1,0x0} -nP -eK1|Constness_NotConst,0x0} -nP -Sign_NoIdea,0x0} -nP -eJ1,0x0} -,{3,Sign_NoIdea,0x0} -,{3,0,0x0} -,{3,eJ1,0x0} -,{3,0,0x8} -,{3,Value_OddInt,0x0} -,{3,Value_NonInteger,0x0} -,{3,nY2,0x0} -,{3,nH1,0x0} -,{0,eK1|lV{0,lV{0,nH1|lV{0,nY2|lV{0,tR1,0x1} -,{0,tS1|nH1|lV{0,tT1 -tR1,0x1} -,{0,tT1 -lV{0,Oneness_One|lV{0,eJ1|lV{1,lV{1,nY2|lV{1,tT1 -lV{1,tS1|lV{1,nH1|lV{1,eK1|lV{6,0,0x0} -,{4,0,0x0} -,{4,tS1,0x0} -,{4,lV{4 -tU3 -5,0,0x0} -,{5,lV} -nJ1 -e12 -plist_n_container{static -const -ParamSpec_NumConstant -xK -plist_n[20];} -nJ1 -const -ParamSpec_NumConstant -xK -plist_n_container -xK::plist_n[20]={{iV2(-2 -tY-1 -tY-0.5 -tY-0.25 -tY -0 -tA2 -fp_const_deg_to_rad -xK(tA2 -fp_const_einv -xK(tA2 -fp_const_log10inv -xK(tY -0.5 -tA2 -fp_const_log2 -xK(tY -1 -tA2 -fp_const_log2inv -xK(tY -2 -tA2 -fp_const_log10 -xK(tA2 -fp_const_e -xK(tA2 -fp_const_rad_to_deg -xK(tA2-fp_const_pihalf -xK(),xT1{y21,xT1{fp_const_pihalf -xK(),xT1{fp_const_pi -xK(),xT1} -;cP -plist_s[517]={{{1,15,tS2 -398,tS2 -477,tS2 -15,cNeg,GroupFunction,0} -,tR1,0x1} -,{{1,15,y42 -24,y42 -465,y42 -466,y42 -498,cInv,lT -2,327995 -xE -l0 -2,48276 -xE -l6 -260151 -xE -l6 -470171 -xE -l6 -169126 -xE -l6 -48418 -xE -l6 -1328 -xE -l6 -283962 -xE -l6 -169275 -xE -l6 -39202 -xE -l6 -283964 -xE -l6 -283973 -xE -l6 -476619 -xE -l6 -296998 -xE -l6 -47 -xE -SelectedParams,0} -,0,0x4 -nH -161839 -xE -l6 -25036 -xE -l6 -35847 -xE -l6 -60440 -xE -l6 -30751 -xE -l6 -270599 -xE -l6 -60431 -xE -l6 -259119 -xE -l6 -183474 -xE -l6 -332066 -xE -l6 -7168 -xE -l6 -197632 -xE -l6 -291840 -xE -l6 -283648 -xE -l6 -238866 -xE -l6 -239902 -xE -l6 -31751 -xE -l6 -244743 -xE -l6 -384022 -xE -SelectedParams,0} -,0,0x4 -nH -385262 -xE -l6 -386086 -xE -l6 -393254 -xE -SelectedParams,0} -,0,0x5 -nH -393254 -xE -l6 -386095 -xE -l6 -387312 -xE -l6 -18662 -xE -l6 -61670 -xE -l6 -387397 -xE -l6 -247855 -xE -SelectedParams,0} -,0,0x1 -nH -342063 -xE -l6 -297007 -xE -l6 -15820 -xE -l6 -393263 -xE -l6 -393263 -xE -SelectedParams,0} -,0,0x5 -nH -161847 -xE -l6 -258103 -xE -l6 -249073 -xE -l6 -249076 -xE -iD -0,0 -xE -nF -0,0 -tU1 -1,45 -xE -nF -1,53 -xE -nF -1,54 -xE -nF -1,55 -xE -nF -1,56 -xE -nF -1,26 -xE -nF -1,259 -tJ -1} -tU3{1,253 -xE -nF -1,272 -tU1 -1,323 -tJ -1} -tU3{1,0 -xE -nF -1,21 -xE -nF -1,447 -tJ -1} -lA2 -449 -tJ -1} -lA2 -0 -tJ -1} -lA2 -0 -tJ -2} -lA2 -15 -xE -nF -1,24 -tJ -2} -,0,0x0 -nH -58392 -tU1 -0,0 -tJ -1} -,nH1,0x0 -nH -24591 -yI3 -33807 -yI3 -48143 -yI3 -285720 -yI3 -290840 -yI3 -305152,l9 -312400,l9 -39202,l9 -121894,l9 -421926,l9 -429094,l9 -443430,l9 -317834,l9 -329098,l9 -7633,l9 -7706,l9 -7730,l9 -38,l9 -50587,l9 -406528,l9 -24583,l9 -31751,l9 -405511,l9 -321551,xU1 -327713,l9 -322596,l9 -88361,l9 -335174,l9 -327050,l9 -493606,l9 -496678,l9 -503846,l9 -516134,l9 -7217,l9 -333875,l9 -336896,l9 -524326,l9 -509952,l9 -286727,l9 -90127,l9 -131087,l9 -296976,tB1 -324623,l1 -0x14 -nH -332815,l1 -0x10} -,{{3,7340056,tB1 -289092,l9 -92176,xU1 -337935 -lB2 -7340060,l1 -tT2 -7340176,l9 -338959 -lB2 -7340061,xU1 -7206,l9 -xJ3 -l9 -357414,l9 -368678,l9 -370745,l1 -0x7} -,{{3,7340177,l9 -39277,tB1 -426398,l1 -tT2 -40272286,xU1 -490910,l1 -tT2 -40336798,xU1 -50600,l9 -426462,xU1 -490974,xU1 -370726,l1 -0x6 -nH -371750,l1 -0x6 -nH -428070 -lB2 -40336862,xU1 -38378,l9 -50671 -lB2 -47662080,l9 -477184,l9 -568320,l9 -371727,l1 -0x7} -,{{3,15779306,l9 -370703,l1 -0x7 -nH -39277,l9 -39279,l1 -0x4} -,{{3,15779238,l9 -39338,tB1 -436262,l9 -508966,l9 -39409,tB1 -296998,tB1 -35847,l9 -15,tB1 -377894,l9 -386063,l1 -0x1 -nH -15,l9 -7192,l9 -122904,l9 -121880,l9 -30751,l9 -57,l9 -7456,l9 -15674 -lB2 -67579935,l9 -39237,l9 -58768,l9 -62924,l9 -121856,l9 -15760 -lB2 -64009216,l1 -0x0} -,{{0,0,xG -0,0,iL -2,e31 -2,e41 -3,e31 -3,e41 -38,xG -1,38,iL -14,xG -1,57,xG -1,16,eD2 -0x0 -nH -471103,eD2 -0x1} -,{{1,303,xG -1,323,cE3 -0x0 -nH -471363,eD2 -0x16} -,{{1,293,e31 -294,e41 -295,xG -1,296,iL -400,xG -1,0,xG -1,460,xG -1,465,xG -1,16,eD2 -0x1} -,{{1,57,cE3 -0x1} -,{{1,0,iL -21,xG -1,15,eD2 -0x0 -nH -24591,xG -1,24,iL -517,cE3 -0x0 -nH -46095,lK -46104,lK -15397,lK -287789,lK -66584,lK -404763,lK -62504,lK -15409,lK -39951,lK -24591,lK -33807,lK -50200,lK -62509,lK -50176,lF,178176,eL1 -tV3 -283648,lF,19456,lF,27648,lF,89088,lF,86016,lF,488448,lF,14342,lF,58375,lF,46147 -xZ -46151,lF,284679,lF,7183,lF,46159 -xZ -38993 -xZ -50265,lF,50249,lF,283808,lF,284835,lF,24822,lF,10240,lF,11264,lF,7170,lF,xJ3 -lF,17408,lF,164864,lF,237568,lF,242688,eL1 -0x14 -nH -476160,lF,25607,lF,121871,lF,50252,lF,39374,lF,50183,lF,7192,lF,121887,lF,252979,lF,46155,lF,38919,lF,50267,lF,50268,lF,50253,lF,46190,lF,50295,lF,7563,eL1 -0x10 -nH -416811,lF,416819,lF,40046,lF,46191 -xZ -415795,lF,40047 -xZ -415787,lF,39015,eL1 -0x5 -nH -39326 -xZ -39326,lF,39332,eL1 -0x5 -nH -39333 -cW2 -50590 -xZ -50590,lF,39338 -xZ -39338,lF,39335,eL1 -0x5 -nH -15786 -xZ -146858,lF,39372,lF,39379,lF,39380,lF,39390 -xZ -50654 -xZ -50654,lF,24,eL1 -0x6 -nH -62,lF,24,lF,62,eL1 -0x6 -nH -43,lF,43 -xZ -51,lF,51 -xZ -50269,lF,50176 -xZ -50270,lF,39159,lF,39183 -xZ -7168 -xZ -31744,lF,99328,lF,31746,lF,100376,lF,39409 -xZ -39411 -xZ -39411,lF,39420,lF,39420 -xZ -15,lF,39025,eL1 -0x5 -nH -39422,lF,16384,lF,62853,lF,15360,lF,15 -cW2 -16,lF,7183 -cW2 -7172 -l14 -yX1} -,nH1,0x0 -nH -24591 -l14 -lT -2,50200 -l14 -lT -2,63521 -l14 -lT -2,62500 -l14 -lT -2,50453 -l14 -lT -2,62488,cPow -eP3 -tS3 -7,tS3 -194,tS3 -0,cAcos -tT3 -cAcosh -tT3 -cAsin -tT3 -cAsinh -nQ -119,cAsinh -tT3 -cAtan -eW1 -306176,cAtan2 -eW1 -xJ3 -cAtan2 -tT3 -cAtanh -nQ -246,cCeil -tT3 -cCeil,l13 -0,c92 -0,cCos,l13 -7,c92 -91,c92 -92,c92 -119,c92 -236,c92 -255,c92 -214,l23 -236,l23 -464,l23 -0,cCosh,l13 -0,l23 -0,cExp -nQ -7,cExp -nQ -91,cExp -tT3 -cF3 -7,cF3 -91,cF3 -246,cFloor -tT3 -cFloor,lA -0x4 -nH -309540,cHypot -eW1 -316708,cHypot -eW1 -316724,cHypot,l0 -3,32513024,y52 -34627584 -n61 -31493120,y52 -89213952 -n61 -149042176 -n61 -246647808 -n61 -301234176 -n61 -494360576 -n61 -498558976 -n61 -62933520 -n61 -62933520,y52 -62933526 -n61 -62933526,y52 -24670208 -n61 -579378176 -n61 -573578240 -n61 -32513024 -n61 -566254592 -n61 -7900160 -n61 -588822528,cIf -nQ -119,cInt -nQ -246 -cA2 -0 -cA2 -7 -cA2 -31 -cA2 -194 -cA2 -363 -cA2 -15,cLog,lT -1,24,cLog -eP3 -cLog10 -tT3 -cLog2 -eW1 -xJ3 -cMax -eW1 -35847,cMax -eW1 -30751,cMax -tT3 -cMax,AnyParams,1} -,0,0x4 -nH -xJ3 -cMin -eW1 -35847,cMin -eW1 -30751,cMin -tT3 -cMin,AnyParams,1} -,0,0x4 -nH -24591,cMin -eP3 -nZ2 -7,nZ2 -91,nZ2 -92,nZ2 -119,nZ2 -149,nZ2 -231,cSin,lA -0x5} -,{{1,246,nZ2 -255,nZ2 -254,nZ2 -0,cSin,l13 -273,cSin,lA -0x1} -,{{1,214,y62 -231,cSinh,lA -0x5} -,{{1,246,y62 -254,y62 -255,y62 -464,y62 -0,cSinh,l13 -0,y62 -15,cSqrt -eP3 -cB2 -0,cTan,l13 -115,cTan,l13 -116,cB2 -231,cB2 -246,cB2 -273,cB2 -254,cB2 -255,cB2 -0,y92 -0,cTanh,l13 -213,y92 -231,y92 -246,y92 -254,y92 -255,y92 -0,cTrunc -eW1 -15384,cSub,lT -2,15384,cDiv,lT -2,476626,cDiv,lT -2,121913,tU2 -xJ3 -n42 -lA -tV3 -xJ3 -tU2 -31744,n42 -lA -0x20 -nH -31751,n42 -lA -0x24 -nH -31751,tU2 -121913,eM1 -l0 -2,xJ3 -cLess,lA -tV3 -41984,cLess,lA -0x4 -nH -41984,cLess -eW1 -7,cLess -eW1 -xJ3 -cLessOrEq -eW1 -296182,cLessOrEq -eW1 -7168 -lJ3,lA -tV3 -41984 -lJ3,lA -0x4 -nH -41984 -lJ3 -eW1 -7 -lJ3 -eW1 -xJ3 -yB -l0 -2,296182,cGreaterOrEq -tT3 -n22 -245,n22 -7,n22 -550,n22 -553,n22 -554,n22 -556,n22 -31,n22 -559,n22 -15,n22 -560,cNot -eW1 -7706,n33 -xJ3 -n33 -35847,n33 -30751,n33 -463903,n33 -466975,cAnd,iD -0,0,cAnd,nF -2,xJ3 -eT3 -7706,eT3 -35847,eT3 -463903,eT3 -466975,eT3 -30751,cOr,iD -1,0,n32 -91,n32 -131,n32 -245,n32 -215,n32 -246,cDeg -nQ -246,cRad -eW1 -xJ3 -cAbsAnd,l6 -xJ3 -cAbsOr,iD -1,0,cZ3 -tT3 -cAbsNotNot,l0 -3,32513024,cL3 -lA -0x0} -,} -;} -lF3 -l21{const -Rule -grammar_rules[262]={{ProduceNewTree,17,1,0,{1,0,cAbs,eE2 -409,{1,146,cAtan,eE2 -403 -nP -1324,cG3 -eE2 -405 -nP -307201,cG3 -l2 -c22 -253174 -nP -255224,cG3 -l2 -c22 -259324 -nP -257274,cG3 -eE2 -152,{1,252,cCeil -iO -486,{1,68,tW2 -482,{1,122,tW2 -483,{1,124,tW2 -151,{1,125,tW2 -419,{1,123,tW2 -0,{1,403,cCos,l2 -2,1,246,{1,252,cCos,l2 -18,1,0,{1,400,tW2 -301,{1,406,cCosh,l2 -2,1,246,{1,252,cCosh,l2 -18,1,0,{1,400,cCosh -iO -458,{1,121,cFloor,eE2 -150,{1,252,cFloor,tW3 -156,{3,7382016,eB -549,{3,8430592,eB -556,{3,8436736,eB -157,{3,42998784,eB -550,{3,42999808,eB -562,{3,43039744,eB -557,{3,49291264,eB -538,{3,49325056,eB -469,{3,1058318,eB -473,{3,1058324,eB -473,{3,9438734,eB -469,{3,9438740,cIf,l2 -0,3,32542225,{3,36732434,cIf,l2 -0,3,32542231,{3,36732440,cIf,tX3 -573,{3,32513026,cIf,tX3 -515,{3,455505423,cIf,tX3 -515,{3,433506837,cIf -iO -78,{1,256,tY3 -69,{1,258,tY3 -404,{1,72,tY3 -159,{1,147,cLog,l2 -0,1,0 -nP -487425,cMax -l3 -16,1,445 -nP -cH3 -cMax -l3 -0,1,0 -nP -483329,cMin -l3 -16,1,446 -nP -cH3 -cMin,c0 -0,1,153 -nP -24832 -l14 -tW3 -153 -nP -25854 -l14 -tW3 -154 -nP -129039 -nX3 -32055 -nX3 -32056 -nX3 -32057 -tV2 -166288 -nP -32137 -nX3 -33082 -tV2 -7168 -nP -12688 -tV2 -7434 -nP -12553 -y72 -435 -nP -46146 -y72 -436 -nP -46154 -y72 -437 -nP -46150 -y72 -169 -nP -83983 -y72 -168 -nP -130082 -y72 -175 -nP -133154 -y82 -476160 -nP -471055 -y82 -274432 -nP -273423 -y82 -251904 -nP -266274 -y82 -251904 -nP -263186 -y72 -171,{1,252,cC2 -421,{1,68,cC2 -151,{1,122,cC2 -419,{1,124,cC2 -170,{1,125,cC2 -482,{1,123,cC2 -0,{1,405,cC2 -172,{1,252,cSinh -iO -328,{1,404,cSinh -iO -173,{1,252,l34 -0,{1,408,l34 -176,{1,410,l34 -177,{1,252,cTanh,l2 -0,1,442 -nP -449551,tZ -1,441 -nP -cH3 -tZ -1,167 -nP -268549,tZ -1,181 -nP -276749,tZ -1,180 -nP -276500 -iD3 -190770 -nP -189622 -iD3 -194748 -nP -193723 -iD3 -202943 -nP -196795 -iD3 -59699 -nP -298148 -iD3 -59714 -nP -325815 -iD3 -59724 -nP -343224 -xE -c0 -2,1,337,{1,333 -tJ -1 -l33 -336,{1,338 -tJ -1} -} -l44 -2,1,340 -nP -1363,i0 -342 -nP -1365,i0 -463 -nP -472524,i0 -47 -nP -356711,i0 -349 -nP -200751,i0 -360 -nP -199727,i0 -480 -nP -207053,i0 -481 -nP -208077,i0 -417 -nP -211144,i0 -209 -nP -211145,i0 -418 -nP -215240,i0 -212 -nP -212329,i0 -204 -nP -373097,i0 -211 -nP -372944,i0 -217 -nP -201944,i0 -221 -nP -223448,i0 -367 -nP -508329,i0 -219 -nP -508126,i0 -224 -nP -225705,i0 -223 -nP -225776,i0 -365 -nP -230825,i0 -426 -nP -377057,i0 -497 -nP -377054,i0 -497 -nP -204201,i0 -426 -nP -375280,i0 -224 -nP -375006,cAdd -l3 -2,2,407781 -nP -233698,cAdd -l3 -2,2,59763 -nP -233842,tZ -1,372 -nP -1397,lQ1 -95 -nP -24705,lQ1 -96 -nP -24708,lQ1 -444 -nP -449551,lQ1 -443 -nP -cH3 -lQ1 -100 -nP -101750,lQ1 -108 -nP -106821,lQ1 -105 -nP -103749 -nA2 -0,2,110607 -nP -108869 -nA2 -0,2,107535 -nP -109893,lJ -0 -l33 -112 -nP -111634,cMul,SelectedParams,0 -l33 -567,{1,52,lJ -1 -l33 -568,{1,42,lJ -1} -} -l44 -2,1,467 -nP -45516 -iV -356 -nP -51555 -iV -468 -nP -49612 -iV -357 -nP -47459 -iV -429 -nP -438699 -iV -432 -nP -441774 -iV -486 -nP -498726 -iV -494 -nP -504870 -iV -382 -nP -435579 -iV -497 -nP -435709 -iV -426 -nP -508287 -iV -414 -nP -500092 -iV -499 -nP -352744 -iV -345 -nP -367092 -iV -381 -nP -425318 -iV -478 -nP -425460 -iV -47 -nP -512501 -iV -505 -nP -355817 -iV -47 -nP -516598 -iV -507 -nP -518182 -iV -508 -nP -358896 -iV -351 -nP -388605 -iV -511 -nP -360939 -iV -503 -nP -354788 -iV -514 -nP -525350 -iV -510 -nP -394342 -iV -386 -nP -351346 -nA2 -2,2,363004 -nP -361968 -nA2 -16,1,117 -nP -1157 -nA2 -16,1,118 -nP -1158 -nA2 -16,1,402 -nP -411024 -nA2 -16,2,58768 -nP -1472 -nA2 -16,2,15760 -nP -1474 -nA2 -17,1,0,{1,400 -nA2 -17,1,57,{1,14,lJ -0 -l91 -4 -n43 -41,n42 -l4 -4,1,0 -nP -5167,n42 -yA2 -41984 -nP -409641,cEqual -c4 -n42 -yA2 -eY -n42 -l43 -n42 -l2 -xB1 -24849 -tN2 -iE -tN2 -n63 -281873 -tN2 -lA1 -tN2 -lB1 -n42 -l4 -4 -y43 -41,eM1 -l4 -4 -n43 -5167,eM1 -yA2 -41984 -nP -409641,cNEqual -c4 -eM1 -yA2 -eY -eM1 -l43 -eM1 -l2 -xB1 -24849,eM1 -l2 -cI3 -eM1 -l2 -c22 -n63 -281873,eM1 -l2 -c22 -lA1,eM1 -l2 -c22 -lB1 -cNEqual -c4 -eO1 -16,2,eY -eO1 -16 -eI -cLess,eE2 -571 -nP -46080,eO1 -xB1 -24832,eO1 -c22 -yT1,eO1 -cI3 -eO1 -cJ3 -eO1 -c22 -xW1,eO1 -c22 -lA1,eO1 -c22 -lB1 -cLess,l4 -20 -y43 -409641,cLess -c4 -t6 -16,2,eY -t6 -16 -eI -cLessOrEq,eE2 -565 -nP -409615,t6 -xB1 -24832,t6 -c22 -yT1,t6 -cI3 -t6 -cJ3 -t6 -c22 -xW1,t6 -c22 -lA1,t6 -c22 -lB1 -cLessOrEq,l4 -20 -y43 -409647,cLessOrEq -c4 -lK3 -yA2 -eY -lK3 -l43 -lK3 -eE2 -539 -nP -409615 -eP -529654 -nP -24832 -eP -yT1 -eP -iE -eP -n63 -281856 -eP -xW1 -eP -lA1 -eP -lB1 -lK3 -l4 -20 -n43 -409647 -lJ3 -c4 -yB -yA2 -eY -yB -l43 -yB -eE2 -572 -nP -46080,yB -l2 -xB1 -24832,yB -l2 -c22 -yT1,yB -l2 -cI3 -yB -l2 -cJ3 -yB -l2 -c22 -xW1,yB -l2 -c22 -lA1,yB -l2 -c22 -lB1 -yB -l4 -20 -n43 -409641,yB -l4 -4,1,519,{1,137,cNot,tX3 -571,{1,2,cNot,l2 -0,1,452 -nP -cH3 -n73 -0,2,537097,{3,547892744,cAnd,c0 -16,1,566,{1,5,cAnd,AnyParams,1} -} -l44 -16,1,569 -nP -13314,n73 -16,1,544 -nP -553498,n73 -16,1,546 -nP -462369,n73 -16,1,548 -nP -466465,n73 -0,1,457 -nP -cH3 -xX1 -570 -nP -13314,xX1 -563 -nP -8197,xX1 -541 -nP -553498,xX1 -542 -nP -462369,xX1 -543 -nP -466465,xX1 -564 -nP -143365,cOr,c0 -4,1,525,{1,137,cK3 -tX3 -572,{1,2,cK3 -l4 -17,1,0,{1,0,cK3 -eE2 -537,{1,256,cAbsNotNot,c0 -18,1,531,{1,254,cAbsNotNot,c0 -0,1,572,{3,43039744,cL3 -tW3 -571,{3,49325056,cL3 -tX3 -454,{3,32513586,cL3 -l2 -16,3,32542225,{3,36732434,cL3 -yX1} -} -,} -;e12 -grammar_optimize_abslogical_type{y2 -9 -cS -grammar_optimize_abslogical_type -grammar_optimize_abslogical={9,{34,192,228,238,242,247,254,260,261} -} -;} -e12 -grammar_optimize_ignore_if_sideeffects_type{y2 -59 -cS -grammar_optimize_ignore_if_sideeffects_type -grammar_optimize_ignore_if_sideeffects={59,{0,20,21,22,23,24,25,26,cQ -iO1 -78,cR -cT -e12 -grammar_optimize_nonshortcut_logical_evaluation_type{y2 -56 -cS -grammar_optimize_nonshortcut_logical_evaluation_type -grammar_optimize_nonshortcut_logical_evaluation={56,{0,25,cQ -iO1 -78,cR -241,243,244,245,246,248,249,250,251,252,253,255,256,257,258,259} -} -;} -e12 -grammar_optimize_recreate_type{y2 -22 -cS -grammar_optimize_recreate_type -grammar_optimize_recreate={22,{18,55,56,57,80,81,82,83,84,85,117,118,120,121,130,131,132,133,134,135,136,137} -} -;} -e12 -grammar_optimize_round1_type{y2 -125 -cS -grammar_optimize_round1_type -grammar_optimize_round1={125,{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,25,cQ -37,38,iO1 -45,46,47,48,49,50,51,52,53,54,58,59,60,61,62,63,64,65,66,67,68,69,70,71,78,79,80,81,82,83,84,85,86,87,88,93,94,95,96,97,98,99,100,101,117,118,119,120,121,122,123,124,125,126,127,128,129,138,160,161,162,163,164,165,166,167,168,169,178,179,180,200,204,212,216,224,236,237,239,240,cT -e12 -grammar_optimize_round2_type{y2 -103 -cS -grammar_optimize_round2_type -grammar_optimize_round2={103,{0,15,16,17,25,cQ -39,40,iO1 -45,46,47,48,49,50,51,52,53,54,59,60,72,73,78,79,86,87,88,89,90,91,92,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,119,122,123,124,125,126,127,128,139,159,160,161,162,163,164,165,166,167,168,169,178,179,180,200,204,212,216,224,236,237,239,240,cT -e12 -grammar_optimize_round3_type{y2 -79 -cS -grammar_optimize_round3_type -grammar_optimize_round3={79,{74,75,76,77,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,170,171,172,173,174,175,176,177,181,182,183,184,185,186,187,188,189,190,191,193,194,195,196,197,198,199,201,202,203,205,206,207,208,209,210,211,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,232,233,234,235} -} -;} -e12 -grammar_optimize_round4_type{y2 -12 -cS -grammar_optimize_round4_type -grammar_optimize_round4={12,{18,55,56,57,130,131,132,133,134,135,136,137} -} -;} -e12 -grammar_optimize_shortcut_logical_evaluation_type{y2 -53 -cS -grammar_optimize_shortcut_logical_evaluation_type -grammar_optimize_shortcut_logical_evaluation={53,{0,25,cQ -iO1 -78,cR -cT} -lF3 -l21{xW3 -e42 -e81 -nT2 -paramlist,nA1){index=(paramlist>>(index*10))&1023;if(index>=57)return -e42(SubFunction,cD2 -plist_s[index-57]eY3 -index>=37)return -e42(NumConstant,cD2 -plist_n_container -xK::plist_n[index-37])n31 -e42(tG3,cD2 -plist_p[index]);} -} -#ifdef FP_SUPPORT_OPTIMIZER -#include -#include -#include -#include -using -lF3 -FUNCTIONPARSERTYPES;using -lF3 -l21;using -t5;using -yL1;lF3{nR1 -It,xK3 -T,xK3 -Comp>eP1 -MyEqualRange(It -first,It -last,const -T&val,Comp -comp){size_t -len=last-first;while(len>0){size_t -yA3 -len/2;It -xG3(first);xG3+=half;if(comp(*xG3,val)){first=xG3;++first;len=len-half-1;} -lJ2 -comp(val,*xG3)){len=half;} -else{It -left(first);{It&eF2=left;It -last2(xG3);size_t -len2=last2-eF2;while(len2>0){size_t -half2=len2/2;It -cD3(eF2);cD3+=half2;if(comp(*cD3,val)){eF2=cD3;++eF2;len2=len2-half2-1;} -else -len2=half2;} -} -first+=len;It -right(++xG3);{It&eF2=right;It&last2=first;size_t -len2=last2-eF2;while(len2>0){size_t -half2=len2/2;It -cD3(eF2);cD3+=half2;if(comp(val,*cD3))len2=half2;else{eF2=cD3;++eF2;len2=len2-half2-1;} -eW2 -eP1(left,right);eW2 -eP1(first,first);} -xW3 -e12 -OpcodeRuleCompare{iG2()lQ3 -tree,iF2 -yB2 -e83{const -Rule&rule=grammar_rules[yB2]n31 -i01range=MyEqualRange(tX2.rule_list,tX2.rule_list+tX2.rule_count,tree,OpcodeRuleCompare -xK());std -xV3rules;rules.xS3 -range -tE3-range.first);for -y5 -if(IsLogisticallyPlausibleParamsMatch(tD1 -cE2,tree))rules.push_back(*r);} -range.first=!rules -cT3?&rules[0]:0;range -tE3=!rules -cT3?&rules[rules.tF3-1]+1:0;if(range.first!=range -iO2{ -#ifdef DEBUG_SUBSTITUTIONS -if(range.first!=range -iO2 -yC2"Input (" -< -#include -#include -#include -#include /* for auto_ptr */ -using -lF3 -FUNCTIONPARSERTYPES;using -lF3 -l21;using -t5;using -yL1;lF3{xN1 -TestImmedConstraints -nT2 -bitmask,lC2 -tree -y13 -bitmask&ValueMask -y33 -Value_AnyNum:case -ValueMask:lC -nY2:if(GetEvennessInfo -eZ3 -n52 -Value_OddInt:if(GetEvennessInfo -eZ3 -x02 -tS1:if(GetIntegerInfo -eZ3 -n52 -Value_NonInteger:if(GetIntegerInfo -eZ3 -x02 -eJ1:if(!IsLogicalValue(tree)cL -nI1 -SignMask -y33 -Sign_AnySign:lC -nH1:if(l01 -n52 -eK1:if(l01 -x02 -Sign_NoIdea:if(l01 -Unknown -cL -nI1 -OnenessMask -y33 -Oneness_Any:case -OnenessMask:lC -Oneness_One:if(!yN1 -if(!cB3 -fp_abs(eC3)tG1 -1))cL -lC -Oneness_NotOne:if(!yN1 -if(cB3 -fp_abs(eC3)tG1 -1))cL -nI1 -ConstnessMask -y33 -Constness_Any:lC -tR1:if(!yN1 -lC -Constness_NotConst:if(yN1 -yF3 -return -true;} -i31 -iF2 -extent,iF2 -nbits,xK3 -eG2=iF2 -int>e12 -nbitmap{private:static -const -iF2 -bits_in_char=8;static -const -iF2 -eH2=(cM3 -eG2)*bits_in_char)/nbits;eG2 -data[(extent+eH2-1)/eH2];eX3 -void -inc(nA1,int -by=1){data[pos(index)]+=by*eG2(1<>yD2)&mask()yH3 -pos(nA1)yR -index/eH2 -yH3 -shift(nA1)yR -nbits*(index%eH2)yH3 -mask()yR(1<SubTreesDetail;eJ3(){std::memset(this,0,cM3*this));} -eJ3 -cH1 -eJ3&b){std::memcpy(this,&b,cM3 -b));} -eJ3&eA1=cH1 -eJ3&b){std::memcpy(this,&b,cM3 -b))n31*this;} -} -nJ1 -eJ3 -CreateNeedList_uncached(tC&c32){eJ3 -cN1;for(eQ1=0;ae51;static -e51 -yV1;e51::yV3 -i=yV1.xU2&c32 -eY3 -i!=yV1.cY1&c32)return -i -e82 -n31 -yV1.yR3,std::make_pair(&c32,CreateNeedList_uncached -xK(c32)))e82;} -xW3 -eJ -CalculateGroupFunction -cH1 -e42&yG2 -const -tB -info -y13 -yH2.first -y33 -NumConstant:{const -ParamSpec_NumConstant -xK -yK3 -cH1 -ParamSpec_NumConstant -xK*)yH2 -tE3 -n31 -CodeTreeImmed -y23 -constvalue -i33 -tG3:{cO -yK3(cO*)yH2 -tE3 -n31 -tM3 -GetParamHolderValueIfFound -y23 -index -i33 -SubFunction:{cP -yK3(cP*c61 -eJ -nT3;nT3 -xD -yL3 -l81);nT3.l02).xS3 -yL3 -data -yF2);for(eQ1=0;a0)eU3 -Immeds;else -eU3 -eV3;lC -l03:case -cFCall:case -cPCall:eU3 -eV3;break;c73 -assert(opcode0&&cN1.SubTreesDetail.get(opcode)>0){eU3 -SubTrees;cN1.SubTreesDetail.dec(opcode -t43 -eU3 -eV3;} -} -if(cN1.Immeds>0||cN1.SubTrees>0||cN1.eV3>0)n93} -if(c32.match_type!=AnyParams){if(0||cN1.SubTrees<0||cN1.eV3<0)n93 -eW2 -true;} -xW3 -lX1 -TestParam -cH1 -e42&yG2 -lC2 -tree,const -cW&start_at -tJ3 -y13 -yH2.first -y33 -NumConstant:{const -ParamSpec_NumConstant -xK -yK3 -cH1 -ParamSpec_NumConstant -xK*c61 -if(!yN1 -iV2 -imm=eC3;switch -y23 -modulo -y33 -Modulo_None:lC -Modulo_Radians:imm=e93 -imm,yO -immfp_const_pi -xK())imm-=fp_const_twopi -xK(cT2 -return -cB3 -imm,yL3 -constvalue -i33 -tG3:{cO -yK3(cO*c61 -if(!x0 -return -tM3 -SaveOrTestParamHolder -y23 -index,tree -i33 -SubFunction:{cP -yK3(cP*c61 -yF -GroupFunction){if(!x0 -eJ -xY1=CalculateGroupFunction(yG2 -info); -#ifdef DEBUG_SUBSTITUTIONS -DumpHashes(xY1 -lT2*cH1 -void**)&xY1 -nC1;std::cout<<"\n" -;std::cout<<*cH1 -void**)&eC3;std::cout<<"\n" -;DumpHashes(tree -lT2"Comparing " -i13(xY1 -lT2" and " -i13(tree -lT2": " -;std::cout<<(xY1 -xF -tree)?"true" -:"false" -lT2"\n" -; -#endif -return -xY1 -xF -tree);} -e63!&*start_at){if(!x0 -if(i01!=yL3 -l81 -cL} -return -TestParams -y23 -data,tree,start_at,info,false);} -eW2 -tR3 -xW3 -e12 -iX -x72 -MatchInfo -xK -info;iX():start_at(),info(){} -} -nJ1 -class -MatchPositionSpec_PositionalParams:xE1 -iX -xK>{eX3 -l53 -MatchPositionSpec_PositionalParams -iA1 -n -yB1 -iX -xK>(n){} -} -;e12 -iQ1 -x72 -iQ1():start_at(){} -} -;class -yG:xE1 -iQ1>{eX3 -iF2 -trypos;l53 -yG -iA1 -n -yB1 -iQ1>(n),trypos(0){} -} -nJ1 -lX1 -TestParam_AnyWhere -cH1 -e42&yG2 -lC2 -tree,const -cW&start_at -tJ3,std::eV2&used,bool -eY2{xRx5;tY2 -yG -eU2 -a=x5->trypos;goto -retry_anywhere_2 -tC2 -yG(eM);a=0;} -for(;atrypos=a -n31 -lX1(true,&*x5);} -} -retry_anywhere_2 -i23 -goto -retry_anywhere;eW2 -tR3 -xW3 -e12 -yC1 -x72 -MatchInfo -xK -info;std::eV2 -used;l53 -yC1 -iA1 -tZ3):start_at(),info(),used(tZ3){} -} -nJ1 -class -MatchPositionSpec_AnyParams:xE1 -yC1 -xK>{eX3 -l53 -MatchPositionSpec_AnyParams -iA1 -n,size_t -m -yB1 -yC1 -xK>(n,yC1 -xK(m)){} -} -nJ1 -lX1 -TestParams(tC&nN,lC2 -tree,const -cW&start_at -tJ3,bool -eY2{if(nN.match_type!=AnyParams){if(xV!=eM -cL} -if(!IsLogisticallyPlausibleParamsMatch(nN,tree))n93 -l73 -nN.match_type -y33 -PositionalParams:{xRx5;tY2 -cG -eU2 -a=xV-1;goto -lD1 -tC2 -cG(xV);a=0;} -for(;a -eX2{lG2=info;retry_positionalparams -i03=TestParam(cU -a),t33,(i02);iB1 -eR2} -lD1 -i23 -info=lG2;goto -retry_positionalparams;} -if(a>0){--a;goto -lD1;} -info=eD3 -n31 -tR3 -if(eY2 -for(tZ2 -tM3 -SaveMatchedParamIndex(a)n31 -lX1(true,&*x5 -i33 -SelectedParams:case -AnyParams:{xRx5;std::eV2 -used(eM);std -xV3l63(xV);std -xV3yI2(xV);for(tZ2{const -e42 -yH2=cU -a);l63[a]=ParamSpec_GetDepCode(yH2);} -{iF2 -b=0;for(tZ2 -if(l63[a]!=0)yI2[b++]=a;for(tZ2 -if(l63[a]==0)yI2[b++]=a;} -tY2 -t7 -eU2 -if(xV==0){a=0;goto -retry_anyparams_4;} -a=xV-1;goto -e61 -tC2 -t7(xV,eM);a=0;if(xV!=0){eD3=info;(*x5)[0].used=used;} -} -for(;a -eX2{if(a>0){lG2=info;(*x5)[a].used=used;} -retry_anyparams -i03=TestParam_AnyWhere -xK(cU -yI2[a]),tree,(i02,used,eY2;iB1 -eR2} -e61 -i23 -info=lG2;used=(*x5)[a].used;goto -retry_anyparams;} -e71:if(a>0){--a;goto -e61;} -info=eD3 -n31 -tR3 -retry_anyparams_4:if(nN.n1!=0){if(!TopLevel||!tM3 -HasRestHolder(nN.n1)){eH -cF2;cF2.xS3 -eM);for -nT2 -b=0;b -#include -using -t5;using -yL1;lF3{xW3 -eJ -xZ1 -const -e42&yG2 -tB -info,bool -inner=true -y13 -yH2.first -y33 -NumConstant:{const -ParamSpec_NumConstant -xK -yK3 -cH1 -ParamSpec_NumConstant -xK*)yH2 -tE3 -n31 -CodeTreeImmed -y23 -constvalue -i33 -tG3:{cO -yK3(cO*)yH2 -tE3 -n31 -tM3 -GetParamHolderValue -y23 -index -i33 -SubFunction:{cP -yK3(cP*c61 -eJ -tree;tI3 -yL3 -l81);for(eQ1=0;alist=tM3 -GetMatchedParamIndexes();std::sort(list.iN2 -list.end())yM3 -list.tF3;a-->0;)tree -tK2 -list[a]);for(eQ1=0;a -#include -using -lF3 -FUNCTIONPARSERTYPES;using -lF3 -l21;using -t5;using -yL1;lF3 -l21{tZ1 -DumpMatch -cH1 -eT2 -lC2 -tree,const -tB -info,bool -DidMatch,std::ostream&o){DumpMatch(rule -iY3,DidMatch?l24"match" -:l24"mismatch" -,o);} -tZ1 -DumpMatch -cH1 -eT2 -lC2 -tree,const -tB -info,nH3 -i43,std::ostream&o){static -const -char -ParamHolderNames[][2]={"%" -,"&" -,"x" -,"y" -,"z" -,"a" -,"b" -,"c" -} -;o< = " -i13(tM3 -lQ[b -tD3[a],o);o< -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;lF3{xN1 -MarkIncompletes(FPoptimizer_CodeTree::e62{if(tree.Is_Incompletely_Hashed(tI1;bool -iR1 -tO3 -nB1 -iR1|=MarkIncompletes -y91 -a)eY3 -iR1)tree.Mark_Incompletely_Hashed()n31 -iR1;} -tZ1 -FixIncompletes(FPoptimizer_CodeTree::e62{if(tree.Is_Incompletely_Hashed()){nB1 -FixIncompletes -y91 -a));tree -eT1} -} -} -t5{lB -Sort()tN3 -Sort();} -lB -Rehash(bool -constantfolding){if(constantfolding)ConstantFolding(*this);else -Sort();data -x7 -xW3 -e12 -cA{cO3 -iV2 -cP3 -yD1=0; -#if 0 -long -double -value=Value;e5=crc32::calc(cH1 -iF2 -char*)&value,cM3 -value));key^=(key<<24); -#elif 0 -union{e12{iF2 -char -filler1[16]iU2 -v;iF2 -char -filler2[16];} -buf2;e12{iF2 -char -filler3[cM3 -iV2)+16-c -M3 -x91)];e5;} -buf1;} -data;memset(&data,0,cM3 -data));data.buf2.v=Value;e5=data.buf1.key; -#else -int -exponent -iU2 -nM2=std::frexp(Value,&xG2;e5=nT2 -t62+0x8000)&0xFFFF -eY3 -nM2<0){nM2=-nM2;key=key^0xFFFF;} -else -key+=0x10000;nM2-=iV2(0.5);key<<=39;key|=lY1(nM2+nM2)*iV2(1u<<31))<<8; -#endif -lP -#ifdef FP_SUPPORT_COMPLEX_NUMBERS -nR1 -T -cG2 -std::complex >{cO3 -std::complexcP3 -cA::nA3 -cH2,Value.real());nB -fphash_t -temp;cA::nA3 -temp,Value.imag());yD1^=temp.hash2;cH2.hash2^=temp.hash1;} -} -; -#endif -#ifdef FP_SUPPORT_LONG_INT_TYPE -i31 -cG2 -long>{yH -long -Value){e5=Value;lP -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE -i31 -cG2 -GmpInt>{cO3 -GmpInt -cP3 -e5=Value.toInt();lP -#endif -tZ1 -xH2 -xK::Recalculate_Hash_NoRecursion(){fphash_t -cH2(lY1 -Opcode)<<56,Opcode*iP3(0x1131462E270012B));Depth=1;switch(Opcode -y33 -cImmed:{cA -xK::nA3 -cH2,Value -cT2 -case -l03:{yD1|=lY1 -cQ1<<48 -lF1((lY1 -cQ1)*11)^iP3(0x3A83A83A83A83A0);yF3 -case -cFCall:case -cPCall:{yD1|=lY1 -cQ1<<48 -lF1((~lY1 -cQ1)*7)^3456789;} -c73{size_t -eR1=0 -yM3 -0;aeR1)eR1=iZ2 -y22;yD1+=((iZ2 -i12 -hash1*(a+1))>>12)lF1 -iZ2 -i12 -hash1 -lF1(3)*iP3(0x9ABCD801357);cH2.hash2*=iP3(0xECADB912345)lF1(~iZ2 -i12 -hash2)^4567890;} -Depth+=eR1;} -} -if(Hash!=cH2){Hash=cH2;l32=0;} -} -lB -FixIncompleteHashes(){MarkIncompletes(*this);FixIncompletes(*this);} -} -#endif -#include -#include -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;lF3{using -t5 -nJ1 -bool -x01 -lC2 -tree,long -count,const -xH1::SequenceOpCode -xK&eU,xH1 -yG3&synth,size_t -max_bytecode_grow_length);static -const -e12 -SinCosTanDataType{OPCODE -whichopcode;OPCODE -inverse_opcode;enum{nominator,nN2,inverse_nominator,lG1} -;OPCODE -codes[4];} -SinCosTanData[12]={{cTan,cCot,{cSin,cCos,cCsc,cSec} -} -,{cCot,cCot,{cCos,cSin,cSec,cCsc} -} -,{cCos,cSec,{cSin,cTan,cCsc,cCot} -} -,{cSec,cCos,{cTan,cSin,cCot,cCsc} -} -,{cSin,cCsc,{cCos,cCot,cSec,cTan} -} -,{cCsc,cSin,{cCot,cCos,cTan,cSec} -} -,{cI2{cSinh,cCosh,cJ2,{cSinh,cNop,{cI2 -cNop,cCosh} -} -,{cCosh,cNop,{cSinh,cI2 -cNop} -} -,{cNop,cTanh,{cCosh,cSinh,cJ2,{cNop,cSinh,{cNop,cTanh,cCosh,cNop} -} -,{cNop,cCosh,{cTanh,cSinh,cJ2} -;} -t5{lB -SynthesizeByteCode(std -xV3&ByteCode,std -xV3 -xK&Immed,size_t&stacktop_max){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Making bytecode for:\n" -;iR -#endif -while(RecreateInversionsAndNegations()){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"One change issued, produced:\n" -;iR -#endif -FixIncompleteHashes();using -yL1;using -lF3 -l21;const -void*g=cD2 -grammar_optimize_recreate;while(ApplyGrammar(*cH1 -Grammar*)g,*this)){FixIncompleteHashes();} -} -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Actually synthesizing, after recreating inv/neg:\n" -;iR -#endif -xH1 -yG3 -synth;SynthesizeByteCode(synth,false);synth.Pull(ByteCode,Immed,stacktop_max);} -lB -SynthesizeByteCode(xH1 -yG3&synth,bool -MustPopTemps -e83{y01*this))yR;} -for -iA1 -a=0;a<12;++a){const -SinCosTanDataType&data=SinCosTanData[a];if(data.whichopcode!=cNop)iD1!=data.whichopcode -cP2;CodeTree -nB3;nB3.lN1 -nB3 -cQ3 -inverse_opcode);nB3.n62 -y01 -nB3)){synth.l11 -else -iD1!=cInv -cP2;if(GetParam(0)nC!=data.inverse_opcode -cP2;y01 -GetParam(0))){synth.l11 -size_t -found[4];i81 -4;++b){CodeTree -tree;if(data.i53]==cNop){tI3 -cInv);CodeTree -nC3;nC3.lN1 -nC3 -cQ3 -i53^2]);nC3.n62 -lP1 -nC3 -t43{tree.lN1 -tree -cQ3 -i53]);} -tree.n62 -found[b]=synth.xU3 -tree);} -if(found[data.yJ2!=tL -nN2]y4 -yJ2);n81 -nN2 -i5 -cDiv -nK1 -yJ2!=tL -lG1]y4 -yJ2);n81 -lG1 -i5 -cMul -nK1 -lR1!=tL -lG1]y4 -lR1);n81 -lG1 -i5 -cRDiv -nK1 -lR1!=tL -nN2]y4 -lR1);n81 -nN2 -i5 -cMul,2,1);synth.l11 -size_t -n_subexpressions_synthesized=SynthCommonSubExpressions(iS2 -switch(iS1{case -l03:synth.PushVar(GetVar());lC -cImmed:lH2 -GetImmed());lC -cAdd:case -cMul:case -cMin:case -cMax:case -cAnd:case -cOr:case -cAbsAnd:case -cAbsOr:iD1==cMul){bool -cR3 -tO3 -yI -lS1 -i61&&isLongInteger(lS1 -nC1)){c82=makeLongInteger(lS1 -nC1);CodeTree -tmp(*this,xK3 -CodeTree::CloneTag());tmp -t31);tmp -eT1 -if(x01 -tmp,value,xH1::tN1 -xK::AddSequence,synth,MAX_MULI_BYTECODE_LENGTH)){cR3=true;yF3} -} -if(cR3)yF3 -int -yE1=0;std::eV2 -done(GetParamCount(),false);CodeTree -iF;iF -xD -iS1;for(;;){bool -found -tO3 -yI -done[a]cP2;if(synth.IsStackTop(lS1)){found=true;done[a]=true;lS1.n7 -iF -c9 -lS1 -eY3++yE1>1){synth -yJ -2);iF.Rehash(false)cI1 -iF);yE1=yE1-2+1;} -} -} -if(!found)yF3 -yI -done[a]cP2;lS1.n7 -iF -c9 -lS1 -eY3++yE1>1){synth -yJ -2);iF.Rehash(false)cI1 -iF);yE1=yE1-2+1;} -} -if(yE1==0 -y13 -iS1{case -cAdd:case -cOr:case -cAbsOr:lH2 -0);lC -cMul:case -cAnd:case -cAbsAnd:lH2 -1);lC -cMin:case -cMax:lH2 -0);break;c73 -yF3++yE1;} -assert(n_stacked==1);yF3 -case -cPow:{lG3 -p0=GetParam(0);lG3 -p1=GetParam(1 -eY3!p1 -i61||!isLongInteger -eH3)||!x01 -p0,makeLongInteger -eH3),xH1::tN1 -xK::MulSequence,synth,MAX_POWI_BYTECODE_LENGTH)){p0.n7 -p1.n7 -synth -yJ -2);i91 -cIf:case -cAbsIf:{xK3 -xH1 -yG3::IfData -ifdata;GetParam(0).n7 -synth.SynthIfStep1(ifdata,iS1;GetParam(1).n7 -synth.SynthIfStep2(ifdata);GetParam(2).n7 -synth.SynthIfStep3(ifdata -cT2 -case -cFCall:case -cPCall:{for -iA1 -a=0;a0){size_t -top=synth.GetStackTop();synth.DoPopNMov(top-1-n_subexpressions_synthesized,top-1);} -} -} -lF3{xN1 -x01 -lC2 -tree,long -count,const -xH1::SequenceOpCode -xK&eU,xH1 -yG3&synth,size_t -max_bytecode_grow_length){if -eL3!=0){xH1 -yG3 -backup=synth;tree.n7 -size_t -bytecodesize_backup=synth.GetByteCodeSize();xH1::x01 -count,eU,iS2 -size_t -bytecode_grow_amount=synth.GetByteCodeSize()-bytecodesize_backup;if(bytecode_grow_amount>max_bytecode_grow_length){synth=backup -n31 -tR3 -return -true;} -else{xH1::x01 -count,eU,synth)xJ2} -} -#endif -#include -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;lF3{using -t5; -#define FactorStack std xV3 -const -e12 -PowiMuliType{iF2 -opcode_square;iF2 -opcode_cumulate;iF2 -opcode_invert;iF2 -opcode_half;iF2 -opcode_invhalf;} -iseq_powi={cSqr,cMul,cInv,cSqrt,cRSqrt} -,iseq_muli={iP1 -xE -cNeg,iP1,iP1} -nJ1 -iV2 -eS1 -cH1 -PowiMuliType&cS3,const -std -xV3&xP1,n72&stack -tO2 -1);while(IPy21&&isEvenInteger -xO1 -iV2(0.5);yW -opcode_invhalf){if -iT2>y21&&isEvenInteger -xO1 -iV2(-0.5);++IP;eR2 -size_t -x12=IP -iU2 -lhs(1 -eY3 -iT1==cFetch){nA1=nD2;if(index=iV1){IP=x12;yF3 -lhs=stack[index-y1];goto -yK2;} -if(iT1==cDup){lhs=nT3;goto -yK2;yK2:eX1 -nT3);++IP -iU2 -subexponent=eS1(cS3 -tS -if(IP>=limit||iT1!=cS3.opcode_cumulate){IP=x12;yF3++IP;stack.pop_back();nT3+=lhs*subexponent;eR2 -yF3 -return -nT3;} -xW3 -iV2 -ParsePowiSequence -cH1 -std -xV3&xP1){n72 -stack;eX1 -iV2(1))n31 -eS1(iseq_powi -tS} -xW3 -iV2 -ParseMuliSequence -cH1 -std -xV3&xP1){n72 -stack;eX1 -iV2(1))n31 -eS1(iseq_muli -tS} -xW3 -class -CodeTreeParserData{eX3 -l53 -CodeTreeParserData(bool -k_powi):stack(),clones(),keep_powi(k_powi){} -void -Eat -iA1 -tZ3,OPCODE -opcode){eJ -xI;xI -xD -opcode);eH -c32=Pop(tZ3)tQ1 -c32 -eY3!keep_powi)switch(opcode -y33 -cTanh:{eJ -sinh,cosh;sinh -xD -cSinh);sinh -c9 -xI -lR2 -sinh -eT1 -cosh -xD -cCosh);cosh -yP1 -xI -lR2 -cosh -eT1 -eJ -pow;pow -xD -cPow);pow -yP1 -cosh);pow.yC -iV2(-1)));pow -eT1 -xI -tH3 -xI.nG1 -0,sinh);xI -yP1 -pow -cT2 -case -cTan:{eJ -sin,cos;sin -xD -cSin);sin -c9 -xI -lR2 -sin -eT1 -cos -xD -cCos);cos -yP1 -xI -lR2 -cos -eT1 -eJ -pow;pow -xD -cPow);pow -yP1 -cos);pow.yC -iV2(-1)));pow -eT1 -xI -tH3 -xI.nG1 -0,sin);xI -yP1 -pow -cT2 -case -cPow:{lC2 -p0=xI -l8 -0);lC2 -p1=xI -l8 -1 -eY3 -p1 -nC==cAdd){eH -mulgroup(p1.GetParamCount())yM3 -0;a" -<void -Push(T -tree){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<0;){eZ1 -i13 -iT2[n]tT -nT3[n]);} -#endif -stack.t73 -iV1-n_pop)n31 -nT3;} -size_t -GetStackTop(yZ1 -iV1;} -private:void -FindClone(eJ&,bool=true)yR;} -private:eH -stack;std::multimapclones;bool -keep_powi;private:CodeTreeParserData -cH1 -CodeTreeParserData&);CodeTreeParserData&eA1=cH1 -CodeTreeParserData&);} -nJ1 -e12 -IfInfo{eJ -eI2;eJ -thenbranch;size_t -endif_location;IfInfo():eI2(),thenbranch(),endif_location(){} -} -;} -t5{lB -GenerateFrom -cH1 -xK3 -FunctionParserBase -xK::Data&xH3,bool -keep_powi){eH -xC2;xC2.xS3 -xH3.mVariablesAmount);for -nT2 -n=0;n&ByteCode=xH3.mByteCode;const -std -xV3 -xK&Immed=xH3.mImmed; -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"ENTERS GenerateFrom()\n" -; -#endif -CodeTreeParserData -xK -sim(keep_powi);std -xV3eG;for -iA1 -IP=0,DP=0;;++IP){i22:while(!eG -cT3&&(eG.e6==IP||(IP=i8 -tF3)break;iF2 -opcode=iT1;if((opcode==cSqr||opcode==cDup||(opcode==cInv&&!IsIntType -xK::nT3)||opcode==cNeg||opcode==cSqrt||opcode==cRSqrt||opcode==cFetch)){size_t -was_ip=IP -iU2 -e92 -ParsePowiSequence -xK(ByteCode,IP,eG -cT3?i8 -tF3:eG.e6,sim.xM -1);if -t62!=iV2(1.0)){xL -exponent -xD2;goto -i22;} -if(opcode==cDup||opcode==cFetch||opcode==cNeg -tJ2 -xT2=ParseMuliSequence -xK(ByteCode,IP,eG -cT3?i8 -tF3:eG.e6,sim.xM -1 -eY3 -xT2!=iV2(1.0)){xL -xT2)y3 -cMul);goto -i22;} -} -IP=was_ip;} -if(n82>=l03){nA1=opcode-l03 -nB2 -xC2[index]t43{switch(n82 -y33 -cIf:case -cAbsIf:{eG.t73 -eG.tF3+1);CodeTree -res(sim.yL2);eG.back().eI2.swap(res);eG.e6=i8 -tF3;IP+=2;eR2 -case -cJump:{CodeTree -res(sim.yL2);eG.tE1.swap(res);eG.e6=lE3 -IP+1]+1;IP+=2;eR2 -case -cImmed:xL -Immed[DP++]);lC -cDup:sim.Dup();lC -cNop:lC -cFCall:{iF2 -funcno=nD2;assert(funcno -#ifdef FP_SUPPORT_OPTIMIZER -#include -#define FP_MUL_COMBINE_EXPONENTS -lF3{using -lF3 -FUNCTIONPARSERTYPES;using -t5 -nJ1 -static -void -AdoptChildrenWithSameOpcode(e62{ -#ifdef DEBUG_SUBSTITUTIONS -bool -nO2 -tO3 -#endif -for -iY -if -y91 -a)nC==i01){ -#ifdef DEBUG_SUBSTITUTIONS -if(!nO2)yC2"Before assimilation: " -yA1 -nO2=true;} -#endif -tree.AddParamsMove -y91 -a).GetUniqueRef().l02),a);} -#ifdef DEBUG_SUBSTITUTIONS -if(nO2)yC2"After assimilation: " -yA1} -#endif -} -} -t5{tZ1 -ConstantFolding(e62{tree.Sort(); -#ifdef DEBUG_SUBSTITUTIONS -void*cY3=0;std::cout<<"[" -<<(&cY3)<<"]Runs ConstantFolding for: " -yA1 -DumpHashes(tree -lT2 -std::flush; -#endif -if(false){redo:;tree.Sort(); -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"[" -<<(&cY3)<<"]Re-runs ConstantFolding: " -yA1 -DumpHashes(tree); -#endif -} -if(i01!=cImmed){c23 -p=iN -tree -eY3 -p -n51&&p -nP2 -tF2==e13){xO -p -tF2);nD} -if(false){ReplaceTreeWithOne:xO -iV2(1));goto -do_return;ReplaceTreeWithZero:xO -xD1;goto -do_return;ReplaceTreeWithParam0: -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"Before replace: " -;std::cout<1||(iW1==1&&cB3 -nL1 -tG1 -1))))nM1=true;if(nM1){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"cMul: Will add new " -iU3 -nL1<<"\n" -; -#endif -for -iY -if -y91 -t21{ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<" - For that, deleting " -iU3 -t63 -std::cout<<"\n" -; -#endif -i93!cB3 -nL1 -tG1 -1)))i83 -e21 -nL1));l73 -eM -y33 -0:i6 -1:nY3 -c73 -if(ConstantFolding_MulGrouping(eJ2 -if(ConstantFolding_MulLogicItems(eJ2 -i91 -cAdd:eQ -iV2 -nE2=0.0;size_t -iW1=0;bool -nM1 -tO3 -nB1{if(!lE2 -t21 -continue -iU2 -immed=t63 -nE2+=immed;++iW1;} -if(iW1>1||(iW1==1&&nE2==xD1)nM1=true;if(nM1){ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"cAdd: Will add new " -iU3 -nE2<<"\n" -;std::cout<<"In: " -yA1 -#endif -for -iY -if -y91 -t21{ -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<" - For that, deleting " -iU3 -t63 -std::cout<<"\n" -; -#endif -i93!(nE2==x22)i83 -e21 -nE2));l73 -eM -y33 -0 -eL -1:nY3 -c73 -if(ConstantFolding_AddGrouping(eJ2 -if(ConstantFolding_AddLogicItems(eJ2 -i91 -cMin:eQ -size_t -yM2=0;c23 -e0;nB1{while(a+1=e0 -yN -val)i93 -eM==1){nY3 -i91 -cMax:eQ -size_t -yM2=0;c23 -eZ;nB1{while(a+1eZ -tF2)){eZ -tF2=p -tF2;eZ -n51=true;yM2=a;} -} -if(eZ -n51){for -iY{c33 -max -lB3 -a!=yM2&&(e13)=t61 -xD1;nD} -tM2 -cB3 -tH,xD1){if(p0 -cL2 -p0 -e23 -xD1{xO-fp_const_pihalf -e53 -if -iC3 -p0 -tF2>xD1{xO -fp_const_pihalf -e53} -if -lI -fp_atan2(lR,tH));nD -if((p1 -n51&&p1 -tF2>xD1||(p1 -cL2 -p1 -e23 -fp_const_negativezero -xK())){eJ -yO2;yO2 -xD -cPow);yO2.AddParamMove -y91 -1));yO2.yC -iV2(-1)));yO2 -eT1 -eJ -yP2;yP2 -tH3 -yP2.AddParamMove -y91 -0));yP2 -yP1 -yO2);yP2 -eT1 -tI3 -cAtan);tree.nG1 -0,yP2)yO3 -1);i91 -cPow:{if(ConstantFolding_PowOperations(eJ2 -yF3 -case -cDiv:nR&&eO3 -i61&&tH!=t61 -lR/tH -tH2 -cInv:nR&&lR!=t61 -iV2(1)/lR -tH2 -cSub:if -lI -lR-tH -tH2 -cNeg:nR){xO-lR -tH2 -cRad:nR){xO -RadiansToDegrees(lR)tH2 -cDeg:nR){xO -DegreesToRadians(lR)tH2 -cSqr:nR){xO -lR*lR -tH2 -cExp2:iK3(fp_exp2);lC -cRSqrt:nR){xO -iV2(1)/fp_sqrt(lR)tH2 -cCot:tI2 -fp_tan(lZ -cSec:tI2 -fp_cos(lZ -cCsc:tI2 -fp_sin(lZ -cHypot:if -lI -fp_hypot(x32 -cRDiv:case -cRSub:case -cDup:case -cFetch:case -cPopNMov:case -cSinCos:case -cSinhCosh:case -cNop:case -cJump:lC -cPCall:case -cFCall:yF3 -do_return:; -#ifdef DEBUG_SUBSTITUTIONS -std::cout<<"[" -<<(&cY3)<<"]Done ConstantFolding, result: " -yA1 -DumpHashes(tree); -#endif -} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -t5{tZ1 -c23::set_abs(nL -bool -has_negative=!min.known||min.valiV2();bool -crosses_axis=has_negative&&has_positive;cJ1 -xK -newmax;if(min -lB3 -t13)newmax.set(fp_max(tV1,tW1 -eY3 -crosses_axis)min.set(iV2());e63 -min -lB3 -t13)min.set(fp_min(tV1,tW1);lJ2 -min.known)min.set(tV1);else -min.set(tW1;} -max=newmax;} -tZ1 -c23::set_neg(){std::swap(min,max);min.val=-min.val;iA3=-iA3;} -xN1 -IsLogicalTrueValue -cH1 -c23&p -tR2{if(nB -IsIntType -xK::nT3){if(p -n51&&p -tF2>=iV2(1 -tI1;if(!abs&&p -nP2 -yN -val<=iV2(-1 -tI1;} -e63 -p -n51&&p -tF2>=iV2(0.5 -tI1;if(!abs&&p -nP2 -yN -val<=iV2(-0.5 -tI1;} -return -tR3 -xN1 -IsLogicalFalseValue -cH1 -c23&p -tR2{if(nB -IsIntType -xK::nT3){if(abs)return -p -yN -known -lH1 -1);else -return -p -n51&&p -nP2 -tF2>iV2(-1)lH1 -1);} -e63 -abs)return -p -yN -known -lH1 -0.5);else -return -p -n51&&p -nP2 -tF2>iV2(-0.5)lH1 -0.5);} -} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;using -t5;t5{xW3 -c23 -iN -lC2 -tree) -#ifdef DEBUG_SUBSTITUTIONS_extra_verbose -{using -lF3 -FUNCTIONPARSERTYPES;c23 -tmp=CalculateResultBoundaries_do(tree -lT2"Estimated boundaries: " -;if(tmp -n51)std::cout<=iV2(-1))?fp_acos -nU3:fp_const_pi -xK()i33 -cAsin:lD -yK -n3-1),fp_asin,yF1 -tF2)xQ1 -cLess -t71 -fp_asin,yF1 -yN -val);tV -cAtan:lD -yK -set(fp_atan,yF1 -tF2);m -yN -set(fp_atan,yF1 -yN -val);tV -cAtan2:{nR&&cB3 -lR,xD1)yR -abs_pi_limits;} -tM2 -cB3 -tH,xD1)yR -yF1;} -return -pi_limits;} -case -cSin:lD -bool -x11=!x43||!c71||(c81-yK -val)>=(yO -x11)eR -iV2 -min=e93 -yK -val,yO -min=fp_const_pihalf -xK());bool -nN1=(min<=cD&&max>=cD -eY3 -y11&&nN1)eR -if(nN1)nM -iV2(-1)lK2 -if(y11)nM -eL2 -tG1 -1));nM -eL2 -lK2} -case -cCos:lD -if(x43)yK -val+=fp_const_pihalf -xK(eY3 -c71)c81+=fp_const_pihalf -xK();bool -x11=!x43||!c71||(c81-yK -val)>=(yO -x11)eR -iV2 -min=e93 -yK -val,yO -min=fp_const_pihalf -xK());bool -nN1=(min<=cD&&max>=cD -eY3 -y11&&nN1)eR -if(nN1)nM -iV2(-1)lK2 -if(y11)nM -eL2 -tG1 -1));nM -eL2 -lK2} -case -cTan:{nM -i33 -cCeil:lD -c91 -cFloor:lD -tH1 -tV -cTrunc:lD -tH1 -c91 -cInt:lD -tH1 -c91 -cSinh:lD -yK -set(fp_sinh);m -yN -set(fp_sinh);tV -cTanh:lD -yK -set(fp_tanh,plusminus1_limits.min);m -yN -set(fp_tanh,plusminus1_limits.max);tV -cCosh:lD -if(x43){if(c71){if(yK -val>=y21&&c81>=xD1{yK -val -xU} -lJ2 -nU3=xD1{iV2 -tmp -xU -if(tmp>c81)c81=tmp;yK -val=iV2(1 -t43{yK -val -xU -std::swap(yK -val,c81);} -} -e63 -yK -val>=xD1{m -t0 -yK -val=fp_cosh -nU3;} -else{m -t0 -yK -val=iV2(1);} -} -} -else{x43=true;yK -val=iV2(1 -eY3 -c71){yK -val=fp_cosh(c81);m -t0} -else -m -t0} -tV -cIf:case -cAbsIf:{c23 -res1 -tI -1));c23 -res2 -tI -2)eY3!res2 -n51)res1 -n51 -tO3 -lJ2 -res1 -n51&&(res2 -tF2)res1 -yN -val)res1 -yN -val=res2 -yN -val -n31 -res1;} -case -cMin:{bool -iH -tO3 -bool -iI -tO3 -c43;x2 -m -tI -a)eY3!x43)iH -x53 -n51||nU3nK3)nK3=yK -val;if(!c71)iI -x53 -yN -known||c81>nL3)nL3=c81;} -if(iH)nM3 -iI)nT3 -t0 -return -nT3;} -case -cAdd:{c43(y21,xD1;x2 -item -tI -a)eY3 -item -n51)nK3+=item -tF2;else -nM3 -item -xF2 -nL3+=item -yN -val;else -nT3 -t0 -if(!nP3&&!nT3 -xF2 -yF3 -if -iT2 -n51&&nQ3&&nK3>nL3)std::swap -iT2 -tF2,nL3)n31 -nT3;} -case -cMul:{e12 -Value{enum -x73{eA3,iX1,iW2} -;x73 -tK -iU2 -value;Value(x73 -t):tK(t),value(0){} -Value(iV2 -v):tK(eA3),value(v){} -bool -cM2 -yZ1 -tK==iX1||cU2 -valuenL3)std::swap -iT2 -tF2,nL3)n31 -nT3;} -case -cMod:{c23 -x -tI -yS2 -y -tI -1)eY3 -y -xF2{if(y -yN -val>=xD1{if(!x -n51||(x -tF2)=xD1 -nM -y -yN -val,-y -yN -val);iB3 -y -yN -val,fp_const_negativezero -xK());} -} -iB3 -i33 -cPow:{tM2 -tH==xD1{nM -iV2(nR3} -nR&&lR==xD1{nM -y21,xD1;} -nR&&cB3 -lR -xE3 -nM -iV2(nR3} -tM2 -tH>y21&&GetEvennessInfo -y91 -1))==IsAlways -tJ2 -e92 -tH;c23 -tmp -tI -yS2 -nT3;nP3=true;nK3=0;if(tmp -n51&&tmp -tF2>=xD1 -nK3 -t03 -tmp -tF2,xG2;lJ2 -tmp -yN -known&&tmp -yN -val<=xD1 -nK3 -t03 -tmp -yN -val,xG2;nT3 -t0 -if(tmp -n51&&tmp -xF2{nQ3=true;nL3=fp_max(fp_abs(tmp -tF2),fp_abs(tmp -yN -val));nL3=fp_pow -iT2 -yN -val,xG2;} -return -nT3;} -c23 -p0 -tI -yS2 -p1 -tI -1));TriTruthValue -p0_positivity=iC3(p0 -tF2)>=xD1?IsAlways:(p0 -cL2 -p0 -e23 -y21?lC3 -Unknown);TriTruthValue -cN2=GetEvennessInfo -y91 -1));TriTruthValue -t1=Unknown;switch(p0_positivity)l92 -t1=IsAlways;lC -lC3{t1=cN2;yF3 -c73 -switch(cN2)l92 -t1=IsAlways;lC -lC3 -lC -Unknown:{tM2!isInteger -tG&&tH>=xD1{t1=IsAlways;} -yF3} -l73 -t1)l92{iV2 -min=y21;if -iC3 -p1 -n51){min -t03 -p0 -tF2,p1 -tF2 -eY3 -p0 -tF2=xD1&&min>=xD1 -min=y21;} -if -iC3 -p0 -tF2>=y21&&p0 -yN -known&&p1 -xF2{iV2 -max -t03 -p0 -yN -val,p1 -yN -val -eY3 -min>max)std::swap(min,max);nM -min,max);} -nM -min,false -i33 -lC3{nM -false,fp_const_negativezero -xK());} -c73{yF3 -i91 -cNeg:lD -m.set_neg();tV -cSub:{yM -cNeg);iE3 -1));tmp -xD -cAdd);tmp.nJ -0));tmp -yP1 -tmp2 -y53 -cInv:{cO2-1 -yT2 -cDiv:{yM -cInv);iE3 -1));tmp -xD -x71 -AddParamMove(tmp2 -y53 -cRad:{t81 -x71 -yC -fp_const_rad_to_deg -xK(yT2 -cDeg:{t81 -x71 -yC -fp_const_deg_to_rad -xK(yT2 -cSqr:{cO2 -2 -yT2 -cExp:{t81 -cPow);tmp.yC -fp_const_e -xK()));tmp.nJ -0)y53 -cExp2:{t81 -cPow);tmp.yC -x42 -tmp.nJ -0)y53 -cCbrt:lD -yK -set(fp_cbrt);m -yN -set(fp_cbrt);tV -cSqrt:lD -if(x43)yK -val=nU3 -#endif -lF3 -xH1{extern -const -iF2 -char -powi_table[256];} -lF3{using -t5 -nJ1 -bool -IsOptimizableUsingPowi(long -immed,long -penalty=0){xH1 -yG3 -synth;synth.PushVar(l03);size_t -bytecodesize_backup=synth.GetByteCodeSize();xH1::x01 -immed,xH1::tN1 -xK::MulSequence,iS2 -size_t -bytecode_grow_amount=synth.GetByteCodeSize()-bytecodesize_backup -n31 -bytecode_grow_amount0){t81 -cCbrt);iF3 -tmp -eT1 -tree.i72--i62;} -while(i52>0){t81 -cSqrt -eY3 -lD3){tmp -xD -cRSqrt);lD3 -tO3} -iF3 -tmp -eT1 -tree.i72--i52;} -if(lD3){t81 -cInv);iF3 -tree.i72} -} -xW3 -e12 -RootPowerTable{static -const -iV2 -RootPowers[(1+4)*(1+3)];} -nJ1 -const -iV2 -t8(1+4)*(1+3)]={iV2(1)lS -iG3 -iG3 -2*iG3 -i11)lS -3*2)lS -3*2*2)lS -3*i11*2*i11*3 -cV2 -2 -cV2 -2*2 -cV2 -i11*3*2*i11*3*3 -cV2 -3*2 -cV2 -3*2*2 -cV2 -3*i11*3*3*2*2*2*2)} -;e12 -PowiResolver{static -const -iF2 -MaxSep=4;static -xC3 -MaxOp=5;typedef -int -eE3;typedef -long -xI3;typedef -long -tW;e12 -yU2{yU2():n_int_sqrt(0),n_int_cbrt(0),sep_list(),lV1(0){} -int -n_int_sqrt;int -n_int_cbrt;int -tL1 -MaxSep];tW -lV1;} -nJ1 -static -yU2 -CreatePowiResult(iV2 -xG2{yU2 -nT3;eE3 -t9=FindIntegerFactor(xG2;if(t9==0){ -#ifdef DEBUG_POWI -i82"no factor found for %Lg\n" -,yK1 -xG2; -#endif -return -nT3;} -nT3.lV1=y31 -exponent,t9);xI3 -eM2=EvaluateFactorCost(t9,0,0,0)+cB -nT3.lV1);int -iH3=0;int -iI3=0;int -mul_count=0; -#ifdef DEBUG_POWI -i82"orig = %Lg\n" -,yK1 -xG2;i82"plain factor = " -iW3"%ld\n" -,(int)t9,(long)eM2); -#endif -for -nT2 -n_s=0;n_s=MaxOp)break; -#endif -int -n_sqrt=s%MaxOp;int -n_cbrt=s/MaxOp;if(n_sqrt+n_cbrt>4 -cP2 -iU2 -lI1=exponent;lI1-=t8 -s];i41=FindIntegerFactor(lI1 -eY3 -xT2!=0){tW -xP=y31 -lI1,xT2);xI3 -cost=EvaluateFactorCost(xT2,iH3+n_sqrt,iI3+n_cbrt,mul_count+1)+cB -xP); -#ifdef DEBUG_POWI -i82"Candidate sep %u (%d*sqrt %d*cbrt)factor = " -iW3"%ld (for %Lg to %ld)\n" -,s,n_sqrt,n_cbrt,xT2,(long)cost,yK1 -lI1,(long)xP); -#endif -if(cost%Lg\n" -,x9,x9%MaxOp,x9/MaxOp,yW1,yI1,yK1(xG2,yK1 -t62-t8 -x9])); -#endif -nT3.tL1 -n_s]=x9;exponent-=t8 -x9];iH3+=x9%MaxOp;iI3+=x9/MaxOp;eM2=yI1;t9=yW1;mul_count+=1;} -nT3.lV1=y31 -exponent,t9); -#ifdef DEBUG_POWI -i82"resulting exponent is %ld (from exponent=%Lg, best_factor=%Lg)\n" -,nT3.lV1,yK1 -exponent,yK1 -t9); -#endif -while(t9%2==0){++nT3 -tD2;t9/=2;} -while(t9%3==0){++nT3.n_int_cbrt;t9/=3;} -return -nT3;} -private:static -xI3 -cB -tW -xP){static -std::map -cR2 -iB;if(xP<0){xI3 -cost=22 -n31 -cost+cB-xP);} -std::map -cR2::yV3 -i=iB.xU2 -xP -eY3 -i!=iB.cY1 -xP)return -i -e82;std::pair -cR2 -nT3(xP,0.0);xI3&cost=nT3 -tE3;while(xP>1){int -xT2=0;if(xP<256){xT2=xH1::powi_table[xP];if(xT2&128)xT2&=127;else -xT2=0;if(xT2&64)xT2=-(xT2&63)-1;} -if(xT2){cost+=cB -xT2);xP/=xT2;eR2 -if(!(xP&1)){xP/=2;cost+=6;} -else{cost+=7;xP-=1;} -} -iB.yR3,nT3)n31 -cost;} -cA1 -tW -y31 -yJ1,i41)yR -makeLongInteger(value*iV2(xT2));} -cA1 -bool -yR1 -yJ1,i41 -tJ2 -v=value*iV2(xT2)n31 -isLongInteger(v);} -cA1 -eE3 -FindIntegerFactor(yJ1){i41=(2*2*2*2); -#ifdef CBRT_IS_SLOW -#else -xT2*=(3*3*3); -#endif -eE3 -nT3=0;if(yR1 -value,xT2)){nT3=xT2;while((xT2%2)==0&&yR1 -value,xT2/2))nT3=xT2/=2;while((xT2%3)==0&&yR1 -value,xT2/3))nT3=xT2/=3;} -#ifdef CBRT_IS_SLOW -if -iT2==0){if(yR1 -value,3 -nE3 -3;} -#endif -return -nT3;} -static -int -EvaluateFactorCost(int -xT2,int -s,int -c,int -nmuls){xC3 -xD3=6; -#ifdef CBRT_IS_SLOW -xC3 -eN2=25; -#else -xC3 -eN2=8; -#endif -int -nT3=s*xD3+c*eN2;while(xT2%2==0){xT2/=2;nT3+=xD3;} -while(xT2%3==0){xT2/=3;nT3+=eN2;} -nT3+=nmuls -n31 -nT3;} -} -;} -t5{xN1 -eJ::RecreateInversionsAndNegations(bool -prefer_base2){bool -changed=false -yM3 -0;a0;){eJ&powgroup=lS1;if(powgroup -yV2 -0)cX2 -tO -iJ3 -eJ&log2=tO -0);log2.l61 -log2 -xD -eF3);log2.yC -fp_pow(immeds -tG1 -1)/x52)));log2 -eT1 -yF3} -} -} -yP3 -yV2 -iJ3 -lC2 -exp_param=tO -1)iU2 -e92 -exp_param -nC1;if(e01 -tG1-1))){l61 -nF2.push_back(lS1 -lR2 -t41 -lJ2 -exponent=i21.y22){nH2 -cDiv)eO -nN3 -eO -i21 -t43{nH2 -cRDiv)eO -i21)eO -nN3;} -} -} -if(nG2.t91 -eJ -y41 -iS1;yQ1 -SetParamsMove -eF -while(yQ1 -RecreateInversionsAndNegations(prefer_base2))yQ1 -FixIncompleteHashes();nH2 -eF3)eO -nG2)eO -nN3;x62} -if(cT1.t91 -eJ -y41 -cMul);mulgroup -yP1 -cT1 -l8 -1));yQ1 -AddParamsMove -eF -while(yQ1 -RecreateInversionsAndNegations(prefer_base2))yQ1 -FixIncompleteHashes();DelParams();nH2 -eF3)eO -cT1 -l8 -0))eO -nN3;x62 -i91 -cAdd:{eH -iA2;for -iJ-->0;)if(eG3 -cMul){nV3 -y51:;eJ&mulgroup=x82 -for -iA1 -b=yQ1 -xF1 -b-->0;){if -lR3 -l8 -b)l71 -xT2=mulgroup -l8 -b)nC1 -cA3 -xT2 -i92 -y51;} -yQ1 -l61 -yQ1 -DelParam(b);nW3 -lJ2 -cB3 -xT2 -tG1-2)))xC -y51;} -yQ1 -l61 -yQ1 -DelParam(b);yQ1 -yC -x42 -nW3} -} -if(t2){yQ1 -tA -nN3;t41} -lJ2 -eG3 -cDiv&&!IsIntType -xK::nT3){nV3 -y61:;eJ&i21=x82 -if(i21 -l8 -0)i51 -cB3 -i21 -l8 -0)nC1 -i92 -y61;} -i21.l61 -i21 -tK2 -0);i21 -xD -cInv);nW3} -if(t2)xC -y61;} -i21.tA -i21);t41} -lJ2 -eG3 -cRDiv&&!IsIntType -xK::nT3){nV3 -x81:;eJ&i21=x82 -if(i21 -l8 -1)i51 -cB3 -i21 -l8 -1)nC1 -i92 -x81;} -i21.l61 -i21 -tK2 -1);i21 -xD -cInv);nW3} -if(t2)xC -x81;} -i21.tA -i21);t41} -if(!iA2 -cT3){ -#ifdef DEBUG_SUBSTITUTIONS -i82"Will make a Sub conversion in:\n" -);fflush(stdout);iR -#endif -eJ -yW2;yW2 -xD -cAdd);yW2 -iO3 -iA2);yW2 -eT1 -eJ -cU1;cU1 -xD -cAdd);cU1 -iO3 -l02));cU1 -eT1 -if(cU1 -i61&&cB3 -cU1 -nC1,xD1){nH2 -cNeg);e7);} -e63 -cU1.y22==1){nH2 -cRSub);e7)eO -cU1);} -lJ2 -yW2 -nC==cAdd){nH2 -cSub)eO -cU1);e7 -lR2 -for -iA1 -a=1;a0){iY1=true;} -#ifdef DEBUG_POWI -i82"Will resolve powi %Lg as powi(chain(%d,%d),%ld)" -,yK1 -fp_abs -eH3),r -tD2,r.n_int_cbrt,r.lV1);for -nT2 -n=0;nx22{if(prefer_base2 -tJ2 -yY2=fp_log2(p0 -nC1)cA3 -yY2 -xE3 -DelParam(0 -t43{n0 -e21 -yY2)tF1 -c9 -p1 -tF1 -eT1 -nG1 -nD1} -nH2 -cExp2);x62} -else{iV2 -yY2=fp_log(p0 -nC1)cA3 -yY2 -xE3 -DelParam(0 -t43{n0 -e21 -yY2)tF1 -c9 -p1 -tF1 -eT1 -nG1 -nD1} -nH2 -cExp);x62} -} -lJ2 -GetPositivityInfo(p0)==IsAlways){if(prefer_base2){eJ -log;log -xD -cLog2);log -c9 -p0);log -eT1 -n0 -p1 -tF1 -yP1 -log -tF1 -eT1 -nH2 -cExp2);nG1 -nD1 -x62} -else{eJ -log;log -xD -cLog);log -c9 -p0);log -eT1 -n0 -p1 -tF1 -yP1 -log -tF1 -eT1 -nH2 -cExp);nG1 -nD1 -x62} -} -i91 -cDiv:{if(GetParam(0)i61&&cB3 -GetParam(0)nC1 -xE3 -nH2 -cInv);DelParam(0);} -yF3 -c73 -yF3 -if(changed)goto -exit_changed -n31 -changed;} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -using -lF3 -FUNCTIONPARSERTYPES;lF3{using -t5;class -e43{size_t -nP1;size_t -eD;size_t -eE;size_t -lJ1;size_t -t3;size_t -t4;size_t -n01;eX3 -e43():nP1(0),eD(0),eE(0),lJ1(0),t3(0),t4(0),n01(0){} -void -t23 -OPCODE -op){nP1+=1;e33 -cCos)++eD;e33 -cSin)++eE;e33 -cSec)++eD;e33 -cCsc)++eE;e33 -cTan)++lJ1;e33 -cCot)++lJ1;e33 -cSinh)++t4;e33 -cCosh)++t3;e33 -cTanh)++n01;} -size_t -GetCSEscore -e73 -size_t -nT3=nP1 -n31 -nT3;} -int -NeedsSinCos -e73 -bool -y71=(nP1==(eD+eE+lJ1)eY3(lJ1&&(eE||eD))||(eE&&eD)){if(y71)return -1 -n31 -2;} -return -0;} -int -NeedsSinhCosh -e73 -bool -y71=(nP1==(t3+t4+n01)eY3(n01&&(t4||t3))||(t4&&t3)){if(y71)return -1 -n31 -2;} -return -0;} -size_t -MinimumDepth -e73 -size_t -n_sincos=std::min(eD,eE);size_t -n_sinhcosh=std::min(t3,t4 -eY3 -n_sincos==0&&n_sinhcosh==0)return -2 -n31 -1;} -} -nJ1 -class -TreeCountType:public -std::multimap >{} -xR3 -FindTreeCounts(tK1&nI2,lC2 -tree,OPCODE -x92,bool -skip_root=false){cV -i=nI2.xU2 -tree.GetHash()eY3!skip_root){bool -found -tO3 -for(;i!=nI2.cY1 -tree.GetHash();++i){if(tree -xF -i -e82 -iO2){i -e82.first.t23 -x92);found=true;yF3} -if(!found){e43 -count;count.t23 -x92);nI2.yR3,std::make_pair(tree.GetHash(),std::make_pair -eL3,tree)));} -} -nB1 -FindTreeCounts(nI2,t33,i01);} -e12 -yU{bool -BalanceGood;bool -FoundChild;} -nJ1 -yU -lK1 -lC2 -root,lC2 -child){if(root -xF -child)){yU -nT3={true,true} -n31 -nT3;} -yU -nT3={true,false} -;if(root -nC==cIf||root -nC==yW3{yU -cond=lK1 -root -l8 -0 -nO3 -yU -xX=lK1 -root -l8 -1 -nO3 -yU -y6=lK1 -root -l8 -2 -nO3 -if -y03||xX -yV||y6 -yV){nT3 -yV=true;} -nT3 -e8=((xX -yV==y6 -yV)||y03 -cZ2&&(cond -e8||(xX -yV&&y6 -yV))&&(xX -e8||y03 -cZ2&&(y6 -e8||y03 -cZ2;} -else{bool -iE1 -tO3 -bool -nQ1 -tO3 -for -iA1 -b=root.GetParamCount(),a=0;afirst!=leaf.GetHash()cP2;const -e43&occ -nQ2 -first;size_t -score=occ.GetCSEscore();lC2 -candidate -nQ2 -second;if(tM1 -candidate)cP2;if(leaf.y22yZ2){yZ2=score;cs_it=i;} -} -if(yZ2<=0){ -#ifdef DEBUG_SUBSTITUTIONS_CSE -std::cout<<"No more CSE candidates.\n" -<(lT2"Done with Common Subexpression:" -i13 -xK(tree -lT2 -std::endl; -#endif -#if 0 -if(lW1){if(lW1==2||i1){synth.e91} -yE3 -cSinCos,1,2)cI1 -iC2,1)cI1 -iD2,0);} -if(i1){if(lW1)synth.e91 -if(i1==2){synth.e91} -yE3 -cSinhCosh,1,2)cI1 -c02,1)cI1 -c12,0);} -#endif -} -return -yD3 -stacktop_before;} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -tZ1 -FunctionParserBase -xK::Optimize(){using -t5;l61 -eJ -tree;tree.GenerateFrom(*mData);FPoptimizer_Optimize::ApplyGrammars(tree);std -xV3eI3;std -xV3 -xK -immed;size_t -stacktop_max=0;tree.SynthesizeByteCode(eI3,immed,stacktop_max -eY3 -mData->mStackSize!=stacktop_max){mData->mStackSize=iF2(stacktop_max); -#if !defined(FP_USE_THREAD_SAFE_EVAL) && \ - !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) -mData->mStack.t73 -stacktop_max); -#endif -} -mData->mByteCode.swap(eI3);mData->mImmed.swap(immed);} -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -x8 -MpfrFloat -n11 -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE -x8 -GmpInt -n11 -#endif -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE -x8 -std::complexn11 -#endif -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE -x8 -std::complexn11 -#endif -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE -x8 -std::complexn11 -#endif -FUNCTIONPARSER_INSTANTIATE_TYPES -#endif - -#endif diff --git a/deal.II/contrib/functionparser/lgpl-3.0.txt b/deal.II/contrib/functionparser/lgpl-3.0.txt deleted file mode 100644 index 65c5ca88a6..0000000000 --- a/deal.II/contrib/functionparser/lgpl-3.0.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/deal.II/contrib/functionparser/mpfr/GmpInt.cc b/deal.II/contrib/functionparser/mpfr/GmpInt.cc deleted file mode 100644 index 490add4b98..0000000000 --- a/deal.II/contrib/functionparser/mpfr/GmpInt.cc +++ /dev/null @@ -1,710 +0,0 @@ -#include "GmpInt.hh" -#include -#include -#include -#include -#include - -//=========================================================================== -// Shared data -//=========================================================================== -namespace -{ - unsigned long gIntDefaultNumberOfBits = 256; - - std::vector& intString() - { - static std::vector str; - return str; - } -} - -//=========================================================================== -// Auxiliary structs -//=========================================================================== -struct GmpInt::GmpIntData -{ - unsigned mRefCount; - GmpIntData* nextFreeNode; - mpz_t mInteger; - - GmpIntData(): mRefCount(1), nextFreeNode(0) {} -}; - -class GmpInt::GmpIntDataContainer -{ - std::deque mData; - GmpInt::GmpIntData* mFirstFreeNode; - GmpInt::GmpIntData* mConst_0; - - public: - GmpIntDataContainer(): mFirstFreeNode(0), mConst_0(0) {} - - ~GmpIntDataContainer() - { - for(size_t i = 0; i < mData.size(); ++i) - mpz_clear(mData[i].mInteger); - } - - GmpInt::GmpIntData* allocateGmpIntData(unsigned long numberOfBits, - bool initToZero) - { - if(mFirstFreeNode) - { - GmpInt::GmpIntData* node = mFirstFreeNode; - mFirstFreeNode = node->nextFreeNode; - if(initToZero) mpz_set_si(node->mInteger, 0); - ++(node->mRefCount); - return node; - } - - mData.push_back(GmpInt::GmpIntData()); - if(numberOfBits > 0) - mpz_init2(mData.back().mInteger, numberOfBits); - else - mpz_init(mData.back().mInteger); - return &mData.back(); - } - - void releaseGmpIntData(GmpIntData* data) - { - if(--(data->mRefCount) == 0) - { - data->nextFreeNode = mFirstFreeNode; - mFirstFreeNode = data; - } - } - - GmpInt::GmpIntData* const_0() - { - if(!mConst_0) - mConst_0 = allocateGmpIntData(gIntDefaultNumberOfBits, true); - return mConst_0; - } -}; - - -GmpInt::GmpIntDataContainer& GmpInt::gmpIntDataContainer() -{ - static GmpIntDataContainer container; - return container; -} - -//=========================================================================== -// Auxiliary functions -//=========================================================================== -void GmpInt::setDefaultNumberOfBits(unsigned long value) -{ - gIntDefaultNumberOfBits = value; -} - -unsigned long GmpInt::getDefaultNumberOfBits() -{ - return gIntDefaultNumberOfBits; -} - -inline void GmpInt::copyIfShared() -{ - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - GmpIntData* oldData = mData; - mData = gmpIntDataContainer().allocateGmpIntData(0, false); - mpz_set(mData->mInteger, oldData->mInteger); - } -} - - -//=========================================================================== -// Constructors, destructor, assignment -//=========================================================================== -GmpInt::GmpInt(DummyType): - mData(gmpIntDataContainer().allocateGmpIntData(0, false)) -{} - -GmpInt::GmpInt() -{ - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); -} - -GmpInt::GmpInt(long value) -{ - if(value == 0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_si(mData->mInteger, value); - } -} - -GmpInt::GmpInt(unsigned long value) -{ - if(value == 0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_ui(mData->mInteger, value); - } -} - -GmpInt::GmpInt(int value) -{ - if(value == 0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_si(mData->mInteger, value); - } -} - -GmpInt::GmpInt(double value) -{ - const double absValue = value >= 0.0 ? value : -value; - if(absValue < 1.0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_d(mData->mInteger, value); - } -} - -GmpInt::GmpInt(long double value) -{ - const long double absValue = value >= 0.0L ? value : -value; - if(absValue < 1.0L) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_d(mData->mInteger, double(value)); - } -} - -GmpInt::GmpInt(const GmpInt& rhs): - mData(rhs.mData) -{ - ++(mData->mRefCount); -} - -GmpInt& GmpInt::operator=(const GmpInt& rhs) -{ - if(mData != rhs.mData) - { - gmpIntDataContainer().releaseGmpIntData(mData); - mData = rhs.mData; - ++(mData->mRefCount); - } - return *this; -} - -GmpInt& GmpInt::operator=(signed long value) -{ - if(value == 0) - { - gmpIntDataContainer().releaseGmpIntData(mData); - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - } - mpz_set_si(mData->mInteger, value); - } - return *this; -} - -GmpInt::~GmpInt() -{ - gmpIntDataContainer().releaseGmpIntData(mData); -} - - -//=========================================================================== -// Data getters -//=========================================================================== -template<> -void GmpInt::get_raw_mpfr_data(mpz_t& dest_mpz_t) -{ - std::memcpy(&dest_mpz_t, mData->mInteger, sizeof(mpz_t)); -} - -const char* GmpInt::getAsString(int base) const -{ - intString().resize(mpz_sizeinbase(mData->mInteger, base) + 2); - return mpz_get_str(&intString()[0], base, mData->mInteger); -} - -long GmpInt::toInt() const -{ - return mpz_get_si(mData->mInteger); -} - - -//=========================================================================== -// Modifying operators -//=========================================================================== -GmpInt& GmpInt::operator+=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_add(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator+=(long value) -{ - copyIfShared(); - if(value >= 0) - mpz_add_ui(mData->mInteger, mData->mInteger, value); - else - mpz_sub_ui(mData->mInteger, mData->mInteger, -value); - return *this; -} - -GmpInt& GmpInt::operator-=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_sub(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator-=(long value) -{ - copyIfShared(); - if(value >= 0) - mpz_sub_ui(mData->mInteger, mData->mInteger, value); - else - mpz_add_ui(mData->mInteger, mData->mInteger, -value); - return *this; -} - -GmpInt& GmpInt::operator*=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_mul(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator*=(long value) -{ - copyIfShared(); - mpz_mul_si(mData->mInteger, mData->mInteger, value); - return *this; -} - -GmpInt& GmpInt::operator/=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_tdiv_q(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator/=(long value) -{ - copyIfShared(); - if(value >= 0) - mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, value); - else - { - mpz_neg(mData->mInteger, mData->mInteger); - mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, -value); - } - return *this; -} - -GmpInt& GmpInt::operator%=(const GmpInt& rhs) -{ - copyIfShared(); - if(operator<(0)) - { - negate(); - mpz_mod(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - negate(); - } - else - { - mpz_mod(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - } - return *this; -} - -GmpInt& GmpInt::operator%=(long value) -{ - copyIfShared(); - if(value < 0) value = -value; - if(operator<(0)) - { - negate(); - mpz_mod_ui(mData->mInteger, mData->mInteger, value); - negate(); - } - else - { - mpz_mod_ui(mData->mInteger, mData->mInteger, value); - } - return *this; -} - -GmpInt& GmpInt::operator<<=(unsigned long bits) -{ - copyIfShared(); - mpz_mul_2exp(mData->mInteger, mData->mInteger, bits); - return *this; -} - -GmpInt& GmpInt::operator>>=(unsigned long bits) -{ - copyIfShared(); - mpz_tdiv_q_2exp(mData->mInteger, mData->mInteger, bits); - return *this; -} - - -//=========================================================================== -// Modifying functions -//=========================================================================== -void GmpInt::addProduct(const GmpInt& value1, const GmpInt& value2) -{ - copyIfShared(); - mpz_addmul(mData->mInteger, value1.mData->mInteger, value2.mData->mInteger); -} - -void GmpInt::addProduct(const GmpInt& value1, unsigned long value2) -{ - copyIfShared(); - mpz_addmul_ui(mData->mInteger, value1.mData->mInteger, value2); -} - -void GmpInt::subProduct(const GmpInt& value1, const GmpInt& value2) -{ - copyIfShared(); - mpz_submul(mData->mInteger, value1.mData->mInteger, value2.mData->mInteger); -} - -void GmpInt::subProduct(const GmpInt& value1, unsigned long value2) -{ - copyIfShared(); - mpz_submul_ui(mData->mInteger, value1.mData->mInteger, value2); -} - -void GmpInt::negate() -{ - copyIfShared(); - mpz_neg(mData->mInteger, mData->mInteger); -} - -void GmpInt::abs() -{ - copyIfShared(); - mpz_abs(mData->mInteger, mData->mInteger); -} - -GmpInt GmpInt::abs(const GmpInt& value) -{ - GmpInt retval(kNoInitialization); - mpz_abs(retval.mData->mInteger, value.mData->mInteger); - return retval; -} - - -//=========================================================================== -// Non-modifying operators -//=========================================================================== -GmpInt GmpInt::operator+(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_add(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator+(long value) const -{ - GmpInt retval(kNoInitialization); - if(value >= 0) - mpz_add_ui(retval.mData->mInteger, mData->mInteger, value); - else - mpz_sub_ui(retval.mData->mInteger, mData->mInteger, -value); - return retval; -} - -GmpInt GmpInt::operator-(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_sub(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator-(long value) const -{ - GmpInt retval(kNoInitialization); - if(value >= 0) - mpz_sub_ui(retval.mData->mInteger, mData->mInteger, value); - else - mpz_add_ui(retval.mData->mInteger, mData->mInteger, -value); - return retval; -} - -GmpInt GmpInt::operator*(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_mul(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator*(long value) const -{ - GmpInt retval(kNoInitialization); - mpz_mul_si(retval.mData->mInteger, mData->mInteger, value); - return retval; -} - -GmpInt GmpInt::operator/(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_tdiv_q(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator/(long value) const -{ - GmpInt retval(kNoInitialization); - if(value >= 0) - mpz_tdiv_q_ui(retval.mData->mInteger, mData->mInteger, value); - else - { - mpz_neg(retval.mData->mInteger, mData->mInteger); - mpz_tdiv_q_ui(retval.mData->mInteger, retval.mData->mInteger, -value); - } - return retval; -} - -GmpInt GmpInt::operator%(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - if(operator<(0)) - { - mpz_neg(retval.mData->mInteger, mData->mInteger); - mpz_mod(retval.mData->mInteger, - retval.mData->mInteger, rhs.mData->mInteger); - retval.negate(); - } - else - { - mpz_mod(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - } - return retval; -} - -GmpInt GmpInt::operator%(long value) const -{ - GmpInt retval(kNoInitialization); - if(value < 0) value = -value; - if(operator<(0)) - { - mpz_neg(retval.mData->mInteger, mData->mInteger); - mpz_mod_ui(retval.mData->mInteger, retval.mData->mInteger, value); - retval.negate(); - } - else - { - mpz_mod_ui(retval.mData->mInteger, mData->mInteger, value); - } - return retval; -} - -GmpInt GmpInt::operator-() const -{ - GmpInt retval(kNoInitialization); - mpz_neg(retval.mData->mInteger, mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator<<(unsigned long bits) const -{ - GmpInt retval(kNoInitialization); - mpz_mul_2exp(retval.mData->mInteger, mData->mInteger, bits); - return retval; -} - -GmpInt GmpInt::operator>>(unsigned long bits) const -{ - GmpInt retval(kNoInitialization); - mpz_tdiv_q_2exp(retval.mData->mInteger, mData->mInteger, bits); - return retval; -} - - -//=========================================================================== -// Comparison operators -//=========================================================================== -bool GmpInt::operator<(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) < 0; -} - -bool GmpInt::operator<(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) < 0; -} - -bool GmpInt::operator<=(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) <= 0; -} - -bool GmpInt::operator<=(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) <= 0; -} - -bool GmpInt::operator>(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) > 0; -} - -bool GmpInt::operator>(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) > 0; -} - -bool GmpInt::operator>=(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) >= 0; -} - -bool GmpInt::operator>=(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) >= 0; -} - -bool GmpInt::operator==(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) == 0; -} - -bool GmpInt::operator==(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) == 0; -} - -bool GmpInt::operator!=(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) != 0; -} - -bool GmpInt::operator!=(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) != 0; -} - -void GmpInt::parseValue(const char* value) -{ - mpz_set_str(mData->mInteger, value, 10); -} - -void GmpInt::parseValue(const char* value, char** endptr) -{ - static std::vector str; - - unsigned startIndex = 0; - while(value[startIndex] && std::isspace(value[startIndex])) ++startIndex; - if(!value[startIndex]) { *endptr = const_cast(value); return; } - - unsigned endIndex = startIndex; - if(value[endIndex] == '-') ++endIndex; - if(!std::isdigit(value[endIndex])) - { *endptr = const_cast(value); return; } - if(value[endIndex] == '0' && value[endIndex+1] == 'x') - { - endIndex += 1; - while(std::isxdigit(value[++endIndex])) {} - } - else - { - while(std::isdigit(value[++endIndex])) {} - } - - str.reserve(endIndex - startIndex + 1); - str.assign(value + startIndex, value + endIndex); - str.push_back(0); - - mpz_set_str(mData->mInteger, &str[0], 0); - *endptr = const_cast(value + endIndex); -} - -GmpInt GmpInt::parseString(const char* str, char** endptr) -{ - GmpInt retval(kNoInitialization); - retval.parseValue(str, endptr); - return retval; -} - -//=========================================================================== -// Operator functions -//=========================================================================== -GmpInt operator+(long lhs, const GmpInt& rhs) -{ - GmpInt retval(GmpInt::kNoInitialization); - if(lhs >= 0) - mpz_add_ui(retval.mData->mInteger, rhs.mData->mInteger, lhs); - else - mpz_sub_ui(retval.mData->mInteger, rhs.mData->mInteger, -lhs); - return retval; -} - -GmpInt operator-(long lhs, const GmpInt& rhs) -{ - GmpInt retval(GmpInt::kNoInitialization); - if(lhs >= 0) - mpz_ui_sub(retval.mData->mInteger, lhs, rhs.mData->mInteger); - else - { - mpz_add_ui(retval.mData->mInteger, rhs.mData->mInteger, -lhs); - mpz_neg(retval.mData->mInteger, retval.mData->mInteger); - } - return retval; -} - -GmpInt operator*(long lhs, const GmpInt& rhs) -{ - return rhs * lhs; -} - -GmpInt operator/(long lhs, const GmpInt& rhs) -{ - return GmpInt(lhs) / rhs; -} - -GmpInt operator%(long lhs, const GmpInt& rhs) -{ - return GmpInt(lhs) % rhs; -} diff --git a/deal.II/contrib/functionparser/mpfr/GmpInt.hh b/deal.II/contrib/functionparser/mpfr/GmpInt.hh deleted file mode 100644 index 1c1c1712dc..0000000000 --- a/deal.II/contrib/functionparser/mpfr/GmpInt.hh +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef ONCE_FP_GMP_INT_HH_ -#define ONCE_FP_GMP_INT_HH_ - -#include - -class GmpInt -{ - public: - /* A default of 256 bits will be used for all newly-instantiated GmpInt - objects. This default can be changed with the function below. - */ - static void setDefaultNumberOfBits(unsigned long); - static unsigned long getDefaultNumberOfBits(); - - GmpInt(); - GmpInt(long value); - GmpInt(unsigned long value); - GmpInt(int value); - GmpInt(double value); - GmpInt(long double value); - - GmpInt(const GmpInt&); - GmpInt& operator=(const GmpInt&); - GmpInt& operator=(signed long value); - - ~GmpInt(); - - - /* This function can be used to retrieve the raw mpz_t data structure - used by this object. (The template trick is used to avoid a dependency - of this header file with .) - In other words, it can be called like: - - mpz_t raw_mpz_data; - intValue.get_raw_mpz_data(raw_mpz_data); - - Note that the returned mpz_t should be considered as read-only and - not be modified from the outside because it may be shared among - several objects. If the calling code needs to modify the data, it - should copy it for itself first with the appropriate GMP library - functions. - */ - template - void get_raw_mpfr_data(Mpz_t& dest_mpz_t); - - - // Note that the returned char* points to an internal (shared) buffer - // which will be valid until the next time this function is called - // (by any object). - const char* getAsString(int base = 10) const; - long toInt() const; - - GmpInt& operator+=(const GmpInt&); - GmpInt& operator+=(long); - GmpInt& operator-=(const GmpInt&); - GmpInt& operator-=(long); - GmpInt& operator*=(const GmpInt&); - GmpInt& operator*=(long); - GmpInt& operator/=(const GmpInt&); - GmpInt& operator/=(long); - GmpInt& operator%=(const GmpInt&); - GmpInt& operator%=(long); - - GmpInt& operator<<=(unsigned long); - GmpInt& operator>>=(unsigned long); - - // Equivalent to "+= value1 * value2;" - void addProduct(const GmpInt& value1, const GmpInt& value2); - void addProduct(const GmpInt& value1, unsigned long value2); - - // Equivalent to "-= value1 * value2;" - void subProduct(const GmpInt& value1, const GmpInt& value2); - void subProduct(const GmpInt& value1, unsigned long value2); - - void negate(); - void abs(); - static GmpInt abs(const GmpInt&); - - GmpInt operator+(const GmpInt&) const; - GmpInt operator+(long) const; - GmpInt operator-(const GmpInt&) const; - GmpInt operator-(long) const; - GmpInt operator*(const GmpInt&) const; - GmpInt operator*(long) const; - GmpInt operator/(const GmpInt&) const; - GmpInt operator/(long) const; - GmpInt operator%(const GmpInt&) const; - GmpInt operator%(long) const; - - GmpInt operator-() const; - - GmpInt operator<<(unsigned long) const; - GmpInt operator>>(unsigned long) const; - - bool operator<(const GmpInt&) const; - bool operator<(long) const; - bool operator<=(const GmpInt&) const; - bool operator<=(long) const; - bool operator>(const GmpInt&) const; - bool operator>(long) const; - bool operator>=(const GmpInt&) const; - bool operator>=(long) const; - bool operator==(const GmpInt&) const; - bool operator==(long) const; - bool operator!=(const GmpInt&) const; - bool operator!=(long) const; - - void parseValue(const char* value); - void parseValue(const char* value, char** endptr); - static GmpInt parseString(const char* str, char** endptr); - - - private: - struct GmpIntData; - class GmpIntDataContainer; - - GmpIntData* mData; - - enum DummyType { kNoInitialization }; - GmpInt(DummyType); - - void copyIfShared(); - static GmpIntDataContainer& gmpIntDataContainer(); - - friend GmpInt operator+(long lhs, const GmpInt& rhs); - friend GmpInt operator-(long lhs, const GmpInt& rhs); -}; - -GmpInt operator+(long lhs, const GmpInt& rhs); -GmpInt operator-(long lhs, const GmpInt& rhs); -GmpInt operator*(long lhs, const GmpInt& rhs); -GmpInt operator/(long lhs, const GmpInt& rhs); -GmpInt operator%(long lhs, const GmpInt& rhs); - -inline bool operator<(long lhs, const GmpInt& rhs) { return rhs > lhs; } -inline bool operator<=(long lhs, const GmpInt& rhs) { return rhs >= lhs; } -inline bool operator>(long lhs, const GmpInt& rhs) { return rhs < lhs; } -inline bool operator>=(long lhs, const GmpInt& rhs) { return rhs <= lhs; } -inline bool operator==(long lhs, const GmpInt& rhs) { return rhs == lhs; } -inline bool operator!=(long lhs, const GmpInt& rhs) { return rhs != lhs; } - -inline std::ostream& operator<<(std::ostream& os, const GmpInt& value) -{ - os << value.getAsString(); - return os; -} - -#endif diff --git a/deal.II/contrib/functionparser/mpfr/MpfrFloat.cc b/deal.II/contrib/functionparser/mpfr/MpfrFloat.cc deleted file mode 100644 index 112c684aec..0000000000 --- a/deal.II/contrib/functionparser/mpfr/MpfrFloat.cc +++ /dev/null @@ -1,976 +0,0 @@ -#include "MpfrFloat.hh" -#include -#include -#include -#include -#include -#include - -//=========================================================================== -// Auxiliary structs -//=========================================================================== -struct MpfrFloat::MpfrFloatData -{ - unsigned mRefCount; - MpfrFloatData* nextFreeNode; - mpfr_t mFloat; - - MpfrFloatData(): mRefCount(1), nextFreeNode(0) {} -}; - -class MpfrFloat::MpfrFloatDataContainer -{ - unsigned long mDefaultPrecision; - std::deque mData; - MpfrFloatData* mFirstFreeNode; - - MpfrFloatData - *mConst_0, *mConst_pi, *mConst_e, *mConst_log2, *mConst_epsilon; - - void recalculateEpsilon() - { - mpfr_set_si(mConst_epsilon->mFloat, 1, GMP_RNDN); - mpfr_div_2ui(mConst_epsilon->mFloat, mConst_epsilon->mFloat, - mDefaultPrecision*7/8 - 1, GMP_RNDN); - } - - public: - MpfrFloatDataContainer(): - mDefaultPrecision(256), mFirstFreeNode(0), mConst_0(0), - mConst_pi(0), mConst_e(0), mConst_log2(0), mConst_epsilon(0) - {} - - ~MpfrFloatDataContainer() - { - for(size_t i = 0; i < mData.size(); ++i) - mpfr_clear(mData[i].mFloat); - } - - MpfrFloatData* allocateMpfrFloatData(bool initToZero) - { - if(mFirstFreeNode) - { - MpfrFloatData* node = mFirstFreeNode; - mFirstFreeNode = node->nextFreeNode; - if(initToZero) mpfr_set_si(node->mFloat, 0, GMP_RNDN); - ++(node->mRefCount); - return node; - } - - mData.push_back(MpfrFloatData()); - mpfr_init2(mData.back().mFloat, mDefaultPrecision); - if(initToZero) mpfr_set_si(mData.back().mFloat, 0, GMP_RNDN); - return &mData.back(); - } - - void releaseMpfrFloatData(MpfrFloatData* data) - { - if(--(data->mRefCount) == 0) - { - data->nextFreeNode = mFirstFreeNode; - mFirstFreeNode = data; - } - } - - void setDefaultPrecision(unsigned long bits) - { - if(bits != mDefaultPrecision) - { - mDefaultPrecision = bits; - for(size_t i = 0; i < mData.size(); ++i) - mpfr_prec_round(mData[i].mFloat, bits, GMP_RNDN); - - if(mConst_pi) mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN); - if(mConst_e) - { - mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN); - mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN); - } - if(mConst_log2) mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN); - if(mConst_epsilon) recalculateEpsilon(); - } - } - - unsigned long getDefaultPrecision() const - { - return mDefaultPrecision; - } - - MpfrFloatData* const_0() - { - if(!mConst_0) mConst_0 = allocateMpfrFloatData(true); - return mConst_0; - } - - MpfrFloat const_pi() - { - if(!mConst_pi) - { - mConst_pi = allocateMpfrFloatData(false); - mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN); - } - return MpfrFloat(mConst_pi); - } - - MpfrFloat const_e() - { - if(!mConst_e) - { - mConst_e = allocateMpfrFloatData(false); - mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN); - mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN); - } - return MpfrFloat(mConst_e); - } - - MpfrFloat const_log2() - { - if(!mConst_log2) - { - mConst_log2 = allocateMpfrFloatData(false); - mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN); - } - return MpfrFloat(mConst_log2); - } - - MpfrFloat const_epsilon() - { - if(!mConst_epsilon) - { - mConst_epsilon = allocateMpfrFloatData(false); - recalculateEpsilon(); - } - return MpfrFloat(mConst_epsilon); - } -}; - - -//=========================================================================== -// Shared data -//=========================================================================== -// This should ensure that the container is not accessed by any MpfrFloat -// instance before it has been constructed or after it has been destroyed -// (which might otherwise happen if MpfrFloat is instantiated globally.) -MpfrFloat::MpfrFloatDataContainer& MpfrFloat::mpfrFloatDataContainer() -{ - static MpfrFloat::MpfrFloatDataContainer container; - return container; -} - - -//=========================================================================== -// Auxiliary functions -//=========================================================================== -void MpfrFloat::setDefaultMantissaBits(unsigned long bits) -{ - mpfrFloatDataContainer().setDefaultPrecision(bits); -} - -unsigned long MpfrFloat::getCurrentDefaultMantissaBits() -{ - return mpfrFloatDataContainer().getDefaultPrecision(); -} - -inline void MpfrFloat::copyIfShared() -{ - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - MpfrFloatData* oldData = mData; - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set(mData->mFloat, oldData->mFloat, GMP_RNDN); - } -} - - -//=========================================================================== -// Constructors, destructor, assignment -//=========================================================================== -MpfrFloat::MpfrFloat(DummyType): - mData(mpfrFloatDataContainer().allocateMpfrFloatData(false)) -{} - -MpfrFloat::MpfrFloat(MpfrFloatData* data): - mData(data) -{ - assert(data != 0); - ++(mData->mRefCount); -} - -MpfrFloat::MpfrFloat(): - mData(mpfrFloatDataContainer().const_0()) -{ - ++(mData->mRefCount); -} - -MpfrFloat::MpfrFloat(double value) -{ - if(value == 0.0) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_d(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(long double value) -{ - if(value == 0.0L) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_ld(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(long value) -{ - if(value == 0) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(int value) -{ - if(value == 0) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(const char* value, char** endptr): - mData(mpfrFloatDataContainer().allocateMpfrFloatData(false)) -{ - mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN); -} - -MpfrFloat::~MpfrFloat() -{ - mpfrFloatDataContainer().releaseMpfrFloatData(mData); -} - -MpfrFloat::MpfrFloat(const MpfrFloat& rhs): - mData(rhs.mData) -{ - ++(mData->mRefCount); -} - -MpfrFloat& MpfrFloat::operator=(const MpfrFloat& rhs) -{ - if(mData != rhs.mData) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = rhs.mData; - ++(mData->mRefCount); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(double value) -{ - if(value == 0.0) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_d(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(long double value) -{ - if(value == 0.0L) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_ld(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(long value) -{ - if(value == 0) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(int value) -{ - if(value == 0) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -/* -MpfrFloat& MpfrFloat::operator=(const char* value) -{ - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - - mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN); - return *this; -} -*/ - -void MpfrFloat::parseValue(const char* value) -{ - copyIfShared(); - mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN); -} - -void MpfrFloat::parseValue(const char* value, char** endptr) -{ - copyIfShared(); - mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN); -} - - -//=========================================================================== -// Data getters -//=========================================================================== -template<> -void MpfrFloat::get_raw_mpfr_data(mpfr_t& dest_mpfr_t) -{ - std::memcpy(&dest_mpfr_t, mData->mFloat, sizeof(mpfr_t)); -} - -const char* MpfrFloat::getAsString(unsigned precision) const -{ -#if(MPFR_VERSION_MAJOR < 2 || (MPFR_VERSION_MAJOR == 2 && MPFR_VERSION_MINOR < 4)) - static const char* retval = - "[mpfr_snprintf() is not supported in mpfr versions prior to 2.4]"; - return retval; -#else - static std::vector str; - str.resize(precision+30); - mpfr_snprintf(&(str[0]), precision+30, "%.*RNg", precision, mData->mFloat); - return &(str[0]); -#endif -} - -bool MpfrFloat::isInteger() const -{ - return mpfr_integer_p(mData->mFloat) != 0; -} - -long MpfrFloat::toInt() const -{ - return mpfr_get_si(mData->mFloat, GMP_RNDN); -} - -double MpfrFloat::toDouble() const -{ - return mpfr_get_d(mData->mFloat, GMP_RNDN); -} - - -//=========================================================================== -// Modifying operators -//=========================================================================== -MpfrFloat& MpfrFloat::operator+=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_add(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator+=(double value) -{ - copyIfShared(); - mpfr_add_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator-=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_sub(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator-=(double value) -{ - copyIfShared(); - mpfr_sub_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator*=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_mul(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator*=(double value) -{ - copyIfShared(); - mpfr_mul_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator/=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_div(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator/=(double value) -{ - copyIfShared(); - mpfr_div_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator%=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_fmod(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - - -//=========================================================================== -// Modifying functions -//=========================================================================== -void MpfrFloat::negate() -{ - copyIfShared(); - mpfr_neg(mData->mFloat, mData->mFloat, GMP_RNDN); -} - -void MpfrFloat::abs() -{ - copyIfShared(); - mpfr_abs(mData->mFloat, mData->mFloat, GMP_RNDN); -} - - -//=========================================================================== -// Non-modifying operators -//=========================================================================== -MpfrFloat MpfrFloat::operator+(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_add(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator+(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_add_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator-(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_sub(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator-(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_sub_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator*(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_mul(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator*(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_mul_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator/(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_div(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator/(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_div_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator%(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_fmod(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator-() const -{ - MpfrFloat retval(kNoInitialization); - mpfr_neg(retval.mData->mFloat, mData->mFloat, GMP_RNDN); - return retval; -} - - - -//=========================================================================== -// Comparison operators -//=========================================================================== -bool MpfrFloat::operator<(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) < 0; -} - -bool MpfrFloat::operator<(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) < 0; -} - -bool MpfrFloat::operator<=(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) <= 0; -} - -bool MpfrFloat::operator<=(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) <= 0; -} - -bool MpfrFloat::operator>(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) > 0; -} - -bool MpfrFloat::operator>(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) > 0; -} - -bool MpfrFloat::operator>=(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) >= 0; -} - -bool MpfrFloat::operator>=(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) >= 0; -} - -bool MpfrFloat::operator==(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) == 0; -} - -bool MpfrFloat::operator==(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) == 0; -} - -bool MpfrFloat::operator!=(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) != 0; -} - -bool MpfrFloat::operator!=(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) != 0; -} - - -//=========================================================================== -// Operator functions -//=========================================================================== -MpfrFloat operator+(double lhs, const MpfrFloat& rhs) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_add_d(retval.mData->mFloat, rhs.mData->mFloat, lhs, GMP_RNDN); - return retval; -} - -MpfrFloat operator-(double lhs, const MpfrFloat& rhs) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_d_sub(retval.mData->mFloat, lhs, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat operator*(double lhs, const MpfrFloat& rhs) -{ - return rhs * lhs; -} - -MpfrFloat operator/(double lhs, const MpfrFloat& rhs) -{ - return MpfrFloat(lhs) / rhs; -} - -MpfrFloat operator%(double lhs, const MpfrFloat& rhs) -{ - return MpfrFloat(lhs) % rhs; -} - -std::ostream& operator<<(std::ostream& os, const MpfrFloat& value) -{ - os << value.getAsString(unsigned(os.precision())); - return os; -} - -//=========================================================================== -// Static functions -//=========================================================================== -MpfrFloat MpfrFloat::log(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_log(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::log2(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_log2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::log10(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_log10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::exp(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_exp(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::exp2(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_exp2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::exp10(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_exp10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cos(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sin(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::tan(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_tan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sec(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sec(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::csc(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_csc(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cot(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cot(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -void MpfrFloat::sincos(const MpfrFloat& value, - MpfrFloat& sin, - MpfrFloat& cos) -{ - sin.copyIfShared(); - cos.copyIfShared(); - mpfr_sin_cos - (sin.mData->mFloat, cos.mData->mFloat, value.mData->mFloat, GMP_RNDN); -} - -MpfrFloat MpfrFloat::acos(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_acos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::asin(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_asin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::atan(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_atan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::atan2(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_atan2(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::hypot(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_hypot(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cosh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sinh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::tanh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_tanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::acosh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_acosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::asinh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_asinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::atanh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_atanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sqrt(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sqrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cbrt(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cbrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::root(const MpfrFloat& value, unsigned long root) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_root(retval.mData->mFloat, value.mData->mFloat, root, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::pow(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_pow(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::pow(const MpfrFloat& value, long exponent) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_pow_si(retval.mData->mFloat, value.mData->mFloat, exponent, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::abs(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_abs(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::dim(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_dim(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::round(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_round(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::ceil(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_ceil(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::floor(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_floor(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::trunc(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_trunc(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::parseString(const char* str, char** endptr) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_strtofr(retval.mData->mFloat, str, endptr, 0, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::const_pi() -{ - return mpfrFloatDataContainer().const_pi(); -} - -MpfrFloat MpfrFloat::const_e() -{ - return mpfrFloatDataContainer().const_e(); -} - -MpfrFloat MpfrFloat::const_log2() -{ - return mpfrFloatDataContainer().const_log2(); -} - -MpfrFloat MpfrFloat::someEpsilon() -{ - return mpfrFloatDataContainer().const_epsilon(); -} diff --git a/deal.II/contrib/functionparser/mpfr/MpfrFloat.hh b/deal.II/contrib/functionparser/mpfr/MpfrFloat.hh deleted file mode 100644 index d455d24ce4..0000000000 --- a/deal.II/contrib/functionparser/mpfr/MpfrFloat.hh +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef ONCE_FP_MPFR_FLOAT_ -#define ONCE_FP_MPFR_FLOAT_ - -#include - -class MpfrFloat -{ - public: - /* A default of 256 bits will be used unless changed with this function. - Note that all existing and cached GMP objects will be resized to the - specified precision (which can be a somewhat heavy operation). - */ - static void setDefaultMantissaBits(unsigned long bits); - - static unsigned long getCurrentDefaultMantissaBits(); - - /* The default constructor initializes the object to the value 0. - It's efficient to instantiate such zero-initialized objects because - all of them will share the same mpfr data. (Also any object initialized - with or assigned the explicit value of zero will also share that one - mpfr data.) Thus multiple zero-initialized MpfrFloat instances won't - consume significant amounts of memory (until they are modified to - contain some other value, of course). - - Important caveat: - ---------------- - Note that initializing an MpfrFloat object with, for example, 0.1 will - suffer from accuracy problems (at least if the MpfrFloat object has - more mantissa bits than a double). The C++ double value 0.1 has only - 53 mantissa bits, while the MpfrFloat object usually has more. If the - MpfrFloat object is initialized with a double, only that many bits of - accuracy will end up in the value of the MpfrFloat object. This can - create significant rounding/accuracy problems in some cases. - If you need to initialize the MpfrObject with some value (which cannot - be represented accurately by base-2 floating point numbers, eg. 0.1) - at full mantissa precision, you have to use parseValue("0.1") instead, - rather than relying on the constructor taking a double type value. - */ - MpfrFloat(); - MpfrFloat(double value); - MpfrFloat(long double value); - MpfrFloat(long value); - MpfrFloat(int value); - MpfrFloat(const char* value, char** endptr); - - ~MpfrFloat(); - - MpfrFloat(const MpfrFloat&); - - MpfrFloat& operator=(const MpfrFloat&); - MpfrFloat& operator=(double value); - MpfrFloat& operator=(long double value); - MpfrFloat& operator=(long value); - MpfrFloat& operator=(int value); - //MpfrFloat& operator=(const char* value); - - void parseValue(const char* value); - void parseValue(const char* value, char** endptr); - - - /* This function can be used to retrieve the raw mpfr_t data structure - used by this object. (The template trick is used to avoid a dependency - of this header file with .) - In other words, it can be called like: - - mpfr_t raw_mpfr_data; - floatValue.get_raw_mpfr_data(raw_mpfr_data); - - Note that the returned mpfr_t should be considered as read-only and - not be modified from the outside because it may be shared among - several objects. If the calling code needs to modify the data, it - should copy it for itself first with the appropriate MPFR library - functions. - */ - template - void get_raw_mpfr_data(Mpfr_t& dest_mpfr_t); - - - /* Note that the returned char* points to an internal (shared) buffer - which will be valid until the next time this function is called - (by any object). - */ - const char* getAsString(unsigned precision) const; - - bool isInteger() const; - long toInt() const; - double toDouble() const; - - MpfrFloat& operator+=(const MpfrFloat&); - MpfrFloat& operator+=(double); - MpfrFloat& operator-=(const MpfrFloat&); - MpfrFloat& operator-=(double); - MpfrFloat& operator*=(const MpfrFloat&); - MpfrFloat& operator*=(double); - MpfrFloat& operator/=(const MpfrFloat&); - MpfrFloat& operator/=(double); - MpfrFloat& operator%=(const MpfrFloat&); - - void negate(); - void abs(); - - MpfrFloat operator+(const MpfrFloat&) const; - MpfrFloat operator+(double) const; - MpfrFloat operator-(const MpfrFloat&) const; - MpfrFloat operator-(double) const; - MpfrFloat operator*(const MpfrFloat&) const; - MpfrFloat operator*(double) const; - MpfrFloat operator/(const MpfrFloat&) const; - MpfrFloat operator/(double) const; - MpfrFloat operator%(const MpfrFloat&) const; - - MpfrFloat operator-() const; - - bool operator<(const MpfrFloat&) const; - bool operator<(double) const; - bool operator<=(const MpfrFloat&) const; - bool operator<=(double) const; - bool operator>(const MpfrFloat&) const; - bool operator>(double) const; - bool operator>=(const MpfrFloat&) const; - bool operator>=(double) const; - bool operator==(const MpfrFloat&) const; - bool operator==(double) const; - bool operator!=(const MpfrFloat&) const; - bool operator!=(double) const; - - static MpfrFloat log(const MpfrFloat&); - static MpfrFloat log2(const MpfrFloat&); - static MpfrFloat log10(const MpfrFloat&); - static MpfrFloat exp(const MpfrFloat&); - static MpfrFloat exp2(const MpfrFloat&); - static MpfrFloat exp10(const MpfrFloat&); - static MpfrFloat cos(const MpfrFloat&); - static MpfrFloat sin(const MpfrFloat&); - static MpfrFloat tan(const MpfrFloat&); - static MpfrFloat sec(const MpfrFloat&); - static MpfrFloat csc(const MpfrFloat&); - static MpfrFloat cot(const MpfrFloat&); - static void sincos(const MpfrFloat&, MpfrFloat& sin, MpfrFloat& cos); - static MpfrFloat acos(const MpfrFloat&); - static MpfrFloat asin(const MpfrFloat&); - static MpfrFloat atan(const MpfrFloat&); - static MpfrFloat atan2(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat hypot(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat cosh(const MpfrFloat&); - static MpfrFloat sinh(const MpfrFloat&); - static MpfrFloat tanh(const MpfrFloat&); - static MpfrFloat acosh(const MpfrFloat&); - static MpfrFloat asinh(const MpfrFloat&); - static MpfrFloat atanh(const MpfrFloat&); - static MpfrFloat sqrt(const MpfrFloat&); - static MpfrFloat cbrt(const MpfrFloat&); - static MpfrFloat root(const MpfrFloat&, unsigned long root); - static MpfrFloat pow(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat pow(const MpfrFloat&, long exponent); - static MpfrFloat abs(const MpfrFloat&); - static MpfrFloat dim(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat round(const MpfrFloat&); - static MpfrFloat ceil(const MpfrFloat&); - static MpfrFloat floor(const MpfrFloat&); - static MpfrFloat trunc(const MpfrFloat&); - - static MpfrFloat parseString(const char* str, char** endptr); - - // These values are cached (and recalculated every time the mantissa bits - // change), so it's efficient to call these repeatedly: - static MpfrFloat const_pi(); - static MpfrFloat const_e(); - static MpfrFloat const_log2(); - static MpfrFloat someEpsilon(); - - - private: - struct MpfrFloatData; - class MpfrFloatDataContainer; - - MpfrFloatData* mData; - - enum DummyType { kNoInitialization }; - MpfrFloat(DummyType); - MpfrFloat(MpfrFloatData*); - - void copyIfShared(); - static MpfrFloatDataContainer& mpfrFloatDataContainer(); - - friend MpfrFloat operator+(double lhs, const MpfrFloat& rhs); - friend MpfrFloat operator-(double lhs, const MpfrFloat& rhs); -}; - -MpfrFloat operator+(double lhs, const MpfrFloat& rhs); -MpfrFloat operator-(double lhs, const MpfrFloat& rhs); -MpfrFloat operator*(double lhs, const MpfrFloat& rhs); -MpfrFloat operator/(double lhs, const MpfrFloat& rhs); -MpfrFloat operator%(double lhs, const MpfrFloat& rhs); - -inline bool operator<(double lhs, const MpfrFloat& rhs) { return rhs > lhs; } -inline bool operator<=(double lhs, const MpfrFloat& rhs) { return rhs >= lhs; } -inline bool operator>(double lhs, const MpfrFloat& rhs) { return rhs < lhs; } -inline bool operator>=(double lhs, const MpfrFloat& rhs) { return rhs <= lhs; } -inline bool operator==(double lhs, const MpfrFloat& rhs) { return rhs == lhs; } -inline bool operator!=(double lhs, const MpfrFloat& rhs) { return rhs != lhs; } - -// This function takes into account the value of os.precision() -std::ostream& operator<<(std::ostream& os, const MpfrFloat& value); - -#endif