C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
Classes | Namespaces | Macros | Typedefs | Enumerations | Functions | Variables
exprtk.hpp File Reference
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
#include <ctime>
#include <sys/time.h>
#include <sys/types.h>
#include <fstream>
Include dependency graph for exprtk.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  exprtk::details::ilesscompare
 
class  exprtk::details::build_string
 
struct  exprtk::details::cs_match
 
struct  exprtk::details::cis_match
 
struct  exprtk::details::set_zero_value_impl< T >
 
struct  exprtk::details::set_zero_value_impl< float >
 
struct  exprtk::details::set_zero_value_impl< double >
 
struct  exprtk::details::set_zero_value_impl< long double >
 
struct  exprtk::details::numeric::details::unknown_type_tag
 
struct  exprtk::details::numeric::details::real_type_tag
 
struct  exprtk::details::numeric::details::int_type_tag
 
struct  exprtk::details::numeric::details::number_type< T >
 
struct  exprtk::details::numeric::details::number_type< float >
 
struct  exprtk::details::numeric::details::number_type< double >
 
struct  exprtk::details::numeric::details::number_type< long double >
 
struct  exprtk::details::numeric::details::number_type< short >
 
struct  exprtk::details::numeric::details::number_type< int >
 
struct  exprtk::details::numeric::details::number_type< _int64_t >
 
struct  exprtk::details::numeric::details::number_type< unsigned short >
 
struct  exprtk::details::numeric::details::number_type< unsigned int >
 
struct  exprtk::details::numeric::details::number_type< _uint64_t >
 
struct  exprtk::details::numeric::details::epsilon_type< T >
 
struct  exprtk::details::numeric::details::epsilon_type< float >
 
struct  exprtk::details::numeric::details::epsilon_type< double >
 
struct  exprtk::details::numeric::details::epsilon_type< long double >
 
struct  exprtk::details::numeric::numeric_info< Type >
 
struct  exprtk::details::numeric::numeric_info< int >
 
struct  exprtk::details::numeric::numeric_info< float >
 
struct  exprtk::details::numeric::numeric_info< double >
 
struct  exprtk::details::numeric::numeric_info< long double >
 
struct  exprtk::details::numeric::fast_exp< T, N >
 
struct  exprtk::details::numeric::fast_exp< T, 10 >
 
struct  exprtk::details::numeric::fast_exp< T, 9 >
 
struct  exprtk::details::numeric::fast_exp< T, 8 >
 
struct  exprtk::details::numeric::fast_exp< T, 7 >
 
struct  exprtk::details::numeric::fast_exp< T, 6 >
 
struct  exprtk::details::numeric::fast_exp< T, 5 >
 
struct  exprtk::details::numeric::fast_exp< T, 4 >
 
struct  exprtk::details::numeric::fast_exp< T, 3 >
 
struct  exprtk::details::numeric::fast_exp< T, 2 >
 
struct  exprtk::details::numeric::fast_exp< T, 1 >
 
struct  exprtk::details::numeric::fast_exp< T, 0 >
 
struct  exprtk::details::functor_t< T >
 
struct  exprtk::loop_runtime_check
 
struct  exprtk::loop_runtime_check::violation_context
 
struct  exprtk::vector_access_runtime_check
 
struct  exprtk::vector_access_runtime_check::violation_context
 
struct  exprtk::assert_check
 
struct  exprtk::assert_check::assert_context
 
struct  exprtk::compilation_check
 
struct  exprtk::compilation_check::compilation_context
 
struct  exprtk::lexer::token
 
class  exprtk::lexer::generator
 
class  exprtk::lexer::helper_interface
 
class  exprtk::lexer::token_scanner
 
class  exprtk::lexer::token_modifier
 
class  exprtk::lexer::token_inserter
 
class  exprtk::lexer::token_joiner
 
class  exprtk::lexer::helper::commutative_inserter
 
class  exprtk::lexer::helper::operator_joiner
 
class  exprtk::lexer::helper::bracket_checker
 
class  exprtk::lexer::helper::numeric_checker< T >
 
class  exprtk::lexer::helper::symbol_replacer
 
class  exprtk::lexer::helper::sequence_validator
 
class  exprtk::lexer::helper::sequence_validator_3tokens
 
struct  exprtk::lexer::helper::helper_assembly
 
class  exprtk::lexer::parser_helper
 
class  exprtk::vector_view< T >
 
struct  exprtk::type_store< T >
 
class  exprtk::type_store< T >::parameter_list
 
struct  exprtk::type_store< T >::type_view< ViewType >
 
struct  exprtk::type_store< T >::scalar_view
 
class  exprtk::results_context< T >
 
struct  exprtk::details::base_operation_t
 
struct  exprtk::details::loop_unroll::details
 
class  exprtk::details::vec_data_store< T >
 
struct  exprtk::details::vec_data_store< T >::control_block
 
struct  exprtk::details::node_collector_interface< Node >
 
class  exprtk::details::expression_node< T >
 
class  exprtk::details::node_collection_destructor< Node >
 
struct  exprtk::details::node_depth_base< Node >
 
class  exprtk::details::vector_holder< Type >
 
class  exprtk::details::vector_holder< Type >::vector_holder_base
 
class  exprtk::details::vector_holder< Type >::array_vector_impl
 
class  exprtk::details::vector_holder< Type >::sequence_vector_impl< Allocator, Sequence >
 
class  exprtk::details::vector_holder< Type >::vector_view_impl
 
class  exprtk::details::vector_holder< Type >::resizable_vector_impl
 
class  exprtk::details::null_node< T >
 
class  exprtk::details::null_eq_node< T >
 
class  exprtk::details::literal_node< T >
 
class  exprtk::details::range_interface< T >
 
class  exprtk::details::string_base_node< T >
 
class  exprtk::details::string_literal_node< T >
 
class  exprtk::details::unary_node< T >
 
class  exprtk::details::binary_node< T >
 
class  exprtk::details::binary_ext_node< T, Operation >
 
class  exprtk::details::trinary_node< T >
 
class  exprtk::details::quaternary_node< T >
 
class  exprtk::details::conditional_node< T >
 
class  exprtk::details::cons_conditional_node< T >
 
class  exprtk::details::break_exception< T >
 
class  exprtk::details::continue_exception
 
class  exprtk::details::break_node< T >
 
class  exprtk::details::continue_node< T >
 
struct  exprtk::details::loop_runtime_checker
 
class  exprtk::details::while_loop_node< T >
 
class  exprtk::details::while_loop_rtc_node< T >
 
class  exprtk::details::repeat_until_loop_node< T >
 
class  exprtk::details::repeat_until_loop_rtc_node< T >
 
class  exprtk::details::for_loop_node< T >
 
class  exprtk::details::for_loop_rtc_node< T >
 
class  exprtk::details::while_loop_bc_node< T >
 
class  exprtk::details::while_loop_bc_rtc_node< T >
 
class  exprtk::details::repeat_until_loop_bc_node< T >
 
class  exprtk::details::repeat_until_loop_bc_rtc_node< T >
 
class  exprtk::details::for_loop_bc_node< T >
 
class  exprtk::details::for_loop_bc_rtc_node< T >
 
class  exprtk::details::switch_node< T >
 
class  exprtk::details::switch_n_node< T, Switch_N >
 
class  exprtk::details::multi_switch_node< T >
 
class  exprtk::details::ivariable< T >
 
class  exprtk::details::variable_node< T >
 
struct  exprtk::details::range_pack< T >
 
struct  exprtk::details::range_data_type< T >
 
class  exprtk::details::vector_interface< T >
 
class  exprtk::details::vector_node< T >
 
class  exprtk::details::vector_size_node< T >
 
class  exprtk::details::vector_elem_node< T >
 
class  exprtk::details::vector_celem_node< T >
 
class  exprtk::details::vector_elem_rtc_node< T >
 
class  exprtk::details::vector_celem_rtc_node< T >
 
class  exprtk::details::rebasevector_elem_node< T >
 
class  exprtk::details::rebasevector_celem_node< T >
 
class  exprtk::details::rebasevector_elem_rtc_node< T >
 
class  exprtk::details::rebasevector_celem_rtc_node< T >
 
class  exprtk::details::vector_initialisation_node< T >
 
class  exprtk::details::vector_init_zero_value_node< T >
 
class  exprtk::details::vector_init_single_constvalue_node< T >
 
class  exprtk::details::vector_init_single_value_node< T >
 
class  exprtk::details::vector_init_iota_constconst_node< T >
 
class  exprtk::details::vector_init_iota_constnconst_node< T >
 
class  exprtk::details::vector_init_iota_nconstconst_node< T >
 
class  exprtk::details::vector_init_iota_nconstnconst_node< T >
 
class  exprtk::details::swap_node< T >
 
class  exprtk::details::swap_generic_node< T >
 
class  exprtk::details::swap_vecvec_node< T >
 
class  exprtk::details::stringvar_node< T >
 
class  exprtk::details::string_range_node< T >
 
class  exprtk::details::const_string_range_node< T >
 
class  exprtk::details::generic_string_range_node< T >
 
class  exprtk::details::string_concat_node< T >
 
class  exprtk::details::swap_string_node< T >
 
class  exprtk::details::swap_genstrings_node< T >
 
class  exprtk::details::stringvar_size_node< T >
 
class  exprtk::details::string_size_node< T >
 
struct  exprtk::details::asn_assignment
 
struct  exprtk::details::asn_addassignment
 
class  exprtk::details::assignment_string_node< T, AssignmentProcess >
 
class  exprtk::details::assignment_string_range_node< T, AssignmentProcess >
 
class  exprtk::details::conditional_string_node< T >
 
class  exprtk::details::cons_conditional_str_node< T >
 
class  exprtk::details::str_vararg_node< T, VarArgFunction >
 
class  exprtk::details::assert_node< T >
 
struct  exprtk::details::sf_base< T >
 
struct  exprtk::details::sf00_op< T >
 
struct  exprtk::details::sf01_op< T >
 
struct  exprtk::details::sf02_op< T >
 
struct  exprtk::details::sf03_op< T >
 
struct  exprtk::details::sf04_op< T >
 
struct  exprtk::details::sf05_op< T >
 
struct  exprtk::details::sf06_op< T >
 
struct  exprtk::details::sf07_op< T >
 
struct  exprtk::details::sf08_op< T >
 
struct  exprtk::details::sf09_op< T >
 
struct  exprtk::details::sf10_op< T >
 
struct  exprtk::details::sf11_op< T >
 
struct  exprtk::details::sf12_op< T >
 
struct  exprtk::details::sf13_op< T >
 
struct  exprtk::details::sf14_op< T >
 
struct  exprtk::details::sf15_op< T >
 
struct  exprtk::details::sf16_op< T >
 
struct  exprtk::details::sf17_op< T >
 
struct  exprtk::details::sf18_op< T >
 
struct  exprtk::details::sf19_op< T >
 
struct  exprtk::details::sf20_op< T >
 
struct  exprtk::details::sf21_op< T >
 
struct  exprtk::details::sf22_op< T >
 
struct  exprtk::details::sf23_op< T >
 
struct  exprtk::details::sf24_op< T >
 
struct  exprtk::details::sf25_op< T >
 
struct  exprtk::details::sf26_op< T >
 
struct  exprtk::details::sf27_op< T >
 
struct  exprtk::details::sf28_op< T >
 
struct  exprtk::details::sf29_op< T >
 
struct  exprtk::details::sf30_op< T >
 
struct  exprtk::details::sf31_op< T >
 
struct  exprtk::details::sf32_op< T >
 
struct  exprtk::details::sf33_op< T >
 
struct  exprtk::details::sf34_op< T >
 
struct  exprtk::details::sf35_op< T >
 
struct  exprtk::details::sf36_op< T >
 
struct  exprtk::details::sf37_op< T >
 
struct  exprtk::details::sf38_op< T >
 
struct  exprtk::details::sf39_op< T >
 
struct  exprtk::details::sf40_op< T >
 
struct  exprtk::details::sf41_op< T >
 
struct  exprtk::details::sf42_op< T >
 
struct  exprtk::details::sf43_op< T >
 
struct  exprtk::details::sf44_op< T >
 
struct  exprtk::details::sf45_op< T >
 
struct  exprtk::details::sf46_op< T >
 
struct  exprtk::details::sf47_op< T >
 
struct  exprtk::details::sf48_op< T >
 
struct  exprtk::details::sf49_op< T >
 
struct  exprtk::details::sf50_op< T >
 
struct  exprtk::details::sf51_op< T >
 
struct  exprtk::details::sf52_op< T >
 
struct  exprtk::details::sf53_op< T >
 
struct  exprtk::details::sf54_op< T >
 
struct  exprtk::details::sf55_op< T >
 
struct  exprtk::details::sf56_op< T >
 
struct  exprtk::details::sf57_op< T >
 
struct  exprtk::details::sf58_op< T >
 
struct  exprtk::details::sf59_op< T >
 
struct  exprtk::details::sf60_op< T >
 
struct  exprtk::details::sf61_op< T >
 
struct  exprtk::details::sf62_op< T >
 
struct  exprtk::details::sf63_op< T >
 
struct  exprtk::details::sf64_op< T >
 
struct  exprtk::details::sf65_op< T >
 
struct  exprtk::details::sf66_op< T >
 
struct  exprtk::details::sf67_op< T >
 
struct  exprtk::details::sf68_op< T >
 
struct  exprtk::details::sf69_op< T >
 
struct  exprtk::details::sf70_op< T >
 
struct  exprtk::details::sf71_op< T >
 
struct  exprtk::details::sf72_op< T >
 
struct  exprtk::details::sf73_op< T >
 
struct  exprtk::details::sf74_op< T >
 
struct  exprtk::details::sf75_op< T >
 
struct  exprtk::details::sf76_op< T >
 
struct  exprtk::details::sf77_op< T >
 
struct  exprtk::details::sf78_op< T >
 
struct  exprtk::details::sf79_op< T >
 
struct  exprtk::details::sf80_op< T >
 
struct  exprtk::details::sf81_op< T >
 
struct  exprtk::details::sf82_op< T >
 
struct  exprtk::details::sf83_op< T >
 
struct  exprtk::details::sf84_op< T >
 
struct  exprtk::details::sf85_op< T >
 
struct  exprtk::details::sf86_op< T >
 
struct  exprtk::details::sf87_op< T >
 
struct  exprtk::details::sf88_op< T >
 
struct  exprtk::details::sf89_op< T >
 
struct  exprtk::details::sf90_op< T >
 
struct  exprtk::details::sf91_op< T >
 
struct  exprtk::details::sf92_op< T >
 
struct  exprtk::details::sf93_op< T >
 
struct  exprtk::details::sf94_op< T >
 
struct  exprtk::details::sf95_op< T >
 
struct  exprtk::details::sf96_op< T >
 
struct  exprtk::details::sf97_op< T >
 
struct  exprtk::details::sf98_op< T >
 
struct  exprtk::details::sf99_op< T >
 
struct  exprtk::details::sfext00_op< T >
 
struct  exprtk::details::sfext01_op< T >
 
struct  exprtk::details::sfext02_op< T >
 
struct  exprtk::details::sfext03_op< T >
 
struct  exprtk::details::sfext04_op< T >
 
struct  exprtk::details::sfext05_op< T >
 
struct  exprtk::details::sfext06_op< T >
 
struct  exprtk::details::sfext07_op< T >
 
struct  exprtk::details::sfext08_op< T >
 
struct  exprtk::details::sfext09_op< T >
 
struct  exprtk::details::sfext10_op< T >
 
struct  exprtk::details::sfext11_op< T >
 
struct  exprtk::details::sfext12_op< T >
 
struct  exprtk::details::sfext13_op< T >
 
struct  exprtk::details::sfext14_op< T >
 
struct  exprtk::details::sfext15_op< T >
 
struct  exprtk::details::sfext16_op< T >
 
struct  exprtk::details::sfext17_op< T >
 
struct  exprtk::details::sfext18_op< T >
 
struct  exprtk::details::sfext19_op< T >
 
struct  exprtk::details::sfext20_op< T >
 
struct  exprtk::details::sfext21_op< T >
 
struct  exprtk::details::sfext22_op< T >
 
struct  exprtk::details::sfext23_op< T >
 
struct  exprtk::details::sfext24_op< T >
 
struct  exprtk::details::sfext25_op< T >
 
struct  exprtk::details::sfext26_op< T >
 
struct  exprtk::details::sfext27_op< T >
 
struct  exprtk::details::sfext28_op< T >
 
struct  exprtk::details::sfext29_op< T >
 
struct  exprtk::details::sfext30_op< T >
 
struct  exprtk::details::sfext31_op< T >
 
struct  exprtk::details::sfext32_op< T >
 
struct  exprtk::details::sfext33_op< T >
 
struct  exprtk::details::sfext34_op< T >
 
struct  exprtk::details::sfext35_op< T >
 
struct  exprtk::details::sfext36_op< T >
 
struct  exprtk::details::sfext37_op< T >
 
struct  exprtk::details::sfext38_op< T >
 
struct  exprtk::details::sfext39_op< T >
 
struct  exprtk::details::sfext40_op< T >
 
struct  exprtk::details::sfext41_op< T >
 
struct  exprtk::details::sfext42_op< T >
 
struct  exprtk::details::sfext43_op< T >
 
struct  exprtk::details::sfext44_op< T >
 
struct  exprtk::details::sfext45_op< T >
 
struct  exprtk::details::sfext46_op< T >
 
struct  exprtk::details::sfext47_op< T >
 
struct  exprtk::details::sfext48_op< T >
 
struct  exprtk::details::sfext49_op< T >
 
struct  exprtk::details::sfext50_op< T >
 
struct  exprtk::details::sfext51_op< T >
 
struct  exprtk::details::sfext52_op< T >
 
struct  exprtk::details::sfext53_op< T >
 
struct  exprtk::details::sfext54_op< T >
 
struct  exprtk::details::sfext55_op< T >
 
struct  exprtk::details::sfext56_op< T >
 
struct  exprtk::details::sfext57_op< T >
 
struct  exprtk::details::sfext58_op< T >
 
struct  exprtk::details::sfext59_op< T >
 
struct  exprtk::details::sfext60_op< T >
 
struct  exprtk::details::sfext61_op< T >
 
class  exprtk::details::sf3_node< T, SpecialFunction >
 
class  exprtk::details::sf4_node< T, SpecialFunction >
 
class  exprtk::details::sf3_var_node< T, SpecialFunction >
 
class  exprtk::details::sf4_var_node< T, SpecialFunction >
 
class  exprtk::details::vararg_node< T, VarArgFunction >
 
class  exprtk::details::vararg_varnode< T, VarArgFunction >
 
class  exprtk::details::vectorize_node< T, VecFunction >
 
class  exprtk::details::assignment_node< T >
 
class  exprtk::details::assignment_vec_elem_node< T >
 
class  exprtk::details::assignment_vec_elem_rtc_node< T >
 
class  exprtk::details::assignment_rebasevec_elem_node< T >
 
class  exprtk::details::assignment_rebasevec_elem_rtc_node< T >
 
class  exprtk::details::assignment_rebasevec_celem_node< T >
 
class  exprtk::details::assignment_vec_node< T >
 
class  exprtk::details::assignment_vecvec_node< T >
 
class  exprtk::details::assignment_op_node< T, Operation >
 
class  exprtk::details::assignment_vec_elem_op_node< T, Operation >
 
class  exprtk::details::assignment_vec_elem_op_rtc_node< T, Operation >
 
class  exprtk::details::assignment_vec_celem_op_rtc_node< T, Operation >
 
class  exprtk::details::assignment_rebasevec_elem_op_node< T, Operation >
 
class  exprtk::details::assignment_rebasevec_celem_op_node< T, Operation >
 
class  exprtk::details::assignment_rebasevec_elem_op_rtc_node< T, Operation >
 
class  exprtk::details::assignment_rebasevec_celem_op_rtc_node< T, Operation >
 
class  exprtk::details::assignment_vec_op_node< T, Operation >
 
class  exprtk::details::assignment_vecvec_op_node< T, Operation >
 
struct  exprtk::details::memory_context_t< T >
 
class  exprtk::details::vec_binop_vecvec_node< T, Operation >
 
class  exprtk::details::vec_binop_vecval_node< T, Operation >
 
class  exprtk::details::vec_binop_valvec_node< T, Operation >
 
class  exprtk::details::unary_vector_node< T, Operation >
 
class  exprtk::details::conditional_vector_node< T >
 
class  exprtk::details::scand_node< T >
 
class  exprtk::details::scor_node< T >
 
class  exprtk::details::function_N_node< T, IFunction, N >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, BranchCount >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, 6 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, 5 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, 4 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, 3 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, 2 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::evaluate_branches< T_, 1 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, ParamCount >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 20 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 19 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 18 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 17 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 16 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 15 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 14 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 13 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 12 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 11 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 10 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 9 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 8 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 7 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 6 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 5 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 4 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 3 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 2 >
 
struct  exprtk::details::function_N_node< T, IFunction, N >::invoke< T_, 1 >
 
class  exprtk::details::function_N_node< T, IFunction, 0 >
 
class  exprtk::details::vararg_function_node< T, VarArgFunction >
 
class  exprtk::details::generic_function_node< T, GenericFunction >
 
class  exprtk::details::string_function_node< T, StringFunction >
 
class  exprtk::details::multimode_genfunction_node< T, GenericFunction >
 
class  exprtk::details::multimode_strfunction_node< T, StringFunction >
 
class  exprtk::details::return_exception
 
class  exprtk::details::null_igenfunc< T >
 
class  exprtk::details::return_node< T >
 
class  exprtk::details::return_envelope_node< T >
 
struct  exprtk::details::abs_op< T >
 
struct  exprtk::details::acos_op< T >
 
struct  exprtk::details::acosh_op< T >
 
struct  exprtk::details::asin_op< T >
 
struct  exprtk::details::asinh_op< T >
 
struct  exprtk::details::atan_op< T >
 
struct  exprtk::details::atanh_op< T >
 
struct  exprtk::details::ceil_op< T >
 
struct  exprtk::details::cos_op< T >
 
struct  exprtk::details::cosh_op< T >
 
struct  exprtk::details::cot_op< T >
 
struct  exprtk::details::csc_op< T >
 
struct  exprtk::details::d2g_op< T >
 
struct  exprtk::details::d2r_op< T >
 
struct  exprtk::details::erf_op< T >
 
struct  exprtk::details::erfc_op< T >
 
struct  exprtk::details::exp_op< T >
 
struct  exprtk::details::expm1_op< T >
 
struct  exprtk::details::floor_op< T >
 
struct  exprtk::details::frac_op< T >
 
struct  exprtk::details::g2d_op< T >
 
struct  exprtk::details::log_op< T >
 
struct  exprtk::details::log10_op< T >
 
struct  exprtk::details::log2_op< T >
 
struct  exprtk::details::log1p_op< T >
 
struct  exprtk::details::ncdf_op< T >
 
struct  exprtk::details::neg_op< T >
 
struct  exprtk::details::notl_op< T >
 
struct  exprtk::details::pos_op< T >
 
struct  exprtk::details::r2d_op< T >
 
struct  exprtk::details::round_op< T >
 
struct  exprtk::details::sec_op< T >
 
struct  exprtk::details::sgn_op< T >
 
struct  exprtk::details::sin_op< T >
 
struct  exprtk::details::sinc_op< T >
 
struct  exprtk::details::sinh_op< T >
 
struct  exprtk::details::sqrt_op< T >
 
struct  exprtk::details::tan_op< T >
 
struct  exprtk::details::tanh_op< T >
 
struct  exprtk::details::trunc_op< T >
 
struct  exprtk::details::opr_base< T >
 
struct  exprtk::details::add_op< T >
 
struct  exprtk::details::mul_op< T >
 
struct  exprtk::details::sub_op< T >
 
struct  exprtk::details::div_op< T >
 
struct  exprtk::details::mod_op< T >
 
struct  exprtk::details::pow_op< T >
 
struct  exprtk::details::lt_op< T >
 
struct  exprtk::details::lte_op< T >
 
struct  exprtk::details::gt_op< T >
 
struct  exprtk::details::gte_op< T >
 
struct  exprtk::details::eq_op< T >
 
struct  exprtk::details::equal_op< T >
 
struct  exprtk::details::ne_op< T >
 
struct  exprtk::details::and_op< T >
 
struct  exprtk::details::nand_op< T >
 
struct  exprtk::details::or_op< T >
 
struct  exprtk::details::nor_op< T >
 
struct  exprtk::details::xor_op< T >
 
struct  exprtk::details::xnor_op< T >
 
struct  exprtk::details::in_op< T >
 
struct  exprtk::details::like_op< T >
 
struct  exprtk::details::ilike_op< T >
 
struct  exprtk::details::inrange_op< T >
 
struct  exprtk::details::vararg_add_op< T >
 
struct  exprtk::details::vararg_mul_op< T >
 
struct  exprtk::details::vararg_avg_op< T >
 
struct  exprtk::details::vararg_min_op< T >
 
struct  exprtk::details::vararg_max_op< T >
 
struct  exprtk::details::vararg_mand_op< T >
 
struct  exprtk::details::vararg_mor_op< T >
 
struct  exprtk::details::vararg_multi_op< T >
 
struct  exprtk::details::vec_add_op< T >
 
struct  exprtk::details::vec_mul_op< T >
 
struct  exprtk::details::vec_avg_op< T >
 
struct  exprtk::details::vec_min_op< T >
 
struct  exprtk::details::vec_max_op< T >
 
class  exprtk::details::vov_base_node< T >
 
class  exprtk::details::cov_base_node< T >
 
class  exprtk::details::voc_base_node< T >
 
class  exprtk::details::vob_base_node< T >
 
class  exprtk::details::bov_base_node< T >
 
class  exprtk::details::cob_base_node< T >
 
class  exprtk::details::boc_base_node< T >
 
class  exprtk::details::uv_base_node< T >
 
class  exprtk::details::sos_base_node< T >
 
class  exprtk::details::sosos_base_node< T >
 
class  exprtk::details::T0oT1oT2_base_node< T >
 
class  exprtk::details::T0oT1oT2oT3_base_node< T >
 
class  exprtk::details::unary_variable_node< T, Operation >
 
class  exprtk::details::uvouv_node< T >
 
class  exprtk::details::unary_branch_node< T, Operation >
 
struct  exprtk::details::is_const< T >
 
struct  exprtk::details::is_const< const T >
 
struct  exprtk::details::is_const_ref< T >
 
struct  exprtk::details::is_const_ref< const T & >
 
struct  exprtk::details::is_ref< T >
 
struct  exprtk::details::is_ref< T & >
 
struct  exprtk::details::is_ref< const T & >
 
struct  exprtk::details::param_to_str< State >
 
struct  exprtk::details::param_to_str< 0 >
 
struct  exprtk::details::T0oT1oT2process< T >
 
struct  exprtk::details::T0oT1oT2process< T >::mode0
 
struct  exprtk::details::T0oT1oT2process< T >::mode1
 
struct  exprtk::details::T0oT1oT20T3process< T >
 
struct  exprtk::details::T0oT1oT20T3process< T >::mode0
 
struct  exprtk::details::T0oT1oT20T3process< T >::mode1
 
struct  exprtk::details::T0oT1oT20T3process< T >::mode2
 
struct  exprtk::details::T0oT1oT20T3process< T >::mode3
 
struct  exprtk::details::T0oT1oT20T3process< T >::mode4
 
struct  exprtk::details::nodetype_T0oT1< T, T0, T1 >
 
struct  exprtk::details::nodetype_T0oT1< T, const T0 &, const T1 & >
 
struct  exprtk::details::nodetype_T0oT1< T, const T0 &, const T1 >
 
struct  exprtk::details::nodetype_T0oT1< T, const T0, const T1 & >
 
struct  exprtk::details::nodetype_T0oT1< T, T0 &, T1 & >
 
struct  exprtk::details::nodetype_T0oT1< T, const T0, const T1 >
 
struct  exprtk::details::nodetype_T0oT1< T, T0 &, const T1 >
 
struct  exprtk::details::nodetype_T0oT1< T, const T0, T1 & >
 
struct  exprtk::details::nodetype_T0oT1< T, const T0 &, T1 & >
 
struct  exprtk::details::nodetype_T0oT1< T, T0 &, const T1 & >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, T0, T1, T2 >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0 &, const T1 &, const T2 & >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0 &, const T1 &, const T2 >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0 &, const T1, const T2 & >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0, const T1 &, const T2 & >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0, const T1 &, const T2 >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0, const T1, const T2 >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0, const T1, const T2 & >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, const T0 &, const T1, const T2 >
 
struct  exprtk::details::nodetype_T0oT1oT2< T, T0 &, T1 &, T2 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, T0, T1, T2, T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1 &, const T2 &, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1 &, const T2 &, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1 &, const T2, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1, const T2 &, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1 &, const T2 &, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1 &, const T2, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1, const T2 &, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1 &, const T2 &, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1, const T2, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1, const T2, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1, const T2, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1, const T2 &, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1 &, const T2, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1, const T2, const T3 >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0, const T1, const T2 &, const T3 & >
 
struct  exprtk::details::nodetype_T0oT1oT2oT3< T, const T0 &, const T1 &, const T2, const T3 >
 
class  exprtk::details::T0oT1< T, T0, T1 >
 
class  exprtk::details::T0oT1oT2< T, T0, T1, T2, ProcessMode >
 
class  exprtk::details::T0oT1oT2oT3< T, T0_, T1_, T2_, T3_, ProcessMode >
 
class  exprtk::details::T0oT1oT2_sf3< T, T0, T1, T2 >
 
class  exprtk::details::sf3ext_type_node< T, T0, T1, T2 >
 
class  exprtk::details::T0oT1oT2_sf3ext< T, T0, T1, T2, SF3Operation >
 
class  exprtk::details::T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 >
 
class  exprtk::details::T0oT1oT2oT3_sf4ext< T, T0, T1, T2, T3, SF4Operation >
 
struct  exprtk::details::T0oT1_define< T, T0, T1 >
 
struct  exprtk::details::T0oT1oT2_define< T, T0, T1, T2 >
 
struct  exprtk::details::T0oT1oT2oT3_define< T, T0, T1, T2, T3 >
 
class  exprtk::details::vov_node< T, Operation >
 
class  exprtk::details::cov_node< T, Operation >
 
class  exprtk::details::voc_node< T, Operation >
 
class  exprtk::details::vob_node< T, Operation >
 
class  exprtk::details::bov_node< T, Operation >
 
class  exprtk::details::cob_node< T, Operation >
 
class  exprtk::details::boc_node< T, Operation >
 
class  exprtk::details::sos_node< T, SType0, SType1, Operation >
 
class  exprtk::details::str_xrox_node< T, SType0, SType1, RangePack, Operation >
 
class  exprtk::details::str_xoxr_node< T, SType0, SType1, RangePack, Operation >
 
class  exprtk::details::str_xroxr_node< T, SType0, SType1, RangePack, Operation >
 
class  exprtk::details::str_sogens_node< T, Operation >
 
class  exprtk::details::sosos_node< T, SType0, SType1, SType2, Operation >
 
class  exprtk::details::ipow_node< T, PowOp >
 
class  exprtk::details::bipow_node< T, PowOp >
 
class  exprtk::details::ipowinv_node< T, PowOp >
 
class  exprtk::details::bipowinv_node< T, PowOp >
 
class  exprtk::details::node_allocator
 
class  exprtk::function_traits
 
class  exprtk::ifunction< T >
 
class  exprtk::ivararg_function< T >
 
class  exprtk::igeneric_function< T >
 
class  exprtk::stringvar_base< T >
 
class  exprtk::symbol_table< T >
 
struct  exprtk::symbol_table< T >::freefunc00
 
struct  exprtk::symbol_table< T >::freefunc01
 
struct  exprtk::symbol_table< T >::freefunc02
 
struct  exprtk::symbol_table< T >::freefunc03
 
struct  exprtk::symbol_table< T >::freefunc04
 
struct  exprtk::symbol_table< T >::freefunc05
 
struct  exprtk::symbol_table< T >::freefunc06
 
struct  exprtk::symbol_table< T >::freefunc07
 
struct  exprtk::symbol_table< T >::freefunc08
 
struct  exprtk::symbol_table< T >::freefunc09
 
struct  exprtk::symbol_table< T >::freefunc10
 
struct  exprtk::symbol_table< T >::freefunc11
 
struct  exprtk::symbol_table< T >::freefunc12
 
struct  exprtk::symbol_table< T >::freefunc13
 
struct  exprtk::symbol_table< T >::freefunc14
 
struct  exprtk::symbol_table< T >::freefunc15
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::deleter
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::tie_array
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::tie_stdvec
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::tie_vecview
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::tie_stddeq
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::ptr_match< TType, TRawType, PtrType >
 
struct  exprtk::symbol_table< T >::type_store< Type, RawType >::ptr_match< TType, TRawType, variable_node_t * >
 
struct  exprtk::symbol_table< T >::control_block
 
struct  exprtk::symbol_table< T >::control_block::st_data
 
class  exprtk::expression< T >
 
struct  exprtk::expression< T >::control_block
 
struct  exprtk::expression< T >::control_block::data_pack
 
class  exprtk::expression_helper< T >
 
struct  exprtk::parser_error::type
 
class  exprtk::parser< T >
 
struct  exprtk::parser< T >::scope_element
 
class  exprtk::parser< T >::scope_element_manager
 
class  exprtk::parser< T >::scope_handler
 
struct  exprtk::parser< T >::halfopen_range_policy< T_ >
 
struct  exprtk::parser< T >::closed_range_policy< T_ >
 
class  exprtk::parser< T >::interval_container_t< IntervalPointType, RangePolicy >
 
class  exprtk::parser< T >::stack_limit_handler
 
struct  exprtk::parser< T >::symtab_store
 
struct  exprtk::parser< T >::symtab_store::variable_context
 
struct  exprtk::parser< T >::symtab_store::vector_context
 
struct  exprtk::parser< T >::symtab_store::string_context
 
struct  exprtk::parser< T >::parser_state
 
struct  exprtk::parser< T >::unknown_symbol_resolver
 
class  exprtk::parser< T >::dependent_entity_collector
 
class  exprtk::parser< T >::settings_store
 
struct  exprtk::parser< T >::state_t
 
struct  exprtk::parser< T >::scoped_expression_delete
 
struct  exprtk::parser< T >::scoped_delete< Type, N >
 
struct  exprtk::parser< T >::scoped_deq_delete< Type >
 
struct  exprtk::parser< T >::scoped_vec_delete< Type >
 
struct  exprtk::parser< T >::scoped_bool_negator
 
struct  exprtk::parser< T >::scoped_bool_or_restorer
 
struct  exprtk::parser< T >::scoped_inc_dec
 
class  exprtk::parser< T >::type_checker
 
struct  exprtk::parser< T >::type_checker::function_prototype_t
 
struct  exprtk::parser< T >::parse_special_function_impl< Type, NumberOfParameters >
 
class  exprtk::parser< T >::expression_generator< Type >
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_1
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_2
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_3
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_4
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_5
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_6
 
struct  exprtk::parser< T >::expression_generator< Type >::switch_nodes::switch_impl_7
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_binary_ext_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vob_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_bov_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_cob_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_boc_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_cocob_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_coboc_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vov_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_cov_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_voc_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_sf3ext_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_sf4ext_expression
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovoc_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovoc_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covoc_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covoc_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_cocov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_cocov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococ_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococ_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovoc_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovocov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covocov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovoc_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovoc_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococov_expression0
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovoc_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovocov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covocov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovoc_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovoc_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococov_expression1
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovov_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovoc_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovocov_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovov_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovov_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covocov_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovoc_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovoc_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococov_expression2
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovov_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovoc_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovocov_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovov_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovov_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covocov_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovoc_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovoc_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococov_expression3
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovov_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovovoc_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vovocov_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovov_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovov_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covocov_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vocovoc_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_covovoc_expression4
 
struct  exprtk::parser< T >::expression_generator< Type >::synthesize_vococov_expression4
 
struct  exprtk::details::collector_helper< T >
 
struct  exprtk::details::collector_helper< T >::resolve_as_vector
 
class  exprtk::polynomial< T, N >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, NumberOfCoefficients >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 12 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 11 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 10 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 9 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 8 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 7 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 6 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 5 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 4 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 3 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 2 >
 
struct  exprtk::polynomial< T, N >::poly_impl< Type, 1 >
 
class  exprtk::function_compositor< T >
 
struct  exprtk::function_compositor< T >::function
 
struct  exprtk::function_compositor< T >::base_func
 
struct  exprtk::function_compositor< T >::scoped_bft< BaseFuncType >
 
struct  exprtk::function_compositor< T >::func_0param
 
struct  exprtk::function_compositor< T >::func_1param
 
struct  exprtk::function_compositor< T >::func_2param
 
struct  exprtk::function_compositor< T >::func_3param
 
struct  exprtk::function_compositor< T >::func_4param
 
struct  exprtk::function_compositor< T >::func_5param
 
struct  exprtk::function_compositor< T >::func_6param
 
struct  exprtk::function_compositor< T >::func_0param_retval
 
struct  exprtk::function_compositor< T >::func_1param_retval
 
struct  exprtk::function_compositor< T >::func_2param_retval
 
struct  exprtk::function_compositor< T >::func_3param_retval
 
struct  exprtk::function_compositor< T >::func_4param_retval
 
struct  exprtk::function_compositor< T >::func_5param_retval
 
struct  exprtk::function_compositor< T >::func_6param_retval
 
class  exprtk::timer
 
struct  exprtk::type_defs< T >
 
struct  exprtk::rtl::io::details::print_impl< T >
 
struct  exprtk::rtl::io::print< T >
 
struct  exprtk::rtl::io::println< T >
 
struct  exprtk::rtl::io::package< T >
 
struct  exprtk::rtl::io::file::details::file_descriptor
 
class  exprtk::rtl::io::file::open< T >
 
struct  exprtk::rtl::io::file::close< T >
 
class  exprtk::rtl::io::file::write< T >
 
class  exprtk::rtl::io::file::read< T >
 
class  exprtk::rtl::io::file::getline< T >
 
struct  exprtk::rtl::io::file::eof< T >
 
struct  exprtk::rtl::io::file::package< T >
 
struct  exprtk::rtl::vecops::helper::load_vector_range< T >
 
class  exprtk::rtl::vecops::all_true< T >
 
class  exprtk::rtl::vecops::all_false< T >
 
class  exprtk::rtl::vecops::any_true< T >
 
class  exprtk::rtl::vecops::any_false< T >
 
class  exprtk::rtl::vecops::count< T >
 
class  exprtk::rtl::vecops::copy< T >
 
class  exprtk::rtl::vecops::rol< T >
 
class  exprtk::rtl::vecops::ror< T >
 
class  exprtk::rtl::vecops::reverse< T >
 
class  exprtk::rtl::vecops::shift_left< T >
 
class  exprtk::rtl::vecops::shift_right< T >
 
class  exprtk::rtl::vecops::sort< T >
 
class  exprtk::rtl::vecops::nthelement< T >
 
class  exprtk::rtl::vecops::assign< T >
 
class  exprtk::rtl::vecops::iota< T >
 
class  exprtk::rtl::vecops::sumk< T >
 
class  exprtk::rtl::vecops::axpy< T >
 
class  exprtk::rtl::vecops::axpby< T >
 
class  exprtk::rtl::vecops::axpyz< T >
 
class  exprtk::rtl::vecops::axpbyz< T >
 
class  exprtk::rtl::vecops::axpbsy< T >
 
class  exprtk::rtl::vecops::axpbsyz< T >
 
class  exprtk::rtl::vecops::axpbz< T >
 
class  exprtk::rtl::vecops::diff< T >
 
class  exprtk::rtl::vecops::dot< T >
 
class  exprtk::rtl::vecops::dotk< T >
 
class  exprtk::rtl::vecops::threshold_below< T >
 
class  exprtk::rtl::vecops::threshold_above< T >
 
struct  exprtk::rtl::vecops::package< T >
 

Namespaces

namespace  exprtk
 
namespace  exprtk::details
 
namespace  exprtk::details::numeric
 
namespace  exprtk::details::numeric::constant
 
namespace  exprtk::details::numeric::details
 
namespace  exprtk::lexer
 
namespace  exprtk::lexer::helper
 
namespace  exprtk::details::loop_unroll
 
namespace  exprtk::parser_error
 
namespace  exprtk::rtl
 
namespace  exprtk::rtl::io
 
namespace  exprtk::rtl::io::details
 
namespace  exprtk::rtl::io::file
 
namespace  exprtk::rtl::io::file::details
 
namespace  exprtk::rtl::vecops
 
namespace  exprtk::rtl::vecops::helper
 
namespace  exprtk::rtl::vecops::details
 
namespace  exprtk::information
 

Macros

#define exprtk_debug(params)   (void)0
 
#define exprtk_error_location    "exprtk.hpp:" + details::to_str(__LINE__) \
 
#define exprtk_override
 
#define exprtk_final
 
#define exprtk_delete
 
#define exprtk_fallthrough   __attribute__ ((fallthrough));
 
#define pod_set_zero_value(T)
 
#define exprtk_register_real_type_tag(T)
 
#define exprtk_register_int_type_tag(T)
 
#define exprtk_define_epsilon_type(Type, Epsilon)
 
#define exprtk_define_erf(TT, impl)    inline TT erf_impl(const TT v) { return impl(v); } \
 
#define exprtk_define_erfc(TT, impl)    inline TT erfc_impl(const TT v) { return impl(v); } \
 
#define exprtk_define_unary_function(FunctionName)
 
#define exprtk_process_digit
 
#define parse_digit_1(d)
 
#define parse_digit_2(d)
 
#define token_inserter_empty_body
 
#define exprtk_loop(N)    std::swap(s0[N], s1[N]); \
 
#define case_stmt(N)
 
#define define_sfop3(NN, OP0, OP1)
 
#define define_sfop4(NN, OP0, OP1)
 
#define exprtk_loop(N)    vec[N] = v; \
 
#define case_stmt(N)
 
#define exprtk_loop(N)    vec0[N] = vec1[N]; \
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    Operation::assign(vec[N],v); \
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    vec0[N] = Operation::process(vec0[N], vec1[N]); \
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    vec2[N] = Operation::process(vec0[N], vec1[N]); \
 
#define case_stmt(N)
 
#define exprtk_loop(N)    vec1[N] = Operation::process(vec0[N], v); \
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    vec0[N] = Operation::process(v, vec1[N]); \
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    vec1[N] = Operation::process(vec0[N]); \
 
#define case_stmt(N)
 
#define exprtk_define_unary_op(OpName)
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    r[N] += vec[N]; \
 
#define case_stmt(N, fall_through)
 
#define case_stmt(N, fall_through)
 
#define exprtk_loop(N)    r[N] *= vec[N]; \
 
#define case_stmt(N, fall_through)
 
#define exprtk_crtype(Type)    param_to_str<is_const_ref< Type >::result>::result() \
 
#define synthesis_node_type_define(T0_, T1_, v_)
 
#define synthesis_node_type_define(T0_, T1_, T2_, v_)
 
#define synthesis_node_type_define(T0_, T1_, T2_, T3_, v_)
 
#define register_op(Symbol, Type, Args)    m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
 
#define empty_method_body(N)
 
#define igeneric_function_empty_body(N)
 
#define exprtk_define_process(Type)
 
#define exprtk_define_freefunction(NN)
 
#define exprtk_define_reserved_function(NN)
 
#define base_opr_case(N)
 
#define register_synthezier(S)    synthesize_map_[S ::node_type::id()] = S ::process; \
 
#define case_stmt(N)    if (is_true(arg[(2 * N)].first)) { return arg[(2 * N) + 1].first->value(); } \
 
#define case_stmt(N)
 
#define unary_opr_switch_statements
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op)
 
#define case_stmt(op)
 
#define case_stmt(op)
 
#define case_stmt(op)
 
#define case_stmt(op)
 
#define case_stmt(op)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define batch_eqineq_logic_case
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define vector_ops
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define basic_opr_switch_statements
 
#define extended_opr_switch_statements
 
#define case_stmt(cp)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op)
 
#define case_stmt0(op)
 
#define case_stmt1(op)
 
#define string_opr_switch_statements
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define case_stmt(op0, op1)
 
#define register_unary_op(Op, UnaryFunctor)    m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
 
#define register_binary_op(Op, BinaryFunctor)    m.insert(value_type(Op,BinaryFunctor<T>::process)); \
 
#define register_binary_op(Op, BinaryFunctor)    m.insert(value_type(BinaryFunctor<T>::process,Op)); \
 
#define register_sf3(Op)    sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
 
#define register_sf3_extid(Id, Op)    sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
 
#define register_sf4(Op)    sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
 
#define register_sf4ext(Op)    sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
 
#define poly_rtrn(NN)    return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
 
#define exprtk_assign(Index)    (*v[Index]) = v##Index; \
 
#define def_fp_retval(N)
 
#define case_stmt(N)
 
#define exprtk_register_function(FunctionName, FunctionType)
 
#define exprtk_register_function(FunctionName, FunctionType)
 
#define exprtk_register_function(FunctionName, FunctionType)
 

Typedefs

typedef char exprtk::details::char_t
 
typedef char_texprtk::details::char_ptr
 
typedef char_t constexprtk::details::char_cptr
 
typedef unsigned char exprtk::details::uchar_t
 
typedef uchar_texprtk::details::uchar_ptr
 
typedef uchar_t constexprtk::details::uchar_cptr
 
typedef unsigned long long int exprtk::details::_uint64_t
 
typedef long long int exprtk::details::_int64_t
 
typedef loop_runtime_checkexprtk::loop_runtime_check_ptr
 
typedef vector_access_runtime_checkexprtk::vector_access_runtime_check_ptr
 
typedef assert_checkexprtk::assert_check_ptr
 
typedef compilation_checkexprtk::compilation_check_ptr
 

Enumerations

enum  exprtk::details::operator_type {
  exprtk::details::e_default , exprtk::details::e_null , exprtk::details::e_add , exprtk::details::e_sub ,
  exprtk::details::e_mul , exprtk::details::e_div , exprtk::details::e_mod , exprtk::details::e_pow ,
  exprtk::details::e_atan2 , exprtk::details::e_min , exprtk::details::e_max , exprtk::details::e_avg ,
  exprtk::details::e_sum , exprtk::details::e_prod , exprtk::details::e_lt , exprtk::details::e_lte ,
  exprtk::details::e_eq , exprtk::details::e_equal , exprtk::details::e_ne , exprtk::details::e_nequal ,
  exprtk::details::e_gte , exprtk::details::e_gt , exprtk::details::e_and , exprtk::details::e_nand ,
  exprtk::details::e_or , exprtk::details::e_nor , exprtk::details::e_xor , exprtk::details::e_xnor ,
  exprtk::details::e_mand , exprtk::details::e_mor , exprtk::details::e_scand , exprtk::details::e_scor ,
  exprtk::details::e_shr , exprtk::details::e_shl , exprtk::details::e_abs , exprtk::details::e_acos ,
  exprtk::details::e_acosh , exprtk::details::e_asin , exprtk::details::e_asinh , exprtk::details::e_atan ,
  exprtk::details::e_atanh , exprtk::details::e_ceil , exprtk::details::e_cos , exprtk::details::e_cosh ,
  exprtk::details::e_exp , exprtk::details::e_expm1 , exprtk::details::e_floor , exprtk::details::e_log ,
  exprtk::details::e_log10 , exprtk::details::e_log2 , exprtk::details::e_log1p , exprtk::details::e_logn ,
  exprtk::details::e_neg , exprtk::details::e_pos , exprtk::details::e_round , exprtk::details::e_roundn ,
  exprtk::details::e_root , exprtk::details::e_sqrt , exprtk::details::e_sin , exprtk::details::e_sinc ,
  exprtk::details::e_sinh , exprtk::details::e_sec , exprtk::details::e_csc , exprtk::details::e_tan ,
  exprtk::details::e_tanh , exprtk::details::e_cot , exprtk::details::e_clamp , exprtk::details::e_iclamp ,
  exprtk::details::e_inrange , exprtk::details::e_sgn , exprtk::details::e_r2d , exprtk::details::e_d2r ,
  exprtk::details::e_d2g , exprtk::details::e_g2d , exprtk::details::e_hypot , exprtk::details::e_notl ,
  exprtk::details::e_erf , exprtk::details::e_erfc , exprtk::details::e_ncdf , exprtk::details::e_frac ,
  exprtk::details::e_trunc , exprtk::details::e_assign , exprtk::details::e_addass , exprtk::details::e_subass ,
  exprtk::details::e_mulass , exprtk::details::e_divass , exprtk::details::e_modass , exprtk::details::e_in ,
  exprtk::details::e_like , exprtk::details::e_ilike , exprtk::details::e_multi , exprtk::details::e_smulti ,
  exprtk::details::e_swap , exprtk::details::e_sf00 = 1000 , exprtk::details::e_sf01 = 1001 , exprtk::details::e_sf02 = 1002 ,
  exprtk::details::e_sf03 = 1003 , exprtk::details::e_sf04 = 1004 , exprtk::details::e_sf05 = 1005 , exprtk::details::e_sf06 = 1006 ,
  exprtk::details::e_sf07 = 1007 , exprtk::details::e_sf08 = 1008 , exprtk::details::e_sf09 = 1009 , exprtk::details::e_sf10 = 1010 ,
  exprtk::details::e_sf11 = 1011 , exprtk::details::e_sf12 = 1012 , exprtk::details::e_sf13 = 1013 , exprtk::details::e_sf14 = 1014 ,
  exprtk::details::e_sf15 = 1015 , exprtk::details::e_sf16 = 1016 , exprtk::details::e_sf17 = 1017 , exprtk::details::e_sf18 = 1018 ,
  exprtk::details::e_sf19 = 1019 , exprtk::details::e_sf20 = 1020 , exprtk::details::e_sf21 = 1021 , exprtk::details::e_sf22 = 1022 ,
  exprtk::details::e_sf23 = 1023 , exprtk::details::e_sf24 = 1024 , exprtk::details::e_sf25 = 1025 , exprtk::details::e_sf26 = 1026 ,
  exprtk::details::e_sf27 = 1027 , exprtk::details::e_sf28 = 1028 , exprtk::details::e_sf29 = 1029 , exprtk::details::e_sf30 = 1030 ,
  exprtk::details::e_sf31 = 1031 , exprtk::details::e_sf32 = 1032 , exprtk::details::e_sf33 = 1033 , exprtk::details::e_sf34 = 1034 ,
  exprtk::details::e_sf35 = 1035 , exprtk::details::e_sf36 = 1036 , exprtk::details::e_sf37 = 1037 , exprtk::details::e_sf38 = 1038 ,
  exprtk::details::e_sf39 = 1039 , exprtk::details::e_sf40 = 1040 , exprtk::details::e_sf41 = 1041 , exprtk::details::e_sf42 = 1042 ,
  exprtk::details::e_sf43 = 1043 , exprtk::details::e_sf44 = 1044 , exprtk::details::e_sf45 = 1045 , exprtk::details::e_sf46 = 1046 ,
  exprtk::details::e_sf47 = 1047 , exprtk::details::e_sf48 = 1048 , exprtk::details::e_sf49 = 1049 , exprtk::details::e_sf50 = 1050 ,
  exprtk::details::e_sf51 = 1051 , exprtk::details::e_sf52 = 1052 , exprtk::details::e_sf53 = 1053 , exprtk::details::e_sf54 = 1054 ,
  exprtk::details::e_sf55 = 1055 , exprtk::details::e_sf56 = 1056 , exprtk::details::e_sf57 = 1057 , exprtk::details::e_sf58 = 1058 ,
  exprtk::details::e_sf59 = 1059 , exprtk::details::e_sf60 = 1060 , exprtk::details::e_sf61 = 1061 , exprtk::details::e_sf62 = 1062 ,
  exprtk::details::e_sf63 = 1063 , exprtk::details::e_sf64 = 1064 , exprtk::details::e_sf65 = 1065 , exprtk::details::e_sf66 = 1066 ,
  exprtk::details::e_sf67 = 1067 , exprtk::details::e_sf68 = 1068 , exprtk::details::e_sf69 = 1069 , exprtk::details::e_sf70 = 1070 ,
  exprtk::details::e_sf71 = 1071 , exprtk::details::e_sf72 = 1072 , exprtk::details::e_sf73 = 1073 , exprtk::details::e_sf74 = 1074 ,
  exprtk::details::e_sf75 = 1075 , exprtk::details::e_sf76 = 1076 , exprtk::details::e_sf77 = 1077 , exprtk::details::e_sf78 = 1078 ,
  exprtk::details::e_sf79 = 1079 , exprtk::details::e_sf80 = 1080 , exprtk::details::e_sf81 = 1081 , exprtk::details::e_sf82 = 1082 ,
  exprtk::details::e_sf83 = 1083 , exprtk::details::e_sf84 = 1084 , exprtk::details::e_sf85 = 1085 , exprtk::details::e_sf86 = 1086 ,
  exprtk::details::e_sf87 = 1087 , exprtk::details::e_sf88 = 1088 , exprtk::details::e_sf89 = 1089 , exprtk::details::e_sf90 = 1090 ,
  exprtk::details::e_sf91 = 1091 , exprtk::details::e_sf92 = 1092 , exprtk::details::e_sf93 = 1093 , exprtk::details::e_sf94 = 1094 ,
  exprtk::details::e_sf95 = 1095 , exprtk::details::e_sf96 = 1096 , exprtk::details::e_sf97 = 1097 , exprtk::details::e_sf98 = 1098 ,
  exprtk::details::e_sf99 = 1099 , exprtk::details::e_sffinal = 1100 , exprtk::details::e_sf4ext00 = 2000 , exprtk::details::e_sf4ext01 = 2001 ,
  exprtk::details::e_sf4ext02 = 2002 , exprtk::details::e_sf4ext03 = 2003 , exprtk::details::e_sf4ext04 = 2004 , exprtk::details::e_sf4ext05 = 2005 ,
  exprtk::details::e_sf4ext06 = 2006 , exprtk::details::e_sf4ext07 = 2007 , exprtk::details::e_sf4ext08 = 2008 , exprtk::details::e_sf4ext09 = 2009 ,
  exprtk::details::e_sf4ext10 = 2010 , exprtk::details::e_sf4ext11 = 2011 , exprtk::details::e_sf4ext12 = 2012 , exprtk::details::e_sf4ext13 = 2013 ,
  exprtk::details::e_sf4ext14 = 2014 , exprtk::details::e_sf4ext15 = 2015 , exprtk::details::e_sf4ext16 = 2016 , exprtk::details::e_sf4ext17 = 2017 ,
  exprtk::details::e_sf4ext18 = 2018 , exprtk::details::e_sf4ext19 = 2019 , exprtk::details::e_sf4ext20 = 2020 , exprtk::details::e_sf4ext21 = 2021 ,
  exprtk::details::e_sf4ext22 = 2022 , exprtk::details::e_sf4ext23 = 2023 , exprtk::details::e_sf4ext24 = 2024 , exprtk::details::e_sf4ext25 = 2025 ,
  exprtk::details::e_sf4ext26 = 2026 , exprtk::details::e_sf4ext27 = 2027 , exprtk::details::e_sf4ext28 = 2028 , exprtk::details::e_sf4ext29 = 2029 ,
  exprtk::details::e_sf4ext30 = 2030 , exprtk::details::e_sf4ext31 = 2031 , exprtk::details::e_sf4ext32 = 2032 , exprtk::details::e_sf4ext33 = 2033 ,
  exprtk::details::e_sf4ext34 = 2034 , exprtk::details::e_sf4ext35 = 2035 , exprtk::details::e_sf4ext36 = 2036 , exprtk::details::e_sf4ext37 = 2037 ,
  exprtk::details::e_sf4ext38 = 2038 , exprtk::details::e_sf4ext39 = 2039 , exprtk::details::e_sf4ext40 = 2040 , exprtk::details::e_sf4ext41 = 2041 ,
  exprtk::details::e_sf4ext42 = 2042 , exprtk::details::e_sf4ext43 = 2043 , exprtk::details::e_sf4ext44 = 2044 , exprtk::details::e_sf4ext45 = 2045 ,
  exprtk::details::e_sf4ext46 = 2046 , exprtk::details::e_sf4ext47 = 2047 , exprtk::details::e_sf4ext48 = 2048 , exprtk::details::e_sf4ext49 = 2049 ,
  exprtk::details::e_sf4ext50 = 2050 , exprtk::details::e_sf4ext51 = 2051 , exprtk::details::e_sf4ext52 = 2052 , exprtk::details::e_sf4ext53 = 2053 ,
  exprtk::details::e_sf4ext54 = 2054 , exprtk::details::e_sf4ext55 = 2055 , exprtk::details::e_sf4ext56 = 2056 , exprtk::details::e_sf4ext57 = 2057 ,
  exprtk::details::e_sf4ext58 = 2058 , exprtk::details::e_sf4ext59 = 2059 , exprtk::details::e_sf4ext60 = 2060 , exprtk::details::e_sf4ext61 = 2061
}
 
enum  exprtk::parser_error::error_mode {
  exprtk::parser_error::e_unknown = 0 , exprtk::parser_error::e_syntax = 1 , exprtk::parser_error::e_token = 2 , exprtk::parser_error::e_numeric = 4 ,
  exprtk::parser_error::e_symtab = 5 , exprtk::parser_error::e_lexer = 6 , exprtk::parser_error::e_synthesis = 7 , exprtk::parser_error::e_helper = 8 ,
  exprtk::parser_error::e_parser = 9
}
 
enum  exprtk::rtl::io::file::details::file_mode { exprtk::rtl::io::file::details::e_error = 0 , exprtk::rtl::io::file::details::e_read = 1 , exprtk::rtl::io::file::details::e_write = 2 , exprtk::rtl::io::file::details::e_rdwrt = 4 }
 

Functions

bool exprtk::details::is_whitespace (const char_t c)
 
bool exprtk::details::is_operator_char (const char_t c)
 
bool exprtk::details::is_letter (const char_t c)
 
bool exprtk::details::is_digit (const char_t c)
 
bool exprtk::details::is_letter_or_digit (const char_t c)
 
bool exprtk::details::is_left_bracket (const char_t c)
 
bool exprtk::details::is_right_bracket (const char_t c)
 
bool exprtk::details::is_bracket (const char_t c)
 
bool exprtk::details::is_sign (const char_t c)
 
bool exprtk::details::is_invalid (const char_t c)
 
bool exprtk::details::is_valid_string_char (const char_t c)
 
void exprtk::details::case_normalise (std::string &s)
 
bool exprtk::details::imatch (const char_t c1, const char_t c2)
 
bool exprtk::details::imatch (const std::string &s1, const std::string &s2)
 
bool exprtk::details::is_valid_sf_symbol (const std::string &symbol)
 
const char_texprtk::details::front (const std::string &s)
 
const char_texprtk::details::back (const std::string &s)
 
std::string exprtk::details::to_str (int i)
 
std::string exprtk::details::to_str (std::size_t i)
 
bool exprtk::details::is_hex_digit (const uchar_t digit)
 
uchar_t exprtk::details::hex_to_bin (uchar_t h)
 
template<typename Iterator >
bool exprtk::details::parse_hex (Iterator &itr, Iterator end, char_t &result)
 
bool exprtk::details::cleanup_escapes (std::string &s)
 
bool exprtk::details::is_reserved_word (const std::string &symbol)
 
bool exprtk::details::is_reserved_symbol (const std::string &symbol)
 
bool exprtk::details::is_base_function (const std::string &function_name)
 
bool exprtk::details::is_control_struct (const std::string &cntrl_strct)
 
bool exprtk::details::is_logic_opr (const std::string &lgc_opr)
 
template<typename Iterator , typename Compare >
bool exprtk::details::match_impl (const Iterator pattern_begin, const Iterator pattern_end, const Iterator data_begin, const Iterator data_end, const typename std::iterator_traits< Iterator >::value_type &zero_or_more, const typename std::iterator_traits< Iterator >::value_type &exactly_one)
 
bool exprtk::details::wc_match (const std::string &wild_card, const std::string &str)
 
bool exprtk::details::wc_imatch (const std::string &wild_card, const std::string &str)
 
bool exprtk::details::sequence_match (const std::string &pattern, const std::string &str, std::size_t &diff_index, char_t &diff_value)
 
template<typename T >
void exprtk::details::set_zero_value (T *data, const std::size_t size)
 
template<typename T >
void exprtk::details::set_zero_value (std::vector< T > &v)
 
template<typename T >
bool exprtk::details::numeric::details::is_nan_impl (const T v, real_type_tag)
 
template<typename T >
int exprtk::details::numeric::details::to_int32_impl (const T v, real_type_tag)
 
template<typename T >
_int64_t exprtk::details::numeric::details::to_int64_impl (const T v, real_type_tag)
 
template<typename T >
_uint64_t exprtk::details::numeric::details::to_uint64_impl (const T v, real_type_tag)
 
template<typename T >
bool exprtk::details::numeric::details::is_true_impl (const T v)
 
template<typename T >
bool exprtk::details::numeric::details::is_false_impl (const T v)
 
template<typename T >
T exprtk::details::numeric::details::abs_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::min_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::max_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::equal_impl (const T v0, const T v1, real_type_tag)
 
float exprtk::details::numeric::details::equal_impl (const float v0, const float v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::equal_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::expm1_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::expm1_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::nequal_impl (const T v0, const T v1, real_type_tag)
 
float exprtk::details::numeric::details::nequal_impl (const float v0, const float v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::nequal_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::modulus_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::modulus_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::pow_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::pow_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::logn_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::logn_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log1p_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log1p_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::root_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::root_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::round_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::roundn_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::roundn_impl (const T v0, const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::hypot_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::hypot_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::atan2_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::atan2_impl (const T, const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::shr_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::shr_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::shl_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::shl_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sgn_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sgn_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::and_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::and_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::nand_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::nand_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::or_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::or_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::nor_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::nor_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::xor_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::xor_impl (const T v0, const T v1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::xnor_impl (const T v0, const T v1, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::xnor_impl (const T v0, const T v1, int_type_tag)
 
float exprtk::details::numeric::details::erf_impl (const float v)
 
double exprtk::details::numeric::details::erf_impl (const double v)
 
long double exprtk::details::numeric::details::erf_impl (const long double v)
 
template<typename T >
T exprtk::details::numeric::details::erf_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::erf_impl (const T v, int_type_tag)
 
float exprtk::details::numeric::details::erfc_impl (const float v)
 
double exprtk::details::numeric::details::erfc_impl (const double v)
 
long double exprtk::details::numeric::details::erfc_impl (const long double v)
 
template<typename T >
T exprtk::details::numeric::details::erfc_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::erfc_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::ncdf_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::ncdf_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sinc_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sinc_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::acosh_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::asinh_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::atanh_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::acos_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::asin_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::atan_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::ceil_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::cos_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::cosh_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::exp_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::floor_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log10_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log2_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::neg_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::pos_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sin_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sinh_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sqrt_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::tan_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::tanh_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::cot_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sec_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::csc_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::r2d_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::d2r_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::d2g_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::g2d_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::notl_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::frac_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::trunc_impl (const T v, real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::const_pi_impl (real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::const_e_impl (real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::const_qnan_impl (real_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::abs_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::exp_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log10_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::log2_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::neg_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::pos_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::ceil_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::floor_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::round_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::notl_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sqrt_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::frac_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::trunc_impl (const T v, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::acos_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::acosh_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::asin_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::asinh_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::atan_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::atanh_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::cos_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::cosh_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sin_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sinh_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::tan_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::tanh_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::cot_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::sec_impl (const T, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::details::csc_impl (const T, int_type_tag)
 
template<typename T >
bool exprtk::details::numeric::details::is_integer_impl (const T &v, real_type_tag)
 
template<typename T >
bool exprtk::details::numeric::details::is_integer_impl (const T &, int_type_tag)
 
template<typename T >
int exprtk::details::numeric::to_int32 (const T v)
 
template<typename T >
_int64_t exprtk::details::numeric::to_int64 (const T v)
 
template<typename T >
_uint64_t exprtk::details::numeric::to_uint64 (const T v)
 
template<typename T >
bool exprtk::details::numeric::is_nan (const T v)
 
template<typename T >
T exprtk::details::numeric::min (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::max (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::equal (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::nequal (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::modulus (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::pow (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::logn (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::root (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::roundn (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::hypot (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::atan2 (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::shr (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::shl (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::and_opr (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::nand_opr (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::or_opr (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::nor_opr (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::xor_opr (const T v0, const T v1)
 
template<typename T >
T exprtk::details::numeric::xnor_opr (const T v0, const T v1)
 
template<typename T >
bool exprtk::details::numeric::is_integer (const T v)
 
template<typename T >
T exprtk::details::numeric::abs (const T v)
 
template<typename T >
T exprtk::details::numeric::acos (const T v)
 
template<typename T >
T exprtk::details::numeric::acosh (const T v)
 
template<typename T >
T exprtk::details::numeric::asin (const T v)
 
template<typename T >
T exprtk::details::numeric::asinh (const T v)
 
template<typename T >
T exprtk::details::numeric::atan (const T v)
 
template<typename T >
T exprtk::details::numeric::atanh (const T v)
 
template<typename T >
T exprtk::details::numeric::ceil (const T v)
 
template<typename T >
T exprtk::details::numeric::cos (const T v)
 
template<typename T >
T exprtk::details::numeric::cosh (const T v)
 
template<typename T >
T exprtk::details::numeric::exp (const T v)
 
template<typename T >
T exprtk::details::numeric::expm1 (const T v)
 
template<typename T >
T exprtk::details::numeric::floor (const T v)
 
template<typename T >
T exprtk::details::numeric::log (const T v)
 
template<typename T >
T exprtk::details::numeric::log10 (const T v)
 
template<typename T >
T exprtk::details::numeric::log2 (const T v)
 
template<typename T >
T exprtk::details::numeric::log1p (const T v)
 
template<typename T >
T exprtk::details::numeric::neg (const T v)
 
template<typename T >
T exprtk::details::numeric::pos (const T v)
 
template<typename T >
T exprtk::details::numeric::round (const T v)
 
template<typename T >
T exprtk::details::numeric::sin (const T v)
 
template<typename T >
T exprtk::details::numeric::sinc (const T v)
 
template<typename T >
T exprtk::details::numeric::sinh (const T v)
 
template<typename T >
T exprtk::details::numeric::sqrt (const T v)
 
template<typename T >
T exprtk::details::numeric::tan (const T v)
 
template<typename T >
T exprtk::details::numeric::tanh (const T v)
 
template<typename T >
T exprtk::details::numeric::cot (const T v)
 
template<typename T >
T exprtk::details::numeric::sec (const T v)
 
template<typename T >
T exprtk::details::numeric::csc (const T v)
 
template<typename T >
T exprtk::details::numeric::r2d (const T v)
 
template<typename T >
T exprtk::details::numeric::d2r (const T v)
 
template<typename T >
T exprtk::details::numeric::d2g (const T v)
 
template<typename T >
T exprtk::details::numeric::g2d (const T v)
 
template<typename T >
T exprtk::details::numeric::notl (const T v)
 
template<typename T >
T exprtk::details::numeric::sgn (const T v)
 
template<typename T >
T exprtk::details::numeric::erf (const T v)
 
template<typename T >
T exprtk::details::numeric::erfc (const T v)
 
template<typename T >
T exprtk::details::numeric::ncdf (const T v)
 
template<typename T >
T exprtk::details::numeric::frac (const T v)
 
template<typename T >
T exprtk::details::numeric::trunc (const T v)
 
template<typename T >
T exprtk::details::compute_pow10 (T d, const int exponent)
 
template<typename Iterator , typename T >
bool exprtk::details::string_to_type_converter_impl_ref (Iterator &itr, const Iterator end, T &result)
 
template<typename Iterator , typename T >
static bool exprtk::details::parse_nan (Iterator &itr, const Iterator end, T &t)
 
template<typename Iterator , typename T >
static bool exprtk::details::parse_inf (Iterator &itr, const Iterator end, T &t, const bool negative)
 
template<typename T >
bool exprtk::details::valid_exponent (const int exponent, numeric::details::real_type_tag)
 
template<typename Iterator , typename T >
bool exprtk::details::string_to_real (Iterator &itr_external, const Iterator end, T &t, numeric::details::real_type_tag)
 
template<typename T >
bool exprtk::details::string_to_real (const std::string &s, T &t)
 
void exprtk::lexer::helper::dump (const lexer::generator &generator)
 
template<typename T >
vector_view< T > exprtk::make_vector_view (T *data, const std::size_t size, const std::size_t offset=0)
 
template<typename T >
vector_view< T > exprtk::make_vector_view (std::vector< T > &v, const std::size_t size, const std::size_t offset=0)
 
template<typename StringView >
std::string exprtk::to_str (const StringView &view)
 
std::string exprtk::details::to_str (const operator_type opr)
 
void exprtk::details::dump_ptr (const std::string &, const void *)
 
void exprtk::details::dump_ptr (const std::string &, const void *, const std::size_t)
 
template<typename T >
void exprtk::details::dump_vector (const std::string &, const T *, const std::size_t)
 
template<typename T >
T exprtk::details::numeric::details::process_impl (const operator_type operation, const T arg)
 
template<typename T >
T exprtk::details::numeric::details::process_impl (const operator_type operation, const T arg0, const T arg1)
 
template<typename T >
T exprtk::details::numeric::details::process_impl (const operator_type operation, const T arg0, const T arg1, int_type_tag)
 
template<typename T >
T exprtk::details::numeric::process (const operator_type operation, const T arg)
 
template<typename T >
T exprtk::details::numeric::process (const operator_type operation, const T arg0, const T arg1)
 
template<typename T >
bool exprtk::details::is_generally_string_node (const expression_node< T > *node)
 
bool exprtk::details::is_true (const double v)
 
bool exprtk::details::is_true (const long double v)
 
bool exprtk::details::is_true (const float v)
 
template<typename T >
bool exprtk::details::is_true (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_true (const std::pair< expression_node< T > *, bool > &node)
 
template<typename T >
bool exprtk::details::is_false (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_false (const std::pair< expression_node< T > *, bool > &node)
 
template<typename T >
bool exprtk::details::is_literal_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_unary_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_neg_unary_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_binary_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_variable_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_ivariable_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_vector_elem_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_vector_celem_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_vector_elem_rtc_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_vector_celem_rtc_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_rebasevector_elem_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_rebasevector_elem_rtc_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_rebasevector_celem_rtc_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_rebasevector_celem_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_vector_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_ivector_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_constant_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_null_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_break_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_continue_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_swap_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_function (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_vararg_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_return_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_negate_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_assert_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::branch_deletable (const expression_node< T > *node)
 
template<std::size_t N, typename T >
bool exprtk::details::all_nodes_valid (expression_node< T > *const (&b)[N])
 
template<typename T , typename Allocator , template< typename, typename > class Sequence>
bool exprtk::details::all_nodes_valid (const Sequence< expression_node< T > *, Allocator > &b)
 
template<std::size_t N, typename T >
bool exprtk::details::all_nodes_variables (expression_node< T > *const (&b)[N])
 
template<typename T , typename Allocator , template< typename, typename > class Sequence>
bool exprtk::details::all_nodes_variables (const Sequence< expression_node< T > *, Allocator > &b)
 
template<typename NodeAllocator , typename T , std::size_t N>
void exprtk::details::free_all_nodes (NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
 
template<typename NodeAllocator , typename T , typename Allocator , template< typename, typename > class Sequence>
void exprtk::details::free_all_nodes (NodeAllocator &node_allocator, Sequence< expression_node< T > *, Allocator > &b)
 
template<typename NodeAllocator , typename T >
void exprtk::details::free_node (NodeAllocator &, expression_node< T > *&node)
 
template<typename T >
void exprtk::details::destroy_node (expression_node< T > *&node)
 
template<typename T , std::size_t N>
void exprtk::details::construct_branch_pair (std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b, const std::size_t &index)
 
template<typename T >
void exprtk::details::construct_branch_pair (std::pair< expression_node< T > *, bool > &branch, expression_node< T > *b)
 
template<std::size_t N, typename T >
void exprtk::details::init_branches (std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b0, expression_node< T > *b1=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b2=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b3=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b4=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b5=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b6=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b7=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b8=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b9=reinterpret_cast< expression_node< T > * >(0))
 
template<typename T , std::size_t N>
T exprtk::details::axn (const T a, const T x)
 
template<typename T , std::size_t N>
T exprtk::details::axnb (const T a, const T x, const T b)
 
template<typename T >
memory_context_t< Texprtk::details::make_memory_context (vector_holder< T > &vec_holder, vec_data_store< T > &vds)
 
template<typename T >
memory_context_t< Texprtk::details::make_memory_context (vector_holder< T > &vec_holder0, vector_holder< T > &vec_holder1, vec_data_store< T > &vds)
 
template<typename T >
T exprtk::details::value (details::expression_node< T > *n)
 
template<typename T >
T exprtk::details::value (std::pair< details::expression_node< T > *, bool > n)
 
template<typename T >
T exprtk::details::value (const T *t)
 
template<typename T >
T exprtk::details::value (const T &t)
 
template<typename T >
bool exprtk::details::is_sf3ext_node (const expression_node< T > *n)
 
template<typename T >
bool exprtk::details::is_sf4ext_node (const expression_node< T > *n)
 
template<typename T >
bool exprtk::details::is_vov_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_cov_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_voc_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_cob_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_boc_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_t0ot1ot2_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_t0ot1ot2ot3_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_uv_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_range_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_const_string_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_const_string_range_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_assignment_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_concat_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_function_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_condition_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_ccondition_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_string_vararg_node (const expression_node< T > *node)
 
template<typename T >
bool exprtk::details::is_genricstring_range_node (const expression_node< T > *node)
 
void exprtk::details::load_operations_map (std::multimap< std::string, details::base_operation_t, details::ilesscompare > &m)
 
template<typename FunctionType >
void exprtk::enable_zero_parameters (FunctionType &func)
 
template<typename FunctionType >
void exprtk::disable_zero_parameters (FunctionType &func)
 
template<typename FunctionType >
void exprtk::enable_has_side_effects (FunctionType &func)
 
template<typename FunctionType >
void exprtk::disable_has_side_effects (FunctionType &func)
 
template<typename FunctionType >
void exprtk::set_min_num_args (FunctionType &func, const std::size_t &num_args)
 
template<typename FunctionType >
void exprtk::set_max_num_args (FunctionType &func, const std::size_t &num_args)
 
template<typename T >
bool exprtk::is_valid (const expression< T > &expr)
 
type exprtk::parser_error::make_error (const error_mode mode, const std::string &diagnostic="", const std::string &src_location="")
 
type exprtk::parser_error::make_error (const error_mode mode, const lexer::token &tk, const std::string &diagnostic="", const std::string &src_location="")
 
std::string exprtk::parser_error::to_str (error_mode mode)
 
bool exprtk::parser_error::update_error (type &error, const std::string &expression)
 
void exprtk::parser_error::dump_error (const type &error)
 
template<typename Parser >
void exprtk::details::disable_type_checking (Parser &p)
 
template<typename Allocator , template< typename, typename > class Sequence>
bool exprtk::collect_variables (const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
 
template<typename T , typename Allocator , template< typename, typename > class Sequence>
bool exprtk::collect_variables (const std::string &expression, exprtk::symbol_table< T > &extrnl_symbol_table, Sequence< std::string, Allocator > &symbol_list)
 
template<typename Allocator , template< typename, typename > class Sequence>
bool exprtk::collect_functions (const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
 
template<typename T , typename Allocator , template< typename, typename > class Sequence>
bool exprtk::collect_functions (const std::string &expression, exprtk::symbol_table< T > &extrnl_symbol_table, Sequence< std::string, Allocator > &symbol_list)
 
template<typename T >
exprtk::integrate (const expression< T > &e, T &x, const T &r0, const T &r1, const std::size_t number_of_intervals=1000000)
 
template<typename T >
exprtk::integrate (const expression< T > &e, const std::string &variable_name, const T &r0, const T &r1, const std::size_t number_of_intervals=1000000)
 
template<typename T >
exprtk::derivative (const expression< T > &e, T &x, const T &h=T(0.00000001))
 
template<typename T >
exprtk::second_derivative (const expression< T > &e, T &x, const T &h=T(0.00001))
 
template<typename T >
exprtk::third_derivative (const expression< T > &e, T &x, const T &h=T(0.0001))
 
template<typename T >
exprtk::derivative (const expression< T > &e, const std::string &variable_name, const T &h=T(0.00000001))
 
template<typename T >
exprtk::second_derivative (const expression< T > &e, const std::string &variable_name, const T &h=T(0.00001))
 
template<typename T >
exprtk::third_derivative (const expression< T > &e, const std::string &variable_name, const T &h=T(0.0001))
 
template<typename T >
bool exprtk::compute (const std::string &expression_string, T &result)
 
template<typename T >
bool exprtk::compute (const std::string &expression_string, const T &x, T &result)
 
template<typename T >
bool exprtk::compute (const std::string &expression_string, const T &x, const T &y, T &result)
 
template<typename T >
bool exprtk::compute (const std::string &expression_string, const T &x, const T &y, const T &z, T &result)
 
template<typename T >
void exprtk::rtl::io::details::print_type (const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
 
template<typename T >
file_descriptorexprtk::rtl::io::file::details::make_handle (T v)
 
template<typename T >
void exprtk::rtl::io::file::details::perform_check ()
 
template<typename Vector >
bool exprtk::rtl::vecops::helper::invalid_range (const Vector &v, const std::size_t r0, const std::size_t r1)
 
template<typename T >
void exprtk::rtl::vecops::details::kahan_sum (T &sum, T &error, const T v)
 
static std::string exprtk::information::data ()
 

Variables

static const std::string exprtk::details::reserved_words []
 
static const std::size_t exprtk::details::reserved_words_size = sizeof(reserved_words) / sizeof(std::string)
 
static const std::string exprtk::details::reserved_symbols []
 
static const std::size_t exprtk::details::reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string)
 
static const std::string exprtk::details::base_function_list []
 
static const std::size_t exprtk::details::base_function_list_size = sizeof(base_function_list) / sizeof(std::string)
 
static const std::string exprtk::details::logic_ops_list []
 
static const std::size_t exprtk::details::logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string)
 
static const std::string exprtk::details::cntrl_struct_list []
 
static const std::size_t exprtk::details::cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string)
 
static const std::string exprtk::details::arithmetic_ops_list []
 
static const std::size_t exprtk::details::arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string)
 
static const std::string exprtk::details::assignment_ops_list []
 
static const std::size_t exprtk::details::assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string)
 
static const std::string exprtk::details::inequality_ops_list []
 
static const std::size_t exprtk::details::inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string)
 
static const double exprtk::details::pow10 []
 
static const std::size_t exprtk::details::pow10_size = sizeof(pow10) / sizeof(double)
 
static const double exprtk::details::numeric::constant::e = 2.71828182845904523536028747135266249775724709369996
 
static const double exprtk::details::numeric::constant::pi = 3.14159265358979323846264338327950288419716939937510
 
static const double exprtk::details::numeric::constant::pi_2 = 1.57079632679489661923132169163975144209858469968755
 
static const double exprtk::details::numeric::constant::pi_4 = 0.78539816339744830961566084581987572104929234984378
 
static const double exprtk::details::numeric::constant::pi_180 = 0.01745329251994329576923690768488612713442871888542
 
static const double exprtk::details::numeric::constant::_1_pi = 0.31830988618379067153776752674502872406891929148091
 
static const double exprtk::details::numeric::constant::_2_pi = 0.63661977236758134307553505349005744813783858296183
 
static const double exprtk::details::numeric::constant::_180_pi = 57.29577951308232087679815481410517033240547246656443
 
static const double exprtk::details::numeric::constant::log2 = 0.69314718055994530941723212145817656807550013436026
 
static const double exprtk::details::numeric::constant::sqrt2 = 1.41421356237309504880168872420969807856967187537695
 
const unsigned int exprtk::details::loop_unroll::global_loop_batch_size
 
static char_cptr exprtk::information::library = "Mathematical Expression Toolkit"
 
static char_cptr exprtk::information::version
 
static char_cptr exprtk::information::date = "20240101"
 
static char_cptr exprtk::information::min_cpp = "199711L"
 

Macro Definition Documentation

◆ base_opr_case

#define base_opr_case (   N)
Value:
case N : { \
expression_node_ptr pl##N[N] = {0}; \
std::copy(param_list, param_list + N, pl##N); \
lodge_symbol(operation_name, e_st_function); \
return expression_generator_(operation.type, pl##N); \
} \

◆ basic_opr_switch_statements

#define basic_opr_switch_statements
Value:
case_stmt(details::e_add , details::add_op) \
case_stmt(details::e_sub , details::sub_op) \
case_stmt(details::e_mul , details::mul_op) \
case_stmt(details::e_div , details::div_op) \
case_stmt(details::e_mod , details::mod_op) \
case_stmt(details::e_pow , details::pow_op) \
#define case_stmt(N)
Definition exprtk.hpp:32731

Definition at line 34691 of file exprtk.hpp.

34716 {
34717 switch (p)
34718 {
34719 #define case_stmt(cp) \
34720 case cp : return node_allocator_-> \
34721 allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
34722
34723 case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
34724 case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
34725 case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
34726 case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
34727 case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
34728 case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
34729 case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
34730 case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
34731 case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
34732 case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
34733 case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
34734 case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
34735 case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
34736 case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
34737 case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
34738 #undef case_stmt
34739 default : return error_node();
34740 }
34741 }
34742
34743 inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c)
34744 {
34745 const bool not_recipricol = (c >= T(0));
34746 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
34747
34748 if (0 == p)
34749 return node_allocator_->allocate_c<literal_node_t>(T(1));
34750 else if (std::equal_to<T>()(T(2),c))
34751 {
34752 return node_allocator_->
34753 template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
34754 }
34755 else
34756 {
34757 if (not_recipricol)
34758 return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p);
34759 else
34760 return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p);
34761 }
34762 }
34763
34764 inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const
34765 {
34766 return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
34767 }
34768
34769 inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr (&branch)[2])
34770 {
34771 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
34772 const bool not_recipricol = (c >= T(0));
34773 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
34774
34775 node_allocator_->free(branch[1]);
34776
34777 if (0 == p)
34778 {
34779 details::free_all_nodes(*node_allocator_, branch);
34780
34781 return node_allocator_->allocate_c<literal_node_t>(T(1));
34782 }
34783 else if (not_recipricol)
34784 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
34785 else
34786 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p);
34787 }
34788 #else
34789 inline expression_node_ptr cardinal_pow_optimisation(T&, const T&)
34790 {
34791 return error_node();
34792 }
34793
34794 inline bool cardinal_pow_optimisable(const details::operator_type&, const T&)
34795 {
34796 return false;
34797 }
34798
34799 inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2])
34800 {
34801 return error_node();
34802 }
34803 #endif
34804
34805 struct synthesize_binary_ext_expression
34806 {
34807 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
34808 const details::operator_type& operation,
34809 expression_node_ptr (&branch)[2])
34810 {
34811 const bool left_neg = is_neg_unary_node(branch[0]);
34812 const bool right_neg = is_neg_unary_node(branch[1]);
34813
34814 if (left_neg && right_neg)
34815 {
34816 if (
34817 (details::e_add == operation) ||
34818 (details::e_sub == operation) ||
34819 (details::e_mul == operation) ||
34820 (details::e_div == operation)
34821 )
34822 {
34823 if (
34824 !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
34825 !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
34826 )
34827 {
34828 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34829
34830 return error_node();
34831 }
34832 }
34833
34834 switch (operation)
34835 {
34836 // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1))
34837 case details::e_add : return expr_gen(details::e_neg,
34838 expr_gen.node_allocator_->
34839 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34840 (branch[0],branch[1]));
34841
34842 // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1)
34843 case details::e_sub : return expr_gen.node_allocator_->
34844 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34845 (branch[1],branch[0]);
34846
34847 default : break;
34848 }
34849 }
34850 else if (left_neg && !right_neg)
34851 {
34852 if (
34853 (details::e_add == operation) ||
34854 (details::e_sub == operation) ||
34855 (details::e_mul == operation) ||
34856 (details::e_div == operation)
34857 )
34858 {
34859 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
34860 {
34861 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34862
34863 return error_node();
34864 }
34865
34866 switch (operation)
34867 {
34868 // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1)
34869 case details::e_add : return expr_gen.node_allocator_->
34870 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34871 (branch[1], branch[0]);
34872
34873 // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1))
34874 case details::e_sub : return expr_gen(details::e_neg,
34875 expr_gen.node_allocator_->
34876 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34877 (branch[0], branch[1]));
34878
34879 // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1))
34880 case details::e_mul : return expr_gen(details::e_neg,
34881 expr_gen.node_allocator_->
34882 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
34883 (branch[0], branch[1]));
34884
34885 // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1))
34886 case details::e_div : return expr_gen(details::e_neg,
34887 expr_gen.node_allocator_->
34888 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
34889 (branch[0], branch[1]));
34890
34891 default : return error_node();
34892 }
34893 }
34894 }
34895 else if (!left_neg && right_neg)
34896 {
34897 if (
34898 (details::e_add == operation) ||
34899 (details::e_sub == operation) ||
34900 (details::e_mul == operation) ||
34901 (details::e_div == operation)
34902 )
34903 {
34904 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
34905 {
34906 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34907
34908 return error_node();
34909 }
34910
34911 switch (operation)
34912 {
34913 // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1)
34914 case details::e_add : return expr_gen.node_allocator_->
34915 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34916 (branch[0], branch[1]);
34917
34918 // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1)
34919 case details::e_sub : return expr_gen.node_allocator_->
34920 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34921 (branch[0], branch[1]);
34922
34923 // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1))
34924 case details::e_mul : return expr_gen(details::e_neg,
34925 expr_gen.node_allocator_->
34926 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
34927 (branch[0], branch[1]));
34928
34929 // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1))
34930 case details::e_div : return expr_gen(details::e_neg,
34931 expr_gen.node_allocator_->
34932 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
34933 (branch[0], branch[1]));
34934
34935 default : return error_node();
34936 }
34937 }
34938 }
34939
34940 switch (operation)
34941 {
34942 #define case_stmt(op0, op1) \
34943 case op0 : return expr_gen.node_allocator_-> \
34944 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
34945 (branch[0], branch[1]); \
34946
34949 #undef case_stmt
34950 default : return error_node();
34951 }
34952 }
34953 };
34954
34955 struct synthesize_vob_expression
34956 {
34957 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
34958 const details::operator_type& operation,
34959 expression_node_ptr (&branch)[2])
34960 {
34961 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34962
34963 #ifndef exprtk_disable_enhanced_features
34964 if (details::is_sf3ext_node(branch[1]))
34965 {
34966 expression_node_ptr result = error_node();
34967
34968 const bool synthesis_result =
34969 synthesize_sf4ext_expression::template compile_right<vtype>
34970 (expr_gen, v, operation, branch[1], result);
34971
34972 if (synthesis_result)
34973 {
34974 details::free_node(*expr_gen.node_allocator_,branch[1]);
34975 return result;
34976 }
34977 }
34978 #endif
34979
34980 if (
34981 (details::e_mul == operation) ||
34982 (details::e_div == operation)
34983 )
34984 {
34985 if (details::is_uv_node(branch[1]))
34986 {
34987 typedef details::uv_base_node<Type>* uvbn_ptr_t;
34988
34989 details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation();
34990
34991 if (details::e_neg == o)
34992 {
34993 const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v();
34994
34995 details::free_node(*expr_gen.node_allocator_,branch[1]);
34996
34997 switch (operation)
34998 {
34999 case details::e_mul : return expr_gen(details::e_neg,
35000 expr_gen.node_allocator_->
35001 template allocate_rr<typename details::
35002 vov_node<Type,details::mul_op<Type> > >(v,v1));
35003
35004 case details::e_div : return expr_gen(details::e_neg,
35005 expr_gen.node_allocator_->
35006 template allocate_rr<typename details::
35007 vov_node<Type,details::div_op<Type> > >(v,v1));
35008
35009 default : break;
35010 }
35011 }
35012 }
35013 }
35014
35015 switch (operation)
35016 {
35017 #define case_stmt(op0, op1) \
35018 case op0 : return expr_gen.node_allocator_-> \
35019 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
35020 (v, branch[1]); \
35021
35024 #undef case_stmt
35025 default : return error_node();
35026 }
35027 }
35028 };
35029
35030 struct synthesize_bov_expression
35031 {
35032 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35033 const details::operator_type& operation,
35034 expression_node_ptr (&branch)[2])
35035 {
35036 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35037
35038 #ifndef exprtk_disable_enhanced_features
35039 if (details::is_sf3ext_node(branch[0]))
35040 {
35041 expression_node_ptr result = error_node();
35042
35043 const bool synthesis_result =
35044 synthesize_sf4ext_expression::template compile_left<vtype>
35045 (expr_gen, v, operation, branch[0], result);
35046
35047 if (synthesis_result)
35048 {
35049 details::free_node(*expr_gen.node_allocator_, branch[0]);
35050
35051 return result;
35052 }
35053 }
35054 #endif
35055
35056 if (
35057 (details::e_add == operation) ||
35058 (details::e_sub == operation) ||
35059 (details::e_mul == operation) ||
35060 (details::e_div == operation)
35061 )
35062 {
35063 if (details::is_uv_node(branch[0]))
35064 {
35065 typedef details::uv_base_node<Type>* uvbn_ptr_t;
35066
35067 details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation();
35068
35069 if (details::e_neg == o)
35070 {
35071 const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v();
35072
35073 details::free_node(*expr_gen.node_allocator_,branch[0]);
35074
35075 switch (operation)
35076 {
35077 case details::e_add : return expr_gen.node_allocator_->
35078 template allocate_rr<typename details::
35079 vov_node<Type,details::sub_op<Type> > >(v,v0);
35080
35081 case details::e_sub : return expr_gen(details::e_neg,
35082 expr_gen.node_allocator_->
35083 template allocate_rr<typename details::
35084 vov_node<Type,details::add_op<Type> > >(v0,v));
35085
35086 case details::e_mul : return expr_gen(details::e_neg,
35087 expr_gen.node_allocator_->
35088 template allocate_rr<typename details::
35089 vov_node<Type,details::mul_op<Type> > >(v0,v));
35090
35091 case details::e_div : return expr_gen(details::e_neg,
35092 expr_gen.node_allocator_->
35093 template allocate_rr<typename details::
35094 vov_node<Type,details::div_op<Type> > >(v0,v));
35095 default : break;
35096 }
35097 }
35098 }
35099 }
35100
35101 switch (operation)
35102 {
35103 #define case_stmt(op0, op1) \
35104 case op0 : return expr_gen.node_allocator_-> \
35105 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
35106 (branch[0], v); \
35107
35110 #undef case_stmt
35111 default : return error_node();
35112 }
35113 }
35114 };
35115
35116 struct synthesize_cob_expression
35117 {
35118 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35119 const details::operator_type& operation,
35120 expression_node_ptr (&branch)[2])
35121 {
35122 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35123
35124 details::free_node(*expr_gen.node_allocator_,branch[0]);
35125
35126 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35127 {
35128 details::free_node(*expr_gen.node_allocator_,branch[1]);
35129
35130 return expr_gen(T(0));
35131 }
35132 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35133 {
35134 details::free_node(*expr_gen.node_allocator_, branch[1]);
35135
35136 return expr_gen(T(0));
35137 }
35138 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35139 return branch[1];
35140 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35141 return branch[1];
35142
35143 if (details::is_cob_node(branch[1]))
35144 {
35145 // Simplify expressions of the form:
35146 // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
35147 // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
35148 if (
35149 (details::e_mul == operation) ||
35150 (details::e_add == operation)
35151 )
35152 {
35153 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35154
35155 if (operation == cobnode->operation())
35156 {
35157 switch (operation)
35158 {
35159 case details::e_add : cobnode->set_c(c + cobnode->c()); break;
35160 case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
35161 default : return error_node();
35162 }
35163
35164 return cobnode;
35165 }
35166 }
35167
35168 if (operation == details::e_mul)
35169 {
35170 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35171 details::operator_type cob_opr = cobnode->operation();
35172
35173 if (
35174 (details::e_div == cob_opr) ||
35175 (details::e_mul == cob_opr)
35176 )
35177 {
35178 switch (cob_opr)
35179 {
35180 case details::e_div : cobnode->set_c(c * cobnode->c()); break;
35181 case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
35182 default : return error_node();
35183 }
35184
35185 return cobnode;
35186 }
35187 }
35188 else if (operation == details::e_div)
35189 {
35190 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35191 details::operator_type cob_opr = cobnode->operation();
35192
35193 if (
35194 (details::e_div == cob_opr) ||
35195 (details::e_mul == cob_opr)
35196 )
35197 {
35198 details::expression_node<Type>* new_cobnode = error_node();
35199
35200 switch (cob_opr)
35201 {
35202 case details::e_div : new_cobnode = expr_gen.node_allocator_->
35203 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
35204 (c / cobnode->c(), cobnode->move_branch(0));
35205 break;
35206
35207 case details::e_mul : new_cobnode = expr_gen.node_allocator_->
35208 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35209 (c / cobnode->c(), cobnode->move_branch(0));
35210 break;
35211
35212 default : return error_node();
35213 }
35214
35215 details::free_node(*expr_gen.node_allocator_,branch[1]);
35216
35217 return new_cobnode;
35218 }
35219 }
35220 }
35221 #ifndef exprtk_disable_enhanced_features
35222 else if (details::is_sf3ext_node(branch[1]))
35223 {
35224 expression_node_ptr result = error_node();
35225
35226 const bool synthesis_result =
35227 synthesize_sf4ext_expression::template compile_right<ctype>
35228 (expr_gen, c, operation, branch[1], result);
35229
35230 if (synthesis_result)
35231 {
35232 details::free_node(*expr_gen.node_allocator_,branch[1]);
35233
35234 return result;
35235 }
35236 }
35237 #endif
35238
35239 switch (operation)
35240 {
35241 #define case_stmt(op0, op1) \
35242 case op0 : return expr_gen.node_allocator_-> \
35243 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
35244 (c, branch[1]); \
35245
35248 #undef case_stmt
35249 default : return error_node();
35250 }
35251 }
35252 };
35253
35254 struct synthesize_boc_expression
35255 {
35256 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35257 const details::operator_type& operation,
35258 expression_node_ptr (&branch)[2])
35259 {
35260 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
35261
35262 details::free_node(*(expr_gen.node_allocator_), branch[1]);
35263
35264 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35265 {
35266 details::free_node(*expr_gen.node_allocator_, branch[0]);
35267
35268 return expr_gen(T(0));
35269 }
35270 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35271 {
35272 details::free_node(*expr_gen.node_allocator_, branch[0]);
35273
35274 return expr_gen(std::numeric_limits<T>::quiet_NaN());
35275 }
35276 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35277 return branch[0];
35278 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35279 return branch[0];
35280
35281 if (details::is_boc_node(branch[0]))
35282 {
35283 // Simplify expressions of the form:
35284 // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
35285 // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
35286 if (
35287 (details::e_mul == operation) ||
35288 (details::e_add == operation)
35289 )
35290 {
35291 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35292
35293 if (operation == bocnode->operation())
35294 {
35295 switch (operation)
35296 {
35297 case details::e_add : bocnode->set_c(c + bocnode->c()); break;
35298 case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
35299 default : return error_node();
35300 }
35301
35302 return bocnode;
35303 }
35304 }
35305 else if (operation == details::e_div)
35306 {
35307 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35308 details::operator_type boc_opr = bocnode->operation();
35309
35310 if (
35311 (details::e_div == boc_opr) ||
35312 (details::e_mul == boc_opr)
35313 )
35314 {
35315 switch (boc_opr)
35316 {
35317 case details::e_div : bocnode->set_c(c * bocnode->c()); break;
35318 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
35319 default : return error_node();
35320 }
35321
35322 return bocnode;
35323 }
35324 }
35325 else if (operation == details::e_pow)
35326 {
35327 // (v ^ c0) ^ c1 --> v ^(c0 * c1)
35328 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35329 details::operator_type boc_opr = bocnode->operation();
35330
35331 if (details::e_pow == boc_opr)
35332 {
35333 bocnode->set_c(bocnode->c() * c);
35334
35335 return bocnode;
35336 }
35337 }
35338 }
35339
35340 #ifndef exprtk_disable_enhanced_features
35341 if (details::is_sf3ext_node(branch[0]))
35342 {
35343 expression_node_ptr result = error_node();
35344
35345 const bool synthesis_result =
35346 synthesize_sf4ext_expression::template compile_left<ctype>
35347 (expr_gen, c, operation, branch[0], result);
35348
35349 if (synthesis_result)
35350 {
35351 free_node(*expr_gen.node_allocator_, branch[0]);
35352
35353 return result;
35354 }
35355 }
35356 #endif
35357
35358 switch (operation)
35359 {
35360 #define case_stmt(op0, op1) \
35361 case op0 : return expr_gen.node_allocator_-> \
35362 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
35363 (branch[0], c); \
35364
35367 #undef case_stmt
35368 default : return error_node();
35369 }
35370 }
35371 };
35372
35373 struct synthesize_cocob_expression
35374 {
35375 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35376 const details::operator_type& operation,
35377 expression_node_ptr (&branch)[2])
35378 {
35379 expression_node_ptr result = error_node();
35380
35381 // (cob) o c --> cob
35382 if (details::is_cob_node(branch[0]))
35383 {
35384 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
35385
35386 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
35387
35388 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35389 {
35390 details::free_node(*expr_gen.node_allocator_, branch[0]);
35391 details::free_node(*expr_gen.node_allocator_, branch[1]);
35392
35393 return expr_gen(T(0));
35394 }
35395 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35396 {
35397 details::free_node(*expr_gen.node_allocator_, branch[0]);
35398 details::free_node(*expr_gen.node_allocator_, branch[1]);
35399
35400 return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
35401 }
35402 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35403 {
35404 details::free_node(*expr_gen.node_allocator_, branch[1]);
35405
35406 return branch[0];
35407 }
35408 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35409 {
35410 details::free_node(*expr_gen.node_allocator_, branch[1]);
35411
35412 return branch[0];
35413 }
35414 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
35415 {
35416 details::free_node(*expr_gen.node_allocator_, branch[1]);
35417
35418 return branch[0];
35419 }
35420
35421 const bool op_addsub = (details::e_add == cobnode->operation()) ||
35422 (details::e_sub == cobnode->operation()) ;
35423
35424 if (op_addsub)
35425 {
35426 switch (operation)
35427 {
35428 case details::e_add : cobnode->set_c(cobnode->c() + c); break;
35429 case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
35430 default : return error_node();
35431 }
35432
35433 result = cobnode;
35434 }
35435 else if (details::e_mul == cobnode->operation())
35436 {
35437 switch (operation)
35438 {
35439 case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
35440 case details::e_div : cobnode->set_c(cobnode->c() / c); break;
35441 default : return error_node();
35442 }
35443
35444 result = cobnode;
35445 }
35446 else if (details::e_div == cobnode->operation())
35447 {
35448 if (details::e_mul == operation)
35449 {
35450 cobnode->set_c(cobnode->c() * c);
35451 result = cobnode;
35452 }
35453 else if (details::e_div == operation)
35454 {
35455 result = expr_gen.node_allocator_->
35456 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35457 (cobnode->c() / c, cobnode->move_branch(0));
35458
35459 details::free_node(*expr_gen.node_allocator_, branch[0]);
35460 }
35461 }
35462
35463 if (result)
35464 {
35465 details::free_node(*expr_gen.node_allocator_,branch[1]);
35466 }
35467 }
35468
35469 // c o (cob) --> cob
35470 else if (details::is_cob_node(branch[1]))
35471 {
35472 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35473
35474 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35475
35476 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35477 {
35478 details::free_node(*expr_gen.node_allocator_, branch[0]);
35479 details::free_node(*expr_gen.node_allocator_, branch[1]);
35480
35481 return expr_gen(T(0));
35482 }
35483 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35484 {
35485 details::free_node(*expr_gen.node_allocator_, branch[0]);
35486 details::free_node(*expr_gen.node_allocator_, branch[1]);
35487
35488 return expr_gen(T(0));
35489 }
35490 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35491 {
35492 details::free_node(*expr_gen.node_allocator_, branch[0]);
35493
35494 return branch[1];
35495 }
35496 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35497 {
35498 details::free_node(*expr_gen.node_allocator_, branch[0]);
35499
35500 return branch[1];
35501 }
35502
35503 if (details::e_add == cobnode->operation())
35504 {
35505 if (details::e_add == operation)
35506 {
35507 cobnode->set_c(c + cobnode->c());
35508 result = cobnode;
35509 }
35510 else if (details::e_sub == operation)
35511 {
35512 result = expr_gen.node_allocator_->
35513 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35514 (c - cobnode->c(), cobnode->move_branch(0));
35515
35516 details::free_node(*expr_gen.node_allocator_,branch[1]);
35517 }
35518 }
35519 else if (details::e_sub == cobnode->operation())
35520 {
35521 if (details::e_add == operation)
35522 {
35523 cobnode->set_c(c + cobnode->c());
35524 result = cobnode;
35525 }
35526 else if (details::e_sub == operation)
35527 {
35528 result = expr_gen.node_allocator_->
35529 template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
35530 (c - cobnode->c(), cobnode->move_branch(0));
35531
35532 details::free_node(*expr_gen.node_allocator_,branch[1]);
35533 }
35534 }
35535 else if (details::e_mul == cobnode->operation())
35536 {
35537 if (details::e_mul == operation)
35538 {
35539 cobnode->set_c(c * cobnode->c());
35540 result = cobnode;
35541 }
35542 else if (details::e_div == operation)
35543 {
35544 result = expr_gen.node_allocator_->
35545 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35546 (c / cobnode->c(), cobnode->move_branch(0));
35547
35548 details::free_node(*expr_gen.node_allocator_,branch[1]);
35549 }
35550 }
35551 else if (details::e_div == cobnode->operation())
35552 {
35553 if (details::e_mul == operation)
35554 {
35555 cobnode->set_c(c * cobnode->c());
35556 result = cobnode;
35557 }
35558 else if (details::e_div == operation)
35559 {
35560 result = expr_gen.node_allocator_->
35561 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
35562 (c / cobnode->c(), cobnode->move_branch(0));
35563
35564 details::free_node(*expr_gen.node_allocator_,branch[1]);
35565 }
35566 }
35567
35568 if (result)
35569 {
35570 details::free_node(*expr_gen.node_allocator_,branch[0]);
35571 }
35572 }
35573
35574 return result;
35575 }
35576 };
35577
35578 struct synthesize_coboc_expression
35579 {
35580 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35581 const details::operator_type& operation,
35582 expression_node_ptr (&branch)[2])
35583 {
35584 expression_node_ptr result = error_node();
35585
35586 // (boc) o c --> boc
35587 if (details::is_boc_node(branch[0]))
35588 {
35589 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35590
35591 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
35592
35593 if (details::e_add == bocnode->operation())
35594 {
35595 switch (operation)
35596 {
35597 case details::e_add : bocnode->set_c(bocnode->c() + c); break;
35598 case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
35599 default : return error_node();
35600 }
35601
35602 result = bocnode;
35603 }
35604 else if (details::e_mul == bocnode->operation())
35605 {
35606 switch (operation)
35607 {
35608 case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
35609 case details::e_div : bocnode->set_c(bocnode->c() / c); break;
35610 default : return error_node();
35611 }
35612
35613 result = bocnode;
35614 }
35615 else if (details::e_sub == bocnode->operation())
35616 {
35617 if (details::e_add == operation)
35618 {
35619 result = expr_gen.node_allocator_->
35620 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
35621 (bocnode->move_branch(0), c - bocnode->c());
35622
35623 details::free_node(*expr_gen.node_allocator_,branch[0]);
35624 }
35625 else if (details::e_sub == operation)
35626 {
35627 bocnode->set_c(bocnode->c() + c);
35628 result = bocnode;
35629 }
35630 }
35631 else if (details::e_div == bocnode->operation())
35632 {
35633 switch (operation)
35634 {
35635 case details::e_div : bocnode->set_c(bocnode->c() * c); break;
35636 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
35637 default : return error_node();
35638 }
35639
35640 result = bocnode;
35641 }
35642
35643 if (result)
35644 {
35645 details::free_node(*expr_gen.node_allocator_, branch[1]);
35646 }
35647 }
35648
35649 // c o (boc) --> boc
35650 else if (details::is_boc_node(branch[1]))
35651 {
35652 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
35653
35654 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35655
35656 if (details::e_add == bocnode->operation())
35657 {
35658 if (details::e_add == operation)
35659 {
35660 bocnode->set_c(c + bocnode->c());
35661 result = bocnode;
35662 }
35663 else if (details::e_sub == operation)
35664 {
35665 result = expr_gen.node_allocator_->
35666 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35667 (c - bocnode->c(), bocnode->move_branch(0));
35668
35669 details::free_node(*expr_gen.node_allocator_,branch[1]);
35670 }
35671 }
35672 else if (details::e_sub == bocnode->operation())
35673 {
35674 if (details::e_add == operation)
35675 {
35676 result = expr_gen.node_allocator_->
35677 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
35678 (bocnode->move_branch(0), c - bocnode->c());
35679
35680 details::free_node(*expr_gen.node_allocator_,branch[1]);
35681 }
35682 else if (details::e_sub == operation)
35683 {
35684 result = expr_gen.node_allocator_->
35685 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35686 (c + bocnode->c(), bocnode->move_branch(0));
35687
35688 details::free_node(*expr_gen.node_allocator_,branch[1]);
35689 }
35690 }
35691 else if (details::e_mul == bocnode->operation())
35692 {
35693 if (details::e_mul == operation)
35694 {
35695 bocnode->set_c(c * bocnode->c());
35696 result = bocnode;
35697 }
35698 else if (details::e_div == operation)
35699 {
35700 result = expr_gen.node_allocator_->
35701 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35702 (c / bocnode->c(), bocnode->move_branch(0));
35703
35704 details::free_node(*expr_gen.node_allocator_,branch[1]);
35705 }
35706 }
35707 else if (details::e_div == bocnode->operation())
35708 {
35709 if (details::e_mul == operation)
35710 {
35711 bocnode->set_c(bocnode->c() / c);
35712 result = bocnode;
35713 }
35714 else if (details::e_div == operation)
35715 {
35716 result = expr_gen.node_allocator_->
35717 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35718 (c * bocnode->c(), bocnode->move_branch(0));
35719
35720 details::free_node(*expr_gen.node_allocator_,branch[1]);
35721 }
35722 }
35723
35724 if (result)
35725 {
35726 details::free_node(*expr_gen.node_allocator_,branch[0]);
35727 }
35728 }
35729
35730 return result;
35731 }
35732 };
35733
35734 #ifndef exprtk_disable_enhanced_features
35735 inline bool synthesize_expression(const details::operator_type& operation,
35736 expression_node_ptr (&branch)[2],
35737 expression_node_ptr& result)
35738 {
35739 result = error_node();
35740
35741 if (!operation_optimisable(operation))
35742 return false;
35743
35744 const std::string node_id = branch_to_id(branch);
35745
35746 const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
35747
35748 if (synthesize_map_.end() != itr)
35749 {
35750 result = itr->second((*this), operation, branch);
35751
35752 return true;
35753 }
35754 else
35755 return false;
35756 }
35757
35758 struct synthesize_vov_expression
35759 {
35760 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35761 const details::operator_type& operation,
35762 expression_node_ptr (&branch)[2])
35763 {
35764 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
35765 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35766
35767 switch (operation)
35768 {
35769 #define case_stmt(op0, op1) \
35770 case op0 : return expr_gen.node_allocator_-> \
35771 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
35772 (v1, v2); \
35773
35776 #undef case_stmt
35777 default : return error_node();
35778 }
35779 }
35780 };
35781
35782 struct synthesize_cov_expression
35783 {
35784 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35785 const details::operator_type& operation,
35786 expression_node_ptr (&branch)[2])
35787 {
35788 const Type c = static_cast<details::literal_node<Type>*> (branch[0])->value();
35789 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref ();
35790
35791 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35792
35793 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35794 return expr_gen(T(0));
35795 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35796 return expr_gen(T(0));
35797 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35798 return static_cast<details::variable_node<Type>*>(branch[1]);
35799 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35800 return static_cast<details::variable_node<Type>*>(branch[1]);
35801
35802 switch (operation)
35803 {
35804 #define case_stmt(op0, op1) \
35805 case op0 : return expr_gen.node_allocator_-> \
35806 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
35807 (c, v); \
35808
35811 #undef case_stmt
35812 default : return error_node();
35813 }
35814 }
35815 };
35816
35817 struct synthesize_voc_expression
35818 {
35819 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35820 const details::operator_type& operation,
35821 expression_node_ptr (&branch)[2])
35822 {
35823 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref ();
35824 const Type c = static_cast<details::literal_node<Type>*> (branch[1])->value();
35825
35826 details::free_node(*(expr_gen.node_allocator_), branch[1]);
35827
35828 if (expr_gen.cardinal_pow_optimisable(operation,c))
35829 {
35830 if (std::equal_to<T>()(T(1),c))
35831 return branch[0];
35832 else
35833 return expr_gen.cardinal_pow_optimisation(v,c);
35834 }
35835 else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35836 return expr_gen(T(0));
35837 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35838 return expr_gen(std::numeric_limits<T>::quiet_NaN());
35839 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35840 return static_cast<details::variable_node<Type>*>(branch[0]);
35841 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35842 return static_cast<details::variable_node<Type>*>(branch[0]);
35843 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
35844 return static_cast<details::variable_node<Type>*>(branch[0]);
35845
35846 switch (operation)
35847 {
35848 #define case_stmt(op0, op1) \
35849 case op0 : return expr_gen.node_allocator_-> \
35850 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
35851 (v, c); \
35852
35855 #undef case_stmt
35856 default : return error_node();
35857 }
35858 }
35859 };
35860
35861 struct synthesize_sf3ext_expression
35862 {
35863 template <typename T0, typename T1, typename T2>
35864 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35865 const details::operator_type& sf3opr,
35866 T0 t0, T1 t1, T2 t2)
35867 {
35868 switch (sf3opr)
35869 {
35870 #define case_stmt(op) \
35871 case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
35872 allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
35873
35874 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
35875 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
35876 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
35877 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
35878 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
35879 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
35880 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
35881 case_stmt(28) case_stmt(29) case_stmt(30)
35882 #undef case_stmt
35883 default : return error_node();
35884 }
35885 }
35886
35887 template <typename T0, typename T1, typename T2>
35888 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
35889 T0 t0, T1 t1, T2 t2,
35890 expression_node_ptr& result)
35891 {
35892 details::operator_type sf3opr;
35893
35894 if (!expr_gen.sf3_optimisable(id,sf3opr))
35895 return false;
35896 else
35897 result = synthesize_sf3ext_expression::template process<T0, T1, T2>
35898 (expr_gen, sf3opr, t0, t1, t2);
35899
35900 return true;
35901 }
35902 };
35903
35904 struct synthesize_sf4ext_expression
35905 {
35906 template <typename T0, typename T1, typename T2, typename T3>
35907 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
35908 const details::operator_type& sf4opr,
35909 T0 t0, T1 t1, T2 t2, T3 t3)
35910 {
35911 switch (sf4opr)
35912 {
35913 #define case_stmt0(op) \
35914 case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
35915 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
35916
35917 #define case_stmt1(op) \
35918 case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
35919 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
35920
35930
35946 case_stmt1(60) case_stmt1(61)
35947
35948 #undef case_stmt0
35949 #undef case_stmt1
35950 default : return error_node();
35951 }
35952 }
35953
35954 template <typename T0, typename T1, typename T2, typename T3>
35955 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
35956 T0 t0, T1 t1, T2 t2, T3 t3,
35957 expression_node_ptr& result)
35958 {
35959 details::operator_type sf4opr;
35960
35961 if (!expr_gen.sf4_optimisable(id,sf4opr))
35962 return false;
35963 else
35964 result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3>
35965 (expr_gen, sf4opr, t0, t1, t2, t3);
35966
35967 return true;
35968 }
35969
35970 // T o (sf3ext)
35971 template <typename ExternalType>
35972 static inline bool compile_right(expression_generator<Type>& expr_gen,
35973 ExternalType t,
35974 const details::operator_type& operation,
35975 expression_node_ptr& sf3node,
35976 expression_node_ptr& result)
35977 {
35978 if (!details::is_sf3ext_node(sf3node))
35979 return false;
35980
35981 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
35982
35983 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
35984 const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
35985
35986 switch (n->type())
35987 {
35988 case details::expression_node<Type>::e_covoc : return compile_right_impl
35989 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
35990 (expr_gen, id, t, sf3node, result);
35991
35992 case details::expression_node<Type>::e_covov : return compile_right_impl
35993 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
35994 (expr_gen, id, t, sf3node, result);
35995
35996 case details::expression_node<Type>::e_vocov : return compile_right_impl
35997 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
35998 (expr_gen, id, t, sf3node, result);
35999
36000 case details::expression_node<Type>::e_vovoc : return compile_right_impl
36001 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
36002 (expr_gen, id, t, sf3node, result);
36003
36004 case details::expression_node<Type>::e_vovov : return compile_right_impl
36005 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
36006 (expr_gen, id, t, sf3node, result);
36007
36008 default : return false;
36009 }
36010 }
36011
36012 // (sf3ext) o T
36013 template <typename ExternalType>
36014 static inline bool compile_left(expression_generator<Type>& expr_gen,
36015 ExternalType t,
36016 const details::operator_type& operation,
36017 expression_node_ptr& sf3node,
36018 expression_node_ptr& result)
36019 {
36020 if (!details::is_sf3ext_node(sf3node))
36021 return false;
36022
36023 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
36024
36025 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
36026
36027 const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
36028
36029 switch (n->type())
36030 {
36031 case details::expression_node<Type>::e_covoc : return compile_left_impl
36032 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
36033 (expr_gen, id, t, sf3node, result);
36034
36035 case details::expression_node<Type>::e_covov : return compile_left_impl
36036 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
36037 (expr_gen, id, t, sf3node, result);
36038
36039 case details::expression_node<Type>::e_vocov : return compile_left_impl
36040 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
36041 (expr_gen, id, t, sf3node, result);
36042
36043 case details::expression_node<Type>::e_vovoc : return compile_left_impl
36044 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
36045 (expr_gen, id, t, sf3node, result);
36046
36047 case details::expression_node<Type>::e_vovov : return compile_left_impl
36048 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
36049 (expr_gen, id, t, sf3node, result);
36050
36051 default : return false;
36052 }
36053 }
36054
36055 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
36056 static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
36057 const std::string& id,
36058 ExternalType t,
36059 expression_node_ptr& node,
36060 expression_node_ptr& result)
36061 {
36062 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
36063
36064 if (n)
36065 {
36066 T0 t0 = n->t0();
36067 T1 t1 = n->t1();
36068 T2 t2 = n->t2();
36069
36070 return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2>
36071 (expr_gen, id, t, t0, t1, t2, result);
36072 }
36073 else
36074 return false;
36075 }
36076
36077 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
36078 static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
36079 const std::string& id,
36080 ExternalType t,
36081 expression_node_ptr& node,
36082 expression_node_ptr& result)
36083 {
36084 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
36085
36086 if (n)
36087 {
36088 T0 t0 = n->t0();
36089 T1 t1 = n->t1();
36090 T2 t2 = n->t2();
36091
36092 return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType>
36093 (expr_gen, id, t0, t1, t2, t, result);
36094 }
36095 else
36096 return false;
36097 }
36098 };
36099
36100 struct synthesize_vovov_expression0
36101 {
36102 typedef typename vovov_t::type0 node_type;
36103 typedef typename vovov_t::sf3_type sf3_type;
36104
36105 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36106 const details::operator_type& operation,
36107 expression_node_ptr (&branch)[2])
36108 {
36109 // (v0 o0 v1) o1 (v2)
36110 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
36111 const Type& v0 = vov->v0();
36112 const Type& v1 = vov->v1();
36113 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36114 const details::operator_type o0 = vov->operation();
36115 const details::operator_type o1 = operation;
36116
36117 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36118
36119 expression_node_ptr result = error_node();
36120
36121 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36122 {
36123 // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)
36124 if ((details::e_div == o0) && (details::e_div == o1))
36125 {
36126 const bool synthesis_result =
36127 synthesize_sf3ext_expression::
36128 template compile<vtype, vtype, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result);
36129
36130 exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
36131
36132 return (synthesis_result) ? result : error_node();
36133 }
36134 }
36135
36136 const bool synthesis_result =
36137 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
36138 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
36139
36140 if (synthesis_result)
36141 return result;
36142
36143 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36144 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36145
36146 if (!expr_gen.valid_operator(o0,f0))
36147 return error_node();
36148 else if (!expr_gen.valid_operator(o1,f1))
36149 return error_node();
36150 else
36151 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
36152 }
36153
36154 static inline std::string id(expression_generator<Type>& expr_gen,
36155 const details::operator_type o0,
36156 const details::operator_type o1)
36157 {
36158 return details::build_string()
36159 << "(t" << expr_gen.to_str(o0)
36160 << "t)" << expr_gen.to_str(o1)
36161 << "t";
36162 }
36163 };
36164
36165 struct synthesize_vovov_expression1
36166 {
36167 typedef typename vovov_t::type1 node_type;
36168 typedef typename vovov_t::sf3_type sf3_type;
36169
36170 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36171 const details::operator_type& operation,
36172 expression_node_ptr (&branch)[2])
36173 {
36174 // (v0) o0 (v1 o1 v2)
36175 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36176 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36177 const Type& v1 = vov->v0();
36178 const Type& v2 = vov->v1();
36179 const details::operator_type o0 = operation;
36180 const details::operator_type o1 = vov->operation();
36181
36182 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36183
36184 expression_node_ptr result = error_node();
36185
36186 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36187 {
36188 // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1
36189 if ((details::e_div == o0) && (details::e_div == o1))
36190 {
36191 const bool synthesis_result =
36192 synthesize_sf3ext_expression::
36193 template compile<vtype, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result);
36194
36195 exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
36196
36197 return (synthesis_result) ? result : error_node();
36198 }
36199 }
36200
36201 const bool synthesis_result =
36202 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
36203 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
36204
36205 if (synthesis_result)
36206 return result;
36207
36208 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36209 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36210
36211 if (!expr_gen.valid_operator(o0,f0))
36212 return error_node();
36213 else if (!expr_gen.valid_operator(o1,f1))
36214 return error_node();
36215 else
36216 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
36217 }
36218
36219 static inline std::string id(expression_generator<Type>& expr_gen,
36220 const details::operator_type o0,
36221 const details::operator_type o1)
36222 {
36223 return details::build_string()
36224 << "t" << expr_gen.to_str(o0)
36225 << "(t" << expr_gen.to_str(o1)
36226 << "t)";
36227 }
36228 };
36229
36230 struct synthesize_vovoc_expression0
36231 {
36232 typedef typename vovoc_t::type0 node_type;
36233 typedef typename vovoc_t::sf3_type sf3_type;
36234
36235 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36236 const details::operator_type& operation,
36237 expression_node_ptr (&branch)[2])
36238 {
36239 // (v0 o0 v1) o1 (c)
36240 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
36241 const Type& v0 = vov->v0();
36242 const Type& v1 = vov->v1();
36243 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
36244 const details::operator_type o0 = vov->operation();
36245 const details::operator_type o1 = operation;
36246
36247 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36248 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36249
36250 expression_node_ptr result = error_node();
36251
36252 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36253 {
36254 // (v0 / v1) / c --> (vovoc) v0 / (v1 * c)
36255 if ((details::e_div == o0) && (details::e_div == o1))
36256 {
36257 const bool synthesis_result =
36258 synthesize_sf3ext_expression::
36259 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
36260
36261 exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
36262
36263 return (synthesis_result) ? result : error_node();
36264 }
36265 }
36266
36267 const bool synthesis_result =
36268 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
36269 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
36270
36271 if (synthesis_result)
36272 return result;
36273
36274 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36275 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36276
36277 if (!expr_gen.valid_operator(o0,f0))
36278 return error_node();
36279 else if (!expr_gen.valid_operator(o1,f1))
36280 return error_node();
36281 else
36282 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
36283 }
36284
36285 static inline std::string id(expression_generator<Type>& expr_gen,
36286 const details::operator_type o0,
36287 const details::operator_type o1)
36288 {
36289 return details::build_string()
36290 << "(t" << expr_gen.to_str(o0)
36291 << "t)" << expr_gen.to_str(o1)
36292 << "t";
36293 }
36294 };
36295
36296 struct synthesize_vovoc_expression1
36297 {
36298 typedef typename vovoc_t::type1 node_type;
36299 typedef typename vovoc_t::sf3_type sf3_type;
36300
36301 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36302 const details::operator_type& operation,
36303 expression_node_ptr (&branch)[2])
36304 {
36305 // (v0) o0 (v1 o1 c)
36306 const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
36307 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36308 const Type& v1 = voc->v();
36309 const Type c = voc->c();
36310 const details::operator_type o0 = operation;
36311 const details::operator_type o1 = voc->operation();
36312
36313 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36314
36315 expression_node_ptr result = error_node();
36316
36317 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36318 {
36319 // v0 / (v1 / c) --> (vocov) (v0 * c) / v1
36320 if ((details::e_div == o0) && (details::e_div == o1))
36321 {
36322 const bool synthesis_result =
36323 synthesize_sf3ext_expression::
36324 template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result);
36325
36326 exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
36327
36328 return (synthesis_result) ? result : error_node();
36329 }
36330 }
36331
36332 const bool synthesis_result =
36333 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
36334 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
36335
36336 if (synthesis_result)
36337 return result;
36338
36339 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36340 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36341
36342 if (!expr_gen.valid_operator(o0,f0))
36343 return error_node();
36344 else if (!expr_gen.valid_operator(o1,f1))
36345 return error_node();
36346 else
36347 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
36348 }
36349
36350 static inline std::string id(expression_generator<Type>& expr_gen,
36351 const details::operator_type o0,
36352 const details::operator_type o1)
36353 {
36354 return details::build_string()
36355 << "t" << expr_gen.to_str(o0)
36356 << "(t" << expr_gen.to_str(o1)
36357 << "t)";
36358 }
36359 };
36360
36361 struct synthesize_vocov_expression0
36362 {
36363 typedef typename vocov_t::type0 node_type;
36364 typedef typename vocov_t::sf3_type sf3_type;
36365
36366 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36367 const details::operator_type& operation,
36368 expression_node_ptr (&branch)[2])
36369 {
36370 // (v0 o0 c) o1 (v1)
36371 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
36372 const Type& v0 = voc->v();
36373 const Type c = voc->c();
36374 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36375 const details::operator_type o0 = voc->operation();
36376 const details::operator_type o1 = operation;
36377
36378 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36379
36380 expression_node_ptr result = error_node();
36381
36382 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36383 {
36384 // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c)
36385 if ((details::e_div == o0) && (details::e_div == o1))
36386 {
36387 const bool synthesis_result =
36388 synthesize_sf3ext_expression::
36389 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
36390
36391 exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
36392
36393 return (synthesis_result) ? result : error_node();
36394 }
36395 }
36396
36397 const bool synthesis_result =
36398 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
36399 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
36400
36401 if (synthesis_result)
36402 return result;
36403
36404 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36405 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36406
36407 if (!expr_gen.valid_operator(o0,f0))
36408 return error_node();
36409 else if (!expr_gen.valid_operator(o1,f1))
36410 return error_node();
36411 else
36412 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
36413 }
36414
36415 static inline std::string id(expression_generator<Type>& expr_gen,
36416 const details::operator_type o0,
36417 const details::operator_type o1)
36418 {
36419 return details::build_string()
36420 << "(t" << expr_gen.to_str(o0)
36421 << "t)" << expr_gen.to_str(o1)
36422 << "t";
36423 }
36424 };
36425
36426 struct synthesize_vocov_expression1
36427 {
36428 typedef typename vocov_t::type1 node_type;
36429 typedef typename vocov_t::sf3_type sf3_type;
36430
36431 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36432 const details::operator_type& operation,
36433 expression_node_ptr (&branch)[2])
36434 {
36435 // (v0) o0 (c o1 v1)
36436 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36437 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36438 const Type c = cov->c();
36439 const Type& v1 = cov->v();
36440 const details::operator_type o0 = operation;
36441 const details::operator_type o1 = cov->operation();
36442
36443 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36444
36445 expression_node_ptr result = error_node();
36446
36447 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36448 {
36449 // v0 / (c / v1) --> (vovoc) (v0 * v1) / c
36450 if ((details::e_div == o0) && (details::e_div == o1))
36451 {
36452 const bool synthesis_result =
36453 synthesize_sf3ext_expression::
36454 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result);
36455
36456 exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
36457
36458 return (synthesis_result) ? result : error_node();
36459 }
36460 }
36461
36462 const bool synthesis_result =
36463 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
36464 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
36465
36466 if (synthesis_result)
36467 return result;
36468
36469 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36470 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36471
36472 if (!expr_gen.valid_operator(o0,f0))
36473 return error_node();
36474 else if (!expr_gen.valid_operator(o1,f1))
36475 return error_node();
36476 else
36477 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
36478 }
36479
36480 static inline std::string id(expression_generator<Type>& expr_gen,
36481 const details::operator_type o0,
36482 const details::operator_type o1)
36483 {
36484 return details::build_string()
36485 << "t" << expr_gen.to_str(o0)
36486 << "(t" << expr_gen.to_str(o1)
36487 << "t)";
36488 }
36489 };
36490
36491 struct synthesize_covov_expression0
36492 {
36493 typedef typename covov_t::type0 node_type;
36494 typedef typename covov_t::sf3_type sf3_type;
36495
36496 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36497 const details::operator_type& operation,
36498 expression_node_ptr (&branch)[2])
36499 {
36500 // (c o0 v0) o1 (v1)
36501 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36502 const Type c = cov->c();
36503 const Type& v0 = cov->v();
36504 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36505 const details::operator_type o0 = cov->operation();
36506 const details::operator_type o1 = operation;
36507
36508 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36509
36510 expression_node_ptr result = error_node();
36511
36512 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36513 {
36514 // (c / v0) / v1 --> (covov) c / (v0 * v1)
36515 if ((details::e_div == o0) && (details::e_div == o1))
36516 {
36517 const bool synthesis_result =
36518 synthesize_sf3ext_expression::
36519 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result);
36520
36521 exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
36522
36523 return (synthesis_result) ? result : error_node();
36524 }
36525 }
36526
36527 const bool synthesis_result =
36528 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
36529 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
36530
36531 if (synthesis_result)
36532 return result;
36533
36534 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36535 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36536
36537 if (!expr_gen.valid_operator(o0,f0))
36538 return error_node();
36539 else if (!expr_gen.valid_operator(o1,f1))
36540 return error_node();
36541 else
36542 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
36543 }
36544
36545 static inline std::string id(expression_generator<Type>& expr_gen,
36546 const details::operator_type o0,
36547 const details::operator_type o1)
36548 {
36549 return details::build_string()
36550 << "(t" << expr_gen.to_str(o0)
36551 << "t)" << expr_gen.to_str(o1)
36552 << "t";
36553 }
36554 };
36555
36556 struct synthesize_covov_expression1
36557 {
36558 typedef typename covov_t::type1 node_type;
36559 typedef typename covov_t::sf3_type sf3_type;
36560
36561 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36562 const details::operator_type& operation,
36563 expression_node_ptr (&branch)[2])
36564 {
36565 // (c) o0 (v0 o1 v1)
36566 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36567 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
36568 const Type& v0 = vov->v0();
36569 const Type& v1 = vov->v1();
36570 const details::operator_type o0 = operation;
36571 const details::operator_type o1 = vov->operation();
36572
36573 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36574 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36575
36576 expression_node_ptr result = error_node();
36577
36578 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36579 {
36580 // c / (v0 / v1) --> (covov) (c * v1) / v0
36581 if ((details::e_div == o0) && (details::e_div == o1))
36582 {
36583 const bool synthesis_result =
36584 synthesize_sf3ext_expression::
36585 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result);
36586
36587 exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
36588
36589 return (synthesis_result) ? result : error_node();
36590 }
36591 }
36592
36593 const bool synthesis_result =
36594 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
36595 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
36596
36597 if (synthesis_result)
36598 return result;
36599
36600 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36601 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36602
36603 if (!expr_gen.valid_operator(o0,f0))
36604 return error_node();
36605 else if (!expr_gen.valid_operator(o1,f1))
36606 return error_node();
36607 else
36608 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
36609 }
36610
36611 static inline std::string id(expression_generator<Type>& expr_gen,
36612 const details::operator_type o0,
36613 const details::operator_type o1)
36614 {
36615 return details::build_string()
36616 << "t" << expr_gen.to_str(o0)
36617 << "(t" << expr_gen.to_str(o1)
36618 << "t)";
36619 }
36620 };
36621
36622 struct synthesize_covoc_expression0
36623 {
36624 typedef typename covoc_t::type0 node_type;
36625 typedef typename covoc_t::sf3_type sf3_type;
36626
36627 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36628 const details::operator_type& operation,
36629 expression_node_ptr (&branch)[2])
36630 {
36631 // (c0 o0 v) o1 (c1)
36632 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36633 const Type c0 = cov->c();
36634 const Type& v = cov->v();
36635 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
36636 const details::operator_type o0 = cov->operation();
36637 const details::operator_type o1 = operation;
36638
36639 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36640 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36641
36642 expression_node_ptr result = error_node();
36643
36644 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36645 {
36646 // (c0 + v) + c1 --> (cov) (c0 + c1) + v
36647 if ((details::e_add == o0) && (details::e_add == o1))
36648 {
36649 exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
36650
36651 return expr_gen.node_allocator_->
36652 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36653 }
36654 // (c0 + v) - c1 --> (cov) (c0 - c1) + v
36655 else if ((details::e_add == o0) && (details::e_sub == o1))
36656 {
36657 exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
36658
36659 return expr_gen.node_allocator_->
36660 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36661 }
36662 // (c0 - v) + c1 --> (cov) (c0 + c1) - v
36663 else if ((details::e_sub == o0) && (details::e_add == o1))
36664 {
36665 exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
36666
36667 return expr_gen.node_allocator_->
36668 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36669 }
36670 // (c0 - v) - c1 --> (cov) (c0 - c1) - v
36671 else if ((details::e_sub == o0) && (details::e_sub == o1))
36672 {
36673 exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
36674
36675 return expr_gen.node_allocator_->
36676 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36677 }
36678 // (c0 * v) * c1 --> (cov) (c0 * c1) * v
36679 else if ((details::e_mul == o0) && (details::e_mul == o1))
36680 {
36681 exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
36682
36683 return expr_gen.node_allocator_->
36684 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36685 }
36686 // (c0 * v) / c1 --> (cov) (c0 / c1) * v
36687 else if ((details::e_mul == o0) && (details::e_div == o1))
36688 {
36689 exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
36690
36691 return expr_gen.node_allocator_->
36692 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36693 }
36694 // (c0 / v) * c1 --> (cov) (c0 * c1) / v
36695 else if ((details::e_div == o0) && (details::e_mul == o1))
36696 {
36697 exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
36698
36699 return expr_gen.node_allocator_->
36700 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36701 }
36702 // (c0 / v) / c1 --> (cov) (c0 / c1) / v
36703 else if ((details::e_div == o0) && (details::e_div == o1))
36704 {
36705 exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
36706
36707 return expr_gen.node_allocator_->
36708 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36709 }
36710 }
36711
36712 const bool synthesis_result =
36713 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
36714 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
36715
36716 if (synthesis_result)
36717 return result;
36718
36719 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36720 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36721
36722 if (!expr_gen.valid_operator(o0,f0))
36723 return error_node();
36724 else if (!expr_gen.valid_operator(o1,f1))
36725 return error_node();
36726 else
36727 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
36728 }
36729
36730 static inline std::string id(expression_generator<Type>& expr_gen,
36731 const details::operator_type o0,
36732 const details::operator_type o1)
36733 {
36734 return details::build_string()
36735 << "(t" << expr_gen.to_str(o0)
36736 << "t)" << expr_gen.to_str(o1)
36737 << "t";
36738 }
36739 };
36740
36741 struct synthesize_covoc_expression1
36742 {
36743 typedef typename covoc_t::type1 node_type;
36744 typedef typename covoc_t::sf3_type sf3_type;
36745
36746 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36747 const details::operator_type& operation,
36748 expression_node_ptr (&branch)[2])
36749 {
36750 // (c0) o0 (v o1 c1)
36751 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
36752 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
36753 const Type& v = voc->v();
36754 const Type c1 = voc->c();
36755 const details::operator_type o0 = operation;
36756 const details::operator_type o1 = voc->operation();
36757
36758 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36759 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36760
36761 expression_node_ptr result = error_node();
36762
36763 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36764 {
36765 // (c0) + (v + c1) --> (cov) (c0 + c1) + v
36766 if ((details::e_add == o0) && (details::e_add == o1))
36767 {
36768 exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
36769
36770 return expr_gen.node_allocator_->
36771 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36772 }
36773 // (c0) + (v - c1) --> (cov) (c0 - c1) + v
36774 else if ((details::e_add == o0) && (details::e_sub == o1))
36775 {
36776 exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
36777
36778 return expr_gen.node_allocator_->
36779 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36780 }
36781 // (c0) - (v + c1) --> (cov) (c0 - c1) - v
36782 else if ((details::e_sub == o0) && (details::e_add == o1))
36783 {
36784 exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
36785
36786 return expr_gen.node_allocator_->
36787 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36788 }
36789 // (c0) - (v - c1) --> (cov) (c0 + c1) - v
36790 else if ((details::e_sub == o0) && (details::e_sub == o1))
36791 {
36792 exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
36793
36794 return expr_gen.node_allocator_->
36795 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36796 }
36797 // (c0) * (v * c1) --> (voc) v * (c0 * c1)
36798 else if ((details::e_mul == o0) && (details::e_mul == o1))
36799 {
36800 exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
36801
36802 return expr_gen.node_allocator_->
36803 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36804 }
36805 // (c0) * (v / c1) --> (cov) (c0 / c1) * v
36806 else if ((details::e_mul == o0) && (details::e_div == o1))
36807 {
36808 exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
36809
36810 return expr_gen.node_allocator_->
36811 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36812 }
36813 // (c0) / (v * c1) --> (cov) (c0 / c1) / v
36814 else if ((details::e_div == o0) && (details::e_mul == o1))
36815 {
36816 exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
36817
36818 return expr_gen.node_allocator_->
36819 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36820 }
36821 // (c0) / (v / c1) --> (cov) (c0 * c1) / v
36822 else if ((details::e_div == o0) && (details::e_div == o1))
36823 {
36824 exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
36825
36826 return expr_gen.node_allocator_->
36827 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36828 }
36829 }
36830
36831 const bool synthesis_result =
36832 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
36833 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
36834
36835 if (synthesis_result)
36836 return result;
36837
36838 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36839 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36840
36841 if (!expr_gen.valid_operator(o0,f0))
36842 return error_node();
36843 else if (!expr_gen.valid_operator(o1,f1))
36844 return error_node();
36845 else
36846 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
36847 }
36848
36849 static inline std::string id(expression_generator<Type>& expr_gen,
36850 const details::operator_type o0,
36851 const details::operator_type o1)
36852 {
36853 return details::build_string()
36854 << "t" << expr_gen.to_str(o0)
36855 << "(t" << expr_gen.to_str(o1)
36856 << "t)";
36857 }
36858 };
36859
36860 struct synthesize_cocov_expression0
36861 {
36862 typedef typename cocov_t::type0 node_type;
36863 static inline expression_node_ptr process(expression_generator<Type>&,
36864 const details::operator_type&,
36865 expression_node_ptr (&)[2])
36866 {
36867 // (c0 o0 c1) o1 (v) - Not possible.
36868 return error_node();
36869 }
36870 };
36871
36872 struct synthesize_cocov_expression1
36873 {
36874 typedef typename cocov_t::type1 node_type;
36875 typedef typename cocov_t::sf3_type sf3_type;
36876
36877 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36878 const details::operator_type& operation,
36879 expression_node_ptr (&branch)[2])
36880 {
36881 // (c0) o0 (c1 o1 v)
36882 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36883 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
36884 const Type c1 = cov->c();
36885 const Type& v = cov->v();
36886 const details::operator_type o0 = operation;
36887 const details::operator_type o1 = cov->operation();
36888
36889 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36890 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36891
36892 expression_node_ptr result = error_node();
36893
36894 if (expr_gen.parser_->settings_.strength_reduction_enabled())
36895 {
36896 // (c0) + (c1 + v) --> (cov) (c0 + c1) + v
36897 if ((details::e_add == o0) && (details::e_add == o1))
36898 {
36899 exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
36900
36901 return expr_gen.node_allocator_->
36902 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36903 }
36904 // (c0) + (c1 - v) --> (cov) (c0 + c1) - v
36905 else if ((details::e_add == o0) && (details::e_sub == o1))
36906 {
36907 exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
36908
36909 return expr_gen.node_allocator_->
36910 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36911 }
36912 // (c0) - (c1 + v) --> (cov) (c0 - c1) - v
36913 else if ((details::e_sub == o0) && (details::e_add == o1))
36914 {
36915 exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
36916
36917 return expr_gen.node_allocator_->
36918 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36919 }
36920 // (c0) - (c1 - v) --> (cov) (c0 - c1) + v
36921 else if ((details::e_sub == o0) && (details::e_sub == o1))
36922 {
36923 exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
36924
36925 return expr_gen.node_allocator_->
36926 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36927 }
36928 // (c0) * (c1 * v) --> (cov) (c0 * c1) * v
36929 else if ((details::e_mul == o0) && (details::e_mul == o1))
36930 {
36931 exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
36932
36933 return expr_gen.node_allocator_->
36934 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36935 }
36936 // (c0) * (c1 / v) --> (cov) (c0 * c1) / v
36937 else if ((details::e_mul == o0) && (details::e_div == o1))
36938 {
36939 exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
36940
36941 return expr_gen.node_allocator_->
36942 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36943 }
36944 // (c0) / (c1 * v) --> (cov) (c0 / c1) / v
36945 else if ((details::e_div == o0) && (details::e_mul == o1))
36946 {
36947 exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
36948
36949 return expr_gen.node_allocator_->
36950 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36951 }
36952 // (c0) / (c1 / v) --> (cov) (c0 / c1) * v
36953 else if ((details::e_div == o0) && (details::e_div == o1))
36954 {
36955 exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
36956
36957 return expr_gen.node_allocator_->
36958 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36959 }
36960 }
36961
36962 const bool synthesis_result =
36963 synthesize_sf3ext_expression::template compile<ctype, ctype, vtype>
36964 (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result);
36965
36966 if (synthesis_result)
36967 return result;
36968
36969 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36970 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36971
36972 if (!expr_gen.valid_operator(o0,f0))
36973 return error_node();
36974 else if (!expr_gen.valid_operator(o1,f1))
36975 return error_node();
36976 else
36977 return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1);
36978 }
36979
36980 static inline std::string id(expression_generator<Type>& expr_gen,
36981 const details::operator_type o0,
36982 const details::operator_type o1)
36983 {
36984 return details::build_string()
36985 << "t" << expr_gen.to_str(o0)
36986 << "(t" << expr_gen.to_str(o1)
36987 << "t)";
36988 }
36989 };
36990
36991 struct synthesize_vococ_expression0
36992 {
36993 typedef typename vococ_t::type0 node_type;
36994 typedef typename vococ_t::sf3_type sf3_type;
36995
36996 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
36997 const details::operator_type& operation,
36998 expression_node_ptr (&branch)[2])
36999 {
37000 // (v o0 c0) o1 (c1)
37001 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
37002 const Type& v = voc->v();
37003 const Type& c0 = voc->c();
37004 const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
37005 const details::operator_type o0 = voc->operation();
37006 const details::operator_type o1 = operation;
37007
37008 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37009 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37010
37011 expression_node_ptr result = error_node();
37012
37013 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37014 {
37015 // (v + c0) + c1 --> (voc) v + (c0 + c1)
37016 if ((details::e_add == o0) && (details::e_add == o1))
37017 {
37018 exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
37019
37020 return expr_gen.node_allocator_->
37021 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1);
37022 }
37023 // (v + c0) - c1 --> (voc) v + (c0 - c1)
37024 else if ((details::e_add == o0) && (details::e_sub == o1))
37025 {
37026 exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
37027
37028 return expr_gen.node_allocator_->
37029 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1);
37030 }
37031 // (v - c0) + c1 --> (voc) v - (c0 + c1)
37032 else if ((details::e_sub == o0) && (details::e_add == o1))
37033 {
37034 exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
37035
37036 return expr_gen.node_allocator_->
37037 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0);
37038 }
37039 // (v - c0) - c1 --> (voc) v - (c0 + c1)
37040 else if ((details::e_sub == o0) && (details::e_sub == o1))
37041 {
37042 exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
37043
37044 return expr_gen.node_allocator_->
37045 template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1);
37046 }
37047 // (v * c0) * c1 --> (voc) v * (c0 * c1)
37048 else if ((details::e_mul == o0) && (details::e_mul == o1))
37049 {
37050 exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
37051
37052 return expr_gen.node_allocator_->
37053 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1);
37054 }
37055 // (v * c0) / c1 --> (voc) v * (c0 / c1)
37056 else if ((details::e_mul == o0) && (details::e_div == o1))
37057 {
37058 exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
37059
37060 return expr_gen.node_allocator_->
37061 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1);
37062 }
37063 // (v / c0) * c1 --> (voc) v * (c1 / c0)
37064 else if ((details::e_div == o0) && (details::e_mul == o1))
37065 {
37066 exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
37067
37068 return expr_gen.node_allocator_->
37069 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0);
37070 }
37071 // (v / c0) / c1 --> (voc) v / (c0 * c1)
37072 else if ((details::e_div == o0) && (details::e_div == o1))
37073 {
37074 exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
37075
37076 return expr_gen.node_allocator_->
37077 template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1);
37078 }
37079 // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)
37080 else if ((details::e_pow == o0) && (details::e_pow == o1))
37081 {
37082 exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
37083
37084 return expr_gen.node_allocator_->
37085 template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1);
37086 }
37087 }
37088
37089 const bool synthesis_result =
37090 synthesize_sf3ext_expression::template compile<vtype, ctype, ctype>
37091 (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result);
37092
37093 if (synthesis_result)
37094 return result;
37095
37096 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37097 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37098
37099 if (!expr_gen.valid_operator(o0,f0))
37100 return error_node();
37101 else if (!expr_gen.valid_operator(o1,f1))
37102 return error_node();
37103 else
37104 return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1);
37105 }
37106
37107 static inline std::string id(expression_generator<Type>& expr_gen,
37108 const details::operator_type o0,
37109 const details::operator_type o1)
37110 {
37111 return details::build_string()
37112 << "(t" << expr_gen.to_str(o0)
37113 << "t)" << expr_gen.to_str(o1)
37114 << "t";
37115 }
37116 };
37117
37118 struct synthesize_vococ_expression1
37119 {
37120 typedef typename vococ_t::type0 node_type;
37121
37122 static inline expression_node_ptr process(expression_generator<Type>&,
37123 const details::operator_type&,
37124 expression_node_ptr (&)[2])
37125 {
37126 // (v) o0 (c0 o1 c1) - Not possible.
37127 exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n"));
37128 return error_node();
37129 }
37130 };
37131
37132 struct synthesize_vovovov_expression0
37133 {
37134 typedef typename vovovov_t::type0 node_type;
37135 typedef typename vovovov_t::sf4_type sf4_type;
37136 typedef typename node_type::T0 T0;
37137 typedef typename node_type::T1 T1;
37138 typedef typename node_type::T2 T2;
37139 typedef typename node_type::T3 T3;
37140
37141 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37142 const details::operator_type& operation,
37143 expression_node_ptr (&branch)[2])
37144 {
37145 // (v0 o0 v1) o1 (v2 o2 v3)
37146 const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
37147 const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
37148 const Type& v0 = vov0->v0();
37149 const Type& v1 = vov0->v1();
37150 const Type& v2 = vov1->v0();
37151 const Type& v3 = vov1->v1();
37152 const details::operator_type o0 = vov0->operation();
37153 const details::operator_type o1 = operation;
37154 const details::operator_type o2 = vov1->operation();
37155
37156 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37157 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37158
37159 expression_node_ptr result = error_node();
37160
37161 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37162 {
37163 // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)
37164 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37165 {
37166 const bool synthesis_result =
37167 synthesize_sf4ext_expression::
37168 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result);
37169
37170 exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
37171
37172 return (synthesis_result) ? result : error_node();
37173 }
37174 // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)
37175 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37176 {
37177 const bool synthesis_result =
37178 synthesize_sf4ext_expression::
37179 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result);
37180
37181 exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
37182
37183 return (synthesis_result) ? result : error_node();
37184 }
37185 // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
37186 else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
37187 {
37188 const bool synthesis_result =
37189 synthesize_sf4ext_expression::
37190 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result);
37191
37192 exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
37193
37194 return (synthesis_result) ? result : error_node();
37195 }
37196 // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
37197 else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
37198 {
37199 const bool synthesis_result =
37200 synthesize_sf4ext_expression::
37201 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result);
37202
37203 exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
37204
37205 return (synthesis_result) ? result : error_node();
37206 }
37207 // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2
37208 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37209 {
37210 const bool synthesis_result =
37211 synthesize_sf4ext_expression::
37212 template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result);
37213
37214 exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
37215
37216 return (synthesis_result) ? result : error_node();
37217 }
37218 }
37219
37220 const bool synthesis_result =
37221 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37222 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
37223
37224 if (synthesis_result)
37225 return result;
37226
37227 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37228 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37229 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37230
37231 if (!expr_gen.valid_operator(o0,f0))
37232 return error_node();
37233 else if (!expr_gen.valid_operator(o1,f1))
37234 return error_node();
37235 else if (!expr_gen.valid_operator(o2,f2))
37236 return error_node();
37237 else
37238 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37239 }
37240
37241 static inline std::string id(expression_generator<Type>& expr_gen,
37242 const details::operator_type o0,
37243 const details::operator_type o1,
37244 const details::operator_type o2)
37245 {
37246 return details::build_string()
37247 << "(t" << expr_gen.to_str(o0)
37248 << "t)" << expr_gen.to_str(o1)
37249 << "(t" << expr_gen.to_str(o2)
37250 << "t)";
37251 }
37252 };
37253
37254 struct synthesize_vovovoc_expression0
37255 {
37256 typedef typename vovovoc_t::type0 node_type;
37257 typedef typename vovovoc_t::sf4_type sf4_type;
37258 typedef typename node_type::T0 T0;
37259 typedef typename node_type::T1 T1;
37260 typedef typename node_type::T2 T2;
37261 typedef typename node_type::T3 T3;
37262
37263 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37264 const details::operator_type& operation,
37265 expression_node_ptr (&branch)[2])
37266 {
37267 // (v0 o0 v1) o1 (v2 o2 c)
37268 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
37269 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
37270 const Type& v0 = vov->v0();
37271 const Type& v1 = vov->v1();
37272 const Type& v2 = voc->v ();
37273 const Type c = voc->c ();
37274 const details::operator_type o0 = vov->operation();
37275 const details::operator_type o1 = operation;
37276 const details::operator_type o2 = voc->operation();
37277
37278 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37279 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37280
37281 expression_node_ptr result = error_node();
37282
37283 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37284 {
37285 // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)
37286 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37287 {
37288 const bool synthesis_result =
37289 synthesize_sf4ext_expression::
37290 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
37291
37292 exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
37293
37294 return (synthesis_result) ? result : error_node();
37295 }
37296 // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)
37297 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37298 {
37299 const bool synthesis_result =
37300 synthesize_sf4ext_expression::
37301 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
37302
37303 exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
37304
37305 return (synthesis_result) ? result : error_node();
37306 }
37307 }
37308
37309 const bool synthesis_result =
37310 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37311 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37312
37313 if (synthesis_result)
37314 return result;
37315
37316 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37317 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37318 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37319
37320 if (!expr_gen.valid_operator(o0,f0))
37321 return error_node();
37322 else if (!expr_gen.valid_operator(o1,f1))
37323 return error_node();
37324 else if (!expr_gen.valid_operator(o2,f2))
37325 return error_node();
37326 else
37327 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37328 }
37329
37330 static inline std::string id(expression_generator<Type>& expr_gen,
37331 const details::operator_type o0,
37332 const details::operator_type o1,
37333 const details::operator_type o2)
37334 {
37335 return details::build_string()
37336 << "(t" << expr_gen.to_str(o0)
37337 << "t)" << expr_gen.to_str(o1)
37338 << "(t" << expr_gen.to_str(o2)
37339 << "t)";
37340 }
37341 };
37342
37343 struct synthesize_vovocov_expression0
37344 {
37345 typedef typename vovocov_t::type0 node_type;
37346 typedef typename vovocov_t::sf4_type sf4_type;
37347 typedef typename node_type::T0 T0;
37348 typedef typename node_type::T1 T1;
37349 typedef typename node_type::T2 T2;
37350 typedef typename node_type::T3 T3;
37351
37352 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37353 const details::operator_type& operation,
37354 expression_node_ptr (&branch)[2])
37355 {
37356 // (v0 o0 v1) o1 (c o2 v2)
37357 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
37358 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
37359 const Type& v0 = vov->v0();
37360 const Type& v1 = vov->v1();
37361 const Type& v2 = cov->v ();
37362 const Type c = cov->c ();
37363 const details::operator_type o0 = vov->operation();
37364 const details::operator_type o1 = operation;
37365 const details::operator_type o2 = cov->operation();
37366
37367 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37368 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37369
37370 expression_node_ptr result = error_node();
37371
37372 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37373 {
37374 // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)
37375 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37376 {
37377 const bool synthesis_result =
37378 synthesize_sf4ext_expression::
37379 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
37380
37381 exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
37382
37383 return (synthesis_result) ? result : error_node();
37384 }
37385 // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)
37386 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37387 {
37388 const bool synthesis_result =
37389 synthesize_sf4ext_expression::
37390 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
37391
37392 exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
37393
37394 return (synthesis_result) ? result : error_node();
37395 }
37396 }
37397
37398 const bool synthesis_result =
37399 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37400 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37401
37402 if (synthesis_result)
37403 return result;
37404
37405 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37406 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37407 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37408
37409 if (!expr_gen.valid_operator(o0,f0))
37410 return error_node();
37411 else if (!expr_gen.valid_operator(o1,f1))
37412 return error_node();
37413 else if (!expr_gen.valid_operator(o2,f2))
37414 return error_node();
37415 else
37416 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37417 }
37418
37419 static inline std::string id(expression_generator<Type>& expr_gen,
37420 const details::operator_type o0,
37421 const details::operator_type o1,
37422 const details::operator_type o2)
37423 {
37424 return details::build_string()
37425 << "(t" << expr_gen.to_str(o0)
37426 << "t)" << expr_gen.to_str(o1)
37427 << "(t" << expr_gen.to_str(o2)
37428 << "t)";
37429 }
37430 };
37431
37432 struct synthesize_vocovov_expression0
37433 {
37434 typedef typename vocovov_t::type0 node_type;
37435 typedef typename vocovov_t::sf4_type sf4_type;
37436 typedef typename node_type::T0 T0;
37437 typedef typename node_type::T1 T1;
37438 typedef typename node_type::T2 T2;
37439 typedef typename node_type::T3 T3;
37440
37441 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37442 const details::operator_type& operation,
37443 expression_node_ptr (&branch)[2])
37444 {
37445 // (v0 o0 c) o1 (v1 o2 v2)
37446 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
37447 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
37448 const Type c = voc->c ();
37449 const Type& v0 = voc->v ();
37450 const Type& v1 = vov->v0();
37451 const Type& v2 = vov->v1();
37452 const details::operator_type o0 = voc->operation();
37453 const details::operator_type o1 = operation;
37454 const details::operator_type o2 = vov->operation();
37455
37456 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37457 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37458
37459 expression_node_ptr result = error_node();
37460
37461 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37462 {
37463 // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)
37464 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37465 {
37466 const bool synthesis_result =
37467 synthesize_sf4ext_expression::
37468 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result);
37469
37470 exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
37471
37472 return (synthesis_result) ? result : error_node();
37473 }
37474 // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)
37475 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37476 {
37477 const bool synthesis_result =
37478 synthesize_sf4ext_expression::
37479 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result);
37480
37481 exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
37482
37483 return (synthesis_result) ? result : error_node();
37484 }
37485 }
37486
37487 const bool synthesis_result =
37488 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37489 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37490
37491 if (synthesis_result)
37492 return result;
37493
37494 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37495 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37496 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37497
37498 if (!expr_gen.valid_operator(o0,f0))
37499 return error_node();
37500 else if (!expr_gen.valid_operator(o1,f1))
37501 return error_node();
37502 else if (!expr_gen.valid_operator(o2,f2))
37503 return error_node();
37504 else
37505 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37506 }
37507
37508 static inline std::string id(expression_generator<Type>& expr_gen,
37509 const details::operator_type o0,
37510 const details::operator_type o1,
37511 const details::operator_type o2)
37512 {
37513 return details::build_string()
37514 << "(t" << expr_gen.to_str(o0)
37515 << "t)" << expr_gen.to_str(o1)
37516 << "(t" << expr_gen.to_str(o2)
37517 << "t)";
37518 }
37519 };
37520
37521 struct synthesize_covovov_expression0
37522 {
37523 typedef typename covovov_t::type0 node_type;
37524 typedef typename covovov_t::sf4_type sf4_type;
37525 typedef typename node_type::T0 T0;
37526 typedef typename node_type::T1 T1;
37527 typedef typename node_type::T2 T2;
37528 typedef typename node_type::T3 T3;
37529
37530 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37531 const details::operator_type& operation,
37532 expression_node_ptr (&branch)[2])
37533 {
37534 // (c o0 v0) o1 (v1 o2 v2)
37535 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
37536 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
37537 const Type c = cov->c ();
37538 const Type& v0 = cov->v ();
37539 const Type& v1 = vov->v0();
37540 const Type& v2 = vov->v1();
37541 const details::operator_type o0 = cov->operation();
37542 const details::operator_type o1 = operation;
37543 const details::operator_type o2 = vov->operation();
37544
37545 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37546 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37547
37548 expression_node_ptr result = error_node();
37549
37550 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37551 {
37552 // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)
37553 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37554 {
37555 const bool synthesis_result =
37556 synthesize_sf4ext_expression::
37557 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result);
37558
37559 exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
37560
37561 return (synthesis_result) ? result : error_node();
37562 }
37563 // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)
37564 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37565 {
37566 const bool synthesis_result =
37567 synthesize_sf4ext_expression::
37568 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result);
37569
37570 exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
37571
37572 return (synthesis_result) ? result : error_node();
37573 }
37574 }
37575
37576 const bool synthesis_result =
37577 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37578 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37579
37580 if (synthesis_result)
37581 return result;
37582
37583 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37584 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37585 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37586
37587 if (!expr_gen.valid_operator(o0,f0))
37588 return error_node();
37589 else if (!expr_gen.valid_operator(o1,f1))
37590 return error_node();
37591 else if (!expr_gen.valid_operator(o2,f2))
37592 return error_node();
37593 else
37594 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37595 }
37596
37597 static inline std::string id(expression_generator<Type>& expr_gen,
37598 const details::operator_type o0,
37599 const details::operator_type o1,
37600 const details::operator_type o2)
37601 {
37602 return details::build_string()
37603 << "(t" << expr_gen.to_str(o0)
37604 << "t)" << expr_gen.to_str(o1)
37605 << "(t" << expr_gen.to_str(o2)
37606 << "t)";
37607 }
37608 };
37609
37610 struct synthesize_covocov_expression0
37611 {
37612 typedef typename covocov_t::type0 node_type;
37613 typedef typename covocov_t::sf4_type sf4_type;
37614 typedef typename node_type::T0 T0;
37615 typedef typename node_type::T1 T1;
37616 typedef typename node_type::T2 T2;
37617 typedef typename node_type::T3 T3;
37618
37619 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37620 const details::operator_type& operation,
37621 expression_node_ptr (&branch)[2])
37622 {
37623 // (c0 o0 v0) o1 (c1 o2 v1)
37624 const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
37625 const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
37626 const Type c0 = cov0->c();
37627 const Type& v0 = cov0->v();
37628 const Type c1 = cov1->c();
37629 const Type& v1 = cov1->v();
37630 const details::operator_type o0 = cov0->operation();
37631 const details::operator_type o1 = operation;
37632 const details::operator_type o2 = cov1->operation();
37633
37634 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37635 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37636
37637 expression_node_ptr result = error_node();
37638
37639 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37640 {
37641 // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
37642 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
37643 {
37644 const bool synthesis_result =
37645 synthesize_sf3ext_expression::
37646 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
37647
37648 exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
37649
37650 return (synthesis_result) ? result : error_node();
37651 }
37652 // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
37653 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
37654 {
37655 const bool synthesis_result =
37656 synthesize_sf3ext_expression::
37657 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
37658
37659 exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
37660
37661 return (synthesis_result) ? result : error_node();
37662 }
37663 // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1
37664 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
37665 {
37666 const bool synthesis_result =
37667 synthesize_sf3ext_expression::
37668 template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result);
37669
37670 exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
37671
37672 return (synthesis_result) ? result : error_node();
37673 }
37674 // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
37675 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
37676 {
37677 const bool synthesis_result =
37678 synthesize_sf3ext_expression::
37679 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
37680
37681 exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
37682
37683 return (synthesis_result) ? result : error_node();
37684 }
37685 // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)
37686 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
37687 {
37688 const bool synthesis_result =
37689 synthesize_sf3ext_expression::
37690 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
37691
37692 exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
37693
37694 return (synthesis_result) ? result : error_node();
37695 }
37696 // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)
37697 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37698 {
37699 const bool synthesis_result =
37700 synthesize_sf3ext_expression::
37701 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
37702
37703 exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
37704
37705 return (synthesis_result) ? result : error_node();
37706 }
37707 // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0
37708 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37709 {
37710 const bool synthesis_result =
37711 synthesize_sf3ext_expression::
37712 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result);
37713
37714 exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
37715
37716 return (synthesis_result) ? result : error_node();
37717 }
37718 // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
37719 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37720 {
37721 const bool synthesis_result =
37722 synthesize_sf3ext_expression::
37723 template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result);
37724
37725 exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
37726
37727 return (synthesis_result) ? result : error_node();
37728 }
37729 // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)
37730 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
37731 {
37732 const bool synthesis_result =
37733 synthesize_sf3ext_expression::
37734 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
37735
37736 exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
37737
37738 return (synthesis_result) ? result : error_node();
37739 }
37740 // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)
37741 else if (
37742 (std::equal_to<T>()(c0,c1)) &&
37743 (details::e_mul == o0) &&
37744 (details::e_mul == o2) &&
37745 (
37746 (details::e_add == o1) ||
37747 (details::e_sub == o1)
37748 )
37749 )
37750 {
37751 std::string specfunc;
37752
37753 switch (o1)
37754 {
37755 case details::e_add : specfunc = "t*(t+t)"; break;
37756 case details::e_sub : specfunc = "t*(t-t)"; break;
37757 default : return error_node();
37758 }
37759
37760 const bool synthesis_result =
37761 synthesize_sf3ext_expression::
37762 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
37763
37764 exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
37765
37766 return (synthesis_result) ? result : error_node();
37767 }
37768 }
37769
37770 const bool synthesis_result =
37771 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37772 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37773
37774 if (synthesis_result)
37775 return result;
37776
37777 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37778 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37779 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37780
37781 if (!expr_gen.valid_operator(o0,f0))
37782 return error_node();
37783 else if (!expr_gen.valid_operator(o1,f1))
37784 return error_node();
37785 else if (!expr_gen.valid_operator(o2,f2))
37786 return error_node();
37787 else
37788 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37789 }
37790
37791 static inline std::string id(expression_generator<Type>& expr_gen,
37792 const details::operator_type o0,
37793 const details::operator_type o1,
37794 const details::operator_type o2)
37795 {
37796 return details::build_string()
37797 << "(t" << expr_gen.to_str(o0)
37798 << "t)" << expr_gen.to_str(o1)
37799 << "(t" << expr_gen.to_str(o2)
37800 << "t)";
37801 }
37802 };
37803
37804 struct synthesize_vocovoc_expression0
37805 {
37806 typedef typename vocovoc_t::type0 node_type;
37807 typedef typename vocovoc_t::sf4_type sf4_type;
37808 typedef typename node_type::T0 T0;
37809 typedef typename node_type::T1 T1;
37810 typedef typename node_type::T2 T2;
37811 typedef typename node_type::T3 T3;
37812
37813 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
37814 const details::operator_type& operation,
37815 expression_node_ptr (&branch)[2])
37816 {
37817 // (v0 o0 c0) o1 (v1 o2 c1)
37818 const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
37819 const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
37820 const Type c0 = voc0->c();
37821 const Type& v0 = voc0->v();
37822 const Type c1 = voc1->c();
37823 const Type& v1 = voc1->v();
37824 const details::operator_type o0 = voc0->operation();
37825 const details::operator_type o1 = operation;
37826 const details::operator_type o2 = voc1->operation();
37827
37828 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37829 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37830
37831 expression_node_ptr result = error_node();
37832
37833 if (expr_gen.parser_->settings_.strength_reduction_enabled())
37834 {
37835 // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
37836 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
37837 {
37838 const bool synthesis_result =
37839 synthesize_sf3ext_expression::
37840 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
37841
37842 exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
37843
37844 return (synthesis_result) ? result : error_node();
37845 }
37846 // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
37847 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
37848 {
37849 const bool synthesis_result =
37850 synthesize_sf3ext_expression::
37851 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
37852
37853 exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
37854
37855 return (synthesis_result) ? result : error_node();
37856 }
37857 // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1
37858 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
37859 {
37860 const bool synthesis_result =
37861 synthesize_sf3ext_expression::
37862 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result);
37863
37864 exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
37865
37866 return (synthesis_result) ? result : error_node();
37867 }
37868 // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
37869 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
37870 {
37871 const bool synthesis_result =
37872 synthesize_sf3ext_expression::
37873 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
37874
37875 exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
37876
37877 return (synthesis_result) ? result : error_node();
37878 }
37879 // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
37880 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
37881 {
37882 const bool synthesis_result =
37883 synthesize_sf3ext_expression::
37884 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
37885
37886 exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
37887
37888 return (synthesis_result) ? result : error_node();
37889 }
37890 // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1
37891 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37892 {
37893 const bool synthesis_result =
37894 synthesize_sf3ext_expression::
37895 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result);
37896
37897 exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
37898
37899 return (synthesis_result) ? result : error_node();
37900 }
37901 // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1
37902 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37903 {
37904 const bool synthesis_result =
37905 synthesize_sf3ext_expression::
37906 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
37907
37908 exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
37909
37910 return (synthesis_result) ? result : error_node();
37911 }
37912 // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
37913 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37914 {
37915 const bool synthesis_result =
37916 synthesize_sf3ext_expression::
37917 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result);
37918
37919 exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
37920
37921 return (synthesis_result) ? result : error_node();
37922 }
37923 // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1
37924 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
37925 {
37926 const bool synthesis_result =
37927 synthesize_sf3ext_expression::
37928 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result);
37929
37930 exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
37931
37932 return (synthesis_result) ? result : error_node();
37933 }
37934 // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)
37935 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
37936 {
37937 const bool synthesis_result =
37938 synthesize_sf4ext_expression::
37939 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result);
37940
37941 exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
37942
37943 return (synthesis_result) ? result : error_node();
37944 }
37945 // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)
37946 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
37947 {
37948 const bool synthesis_result =
37949 synthesize_sf4ext_expression::
37950 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result);
37951
37952 exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
37953
37954 return (synthesis_result) ? result : error_node();
37955 }
37956 // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
37957 else if (
37958 (std::equal_to<T>()(c0,c1)) &&
37959 (details::e_mul == o0) &&
37960 (details::e_mul == o2) &&
37961 (
37962 (details::e_add == o1) ||
37963 (details::e_sub == o1)
37964 )
37965 )
37966 {
37967 std::string specfunc;
37968
37969 switch (o1)
37970 {
37971 case details::e_add : specfunc = "t*(t+t)"; break;
37972 case details::e_sub : specfunc = "t*(t-t)"; break;
37973 default : return error_node();
37974 }
37975
37976 const bool synthesis_result =
37977 synthesize_sf3ext_expression::
37978 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
37979
37980 exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
37981
37982 return (synthesis_result) ? result : error_node();
37983 }
37984 // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c
37985 else if (
37986 (std::equal_to<T>()(c0,c1)) &&
37987 (details::e_div == o0) &&
37988 (details::e_div == o2) &&
37989 (
37990 (details::e_add == o1) ||
37991 (details::e_sub == o1)
37992 )
37993 )
37994 {
37995 std::string specfunc;
37996
37997 switch (o1)
37998 {
37999 case details::e_add : specfunc = "(t+t)/t"; break;
38000 case details::e_sub : specfunc = "(t-t)/t"; break;
38001 default : return error_node();
38002 }
38003
38004 const bool synthesis_result =
38005 synthesize_sf3ext_expression::
38006 template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result);
38007
38008 exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
38009
38010 return (synthesis_result) ? result : error_node();
38011 }
38012 }
38013
38014 const bool synthesis_result =
38015 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38016 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38017
38018 if (synthesis_result)
38019 return result;
38020
38021 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38022 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38023 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38024
38025 if (!expr_gen.valid_operator(o0,f0))
38026 return error_node();
38027 else if (!expr_gen.valid_operator(o1,f1))
38028 return error_node();
38029 else if (!expr_gen.valid_operator(o2,f2))
38030 return error_node();
38031 else
38032 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38033 }
38034
38035 static inline std::string id(expression_generator<Type>& expr_gen,
38036 const details::operator_type o0,
38037 const details::operator_type o1,
38038 const details::operator_type o2)
38039 {
38040 return details::build_string()
38041 << "(t" << expr_gen.to_str(o0)
38042 << "t)" << expr_gen.to_str(o1)
38043 << "(t" << expr_gen.to_str(o2)
38044 << "t)";
38045 }
38046 };
38047
38048 struct synthesize_covovoc_expression0
38049 {
38050 typedef typename covovoc_t::type0 node_type;
38051 typedef typename covovoc_t::sf4_type sf4_type;
38052 typedef typename node_type::T0 T0;
38053 typedef typename node_type::T1 T1;
38054 typedef typename node_type::T2 T2;
38055 typedef typename node_type::T3 T3;
38056
38057 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38058 const details::operator_type& operation,
38059 expression_node_ptr (&branch)[2])
38060 {
38061 // (c0 o0 v0) o1 (v1 o2 c1)
38062 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
38063 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
38064 const Type c0 = cov->c();
38065 const Type& v0 = cov->v();
38066 const Type c1 = voc->c();
38067 const Type& v1 = voc->v();
38068 const details::operator_type o0 = cov->operation();
38069 const details::operator_type o1 = operation;
38070 const details::operator_type o2 = voc->operation();
38071
38072 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38073 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38074
38075 expression_node_ptr result = error_node();
38076
38077 if (expr_gen.parser_->settings_.strength_reduction_enabled())
38078 {
38079 // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
38080 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
38081 {
38082 const bool synthesis_result =
38083 synthesize_sf3ext_expression::
38084 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
38085
38086 exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
38087
38088 return (synthesis_result) ? result : error_node();
38089 }
38090 // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
38091 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
38092 {
38093 const bool synthesis_result =
38094 synthesize_sf3ext_expression::
38095 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
38096
38097 exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
38098
38099 return (synthesis_result) ? result : error_node();
38100 }
38101 // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1
38102 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
38103 {
38104 const bool synthesis_result =
38105 synthesize_sf3ext_expression::
38106 template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result);
38107
38108 exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
38109
38110 return (synthesis_result) ? result : error_node();
38111 }
38112 // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
38113 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
38114 {
38115 const bool synthesis_result =
38116 synthesize_sf3ext_expression::
38117 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
38118
38119 exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
38120
38121 return (synthesis_result) ? result : error_node();
38122 }
38123 // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
38124 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
38125 {
38126 const bool synthesis_result =
38127 synthesize_sf3ext_expression::
38128 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
38129
38130 exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
38131
38132 return (synthesis_result) ? result : error_node();
38133 }
38134 // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)
38135 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
38136 {
38137 const bool synthesis_result =
38138 synthesize_sf3ext_expression::
38139 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result);
38140
38141 exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
38142
38143 return (synthesis_result) ? result : error_node();
38144 }
38145 // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)
38146 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
38147 {
38148 const bool synthesis_result =
38149 synthesize_sf3ext_expression::
38150 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
38151
38152 exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
38153
38154 return (synthesis_result) ? result : error_node();
38155 }
38156 // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
38157 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
38158 {
38159 const bool synthesis_result =
38160 synthesize_sf3ext_expression::
38161 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result);
38162
38163 exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
38164
38165 return (synthesis_result) ? result : error_node();
38166 }
38167 // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)
38168 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
38169 {
38170 const bool synthesis_result =
38171 synthesize_sf3ext_expression::
38172 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
38173
38174 exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
38175
38176 return (synthesis_result) ? result : error_node();
38177 }
38178 // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
38179 else if (
38180 (std::equal_to<T>()(c0,c1)) &&
38181 (details::e_mul == o0) &&
38182 (details::e_mul == o2) &&
38183 (
38184 (details::e_add == o1) ||
38185 (details::e_sub == o1)
38186 )
38187 )
38188 {
38189 std::string specfunc;
38190
38191 switch (o1)
38192 {
38193 case details::e_add : specfunc = "t*(t+t)"; break;
38194 case details::e_sub : specfunc = "t*(t-t)"; break;
38195 default : return error_node();
38196 }
38197
38198 const bool synthesis_result =
38199 synthesize_sf3ext_expression::
38200 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
38201
38202 exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
38203
38204 return (synthesis_result) ? result : error_node();
38205 }
38206 }
38207
38208 const bool synthesis_result =
38209 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38210 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38211
38212 if (synthesis_result)
38213 return result;
38214
38215 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38216 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38217 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38218
38219 if (!expr_gen.valid_operator(o0,f0))
38220 return error_node();
38221 else if (!expr_gen.valid_operator(o1,f1))
38222 return error_node();
38223 else if (!expr_gen.valid_operator(o2,f2))
38224 return error_node();
38225 else
38226 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38227 }
38228
38229 static inline std::string id(expression_generator<Type>& expr_gen,
38230 const details::operator_type o0,
38231 const details::operator_type o1,
38232 const details::operator_type o2)
38233 {
38234 return details::build_string()
38235 << "(t" << expr_gen.to_str(o0)
38236 << "t)" << expr_gen.to_str(o1)
38237 << "(t" << expr_gen.to_str(o2)
38238 << "t)";
38239 }
38240 };
38241
38242 struct synthesize_vococov_expression0
38243 {
38244 typedef typename vococov_t::type0 node_type;
38245 typedef typename vococov_t::sf4_type sf4_type;
38246 typedef typename node_type::T0 T0;
38247 typedef typename node_type::T1 T1;
38248 typedef typename node_type::T2 T2;
38249 typedef typename node_type::T3 T3;
38250
38251 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38252 const details::operator_type& operation,
38253 expression_node_ptr (&branch)[2])
38254 {
38255 // (v0 o0 c0) o1 (c1 o2 v1)
38256 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
38257 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
38258 const Type c0 = voc->c();
38259 const Type& v0 = voc->v();
38260 const Type c1 = cov->c();
38261 const Type& v1 = cov->v();
38262 const details::operator_type o0 = voc->operation();
38263 const details::operator_type o1 = operation;
38264 const details::operator_type o2 = cov->operation();
38265
38266 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38267 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38268
38269 expression_node_ptr result = error_node();
38270
38271 if (expr_gen.parser_->settings_.strength_reduction_enabled())
38272 {
38273 // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
38274 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
38275 {
38276 const bool synthesis_result =
38277 synthesize_sf3ext_expression::
38278 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
38279
38280 exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
38281
38282 return (synthesis_result) ? result : error_node();
38283 }
38284 // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
38285 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
38286 {
38287 const bool synthesis_result =
38288 synthesize_sf3ext_expression::
38289 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
38290
38291 exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
38292
38293 return (synthesis_result) ? result : error_node();
38294 }
38295 // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)
38296 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
38297 {
38298 const bool synthesis_result =
38299 synthesize_sf3ext_expression::
38300 template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result);
38301
38302 exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
38303
38304 return (synthesis_result) ? result : error_node();
38305 }
38306 // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
38307 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
38308 {
38309 const bool synthesis_result =
38310 synthesize_sf3ext_expression::
38311 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
38312
38313 exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
38314
38315 return (synthesis_result) ? result : error_node();
38316 }
38317 // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)
38318 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
38319 {
38320 const bool synthesis_result =
38321 synthesize_sf3ext_expression::
38322 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
38323
38324 exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
38325
38326 return (synthesis_result) ? result : error_node();
38327 }
38328 // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)
38329 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
38330 {
38331 const bool synthesis_result =
38332 synthesize_sf3ext_expression::
38333 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
38334
38335 exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
38336
38337 return (synthesis_result) ? result : error_node();
38338 }
38339 // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
38340 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
38341 {
38342 const bool synthesis_result =
38343 synthesize_sf3ext_expression::
38344 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result);
38345
38346 exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
38347
38348 return (synthesis_result) ? result : error_node();
38349 }
38350 // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)
38351 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
38352 {
38353 const bool synthesis_result =
38354 synthesize_sf3ext_expression::
38355 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result);
38356
38357 exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
38358
38359 return (synthesis_result) ? result : error_node();
38360 }
38361 // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))
38362 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
38363 {
38364 const bool synthesis_result =
38365 synthesize_sf3ext_expression::
38366 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result);
38367
38368 exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
38369
38370 return (synthesis_result) ? result : error_node();
38371 }
38372 // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)
38373 else if (
38374 (std::equal_to<T>()(c0,c1)) &&
38375 (details::e_mul == o0) &&
38376 (details::e_mul == o2) &&
38377 (
38378 (details::e_add == o1) || (details::e_sub == o1)
38379 )
38380 )
38381 {
38382 std::string specfunc;
38383
38384 switch (o1)
38385 {
38386 case details::e_add : specfunc = "t*(t+t)"; break;
38387 case details::e_sub : specfunc = "t*(t-t)"; break;
38388 default : return error_node();
38389 }
38390
38391 const bool synthesis_result =
38392 synthesize_sf3ext_expression::
38393 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
38394
38395 exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
38396
38397 return (synthesis_result) ? result : error_node();
38398 }
38399 }
38400
38401 const bool synthesis_result =
38402 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38403 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38404
38405 if (synthesis_result)
38406 return result;
38407
38408 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38409 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38410 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38411
38412 if (!expr_gen.valid_operator(o0,f0))
38413 return error_node();
38414 else if (!expr_gen.valid_operator(o1,f1))
38415 return error_node();
38416 else if (!expr_gen.valid_operator(o2,f2))
38417 return error_node();
38418 else
38419 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38420 }
38421
38422 static inline std::string id(expression_generator<Type>& expr_gen,
38423 const details::operator_type o0,
38424 const details::operator_type o1,
38425 const details::operator_type o2)
38426 {
38427 return details::build_string()
38428 << "(t" << expr_gen.to_str(o0)
38429 << "t)" << expr_gen.to_str(o1)
38430 << "(t" << expr_gen.to_str(o2)
38431 << "t)";
38432 }
38433 };
38434
38435 struct synthesize_vovovov_expression1
38436 {
38437 typedef typename vovovov_t::type1 node_type;
38438 typedef typename vovovov_t::sf4_type sf4_type;
38439 typedef typename node_type::T0 T0;
38440 typedef typename node_type::T1 T1;
38441 typedef typename node_type::T2 T2;
38442 typedef typename node_type::T3 T3;
38443
38444 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38445 const details::operator_type& operation,
38446 expression_node_ptr (&branch)[2])
38447 {
38448 // v0 o0 (v1 o1 (v2 o2 v3))
38449 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38450
38451 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38452 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38453 const Type& v1 = vovov->t0();
38454 const Type& v2 = vovov->t1();
38455 const Type& v3 = vovov->t2();
38456 const details::operator_type o0 = operation;
38457 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
38458 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
38459
38460 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38461 binary_functor_t f1 = vovov->f0();
38462 binary_functor_t f2 = vovov->f1();
38463
38464 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38465
38466 expression_node_ptr result = error_node();
38467
38468 const bool synthesis_result =
38469 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38470 (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38471
38472 if (synthesis_result)
38473 return result;
38474 else if (!expr_gen.valid_operator(o0,f0))
38475 return error_node();
38476
38477 exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n"));
38478
38479 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38480 }
38481
38482 static inline std::string id(expression_generator<Type>& expr_gen,
38483 const details::operator_type o0,
38484 const details::operator_type o1,
38485 const details::operator_type o2)
38486 {
38487 return details::build_string()
38488 << "t" << expr_gen.to_str(o0)
38489 << "(t" << expr_gen.to_str(o1)
38490 << "(t" << expr_gen.to_str(o2)
38491 << "t))";
38492 }
38493 };
38494
38495 struct synthesize_vovovoc_expression1
38496 {
38497 typedef typename vovovoc_t::type1 node_type;
38498 typedef typename vovovoc_t::sf4_type sf4_type;
38499 typedef typename node_type::T0 T0;
38500 typedef typename node_type::T1 T1;
38501 typedef typename node_type::T2 T2;
38502 typedef typename node_type::T3 T3;
38503
38504 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38505 const details::operator_type& operation,
38506 expression_node_ptr (&branch)[2])
38507 {
38508 // v0 o0 (v1 o1 (v2 o2 c))
38509 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38510
38511 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38512 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38513 const Type& v1 = vovoc->t0();
38514 const Type& v2 = vovoc->t1();
38515 const Type c = vovoc->t2();
38516 const details::operator_type o0 = operation;
38517 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38518 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38519
38520 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38521 binary_functor_t f1 = vovoc->f0();
38522 binary_functor_t f2 = vovoc->f1();
38523
38524 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38525
38526 expression_node_ptr result = error_node();
38527
38528 const bool synthesis_result =
38529 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38530 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38531
38532 if (synthesis_result)
38533 return result;
38534 else if (!expr_gen.valid_operator(o0,f0))
38535 return error_node();
38536
38537 exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n"));
38538
38539 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38540 }
38541
38542 static inline std::string id(expression_generator<Type>& expr_gen,
38543 const details::operator_type o0,
38544 const details::operator_type o1,
38545 const details::operator_type o2)
38546 {
38547 return details::build_string()
38548 << "t" << expr_gen.to_str(o0)
38549 << "(t" << expr_gen.to_str(o1)
38550 << "(t" << expr_gen.to_str(o2)
38551 << "t))";
38552 }
38553 };
38554
38555 struct synthesize_vovocov_expression1
38556 {
38557 typedef typename vovocov_t::type1 node_type;
38558 typedef typename vovocov_t::sf4_type sf4_type;
38559 typedef typename node_type::T0 T0;
38560 typedef typename node_type::T1 T1;
38561 typedef typename node_type::T2 T2;
38562 typedef typename node_type::T3 T3;
38563
38564 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38565 const details::operator_type& operation,
38566 expression_node_ptr (&branch)[2])
38567 {
38568 // v0 o0 (v1 o1 (c o2 v2))
38569 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38570
38571 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
38572 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38573 const Type& v1 = vocov->t0();
38574 const Type c = vocov->t1();
38575 const Type& v2 = vocov->t2();
38576 const details::operator_type o0 = operation;
38577 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
38578 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
38579
38580 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38581 binary_functor_t f1 = vocov->f0();
38582 binary_functor_t f2 = vocov->f1();
38583
38584 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38585
38586 expression_node_ptr result = error_node();
38587
38588 const bool synthesis_result =
38589 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38590 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38591
38592 if (synthesis_result)
38593 return result;
38594 if (!expr_gen.valid_operator(o0,f0))
38595 return error_node();
38596
38597 exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n"));
38598
38599 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38600 }
38601
38602 static inline std::string id(expression_generator<Type>& expr_gen,
38603 const details::operator_type o0,
38604 const details::operator_type o1,
38605 const details::operator_type o2)
38606 {
38607 return details::build_string()
38608 << "t" << expr_gen.to_str(o0)
38609 << "(t" << expr_gen.to_str(o1)
38610 << "(t" << expr_gen.to_str(o2)
38611 << "t))";
38612 }
38613 };
38614
38615 struct synthesize_vocovov_expression1
38616 {
38617 typedef typename vocovov_t::type1 node_type;
38618 typedef typename vocovov_t::sf4_type sf4_type;
38619 typedef typename node_type::T0 T0;
38620 typedef typename node_type::T1 T1;
38621 typedef typename node_type::T2 T2;
38622 typedef typename node_type::T3 T3;
38623
38624 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38625 const details::operator_type& operation,
38626 expression_node_ptr (&branch)[2])
38627 {
38628 // v0 o0 (c o1 (v1 o2 v2))
38629 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
38630
38631 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
38632 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38633 const Type c = covov->t0();
38634 const Type& v1 = covov->t1();
38635 const Type& v2 = covov->t2();
38636 const details::operator_type o0 = operation;
38637 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
38638 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
38639
38640 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38641 binary_functor_t f1 = covov->f0();
38642 binary_functor_t f2 = covov->f1();
38643
38644 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38645
38646 expression_node_ptr result = error_node();
38647
38648 const bool synthesis_result =
38649 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38650 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38651
38652 if (synthesis_result)
38653 return result;
38654 else if (!expr_gen.valid_operator(o0,f0))
38655 return error_node();
38656
38657 exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n"));
38658
38659 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38660 }
38661
38662 static inline std::string id(expression_generator<Type>& expr_gen,
38663 const details::operator_type o0,
38664 const details::operator_type o1,
38665 const details::operator_type o2)
38666 {
38667 return details::build_string()
38668 << "t" << expr_gen.to_str(o0)
38669 << "(t" << expr_gen.to_str(o1)
38670 << "(t" << expr_gen.to_str(o2)
38671 << "t))";
38672 }
38673 };
38674
38675 struct synthesize_covovov_expression1
38676 {
38677 typedef typename covovov_t::type1 node_type;
38678 typedef typename covovov_t::sf4_type sf4_type;
38679 typedef typename node_type::T0 T0;
38680 typedef typename node_type::T1 T1;
38681 typedef typename node_type::T2 T2;
38682 typedef typename node_type::T3 T3;
38683
38684 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38685 const details::operator_type& operation,
38686 expression_node_ptr (&branch)[2])
38687 {
38688 // c o0 (v0 o1 (v1 o2 v2))
38689 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38690
38691 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38692 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
38693 const Type& v0 = vovov->t0();
38694 const Type& v1 = vovov->t1();
38695 const Type& v2 = vovov->t2();
38696 const details::operator_type o0 = operation;
38697 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
38698 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
38699
38700 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38701 binary_functor_t f1 = vovov->f0();
38702 binary_functor_t f2 = vovov->f1();
38703
38704 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38705 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38706
38707 expression_node_ptr result = error_node();
38708
38709 const bool synthesis_result =
38710 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38711 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38712
38713 if (synthesis_result)
38714 return result;
38715 if (!expr_gen.valid_operator(o0,f0))
38716 return error_node();
38717
38718 exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n"));
38719
38720 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38721 }
38722
38723 static inline std::string id(expression_generator<Type>& expr_gen,
38724 const details::operator_type o0,
38725 const details::operator_type o1,
38726 const details::operator_type o2)
38727 {
38728 return details::build_string()
38729 << "t" << expr_gen.to_str(o0)
38730 << "(t" << expr_gen.to_str(o1)
38731 << "(t" << expr_gen.to_str(o2)
38732 << "t))";
38733 }
38734 };
38735
38736 struct synthesize_covocov_expression1
38737 {
38738 typedef typename covocov_t::type1 node_type;
38739 typedef typename covocov_t::sf4_type sf4_type;
38740 typedef typename node_type::T0 T0;
38741 typedef typename node_type::T1 T1;
38742 typedef typename node_type::T2 T2;
38743 typedef typename node_type::T3 T3;
38744
38745 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38746 const details::operator_type& operation,
38747 expression_node_ptr (&branch)[2])
38748 {
38749 // c0 o0 (v0 o1 (c1 o2 v1))
38750 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38751
38752 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
38753 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
38754 const Type& v0 = vocov->t0();
38755 const Type c1 = vocov->t1();
38756 const Type& v1 = vocov->t2();
38757 const details::operator_type o0 = operation;
38758 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
38759 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
38760
38761 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38762 binary_functor_t f1 = vocov->f0();
38763 binary_functor_t f2 = vocov->f1();
38764
38765 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38766 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38767
38768 expression_node_ptr result = error_node();
38769
38770 const bool synthesis_result =
38771 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38772 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
38773
38774 if (synthesis_result)
38775 return result;
38776 else if (!expr_gen.valid_operator(o0,f0))
38777 return error_node();
38778
38779 exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n"));
38780
38781 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38782 }
38783
38784 static inline std::string id(expression_generator<Type>& expr_gen,
38785 const details::operator_type o0,
38786 const details::operator_type o1,
38787 const details::operator_type o2)
38788 {
38789 return details::build_string()
38790 << "t" << expr_gen.to_str(o0)
38791 << "(t" << expr_gen.to_str(o1)
38792 << "(t" << expr_gen.to_str(o2)
38793 << "t))";
38794 }
38795 };
38796
38797 struct synthesize_vocovoc_expression1
38798 {
38799 typedef typename vocovoc_t::type1 node_type;
38800 typedef typename vocovoc_t::sf4_type sf4_type;
38801 typedef typename node_type::T0 T0;
38802 typedef typename node_type::T1 T1;
38803 typedef typename node_type::T2 T2;
38804 typedef typename node_type::T3 T3;
38805
38806 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38807 const details::operator_type& operation,
38808 expression_node_ptr (&branch)[2])
38809 {
38810 // v0 o0 (c0 o1 (v1 o2 c2))
38811 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
38812
38813 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
38814 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38815 const Type c0 = covoc->t0();
38816 const Type& v1 = covoc->t1();
38817 const Type c1 = covoc->t2();
38818 const details::operator_type o0 = operation;
38819 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
38820 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
38821
38822 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38823 binary_functor_t f1 = covoc->f0();
38824 binary_functor_t f2 = covoc->f1();
38825
38826 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38827
38828 expression_node_ptr result = error_node();
38829
38830 const bool synthesis_result =
38831 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38832 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38833
38834 if (synthesis_result)
38835 return result;
38836 else if (!expr_gen.valid_operator(o0,f0))
38837 return error_node();
38838
38839 exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n"));
38840
38841 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38842 }
38843
38844 static inline std::string id(expression_generator<Type>& expr_gen,
38845 const details::operator_type o0,
38846 const details::operator_type o1,
38847 const details::operator_type o2)
38848 {
38849 return details::build_string()
38850 << "t" << expr_gen.to_str(o0)
38851 << "(t" << expr_gen.to_str(o1)
38852 << "(t" << expr_gen.to_str(o2)
38853 << "t))";
38854 }
38855 };
38856
38857 struct synthesize_covovoc_expression1
38858 {
38859 typedef typename covovoc_t::type1 node_type;
38860 typedef typename covovoc_t::sf4_type sf4_type;
38861 typedef typename node_type::T0 T0;
38862 typedef typename node_type::T1 T1;
38863 typedef typename node_type::T2 T2;
38864 typedef typename node_type::T3 T3;
38865 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38866 const details::operator_type& operation,
38867 expression_node_ptr (&branch)[2])
38868 {
38869 // c0 o0 (v0 o1 (v1 o2 c1))
38870 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38871
38872 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38873 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
38874 const Type& v0 = vovoc->t0();
38875 const Type& v1 = vovoc->t1();
38876 const Type c1 = vovoc->t2();
38877 const details::operator_type o0 = operation;
38878 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38879 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38880
38881 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38882 binary_functor_t f1 = vovoc->f0();
38883 binary_functor_t f2 = vovoc->f1();
38884
38885 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38886 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38887
38888 expression_node_ptr result = error_node();
38889
38890 const bool synthesis_result =
38891 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38892 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38893
38894 if (synthesis_result)
38895 return result;
38896 else if (!expr_gen.valid_operator(o0,f0))
38897 return error_node();
38898
38899 exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n"));
38900
38901 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38902 }
38903
38904 static inline std::string id(expression_generator<Type>& expr_gen,
38905 const details::operator_type o0,
38906 const details::operator_type o1,
38907 const details::operator_type o2)
38908 {
38909 return details::build_string()
38910 << "t" << expr_gen.to_str(o0)
38911 << "(t" << expr_gen.to_str(o1)
38912 << "(t" << expr_gen.to_str(o2)
38913 << "t))";
38914 }
38915 };
38916
38917 struct synthesize_vococov_expression1
38918 {
38919 typedef typename vococov_t::type1 node_type;
38920 typedef typename vococov_t::sf4_type sf4_type;
38921 typedef typename node_type::T0 T0;
38922 typedef typename node_type::T1 T1;
38923 typedef typename node_type::T2 T2;
38924 typedef typename node_type::T3 T3;
38925
38926 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38927 const details::operator_type& operation,
38928 expression_node_ptr (&branch)[2])
38929 {
38930 // v0 o0 (c0 o1 (c1 o2 v1))
38931 typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
38932
38933 const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
38934 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38935 const Type c0 = cocov->t0();
38936 const Type c1 = cocov->t1();
38937 const Type& v1 = cocov->t2();
38938 const details::operator_type o0 = operation;
38939 const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
38940 const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
38941
38942 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38943 binary_functor_t f1 = cocov->f0();
38944 binary_functor_t f2 = cocov->f1();
38945
38946 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38947
38948 expression_node_ptr result = error_node();
38949
38950 const bool synthesis_result =
38951 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38952 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38953
38954 if (synthesis_result)
38955 return result;
38956 else if (!expr_gen.valid_operator(o0,f0))
38957 return error_node();
38958
38959 exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n"));
38960
38961 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38962 }
38963
38964 static inline std::string id(expression_generator<Type>& expr_gen,
38965 const details::operator_type o0,
38966 const details::operator_type o1,
38967 const details::operator_type o2)
38968 {
38969 return details::build_string()
38970 << "t" << expr_gen.to_str(o0)
38971 << "(t" << expr_gen.to_str(o1)
38972 << "(t" << expr_gen.to_str(o2)
38973 << "t))";
38974 }
38975 };
38976
38977 struct synthesize_vovovov_expression2
38978 {
38979 typedef typename vovovov_t::type2 node_type;
38980 typedef typename vovovov_t::sf4_type sf4_type;
38981 typedef typename node_type::T0 T0;
38982 typedef typename node_type::T1 T1;
38983 typedef typename node_type::T2 T2;
38984 typedef typename node_type::T3 T3;
38985
38986 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
38987 const details::operator_type& operation,
38988 expression_node_ptr (&branch)[2])
38989 {
38990 // v0 o0 ((v1 o1 v2) o2 v3)
38991 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38992
38993 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38994 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38995 const Type& v1 = vovov->t0();
38996 const Type& v2 = vovov->t1();
38997 const Type& v3 = vovov->t2();
38998 const details::operator_type o0 = operation;
38999 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
39000 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
39001
39002 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39003 binary_functor_t f1 = vovov->f0();
39004 binary_functor_t f2 = vovov->f1();
39005
39006 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39007
39008 expression_node_ptr result = error_node();
39009
39010 const bool synthesis_result =
39011 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39012 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
39013
39014 if (synthesis_result)
39015 return result;
39016 else if (!expr_gen.valid_operator(o0,f0))
39017 return error_node();
39018
39019 exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n"));
39020
39021 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
39022 }
39023
39024 static inline std::string id(expression_generator<Type>& expr_gen,
39025 const details::operator_type o0,
39026 const details::operator_type o1,
39027 const details::operator_type o2)
39028 {
39029 return details::build_string()
39030 << "t" << expr_gen.to_str(o0)
39031 << "((t" << expr_gen.to_str(o1)
39032 << "t)" << expr_gen.to_str(o2)
39033 << "t)";
39034 }
39035 };
39036
39037 struct synthesize_vovovoc_expression2
39038 {
39039 typedef typename vovovoc_t::type2 node_type;
39040 typedef typename vovovoc_t::sf4_type sf4_type;
39041 typedef typename node_type::T0 T0;
39042 typedef typename node_type::T1 T1;
39043 typedef typename node_type::T2 T2;
39044 typedef typename node_type::T3 T3;
39045
39046 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39047 const details::operator_type& operation,
39048 expression_node_ptr (&branch)[2])
39049 {
39050 // v0 o0 ((v1 o1 v2) o2 c)
39051 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39052
39053 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
39054 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39055 const Type& v1 = vovoc->t0();
39056 const Type& v2 = vovoc->t1();
39057 const Type c = vovoc->t2();
39058 const details::operator_type o0 = operation;
39059 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
39060 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
39061
39062 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39063 binary_functor_t f1 = vovoc->f0();
39064 binary_functor_t f2 = vovoc->f1();
39065
39066 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39067
39068 expression_node_ptr result = error_node();
39069
39070 const bool synthesis_result =
39071 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39072 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
39073
39074 if (synthesis_result)
39075 return result;
39076 else if (!expr_gen.valid_operator(o0,f0))
39077 return error_node();
39078
39079 exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n"));
39080
39081 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
39082 }
39083
39084 static inline std::string id(expression_generator<Type>& expr_gen,
39085 const details::operator_type o0,
39086 const details::operator_type o1,
39087 const details::operator_type o2)
39088 {
39089 return details::build_string()
39090 << "t" << expr_gen.to_str(o0)
39091 << "((t" << expr_gen.to_str(o1)
39092 << "t)" << expr_gen.to_str(o2)
39093 << "t)";
39094 }
39095 };
39096
39097 struct synthesize_vovocov_expression2
39098 {
39099 typedef typename vovocov_t::type2 node_type;
39100 typedef typename vovocov_t::sf4_type sf4_type;
39101 typedef typename node_type::T0 T0;
39102 typedef typename node_type::T1 T1;
39103 typedef typename node_type::T2 T2;
39104 typedef typename node_type::T3 T3;
39105
39106 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39107 const details::operator_type& operation,
39108 expression_node_ptr (&branch)[2])
39109 {
39110 // v0 o0 ((v1 o1 c) o2 v2)
39111 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39112
39113 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
39114 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39115 const Type& v1 = vocov->t0();
39116 const Type c = vocov->t1();
39117 const Type& v2 = vocov->t2();
39118 const details::operator_type o0 = operation;
39119 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
39120 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
39121
39122 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39123 binary_functor_t f1 = vocov->f0();
39124 binary_functor_t f2 = vocov->f1();
39125
39126 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39127
39128 expression_node_ptr result = error_node();
39129
39130 const bool synthesis_result =
39131 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39132 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
39133
39134 if (synthesis_result)
39135 return result;
39136 else if (!expr_gen.valid_operator(o0,f0))
39137 return error_node();
39138
39139 exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n"));
39140
39141 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
39142 }
39143
39144 static inline std::string id(expression_generator<Type>& expr_gen,
39145 const details::operator_type o0,
39146 const details::operator_type o1,
39147 const details::operator_type o2)
39148 {
39149 return details::build_string()
39150 << "t" << expr_gen.to_str(o0)
39151 << "((t" << expr_gen.to_str(o1)
39152 << "t)" << expr_gen.to_str(o2)
39153 << "t)";
39154 }
39155 };
39156
39157 struct synthesize_vocovov_expression2
39158 {
39159 typedef typename vocovov_t::type2 node_type;
39160 typedef typename vocovov_t::sf4_type sf4_type;
39161 typedef typename node_type::T0 T0;
39162 typedef typename node_type::T1 T1;
39163 typedef typename node_type::T2 T2;
39164 typedef typename node_type::T3 T3;
39165
39166 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39167 const details::operator_type& operation,
39168 expression_node_ptr (&branch)[2])
39169 {
39170 // v0 o0 ((c o1 v1) o2 v2)
39171 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39172
39173 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
39174 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39175 const Type c = covov->t0();
39176 const Type& v1 = covov->t1();
39177 const Type& v2 = covov->t2();
39178 const details::operator_type o0 = operation;
39179 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
39180 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
39181
39182 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39183 binary_functor_t f1 = covov->f0();
39184 binary_functor_t f2 = covov->f1();
39185
39186 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39187
39188 expression_node_ptr result = error_node();
39189
39190 const bool synthesis_result =
39191 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39192 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
39193
39194 if (synthesis_result)
39195 return result;
39196 else if (!expr_gen.valid_operator(o0,f0))
39197 return error_node();
39198
39199 exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n"));
39200
39201 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
39202 }
39203
39204 static inline std::string id(expression_generator<Type>& expr_gen,
39205 const details::operator_type o0,
39206 const details::operator_type o1,
39207 const details::operator_type o2)
39208 {
39209 return details::build_string()
39210 << "t" << expr_gen.to_str(o0)
39211 << "((t" << expr_gen.to_str(o1)
39212 << "t)" << expr_gen.to_str(o2)
39213 << "t)";
39214 }
39215 };
39216
39217 struct synthesize_covovov_expression2
39218 {
39219 typedef typename covovov_t::type2 node_type;
39220 typedef typename covovov_t::sf4_type sf4_type;
39221 typedef typename node_type::T0 T0;
39222 typedef typename node_type::T1 T1;
39223 typedef typename node_type::T2 T2;
39224 typedef typename node_type::T3 T3;
39225
39226 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39227 const details::operator_type& operation,
39228 expression_node_ptr (&branch)[2])
39229 {
39230 // c o0 ((v1 o1 v2) o2 v3)
39231 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39232
39233 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
39234 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
39235 const Type& v0 = vovov->t0();
39236 const Type& v1 = vovov->t1();
39237 const Type& v2 = vovov->t2();
39238 const details::operator_type o0 = operation;
39239 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
39240 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
39241
39242 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39243 binary_functor_t f1 = vovov->f0();
39244 binary_functor_t f2 = vovov->f1();
39245
39246 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39247 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39248
39249 expression_node_ptr result = error_node();
39250
39251 const bool synthesis_result =
39252 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39253 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
39254
39255 if (synthesis_result)
39256 return result;
39257 else if (!expr_gen.valid_operator(o0,f0))
39258 return error_node();
39259
39260 exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n"));
39261
39262 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
39263 }
39264
39265 static inline std::string id(expression_generator<Type>& expr_gen,
39266 const details::operator_type o0,
39267 const details::operator_type o1,
39268 const details::operator_type o2)
39269 {
39270 return details::build_string()
39271 << "t" << expr_gen.to_str(o0)
39272 << "((t" << expr_gen.to_str(o1)
39273 << "t)" << expr_gen.to_str(o2)
39274 << "t)";
39275 }
39276 };
39277
39278 struct synthesize_covocov_expression2
39279 {
39280 typedef typename covocov_t::type2 node_type;
39281 typedef typename covocov_t::sf4_type sf4_type;
39282 typedef typename node_type::T0 T0;
39283 typedef typename node_type::T1 T1;
39284 typedef typename node_type::T2 T2;
39285 typedef typename node_type::T3 T3;
39286
39287 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39288 const details::operator_type& operation,
39289 expression_node_ptr (&branch)[2])
39290 {
39291 // c0 o0 ((v0 o1 c1) o2 v1)
39292 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39293
39294 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
39295 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
39296 const Type& v0 = vocov->t0();
39297 const Type c1 = vocov->t1();
39298 const Type& v1 = vocov->t2();
39299 const details::operator_type o0 = operation;
39300 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
39301 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
39302
39303 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39304 binary_functor_t f1 = vocov->f0();
39305 binary_functor_t f2 = vocov->f1();
39306
39307 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39308 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39309
39310 expression_node_ptr result = error_node();
39311
39312 const bool synthesis_result =
39313 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39314 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
39315
39316 if (synthesis_result)
39317 return result;
39318 else if (!expr_gen.valid_operator(o0,f0))
39319 return error_node();
39320
39321 exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n"));
39322
39323 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
39324 }
39325
39326 static inline std::string id(expression_generator<Type>& expr_gen,
39327 const details::operator_type o0,
39328 const details::operator_type o1,
39329 const details::operator_type o2)
39330 {
39331 return details::build_string()
39332 << "t" << expr_gen.to_str(o0)
39333 << "((t" << expr_gen.to_str(o1)
39334 << "t)" << expr_gen.to_str(o2)
39335 << "t)";
39336 }
39337 };
39338
39339 struct synthesize_vocovoc_expression2
39340 {
39341 typedef typename vocovoc_t::type2 node_type;
39342 typedef typename vocovoc_t::sf4_type sf4_type;
39343 typedef typename node_type::T0 T0;
39344 typedef typename node_type::T1 T1;
39345 typedef typename node_type::T2 T2;
39346 typedef typename node_type::T3 T3;
39347
39348 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39349 const details::operator_type& operation,
39350 expression_node_ptr (&branch)[2])
39351 {
39352 // v0 o0 ((c0 o1 v1) o2 c1)
39353 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
39354
39355 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
39356 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39357 const Type c0 = covoc->t0();
39358 const Type& v1 = covoc->t1();
39359 const Type c1 = covoc->t2();
39360 const details::operator_type o0 = operation;
39361 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
39362 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
39363
39364 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39365 binary_functor_t f1 = covoc->f0();
39366 binary_functor_t f2 = covoc->f1();
39367
39368 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39369
39370 expression_node_ptr result = error_node();
39371
39372 const bool synthesis_result =
39373 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39374 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39375
39376 if (synthesis_result)
39377 return result;
39378 else if (!expr_gen.valid_operator(o0,f0))
39379 return error_node();
39380
39381 exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n"));
39382
39383 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39384 }
39385
39386 static inline std::string id(expression_generator<Type>& expr_gen,
39387 const details::operator_type o0,
39388 const details::operator_type o1,
39389 const details::operator_type o2)
39390 {
39391 return details::build_string()
39392 << "t" << expr_gen.to_str(o0)
39393 << "((t" << expr_gen.to_str(o1)
39394 << "t)" << expr_gen.to_str(o2)
39395 << "t)";
39396 }
39397 };
39398
39399 struct synthesize_covovoc_expression2
39400 {
39401 typedef typename covovoc_t::type2 node_type;
39402 typedef typename covovoc_t::sf4_type sf4_type;
39403 typedef typename node_type::T0 T0;
39404 typedef typename node_type::T1 T1;
39405 typedef typename node_type::T2 T2;
39406 typedef typename node_type::T3 T3;
39407
39408 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39409 const details::operator_type& operation,
39410 expression_node_ptr (&branch)[2])
39411 {
39412 // c0 o0 ((v0 o1 v1) o2 c1)
39413 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39414
39415 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
39416 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
39417 const Type& v0 = vovoc->t0();
39418 const Type& v1 = vovoc->t1();
39419 const Type c1 = vovoc->t2();
39420 const details::operator_type o0 = operation;
39421 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
39422 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
39423
39424 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39425 binary_functor_t f1 = vovoc->f0();
39426 binary_functor_t f2 = vovoc->f1();
39427
39428 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39429 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39430
39431 expression_node_ptr result = error_node();
39432
39433 const bool synthesis_result =
39434 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39435 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39436
39437 if (synthesis_result)
39438 return result;
39439 else if (!expr_gen.valid_operator(o0,f0))
39440 return error_node();
39441
39442 exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n"));
39443
39444 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39445 }
39446
39447 static inline std::string id(expression_generator<Type>& expr_gen,
39448 const details::operator_type o0,
39449 const details::operator_type o1,
39450 const details::operator_type o2)
39451 {
39452 return details::build_string()
39453 << "t" << expr_gen.to_str(o0)
39454 << "((t" << expr_gen.to_str(o1)
39455 << "t)" << expr_gen.to_str(o2)
39456 << "t)";
39457 }
39458 };
39459
39460 struct synthesize_vococov_expression2
39461 {
39462 typedef typename vococov_t::type2 node_type;
39463 static inline expression_node_ptr process(expression_generator<Type>&,
39464 const details::operator_type&,
39465 expression_node_ptr (&)[2])
39466 {
39467 // v0 o0 ((c0 o1 c1) o2 v1) - Not possible
39468 exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
39469 return error_node();
39470 }
39471
39472 static inline std::string id(expression_generator<Type>&,
39473 const details::operator_type,
39474 const details::operator_type,
39475 const details::operator_type)
39476 {
39477 return "INVALID";
39478 }
39479 };
39480
39481 struct synthesize_vovovov_expression3
39482 {
39483 typedef typename vovovov_t::type3 node_type;
39484 typedef typename vovovov_t::sf4_type sf4_type;
39485 typedef typename node_type::T0 T0;
39486 typedef typename node_type::T1 T1;
39487 typedef typename node_type::T2 T2;
39488 typedef typename node_type::T3 T3;
39489
39490 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39491 const details::operator_type& operation,
39492 expression_node_ptr (&branch)[2])
39493 {
39494 // ((v0 o0 v1) o1 v2) o2 v3
39495 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39496
39497 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
39498 const Type& v0 = vovov->t0();
39499 const Type& v1 = vovov->t1();
39500 const Type& v2 = vovov->t2();
39501 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39502 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
39503 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
39504 const details::operator_type o2 = operation;
39505
39506 binary_functor_t f0 = vovov->f0();
39507 binary_functor_t f1 = vovov->f1();
39508 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39509
39510 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39511
39512 expression_node_ptr result = error_node();
39513
39514 const bool synthesis_result =
39515 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39516 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
39517
39518 if (synthesis_result)
39519 return result;
39520 else if (!expr_gen.valid_operator(o2,f2))
39521 return error_node();
39522
39523 exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n"));
39524
39525 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
39526 }
39527
39528 static inline std::string id(expression_generator<Type>& expr_gen,
39529 const details::operator_type o0,
39530 const details::operator_type o1,
39531 const details::operator_type o2)
39532 {
39533 return details::build_string()
39534 << "((t" << expr_gen.to_str(o0)
39535 << "t)" << expr_gen.to_str(o1)
39536 << "t)" << expr_gen.to_str(o2)
39537 << "t";
39538 }
39539 };
39540
39541 struct synthesize_vovovoc_expression3
39542 {
39543 typedef typename vovovoc_t::type3 node_type;
39544 typedef typename vovovoc_t::sf4_type sf4_type;
39545 typedef typename node_type::T0 T0;
39546 typedef typename node_type::T1 T1;
39547 typedef typename node_type::T2 T2;
39548 typedef typename node_type::T3 T3;
39549
39550 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39551 const details::operator_type& operation,
39552 expression_node_ptr (&branch)[2])
39553 {
39554 // ((v0 o0 v1) o1 v2) o2 c
39555 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39556
39557 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
39558 const Type& v0 = vovov->t0();
39559 const Type& v1 = vovov->t1();
39560 const Type& v2 = vovov->t2();
39561 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
39562 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
39563 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
39564 const details::operator_type o2 = operation;
39565
39566 binary_functor_t f0 = vovov->f0();
39567 binary_functor_t f1 = vovov->f1();
39568 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39569
39570 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39571 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39572
39573 expression_node_ptr result = error_node();
39574
39575 const bool synthesis_result =
39576 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39577 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
39578
39579 if (synthesis_result)
39580 return result;
39581 else if (!expr_gen.valid_operator(o2,f2))
39582 return error_node();
39583
39584 exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n"));
39585
39586 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
39587 }
39588
39589 static inline std::string id(expression_generator<Type>& expr_gen,
39590 const details::operator_type o0,
39591 const details::operator_type o1,
39592 const details::operator_type o2)
39593 {
39594 return details::build_string()
39595 << "((t" << expr_gen.to_str(o0)
39596 << "t)" << expr_gen.to_str(o1)
39597 << "t)" << expr_gen.to_str(o2)
39598 << "t";
39599 }
39600 };
39601
39602 struct synthesize_vovocov_expression3
39603 {
39604 typedef typename vovocov_t::type3 node_type;
39605 typedef typename vovocov_t::sf4_type sf4_type;
39606 typedef typename node_type::T0 T0;
39607 typedef typename node_type::T1 T1;
39608 typedef typename node_type::T2 T2;
39609 typedef typename node_type::T3 T3;
39610
39611 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39612 const details::operator_type& operation,
39613 expression_node_ptr (&branch)[2])
39614 {
39615 // ((v0 o0 v1) o1 c) o2 v2
39616 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39617
39618 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
39619 const Type& v0 = vovoc->t0();
39620 const Type& v1 = vovoc->t1();
39621 const Type c = vovoc->t2();
39622 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39623 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
39624 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
39625 const details::operator_type o2 = operation;
39626
39627 binary_functor_t f0 = vovoc->f0();
39628 binary_functor_t f1 = vovoc->f1();
39629 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39630
39631 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39632
39633 expression_node_ptr result = error_node();
39634
39635 const bool synthesis_result =
39636 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39637 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
39638
39639 if (synthesis_result)
39640 return result;
39641 else if (!expr_gen.valid_operator(o2,f2))
39642 return error_node();
39643
39644 exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n"));
39645
39646 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
39647 }
39648
39649 static inline std::string id(expression_generator<Type>& expr_gen,
39650 const details::operator_type o0,
39651 const details::operator_type o1,
39652 const details::operator_type o2)
39653 {
39654 return details::build_string()
39655 << "((t" << expr_gen.to_str(o0)
39656 << "t)" << expr_gen.to_str(o1)
39657 << "t)" << expr_gen.to_str(o2)
39658 << "t";
39659 }
39660 };
39661
39662 struct synthesize_vocovov_expression3
39663 {
39664 typedef typename vocovov_t::type3 node_type;
39665 typedef typename vocovov_t::sf4_type sf4_type;
39666 typedef typename node_type::T0 T0;
39667 typedef typename node_type::T1 T1;
39668 typedef typename node_type::T2 T2;
39669 typedef typename node_type::T3 T3;
39670
39671 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39672 const details::operator_type& operation,
39673 expression_node_ptr (&branch)[2])
39674 {
39675 // ((v0 o0 c) o1 v1) o2 v2
39676 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39677
39678 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
39679 const Type& v0 = vocov->t0();
39680 const Type c = vocov->t1();
39681 const Type& v1 = vocov->t2();
39682 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39683 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
39684 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
39685 const details::operator_type o2 = operation;
39686
39687 binary_functor_t f0 = vocov->f0();
39688 binary_functor_t f1 = vocov->f1();
39689 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39690
39691 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39692
39693 expression_node_ptr result = error_node();
39694
39695 const bool synthesis_result =
39696 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39697 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
39698
39699 if (synthesis_result)
39700 return result;
39701 else if (!expr_gen.valid_operator(o2,f2))
39702 return error_node();
39703
39704 exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n"));
39705
39706 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
39707 }
39708
39709 static inline std::string id(expression_generator<Type>& expr_gen,
39710 const details::operator_type o0,
39711 const details::operator_type o1,
39712 const details::operator_type o2)
39713 {
39714 return details::build_string()
39715 << "((t" << expr_gen.to_str(o0)
39716 << "t)" << expr_gen.to_str(o1)
39717 << "t)" << expr_gen.to_str(o2)
39718 << "t";
39719 }
39720 };
39721
39722 struct synthesize_covovov_expression3
39723 {
39724 typedef typename covovov_t::type3 node_type;
39725 typedef typename covovov_t::sf4_type sf4_type;
39726 typedef typename node_type::T0 T0;
39727 typedef typename node_type::T1 T1;
39728 typedef typename node_type::T2 T2;
39729 typedef typename node_type::T3 T3;
39730
39731 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39732 const details::operator_type& operation,
39733 expression_node_ptr (&branch)[2])
39734 {
39735 // ((c o0 v0) o1 v1) o2 v2
39736 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39737
39738 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39739 const Type c = covov->t0();
39740 const Type& v0 = covov->t1();
39741 const Type& v1 = covov->t2();
39742 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39743 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39744 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39745 const details::operator_type o2 = operation;
39746
39747 binary_functor_t f0 = covov->f0();
39748 binary_functor_t f1 = covov->f1();
39749 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39750
39751 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39752
39753 expression_node_ptr result = error_node();
39754
39755 const bool synthesis_result =
39756 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39757 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
39758
39759 if (synthesis_result)
39760 return result;
39761 else if (!expr_gen.valid_operator(o2,f2))
39762 return error_node();
39763
39764 exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n"));
39765
39766 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
39767 }
39768
39769 static inline std::string id(expression_generator<Type>& expr_gen,
39770 const details::operator_type o0,
39771 const details::operator_type o1,
39772 const details::operator_type o2)
39773 {
39774 return details::build_string()
39775 << "((t" << expr_gen.to_str(o0)
39776 << "t)" << expr_gen.to_str(o1)
39777 << "t)" << expr_gen.to_str(o2)
39778 << "t";
39779 }
39780 };
39781
39782 struct synthesize_covocov_expression3
39783 {
39784 typedef typename covocov_t::type3 node_type;
39785 typedef typename covocov_t::sf4_type sf4_type;
39786 typedef typename node_type::T0 T0;
39787 typedef typename node_type::T1 T1;
39788 typedef typename node_type::T2 T2;
39789 typedef typename node_type::T3 T3;
39790
39791 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39792 const details::operator_type& operation,
39793 expression_node_ptr (&branch)[2])
39794 {
39795 // ((c0 o0 v0) o1 c1) o2 v1
39796 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
39797
39798 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
39799 const Type c0 = covoc->t0();
39800 const Type& v0 = covoc->t1();
39801 const Type c1 = covoc->t2();
39802 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39803 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
39804 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
39805 const details::operator_type o2 = operation;
39806
39807 binary_functor_t f0 = covoc->f0();
39808 binary_functor_t f1 = covoc->f1();
39809 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39810
39811 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39812
39813 expression_node_ptr result = error_node();
39814
39815 const bool synthesis_result =
39816 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39817 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
39818
39819 if (synthesis_result)
39820 return result;
39821 else if (!expr_gen.valid_operator(o2,f2))
39822 return error_node();
39823
39824 exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n"));
39825
39826 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
39827 }
39828
39829 static inline std::string id(expression_generator<Type>& expr_gen,
39830 const details::operator_type o0,
39831 const details::operator_type o1,
39832 const details::operator_type o2)
39833 {
39834 return details::build_string()
39835 << "((t" << expr_gen.to_str(o0)
39836 << "t)" << expr_gen.to_str(o1)
39837 << "t)" << expr_gen.to_str(o2)
39838 << "t";
39839 }
39840 };
39841
39842 struct synthesize_vocovoc_expression3
39843 {
39844 typedef typename vocovoc_t::type3 node_type;
39845 typedef typename vocovoc_t::sf4_type sf4_type;
39846 typedef typename node_type::T0 T0;
39847 typedef typename node_type::T1 T1;
39848 typedef typename node_type::T2 T2;
39849 typedef typename node_type::T3 T3;
39850
39851 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39852 const details::operator_type& operation,
39853 expression_node_ptr (&branch)[2])
39854 {
39855 // ((v0 o0 c0) o1 v1) o2 c1
39856 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39857
39858 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
39859 const Type& v0 = vocov->t0();
39860 const Type c0 = vocov->t1();
39861 const Type& v1 = vocov->t2();
39862 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
39863 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
39864 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
39865 const details::operator_type o2 = operation;
39866
39867 binary_functor_t f0 = vocov->f0();
39868 binary_functor_t f1 = vocov->f1();
39869 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39870
39871 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39872 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39873
39874 expression_node_ptr result = error_node();
39875
39876 const bool synthesis_result =
39877 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39878 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39879
39880 if (synthesis_result)
39881 return result;
39882 else if (!expr_gen.valid_operator(o2,f2))
39883 return error_node();
39884
39885 exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n"));
39886
39887 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39888 }
39889
39890 static inline std::string id(expression_generator<Type>& expr_gen,
39891 const details::operator_type o0,
39892 const details::operator_type o1,
39893 const details::operator_type o2)
39894 {
39895 return details::build_string()
39896 << "((t" << expr_gen.to_str(o0)
39897 << "t)" << expr_gen.to_str(o1)
39898 << "t)" << expr_gen.to_str(o2)
39899 << "t";
39900 }
39901 };
39902
39903 struct synthesize_covovoc_expression3
39904 {
39905 typedef typename covovoc_t::type3 node_type;
39906 typedef typename covovoc_t::sf4_type sf4_type;
39907 typedef typename node_type::T0 T0;
39908 typedef typename node_type::T1 T1;
39909 typedef typename node_type::T2 T2;
39910 typedef typename node_type::T3 T3;
39911
39912 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39913 const details::operator_type& operation,
39914 expression_node_ptr (&branch)[2])
39915 {
39916 // ((c0 o0 v0) o1 v1) o2 c1
39917 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39918
39919 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39920 const Type c0 = covov->t0();
39921 const Type& v0 = covov->t1();
39922 const Type& v1 = covov->t2();
39923 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
39924 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39925 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39926 const details::operator_type o2 = operation;
39927
39928 binary_functor_t f0 = covov->f0();
39929 binary_functor_t f1 = covov->f1();
39930 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39931
39932 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39933 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39934
39935 expression_node_ptr result = error_node();
39936
39937 const bool synthesis_result =
39938 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39939 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39940
39941 if (synthesis_result)
39942 return result;
39943 else if (!expr_gen.valid_operator(o2,f2))
39944 return error_node();
39945
39946 exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n"));
39947
39948 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39949 }
39950
39951 static inline std::string id(expression_generator<Type>& expr_gen,
39952 const details::operator_type o0,
39953 const details::operator_type o1,
39954 const details::operator_type o2)
39955 {
39956 return details::build_string()
39957 << "((t" << expr_gen.to_str(o0)
39958 << "t)" << expr_gen.to_str(o1)
39959 << "t)" << expr_gen.to_str(o2)
39960 << "t";
39961 }
39962 };
39963
39964 struct synthesize_vococov_expression3
39965 {
39966 typedef typename vococov_t::type3 node_type;
39967 typedef typename vococov_t::sf4_type sf4_type;
39968 typedef typename node_type::T0 T0;
39969 typedef typename node_type::T1 T1;
39970 typedef typename node_type::T2 T2;
39971 typedef typename node_type::T3 T3;
39972
39973 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
39974 const details::operator_type& operation,
39975 expression_node_ptr (&branch)[2])
39976 {
39977 // ((v0 o0 c0) o1 c1) o2 v1
39978 typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
39979
39980 const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
39981 const Type& v0 = vococ->t0();
39982 const Type c0 = vococ->t1();
39983 const Type c1 = vococ->t2();
39984 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39985 const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
39986 const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
39987 const details::operator_type o2 = operation;
39988
39989 binary_functor_t f0 = vococ->f0();
39990 binary_functor_t f1 = vococ->f1();
39991 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39992
39993 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39994
39995 expression_node_ptr result = error_node();
39996
39997 const bool synthesis_result =
39998 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39999 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
40000
40001 if (synthesis_result)
40002 return result;
40003 else if (!expr_gen.valid_operator(o2,f2))
40004 return error_node();
40005
40006 exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n"));
40007
40008 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
40009 }
40010
40011 static inline std::string id(expression_generator<Type>& expr_gen,
40012 const details::operator_type o0,
40013 const details::operator_type o1,
40014 const details::operator_type o2)
40015 {
40016 return details::build_string()
40017 << "((t" << expr_gen.to_str(o0)
40018 << "t)" << expr_gen.to_str(o1)
40019 << "t)" << expr_gen.to_str(o2)
40020 << "t";
40021 }
40022 };
40023
40024 struct synthesize_vovovov_expression4
40025 {
40026 typedef typename vovovov_t::type4 node_type;
40027 typedef typename vovovov_t::sf4_type sf4_type;
40028 typedef typename node_type::T0 T0;
40029 typedef typename node_type::T1 T1;
40030 typedef typename node_type::T2 T2;
40031 typedef typename node_type::T3 T3;
40032
40033 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40034 const details::operator_type& operation,
40035 expression_node_ptr (&branch)[2])
40036 {
40037 // (v0 o0 (v1 o1 v2)) o2 v3
40038 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
40039
40040 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
40041 const Type& v0 = vovov->t0();
40042 const Type& v1 = vovov->t1();
40043 const Type& v2 = vovov->t2();
40044 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40045 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
40046 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
40047 const details::operator_type o2 = operation;
40048
40049 binary_functor_t f0 = vovov->f0();
40050 binary_functor_t f1 = vovov->f1();
40051 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40052
40053 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40054
40055 expression_node_ptr result = error_node();
40056
40057 const bool synthesis_result =
40058 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40059 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
40060
40061 if (synthesis_result)
40062 return result;
40063 else if (!expr_gen.valid_operator(o2,f2))
40064 return error_node();
40065
40066 exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n"));
40067
40068 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
40069 }
40070
40071 static inline std::string id(expression_generator<Type>& expr_gen,
40072 const details::operator_type o0,
40073 const details::operator_type o1,
40074 const details::operator_type o2)
40075 {
40076 return details::build_string()
40077 << "(t" << expr_gen.to_str(o0)
40078 << "(t" << expr_gen.to_str(o1)
40079 << "t)" << expr_gen.to_str(o2)
40080 << "t";
40081 }
40082 };
40083
40084 struct synthesize_vovovoc_expression4
40085 {
40086 typedef typename vovovoc_t::type4 node_type;
40087 typedef typename vovovoc_t::sf4_type sf4_type;
40088 typedef typename node_type::T0 T0;
40089 typedef typename node_type::T1 T1;
40090 typedef typename node_type::T2 T2;
40091 typedef typename node_type::T3 T3;
40092
40093 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40094 const details::operator_type& operation,
40095 expression_node_ptr (&branch)[2])
40096 {
40097 // ((v0 o0 (v1 o1 v2)) o2 c)
40098 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
40099
40100 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
40101 const Type& v0 = vovov->t0();
40102 const Type& v1 = vovov->t1();
40103 const Type& v2 = vovov->t2();
40104 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
40105 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
40106 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
40107 const details::operator_type o2 = operation;
40108
40109 binary_functor_t f0 = vovov->f0();
40110 binary_functor_t f1 = vovov->f1();
40111 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40112
40113 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40114 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40115
40116 expression_node_ptr result = error_node();
40117
40118 const bool synthesis_result =
40119 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40120 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
40121
40122 if (synthesis_result)
40123 return result;
40124 else if (!expr_gen.valid_operator(o2,f2))
40125 return error_node();
40126
40127 exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n"));
40128
40129 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
40130 }
40131
40132 static inline std::string id(expression_generator<Type>& expr_gen,
40133 const details::operator_type o0,
40134 const details::operator_type o1,
40135 const details::operator_type o2)
40136 {
40137 return details::build_string()
40138 << "(t" << expr_gen.to_str(o0)
40139 << "(t" << expr_gen.to_str(o1)
40140 << "t)" << expr_gen.to_str(o2)
40141 << "t";
40142 }
40143 };
40144
40145 struct synthesize_vovocov_expression4
40146 {
40147 typedef typename vovocov_t::type4 node_type;
40148 typedef typename vovocov_t::sf4_type sf4_type;
40149 typedef typename node_type::T0 T0;
40150 typedef typename node_type::T1 T1;
40151 typedef typename node_type::T2 T2;
40152 typedef typename node_type::T3 T3;
40153
40154 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40155 const details::operator_type& operation,
40156 expression_node_ptr (&branch)[2])
40157 {
40158 // ((v0 o0 (v1 o1 c)) o2 v1)
40159 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
40160
40161 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
40162 const Type& v0 = vovoc->t0();
40163 const Type& v1 = vovoc->t1();
40164 const Type c = vovoc->t2();
40165 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40166 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
40167 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
40168 const details::operator_type o2 = operation;
40169
40170 binary_functor_t f0 = vovoc->f0();
40171 binary_functor_t f1 = vovoc->f1();
40172 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40173
40174 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40175
40176 expression_node_ptr result = error_node();
40177
40178 const bool synthesis_result =
40179 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40180 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
40181
40182 if (synthesis_result)
40183 return result;
40184 else if (!expr_gen.valid_operator(o2,f2))
40185 return error_node();
40186
40187 exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n"));
40188
40189 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
40190 }
40191
40192 static inline std::string id(expression_generator<Type>& expr_gen,
40193 const details::operator_type o0,
40194 const details::operator_type o1,
40195 const details::operator_type o2)
40196 {
40197 return details::build_string()
40198 << "(t" << expr_gen.to_str(o0)
40199 << "(t" << expr_gen.to_str(o1)
40200 << "t)" << expr_gen.to_str(o2)
40201 << "t";
40202 }
40203 };
40204
40205 struct synthesize_vocovov_expression4
40206 {
40207 typedef typename vocovov_t::type4 node_type;
40208 typedef typename vocovov_t::sf4_type sf4_type;
40209 typedef typename node_type::T0 T0;
40210 typedef typename node_type::T1 T1;
40211 typedef typename node_type::T2 T2;
40212 typedef typename node_type::T3 T3;
40213
40214 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40215 const details::operator_type& operation,
40216 expression_node_ptr (&branch)[2])
40217 {
40218 // ((v0 o0 (c o1 v1)) o2 v2)
40219 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
40220
40221 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
40222 const Type& v0 = vocov->t0();
40223 const Type c = vocov->t1();
40224 const Type& v1 = vocov->t2();
40225 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40226 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
40227 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
40228 const details::operator_type o2 = operation;
40229
40230 binary_functor_t f0 = vocov->f0();
40231 binary_functor_t f1 = vocov->f1();
40232 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40233
40234 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40235 expression_node_ptr result = error_node();
40236
40237 const bool synthesis_result =
40238 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40239 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
40240
40241 if (synthesis_result)
40242 return result;
40243 else if (!expr_gen.valid_operator(o2,f2))
40244 return error_node();
40245
40246 exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n"));
40247
40248 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
40249 }
40250
40251 static inline std::string id(expression_generator<Type>& expr_gen,
40252 const details::operator_type o0,
40253 const details::operator_type o1,
40254 const details::operator_type o2)
40255 {
40256 return details::build_string()
40257 << "(t" << expr_gen.to_str(o0)
40258 << "(t" << expr_gen.to_str(o1)
40259 << "t)" << expr_gen.to_str(o2)
40260 << "t";
40261 }
40262 };
40263
40264 struct synthesize_covovov_expression4
40265 {
40266 typedef typename covovov_t::type4 node_type;
40267 typedef typename covovov_t::sf4_type sf4_type;
40268 typedef typename node_type::T0 T0;
40269 typedef typename node_type::T1 T1;
40270 typedef typename node_type::T2 T2;
40271 typedef typename node_type::T3 T3;
40272
40273 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40274 const details::operator_type& operation,
40275 expression_node_ptr (&branch)[2])
40276 {
40277 // ((c o0 (v0 o1 v1)) o2 v2)
40278 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
40279
40280 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
40281 const Type c = covov->t0();
40282 const Type& v0 = covov->t1();
40283 const Type& v1 = covov->t2();
40284 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40285 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
40286 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
40287 const details::operator_type o2 = operation;
40288
40289 binary_functor_t f0 = covov->f0();
40290 binary_functor_t f1 = covov->f1();
40291 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40292
40293 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40294
40295 expression_node_ptr result = error_node();
40296
40297 const bool synthesis_result =
40298 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40299 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
40300
40301 if (synthesis_result)
40302 return result;
40303 else if (!expr_gen.valid_operator(o2,f2))
40304 return error_node();
40305
40306 exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n"));
40307
40308 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
40309 }
40310
40311 static inline std::string id(expression_generator<Type>& expr_gen,
40312 const details::operator_type o0,
40313 const details::operator_type o1,
40314 const details::operator_type o2)
40315 {
40316 return details::build_string()
40317 << "(t" << expr_gen.to_str(o0)
40318 << "(t" << expr_gen.to_str(o1)
40319 << "t)" << expr_gen.to_str(o2)
40320 << "t";
40321 }
40322 };
40323
40324 struct synthesize_covocov_expression4
40325 {
40326 typedef typename covocov_t::type4 node_type;
40327 typedef typename covocov_t::sf4_type sf4_type;
40328 typedef typename node_type::T0 T0;
40329 typedef typename node_type::T1 T1;
40330 typedef typename node_type::T2 T2;
40331 typedef typename node_type::T3 T3;
40332
40333 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40334 const details::operator_type& operation,
40335 expression_node_ptr (&branch)[2])
40336 {
40337 // ((c0 o0 (v0 o1 c1)) o2 v1)
40338 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
40339
40340 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
40341 const Type c0 = covoc->t0();
40342 const Type& v0 = covoc->t1();
40343 const Type c1 = covoc->t2();
40344 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40345 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
40346 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
40347 const details::operator_type o2 = operation;
40348
40349 binary_functor_t f0 = covoc->f0();
40350 binary_functor_t f1 = covoc->f1();
40351 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40352
40353 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40354
40355 expression_node_ptr result = error_node();
40356
40357 const bool synthesis_result =
40358 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40359 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
40360
40361 if (synthesis_result)
40362 return result;
40363 else if (!expr_gen.valid_operator(o2,f2))
40364 return error_node();
40365
40366 exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n"));
40367
40368 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
40369 }
40370
40371 static inline std::string id(expression_generator<Type>& expr_gen,
40372 const details::operator_type o0,
40373 const details::operator_type o1,
40374 const details::operator_type o2)
40375 {
40376 return details::build_string()
40377 << "(t" << expr_gen.to_str(o0)
40378 << "(t" << expr_gen.to_str(o1)
40379 << "t)" << expr_gen.to_str(o2)
40380 << "t";
40381 }
40382 };
40383
40384 struct synthesize_vocovoc_expression4
40385 {
40386 typedef typename vocovoc_t::type4 node_type;
40387 typedef typename vocovoc_t::sf4_type sf4_type;
40388 typedef typename node_type::T0 T0;
40389 typedef typename node_type::T1 T1;
40390 typedef typename node_type::T2 T2;
40391 typedef typename node_type::T3 T3;
40392
40393 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40394 const details::operator_type& operation,
40395 expression_node_ptr (&branch)[2])
40396 {
40397 // ((v0 o0 (c0 o1 v1)) o2 c1)
40398 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
40399
40400 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
40401 const Type& v0 = vocov->t0();
40402 const Type c0 = vocov->t1();
40403 const Type& v1 = vocov->t2();
40404 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
40405 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
40406 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
40407 const details::operator_type o2 = operation;
40408
40409 binary_functor_t f0 = vocov->f0();
40410 binary_functor_t f1 = vocov->f1();
40411 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40412
40413 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40414 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40415
40416 expression_node_ptr result = error_node();
40417
40418 const bool synthesis_result =
40419 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40420 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
40421
40422 if (synthesis_result)
40423 return result;
40424 else if (!expr_gen.valid_operator(o2,f2))
40425 return error_node();
40426
40427 exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n"));
40428
40429 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
40430 }
40431
40432 static inline std::string id(expression_generator<Type>& expr_gen,
40433 const details::operator_type o0,
40434 const details::operator_type o1,
40435 const details::operator_type o2)
40436 {
40437 return details::build_string()
40438 << "(t" << expr_gen.to_str(o0)
40439 << "(t" << expr_gen.to_str(o1)
40440 << "t)" << expr_gen.to_str(o2)
40441 << "t";
40442 }
40443 };
40444
40445 struct synthesize_covovoc_expression4
40446 {
40447 typedef typename covovoc_t::type4 node_type;
40448 typedef typename covovoc_t::sf4_type sf4_type;
40449 typedef typename node_type::T0 T0;
40450 typedef typename node_type::T1 T1;
40451 typedef typename node_type::T2 T2;
40452 typedef typename node_type::T3 T3;
40453
40454 static inline expression_node_ptr process(expression_generator<Type>& expr_gen,
40455 const details::operator_type& operation,
40456 expression_node_ptr (&branch)[2])
40457 {
40458 // ((c0 o0 (v0 o1 v1)) o2 c1)
40459 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
40460
40461 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
40462 const Type c0 = covov->t0();
40463 const Type& v0 = covov->t1();
40464 const Type& v1 = covov->t2();
40465 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
40466 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
40467 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
40468 const details::operator_type o2 = operation;
40469
40470 binary_functor_t f0 = covov->f0();
40471 binary_functor_t f1 = covov->f1();
40472 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40473
40474 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40475 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40476
40477 expression_node_ptr result = error_node();
40478
40479 const bool synthesis_result =
40480 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40481 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
40482
40483 if (synthesis_result)
40484 return result;
40485 else if (!expr_gen.valid_operator(o2,f2))
40486 return error_node();
40487
40488 exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n"));
40489
40490 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
40491 }
40492
40493 static inline std::string id(expression_generator<Type>& expr_gen,
40494 const details::operator_type o0,
40495 const details::operator_type o1,
40496 const details::operator_type o2)
40497 {
40498 return details::build_string()
40499 << "(t" << expr_gen.to_str(o0)
40500 << "(t" << expr_gen.to_str(o1)
40501 << "t)" << expr_gen.to_str(o2)
40502 << "t";
40503 }
40504 };
40505
40506 struct synthesize_vococov_expression4
40507 {
40508 typedef typename vococov_t::type4 node_type;
40509 static inline expression_node_ptr process(expression_generator<Type>&,
40510 const details::operator_type&,
40511 expression_node_ptr (&)[2])
40512 {
40513 // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible
40514 exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
40515 return error_node();
40516 }
40517
40518 static inline std::string id(expression_generator<Type>&,
40519 const details::operator_type,
40520 const details::operator_type,
40521 const details::operator_type)
40522 {
40523 return "INVALID";
40524 }
40525 };
40526 #endif
40527
40528 inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
40529 {
40530 // Definition: uv o uv
40531 details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
40532 details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
40533 const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
40534 const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
40535 unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
40536 unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
40537 binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
40538
40539 if (!valid_operator(o0,u0))
40540 return error_node();
40541 else if (!valid_operator(o1,u1))
40542 return error_node();
40543 else if (!valid_operator(operation,f))
40544 return error_node();
40545
40546 expression_node_ptr result = error_node();
40547
40548 if (
40549 (details::e_neg == o0) &&
40550 (details::e_neg == o1)
40551 )
40552 {
40553 switch (operation)
40554 {
40555 // (-v0 + -v1) --> -(v0 + v1)
40556 case details::e_add : result = (*this)(details::e_neg,
40557 node_allocator_->
40558 allocate_rr<typename details::
40559 vov_node<Type,details::add_op<Type> > >(v0, v1));
40560 exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n"));
40561 break;
40562
40563 // (-v0 - -v1) --> (v1 - v0)
40564 case details::e_sub : result = node_allocator_->
40565 allocate_rr<typename details::
40566 vov_node<Type,details::sub_op<Type> > >(v1, v0);
40567 exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n"));
40568 break;
40569
40570 // (-v0 * -v1) --> (v0 * v1)
40571 case details::e_mul : result = node_allocator_->
40572 allocate_rr<typename details::
40573 vov_node<Type,details::mul_op<Type> > >(v0, v1);
40574 exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n"));
40575 break;
40576
40577 // (-v0 / -v1) --> (v0 / v1)
40578 case details::e_div : result = node_allocator_->
40579 allocate_rr<typename details::
40580 vov_node<Type,details::div_op<Type> > >(v0, v1);
40581 exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n"));
40582 break;
40583
40584 default : break;
40585 }
40586 }
40587
40588 if (0 == result)
40589 {
40590 result = node_allocator_->
40591 allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f);
40592 }
40593
40594 details::free_all_nodes(*node_allocator_,branch);
40595 return result;
40596 }
40597
40598 #undef basic_opr_switch_statements
40599 #undef extended_opr_switch_statements
40600 #undef unary_opr_switch_statements
40601
40602 #ifndef exprtk_disable_string_capabilities
40603
40604 #define string_opr_switch_statements \
40605 case_stmt(details::e_lt , details::lt_op ) \
40606 case_stmt(details::e_lte , details::lte_op ) \
40607 case_stmt(details::e_gt , details::gt_op ) \
40608 case_stmt(details::e_gte , details::gte_op ) \
40609 case_stmt(details::e_eq , details::eq_op ) \
40610 case_stmt(details::e_ne , details::ne_op ) \
40611 case_stmt(details::e_in , details::in_op ) \
40612 case_stmt(details::e_like , details::like_op ) \
40613 case_stmt(details::e_ilike , details::ilike_op) \
40614
40615 template <typename T0, typename T1>
40616 inline expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type& opr,
40617 T0 s0, T1 s1,
40618 range_t rp0)
40619 {
40620 switch (opr)
40621 {
40622 #define case_stmt(op0, op1) \
40623 case op0 : return node_allocator_-> \
40624 allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40625 (s0, s1, rp0); \
40626
40628 #undef case_stmt
40629 default : return error_node();
40630 }
40631 }
40632
40633 template <typename T0, typename T1>
40634 inline expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type& opr,
40635 T0 s0, T1 s1,
40636 range_t rp1)
40637 {
40638 switch (opr)
40639 {
40640 #define case_stmt(op0, op1) \
40641 case op0 : return node_allocator_-> \
40642 allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40643 (s0, s1, rp1); \
40644
40646 #undef case_stmt
40647 default : return error_node();
40648 }
40649 }
40650
40651 template <typename T0, typename T1>
40652 inline expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type& opr,
40653 T0 s0, T1 s1,
40654 range_t rp0, range_t rp1)
40655 {
40656 switch (opr)
40657 {
40658 #define case_stmt(op0, op1) \
40659 case op0 : return node_allocator_-> \
40660 allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40661 (s0, s1, rp0, rp1); \
40662
40664 #undef case_stmt
40665 default : return error_node();
40666 }
40667 }
40668
40669 template <typename T0, typename T1>
40670 inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1)
40671 {
40672 switch (opr)
40673 {
40674 #define case_stmt(op0, op1) \
40675 case op0 : return node_allocator_-> \
40676 allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
40677
40679 #undef case_stmt
40680 default : return error_node();
40681 }
40682 }
40683
40684 inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40685 {
40686 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
40687 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
40688
40689 return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1);
40690 }
40691
40692 inline expression_node_ptr synthesize_sros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40693 {
40694 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
40695 std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
40696 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
40697
40698 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40699
40700 details::free_node(*node_allocator_,branch[0]);
40701
40702 return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0);
40703 }
40704
40705 inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40706 {
40707 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
40708 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
40709 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
40710
40711 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40712
40713 details::free_node(*node_allocator_,branch[1]);
40714
40715 return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1);
40716 }
40717
40718 inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40719 {
40720 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
40721 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40722 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40723
40724 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40725
40726 details::free_node(*node_allocator_,branch[1]);
40727
40728 return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1);
40729 }
40730
40731 inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40732 {
40733 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
40734 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
40735 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
40736 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
40737
40738 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40739 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40740
40741 details::free_node(*node_allocator_,branch[0]);
40742 details::free_node(*node_allocator_,branch[1]);
40743
40744 return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1);
40745 }
40746
40747 inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40748 {
40749 std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
40750 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
40751
40752 details::free_node(*node_allocator_,branch[1]);
40753
40754 return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1);
40755 }
40756
40757 inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40758 {
40759 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
40760 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
40761
40762 details::free_node(*node_allocator_,branch[0]);
40763
40764 return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1);
40765 }
40766
40767 inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40768 {
40769 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
40770 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
40771 range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
40772
40773 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40774
40775 details::free_node(*node_allocator_,branch[0]);
40776 details::free_node(*node_allocator_,branch[1]);
40777
40778 return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1);
40779 }
40780
40781 inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40782 {
40783 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
40784 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
40785 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
40786
40787 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40788
40789 details::free_node(*node_allocator_,branch[0]);
40790 details::free_node(*node_allocator_,branch[1]);
40791
40792 return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0);
40793 }
40794
40795 inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40796 {
40797 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
40798 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40799 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
40800 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40801
40802 static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
40803 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40804
40805 details::free_node(*node_allocator_,branch[0]);
40806 details::free_node(*node_allocator_,branch[1]);
40807
40808 return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1);
40809 }
40810
40811 inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40812 {
40813 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
40814 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
40815
40816 expression_node_ptr result = error_node();
40817
40818 if (details::e_add == opr)
40819 result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
40820 else if (details::e_in == opr)
40821 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op <Type>::process(s0,s1));
40822 else if (details::e_like == opr)
40823 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1));
40824 else if (details::e_ilike == opr)
40825 result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
40826 else
40827 {
40828 expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1);
40829
40830 const Type v = temp->value();
40831
40832 details::free_node(*node_allocator_,temp);
40833
40834 result = node_allocator_->allocate<literal_node_t>(v);
40835 }
40836
40837 details::free_all_nodes(*node_allocator_,branch);
40838
40839 return result;
40840 }
40841
40842 inline expression_node_ptr synthesize_csocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40843 {
40844 const std::string s0 = static_cast<details::string_literal_node<Type>* >(branch[0])->str ();
40845 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40846 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40847
40848 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40849
40850 details::free_node(*node_allocator_,branch[0]);
40851 details::free_node(*node_allocator_,branch[1]);
40852
40853 return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1);
40854 }
40855
40856 inline expression_node_ptr synthesize_csros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40857 {
40858 std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40859 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref ();
40860 range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40861
40862 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40863
40864 details::free_node(*node_allocator_,branch[0]);
40865
40866 return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0);
40867 }
40868
40869 inline expression_node_ptr synthesize_csrosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40870 {
40871 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40872 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
40873 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40874 const range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
40875
40876 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40877 static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
40878
40879 details::free_node(*node_allocator_,branch[0]);
40880 details::free_node(*node_allocator_,branch[1]);
40881
40882 return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1);
40883 }
40884
40885 inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40886 {
40887 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40888 const std::string s1 = static_cast<details::string_literal_node<Type>* >(branch[1])->str ();
40889 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40890
40891 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40892
40893 details::free_all_nodes(*node_allocator_,branch);
40894
40895 return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0);
40896 }
40897
40898 inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40899 {
40900 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40901 const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40902 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40903 const range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40904
40905 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40906 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40907
40908 details::free_all_nodes(*node_allocator_,branch);
40909
40910 return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1);
40911 }
40912
40913 inline expression_node_ptr synthesize_strogen_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40914 {
40915 switch (opr)
40916 {
40917 #define case_stmt(op0, op1) \
40918 case op0 : return node_allocator_-> \
40919 allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
40920 (opr, branch[0], branch[1]); \
40921
40923 #undef case_stmt
40924 default : return error_node();
40925 }
40926 }
40927
40928 #undef string_opr_switch_statements
40929 #endif
40930
40931 #ifndef exprtk_disable_string_capabilities
40932 inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2])
40933 {
40934 if ((0 == branch[0]) || (0 == branch[1]))
40935 {
40936 details::free_all_nodes(*node_allocator_,branch);
40937
40938 return error_node();
40939 }
40940
40941 const bool b0_is_s = details::is_string_node (branch[0]);
40942 const bool b0_is_cs = details::is_const_string_node (branch[0]);
40943 const bool b0_is_sr = details::is_string_range_node (branch[0]);
40944 const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
40945
40946 const bool b1_is_s = details::is_string_node (branch[1]);
40947 const bool b1_is_cs = details::is_const_string_node (branch[1]);
40948 const bool b1_is_sr = details::is_string_range_node (branch[1]);
40949 const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
40950
40951 const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
40952 details::is_genricstring_range_node(branch[0]) ||
40953 details::is_string_concat_node (branch[0]) ||
40954 details::is_string_function_node (branch[0]) ||
40955 details::is_string_condition_node (branch[0]) ||
40956 details::is_string_ccondition_node (branch[0]) ||
40957 details::is_string_vararg_node (branch[0]) ;
40958
40959 const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
40960 details::is_genricstring_range_node(branch[1]) ||
40961 details::is_string_concat_node (branch[1]) ||
40962 details::is_string_function_node (branch[1]) ||
40963 details::is_string_condition_node (branch[1]) ||
40964 details::is_string_ccondition_node (branch[1]) ||
40965 details::is_string_vararg_node (branch[1]) ;
40966
40967 if (details::e_add == opr)
40968 {
40969 if (!b0_is_cs || !b1_is_cs)
40970 {
40971 return synthesize_expression<string_concat_node_t,2>(opr,branch);
40972 }
40973 }
40974
40975 if (b0_is_gen || b1_is_gen)
40976 {
40977 return synthesize_strogen_expression(opr,branch);
40978 }
40979 else if (b0_is_s)
40980 {
40981 if (b1_is_s ) return synthesize_sos_expression (opr,branch);
40982 else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
40983 else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
40984 else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
40985 }
40986 else if (b0_is_cs)
40987 {
40988 if (b1_is_s ) return synthesize_csos_expression (opr,branch);
40989 else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
40990 else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
40991 else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
40992 }
40993 else if (b0_is_sr)
40994 {
40995 if (b1_is_s ) return synthesize_sros_expression (opr,branch);
40996 else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
40997 else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
40998 else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
40999 }
41000 else if (b0_is_csr)
41001 {
41002 if (b1_is_s ) return synthesize_csros_expression (opr,branch);
41003 else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
41004 else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
41005 else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
41006 }
41007
41008 return error_node();
41009 }
41010 #else
41011 inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2])
41012 {
41013 details::free_all_nodes(*node_allocator_,branch);
41014 return error_node();
41015 }
41016 #endif
41017
41018 #ifndef exprtk_disable_string_capabilities
41019 inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3])
41020 {
41021 if (details::e_inrange != opr)
41022 return error_node();
41023 else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
41024 {
41025 details::free_all_nodes(*node_allocator_,branch);
41026
41027 return error_node();
41028 }
41029 else if (
41030 details::is_const_string_node(branch[0]) &&
41031 details::is_const_string_node(branch[1]) &&
41032 details::is_const_string_node(branch[2])
41033 )
41034 {
41035 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41036 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
41037 const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41038
41039 const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
41040
41041 details::free_all_nodes(*node_allocator_,branch);
41042
41043 return node_allocator_->allocate_c<details::literal_node<Type> >(v);
41044 }
41045 else if (
41046 details::is_string_node(branch[0]) &&
41047 details::is_string_node(branch[1]) &&
41048 details::is_string_node(branch[2])
41049 )
41050 {
41051 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
41052 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
41053 std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
41054
41055 typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
41056
41057 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2);
41058 }
41059 else if (
41060 details::is_const_string_node(branch[0]) &&
41061 details::is_string_node(branch[1]) &&
41062 details::is_const_string_node(branch[2])
41063 )
41064 {
41065 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41066 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41067 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41068
41069 typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t;
41070
41071 details::free_node(*node_allocator_,branch[0]);
41072 details::free_node(*node_allocator_,branch[2]);
41073
41074 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2);
41075 }
41076 else if (
41077 details::is_string_node(branch[0]) &&
41078 details::is_const_string_node(branch[1]) &&
41079 details::is_string_node(branch[2])
41080 )
41081 {
41082 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
41083 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
41084 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
41085
41086 typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t;
41087
41088 details::free_node(*node_allocator_,branch[1]);
41089
41090 return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2);
41091 }
41092 else if (
41093 details::is_string_node(branch[0]) &&
41094 details::is_string_node(branch[1]) &&
41095 details::is_const_string_node(branch[2])
41096 )
41097 {
41098 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
41099 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41100 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41101
41102 typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t;
41103
41104 details::free_node(*node_allocator_,branch[2]);
41105
41106 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2);
41107 }
41108 else if (
41109 details::is_const_string_node(branch[0]) &&
41110 details:: is_string_node(branch[1]) &&
41111 details:: is_string_node(branch[2])
41112 )
41113 {
41114 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41115 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41116 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
41117
41118 typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
41119
41120 details::free_node(*node_allocator_,branch[0]);
41121
41122 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2);
41123 }
41124 else
41125 return error_node();
41126 }
41127 #else
41128 inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3])
41129 {
41130 details::free_all_nodes(*node_allocator_,branch);
41131 return error_node();
41132 }
41133 #endif
41134
41135 inline expression_node_ptr synthesize_null_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2])
41136 {
41137 /*
41138 Note: The following are the type promotion rules
41139 that relate to operations that include 'null':
41140 0. null ==/!= null --> true false
41141 1. null operation null --> null
41142 2. x ==/!= null --> true/false
41143 3. null ==/!= x --> true/false
41144 4. x operation null --> x
41145 5. null operation x --> x
41146 */
41147
41148 typedef typename details::null_eq_node<T> nulleq_node_t;
41149
41150 const bool b0_null = details::is_null_node(branch[0]);
41151 const bool b1_null = details::is_null_node(branch[1]);
41152
41153 if (b0_null && b1_null)
41154 {
41155 expression_node_ptr result = error_node();
41156
41157 if (details::e_eq == operation)
41158 result = node_allocator_->allocate_c<literal_node_t>(T(1));
41159 else if (details::e_ne == operation)
41160 result = node_allocator_->allocate_c<literal_node_t>(T(0));
41161
41162 if (result)
41163 {
41164 details::free_node(*node_allocator_,branch[0]);
41165 details::free_node(*node_allocator_,branch[1]);
41166
41167 return result;
41168 }
41169
41170 details::free_node(*node_allocator_,branch[1]);
41171
41172 return branch[0];
41173 }
41174 else if (details::e_eq == operation)
41175 {
41176 expression_node_ptr result = node_allocator_->
41177 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
41178
41179 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
41180
41181 return result;
41182 }
41183 else if (details::e_ne == operation)
41184 {
41185 expression_node_ptr result = node_allocator_->
41186 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
41187
41188 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
41189
41190 return result;
41191 }
41192 else if (b0_null)
41193 {
41194 details::free_node(*node_allocator_,branch[0]);
41195 branch[0] = branch[1];
41196 branch[1] = error_node();
41197 }
41198 else if (b1_null)
41199 {
41200 details::free_node(*node_allocator_,branch[1]);
41201 branch[1] = error_node();
41202 }
41203
41204 if (
41205 (details::e_add == operation) || (details::e_sub == operation) ||
41206 (details::e_mul == operation) || (details::e_div == operation) ||
41207 (details::e_mod == operation) || (details::e_pow == operation)
41208 )
41209 {
41210 return branch[0];
41211 }
41212
41213 details::free_node(*node_allocator_, branch[0]);
41214
41215 if (
41216 (details::e_lt == operation) || (details::e_lte == operation) ||
41217 (details::e_gt == operation) || (details::e_gte == operation) ||
41218 (details::e_and == operation) || (details::e_nand == operation) ||
41219 (details::e_or == operation) || (details::e_nor == operation) ||
41220 (details::e_xor == operation) || (details::e_xnor == operation) ||
41221 (details::e_in == operation) || (details::e_like == operation) ||
41222 (details::e_ilike == operation)
41223 )
41224 {
41225 return node_allocator_->allocate_c<literal_node_t>(T(0));
41226 }
41227
41228 return node_allocator_->allocate<details::null_node<Type> >();
41229 }
41230
41231 template <typename NodeType, std::size_t N>
41232 inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N])
41233 {
41234 if (
41235 (details::e_in == operation) ||
41236 (details::e_like == operation) ||
41237 (details::e_ilike == operation)
41238 )
41239 {
41240 free_all_nodes(*node_allocator_,branch);
41241
41242 return error_node();
41243 }
41244 else if (!details::all_nodes_valid<N>(branch))
41245 {
41246 free_all_nodes(*node_allocator_,branch);
41247
41248 return error_node();
41249 }
41250 else if ((details::e_default != operation))
41251 {
41252 // Attempt simple constant folding optimisation.
41253 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
41254
41255 if (is_constant_foldable<N>(branch))
41256 {
41257 const Type v = expression_point->value();
41258 details::free_node(*node_allocator_,expression_point);
41259
41260 return node_allocator_->allocate<literal_node_t>(v);
41261 }
41262
41263 if (expression_point && expression_point->valid())
41264 {
41265 return expression_point;
41266 }
41267
41268 parser_->set_error(parser_error::make_error(
41269 parser_error::e_parser,
41270 token_t(),
41271 "ERR273 - Failed to synthesize node: NodeType",
41273
41274 details::free_node(*node_allocator_, expression_point);
41275 }
41276
41277 return error_node();
41278 }
41279
41280 template <typename NodeType, std::size_t N>
41281 inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N])
41282 {
41283 if (!details::all_nodes_valid<N>(branch))
41284 {
41285 free_all_nodes(*node_allocator_,branch);
41286
41287 return error_node();
41288 }
41289
41290 typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
41291
41292 // Attempt simple constant folding optimisation.
41293
41294 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
41295 function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
41296
41297 if (0 == func_node_ptr)
41298 {
41299 free_all_nodes(*node_allocator_,branch);
41300
41301 return error_node();
41302 }
41303 else
41304 func_node_ptr->init_branches(branch);
41305
41306 if (is_constant_foldable<N>(branch) && !f->has_side_effects())
41307 {
41308 Type v = expression_point->value();
41309 details::free_node(*node_allocator_,expression_point);
41310
41311 return node_allocator_->allocate<literal_node_t>(v);
41312 }
41313
41314 parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)");
41315
41316 return expression_point;
41317 }
41318
41319 bool strength_reduction_enabled_;
41320 details::node_allocator* node_allocator_;
41321 synthesize_map_t synthesize_map_;
41322 unary_op_map_t* unary_op_map_;
41323 binary_op_map_t* binary_op_map_;
41324 inv_binary_op_map_t* inv_binary_op_map_;
41325 sf3_map_t* sf3_map_;
41326 sf4_map_t* sf4_map_;
41327 parser_t* parser_;
41328 }; // class expression_generator
41329
41330 inline void set_error(const parser_error::type& error_type)
41331 {
41332 error_list_.push_back(error_type);
41333 }
41334
41335 inline void remove_last_error()
41336 {
41337 if (!error_list_.empty())
41338 {
41339 error_list_.pop_back();
41340 }
41341 }
41342
41343 inline void set_synthesis_error(const std::string& synthesis_error_message)
41344 {
41345 if (synthesis_error_.empty())
41346 {
41347 synthesis_error_ = synthesis_error_message;
41348 }
41349 }
41350
41351 inline void register_local_vars(expression<T>& e)
41352 {
41353 for (std::size_t i = 0; i < sem_.size(); ++i)
41354 {
41355 scope_element& se = sem_.get_element(i);
41356
41357 exprtk_debug(("register_local_vars() - se[%s]\n", se.name.c_str()));
41358
41359 if (
41360 (scope_element::e_variable == se.type) ||
41361 (scope_element::e_literal == se.type) ||
41362 (scope_element::e_vecelem == se.type)
41363 )
41364 {
41365 if (se.var_node)
41366 {
41367 e.register_local_var(se.var_node);
41368 }
41369
41370 if (se.data)
41371 {
41372 e.register_local_data(se.data, 1, 0);
41373 }
41374 }
41375 else if (scope_element::e_vector == se.type)
41376 {
41377 if (se.vec_node)
41378 {
41379 e.register_local_var(se.vec_node);
41380 }
41381
41382 if (se.data)
41383 {
41384 e.register_local_data(se.data, se.size, 1);
41385 }
41386 }
41387 #ifndef exprtk_disable_string_capabilities
41388 else if (scope_element::e_string == se.type)
41389 {
41390 if (se.str_node)
41391 {
41392 e.register_local_var(se.str_node);
41393 }
41394
41395 if (se.data)
41396 {
41397 e.register_local_data(se.data, se.size, 2);
41398 }
41399 }
41400 #endif
41401
41402 se.var_node = 0;
41403 se.vec_node = 0;
41404 #ifndef exprtk_disable_string_capabilities
41405 se.str_node = 0;
41406 #endif
41407 se.data = 0;
41408 se.ref_count = 0;
41409 se.active = false;
41410 }
41411 }
41412
41413 inline void register_return_results(expression<T>& e)
41414 {
41415 e.register_return_results(results_context_);
41416 results_context_ = 0;
41417 }
41418
41419 inline void load_unary_operations_map(unary_op_map_t& m)
41420 {
41421 #define register_unary_op(Op, UnaryFunctor) \
41422 m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
41423
41424 register_unary_op(details::e_abs , details::abs_op )
41425 register_unary_op(details::e_acos , details::acos_op )
41426 register_unary_op(details::e_acosh , details::acosh_op)
41427 register_unary_op(details::e_asin , details::asin_op )
41428 register_unary_op(details::e_asinh , details::asinh_op)
41429 register_unary_op(details::e_atanh , details::atanh_op)
41430 register_unary_op(details::e_ceil , details::ceil_op )
41431 register_unary_op(details::e_cos , details::cos_op )
41432 register_unary_op(details::e_cosh , details::cosh_op )
41433 register_unary_op(details::e_exp , details::exp_op )
41434 register_unary_op(details::e_expm1 , details::expm1_op)
41435 register_unary_op(details::e_floor , details::floor_op)
41436 register_unary_op(details::e_log , details::log_op )
41437 register_unary_op(details::e_log10 , details::log10_op)
41438 register_unary_op(details::e_log2 , details::log2_op )
41439 register_unary_op(details::e_log1p , details::log1p_op)
41440 register_unary_op(details::e_neg , details::neg_op )
41441 register_unary_op(details::e_pos , details::pos_op )
41442 register_unary_op(details::e_round , details::round_op)
41443 register_unary_op(details::e_sin , details::sin_op )
41444 register_unary_op(details::e_sinc , details::sinc_op )
41445 register_unary_op(details::e_sinh , details::sinh_op )
41446 register_unary_op(details::e_sqrt , details::sqrt_op )
41447 register_unary_op(details::e_tan , details::tan_op )
41448 register_unary_op(details::e_tanh , details::tanh_op )
41449 register_unary_op(details::e_cot , details::cot_op )
41450 register_unary_op(details::e_sec , details::sec_op )
41451 register_unary_op(details::e_csc , details::csc_op )
41452 register_unary_op(details::e_r2d , details::r2d_op )
41453 register_unary_op(details::e_d2r , details::d2r_op )
41454 register_unary_op(details::e_d2g , details::d2g_op )
41455 register_unary_op(details::e_g2d , details::g2d_op )
41456 register_unary_op(details::e_notl , details::notl_op )
41457 register_unary_op(details::e_sgn , details::sgn_op )
41458 register_unary_op(details::e_erf , details::erf_op )
41459 register_unary_op(details::e_erfc , details::erfc_op )
41460 register_unary_op(details::e_ncdf , details::ncdf_op )
41461 register_unary_op(details::e_frac , details::frac_op )
41462 register_unary_op(details::e_trunc , details::trunc_op)
41463 #undef register_unary_op
41464 }
41465
41466 inline void load_binary_operations_map(binary_op_map_t& m)
41467 {
41468 typedef typename binary_op_map_t::value_type value_type;
41469
41470 #define register_binary_op(Op, BinaryFunctor) \
41471 m.insert(value_type(Op,BinaryFunctor<T>::process)); \
41472
41473 register_binary_op(details::e_add , details::add_op )
41474 register_binary_op(details::e_sub , details::sub_op )
41475 register_binary_op(details::e_mul , details::mul_op )
41476 register_binary_op(details::e_div , details::div_op )
41477 register_binary_op(details::e_mod , details::mod_op )
41478 register_binary_op(details::e_pow , details::pow_op )
41479 register_binary_op(details::e_lt , details::lt_op )
41480 register_binary_op(details::e_lte , details::lte_op )
41481 register_binary_op(details::e_gt , details::gt_op )
41482 register_binary_op(details::e_gte , details::gte_op )
41483 register_binary_op(details::e_eq , details::eq_op )
41484 register_binary_op(details::e_ne , details::ne_op )
41485 register_binary_op(details::e_and , details::and_op )
41486 register_binary_op(details::e_nand , details::nand_op)
41487 register_binary_op(details::e_or , details::or_op )
41488 register_binary_op(details::e_nor , details::nor_op )
41489 register_binary_op(details::e_xor , details::xor_op )
41490 register_binary_op(details::e_xnor , details::xnor_op)
41491 #undef register_binary_op
41492 }
41493
41494 inline void load_inv_binary_operations_map(inv_binary_op_map_t& m)
41495 {
41496 typedef typename inv_binary_op_map_t::value_type value_type;
41497
41498 #define register_binary_op(Op, BinaryFunctor) \
41499 m.insert(value_type(BinaryFunctor<T>::process,Op)); \
41500
41501 register_binary_op(details::e_add , details::add_op )
41502 register_binary_op(details::e_sub , details::sub_op )
41503 register_binary_op(details::e_mul , details::mul_op )
41504 register_binary_op(details::e_div , details::div_op )
41505 register_binary_op(details::e_mod , details::mod_op )
41506 register_binary_op(details::e_pow , details::pow_op )
41507 register_binary_op(details::e_lt , details::lt_op )
41508 register_binary_op(details::e_lte , details::lte_op )
41509 register_binary_op(details::e_gt , details::gt_op )
41510 register_binary_op(details::e_gte , details::gte_op )
41511 register_binary_op(details::e_eq , details::eq_op )
41512 register_binary_op(details::e_ne , details::ne_op )
41513 register_binary_op(details::e_and , details::and_op )
41514 register_binary_op(details::e_nand , details::nand_op)
41515 register_binary_op(details::e_or , details::or_op )
41516 register_binary_op(details::e_nor , details::nor_op )
41517 register_binary_op(details::e_xor , details::xor_op )
41518 register_binary_op(details::e_xnor , details::xnor_op)
41519 #undef register_binary_op
41520 }
41521
41522 inline void load_sf3_map(sf3_map_t& sf3_map)
41523 {
41524 typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
41525
41526 #define register_sf3(Op) \
41527 sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41528
41537 #undef register_sf3
41538
41539 #define register_sf3_extid(Id, Op) \
41540 sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41541
41542 register_sf3_extid("(t-t)-t",23) // (t-t)-t --> t-(t+t)
41543 #undef register_sf3_extid
41544 }
41545
41546 inline void load_sf4_map(sf4_map_t& sf4_map)
41547 {
41548 typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
41549
41550 #define register_sf4(Op) \
41551 sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41552
41562 #undef register_sf4
41563
41564 #define register_sf4ext(Op) \
41565 sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
41566
41583 #undef register_sf4ext
41584 }
41585
41586 inline results_context_t& results_ctx()
41587 {
41588 if (0 == results_context_)
41589 {
41590 results_context_ = new results_context_t();
41591 }
41592
41593 return (*results_context_);
41594 }
41595
41596 inline void return_cleanup()
41597 {
41598 #ifndef exprtk_disable_return_statement
41599 if (results_context_)
41600 {
41601 delete results_context_;
41602 results_context_ = 0;
41603 }
41604
41605 state_.return_stmt_present = false;
41606 #endif
41607 }
41608
41609 private:
41610
41611 parser(const parser<T>&) exprtk_delete;
41612 parser<T>& operator=(const parser<T>&) exprtk_delete;
41613
41614 settings_store settings_;
41615 expression_generator<T> expression_generator_;
41616 details::node_allocator node_allocator_;
41617 symtab_store symtab_store_;
41618 dependent_entity_collector dec_;
41619 std::deque<parser_error::type> error_list_;
41620 std::deque<bool> brkcnt_list_;
41621 parser_state state_;
41622 bool resolve_unknown_symbol_;
41623 results_context_t* results_context_;
41624 unknown_symbol_resolver* unknown_symbol_resolver_;
41625 unknown_symbol_resolver default_usr_;
41626 base_ops_map_t base_ops_map_;
41627 unary_op_map_t unary_op_map_;
41628 binary_op_map_t binary_op_map_;
41629 inv_binary_op_map_t inv_binary_op_map_;
41630 sf3_map_t sf3_map_;
41631 sf4_map_t sf4_map_;
41632 std::string synthesis_error_;
41633 scope_element_manager sem_;
41634 std::vector<state_t> current_state_stack_;
41635
41636 immutable_memory_map_t immutable_memory_map_;
41637 immutable_symtok_map_t immutable_symtok_map_;
41638
41639 lexer::helper::helper_assembly helper_assembly_;
41640
41641 lexer::helper::commutative_inserter commutative_inserter_;
41642 lexer::helper::operator_joiner operator_joiner_2_;
41643 lexer::helper::operator_joiner operator_joiner_3_;
41644 lexer::helper::symbol_replacer symbol_replacer_;
41645 lexer::helper::bracket_checker bracket_checker_;
41646 lexer::helper::numeric_checker<T> numeric_checker_;
41647 lexer::helper::sequence_validator sequence_validator_;
41648 lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
41649
41650 loop_runtime_check_ptr loop_runtime_check_;
41651 vector_access_runtime_check_ptr vector_access_runtime_check_;
41652 compilation_check_ptr compilation_check_ptr_;
41653 assert_check_ptr assert_check_;
41654 std::set<std::string> assert_ids_;
41655
41656 template <typename ParserType>
41657 friend void details::disable_type_checking(ParserType& p);
41658 }; // class parser
41659
41660 namespace details
41661 {
41662 template <typename T>
41663 struct collector_helper
41664 {
41665 typedef exprtk::symbol_table<T> symbol_table_t;
41666 typedef exprtk::expression<T> expression_t;
41667 typedef exprtk::parser<T> parser_t;
41668 typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
41669 typedef typename parser_t::unknown_symbol_resolver usr_t;
41670
41671 struct resolve_as_vector : public usr_t
41672 {
41673 typedef exprtk::parser<T> parser_t;
41674
41675 using usr_t::process;
41676
41677 resolve_as_vector()
41678 : usr_t(usr_t::e_usrmode_extended)
41679 {}
41680
41681 virtual bool process(const std::string& unknown_symbol,
41682 symbol_table_t& symbol_table,
41683 std::string&) exprtk_override
41684 {
41685 static T v[1];
41686 symbol_table.add_vector(unknown_symbol,v);
41687 return true;
41688 }
41689 };
41690
41691 static inline bool collection_pass(const std::string& expression_string,
41692 std::set<std::string>& symbol_set,
41693 const bool collect_variables,
41694 const bool collect_functions,
41695 const bool vector_pass,
41696 symbol_table_t& ext_symbol_table)
41697 {
41698 symbol_table_t symbol_table;
41699 expression_t expression;
41700 parser_t parser;
41701
41702 resolve_as_vector vect_resolver;
41703
41704 expression.register_symbol_table(symbol_table );
41705 expression.register_symbol_table(ext_symbol_table);
41706
41707 if (vector_pass)
41708 parser.enable_unknown_symbol_resolver(&vect_resolver);
41709 else
41710 parser.enable_unknown_symbol_resolver();
41711
41712 if (collect_variables)
41713 parser.dec().collect_variables() = true;
41714
41715 if (collect_functions)
41716 parser.dec().collect_functions() = true;
41717
41718 bool pass_result = false;
41719
41720 details::disable_type_checking(parser);
41721
41722 if (parser.compile(expression_string, expression))
41723 {
41724 pass_result = true;
41725
41726 std::deque<symbol_t> symb_list;
41727 parser.dec().symbols(symb_list);
41728
41729 for (std::size_t i = 0; i < symb_list.size(); ++i)
41730 {
41731 symbol_set.insert(symb_list[i].first);
41732 }
41733 }
41734
41735 return pass_result;
41736 }
41737 };
41738 }
41739
41740 template <typename Allocator,
41741 template <typename, typename> class Sequence>
41742 inline bool collect_variables(const std::string& expression,
41743 Sequence<std::string, Allocator>& symbol_list)
41744 {
41745 typedef double T;
41746 typedef details::collector_helper<T> collect_t;
41747
41748 collect_t::symbol_table_t null_symbol_table;
41749
41750 std::set<std::string> symbol_set;
41751
41752 const bool variable_pass = collect_t::collection_pass
41753 (expression, symbol_set, true, false, false, null_symbol_table);
41754 const bool vector_pass = collect_t::collection_pass
41755 (expression, symbol_set, true, false, true, null_symbol_table);
41756
41757 if (!variable_pass && !vector_pass)
41758 return false;
41759
41760 std::set<std::string>::iterator itr = symbol_set.begin();
41761
41762 while (symbol_set.end() != itr)
41763 {
41764 symbol_list.push_back(*itr);
41765 ++itr;
41766 }
41767
41768 return true;
41769 }
41770
41771 template <typename T,
41772 typename Allocator,
41773 template <typename, typename> class Sequence>
41774 inline bool collect_variables(const std::string& expression,
41775 exprtk::symbol_table<T>& extrnl_symbol_table,
41776 Sequence<std::string, Allocator>& symbol_list)
41777 {
41778 typedef details::collector_helper<T> collect_t;
41779
41780 std::set<std::string> symbol_set;
41781
41782 const bool variable_pass = collect_t::collection_pass
41783 (expression, symbol_set, true, false, false, extrnl_symbol_table);
41784 const bool vector_pass = collect_t::collection_pass
41785 (expression, symbol_set, true, false, true, extrnl_symbol_table);
41786
41787 if (!variable_pass && !vector_pass)
41788 return false;
41789
41790 std::set<std::string>::iterator itr = symbol_set.begin();
41791
41792 while (symbol_set.end() != itr)
41793 {
41794 symbol_list.push_back(*itr);
41795 ++itr;
41796 }
41797
41798 return true;
41799 }
41800
41801 template <typename Allocator,
41802 template <typename, typename> class Sequence>
41803 inline bool collect_functions(const std::string& expression,
41804 Sequence<std::string, Allocator>& symbol_list)
41805 {
41806 typedef double T;
41807 typedef details::collector_helper<T> collect_t;
41808
41809 collect_t::symbol_table_t null_symbol_table;
41810
41811 std::set<std::string> symbol_set;
41812
41813 const bool variable_pass = collect_t::collection_pass
41814 (expression, symbol_set, false, true, false, null_symbol_table);
41815 const bool vector_pass = collect_t::collection_pass
41816 (expression, symbol_set, false, true, true, null_symbol_table);
41817
41818 if (!variable_pass && !vector_pass)
41819 return false;
41820
41821 std::set<std::string>::iterator itr = symbol_set.begin();
41822
41823 while (symbol_set.end() != itr)
41824 {
41825 symbol_list.push_back(*itr);
41826 ++itr;
41827 }
41828
41829 return true;
41830 }
41831
41832 template <typename T,
41833 typename Allocator,
41834 template <typename, typename> class Sequence>
41835 inline bool collect_functions(const std::string& expression,
41836 exprtk::symbol_table<T>& extrnl_symbol_table,
41837 Sequence<std::string, Allocator>& symbol_list)
41838 {
41839 typedef details::collector_helper<T> collect_t;
41840
41841 std::set<std::string> symbol_set;
41842
41843 const bool variable_pass = collect_t::collection_pass
41844 (expression, symbol_set, false, true, false, extrnl_symbol_table);
41845 const bool vector_pass = collect_t::collection_pass
41846 (expression, symbol_set, false, true, true, extrnl_symbol_table);
41847
41848 if (!variable_pass && !vector_pass)
41849 return false;
41850
41851 std::set<std::string>::iterator itr = symbol_set.begin();
41852
41853 while (symbol_set.end() != itr)
41854 {
41855 symbol_list.push_back(*itr);
41856 ++itr;
41857 }
41858
41859 return true;
41860 }
41861
41862 template <typename T>
41863 inline T integrate(const expression<T>& e,
41864 T& x,
41865 const T& r0, const T& r1,
41866 const std::size_t number_of_intervals = 1000000)
41867 {
41868 if (r0 > r1)
41869 return T(0);
41870
41871 const T h = (r1 - r0) / (T(2) * number_of_intervals);
41872 T total_area = T(0);
41873
41874 for (std::size_t i = 0; i < number_of_intervals; ++i)
41875 {
41876 x = r0 + T(2) * i * h;
41877 const T y0 = e.value(); x += h;
41878 const T y1 = e.value(); x += h;
41879 const T y2 = e.value(); x += h;
41880 total_area += h * (y0 + T(4) * y1 + y2) / T(3);
41881 }
41882
41883 return total_area;
41884 }
41885
41886 template <typename T>
41887 inline T integrate(const expression<T>& e,
41888 const std::string& variable_name,
41889 const T& r0, const T& r1,
41890 const std::size_t number_of_intervals = 1000000)
41891 {
41892 const symbol_table<T>& sym_table = e.get_symbol_table();
41893
41894 if (!sym_table.valid())
41895 {
41896 return std::numeric_limits<T>::quiet_NaN();
41897 }
41898
41899 details::variable_node<T>* var = sym_table.get_variable(variable_name);
41900
41901 if (var)
41902 {
41903 T& x = var->ref();
41904 const T x_original = x;
41905 const T result = integrate(e, x, r0, r1, number_of_intervals);
41906 x = x_original;
41907
41908 return result;
41909 }
41910
41911 return std::numeric_limits<T>::quiet_NaN();
41912 }
41913
41914 template <typename T>
41915 inline T derivative(const expression<T>& e,
41916 T& x,
41917 const T& h = T(0.00000001))
41918 {
41919 const T x_init = x;
41920 const T _2h = T(2) * h;
41921
41922 x = x_init + _2h;
41923 const T y0 = e.value();
41924 x = x_init + h;
41925 const T y1 = e.value();
41926 x = x_init - h;
41927 const T y2 = e.value();
41928 x = x_init - _2h;
41929 const T y3 = e.value();
41930 x = x_init;
41931
41932 return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
41933 }
41934
41935 template <typename T>
41936 inline T second_derivative(const expression<T>& e,
41937 T& x,
41938 const T& h = T(0.00001))
41939 {
41940 const T x_init = x;
41941 const T _2h = T(2) * h;
41942
41943 const T y = e.value();
41944 x = x_init + _2h;
41945 const T y0 = e.value();
41946 x = x_init + h;
41947 const T y1 = e.value();
41948 x = x_init - h;
41949 const T y2 = e.value();
41950 x = x_init - _2h;
41951 const T y3 = e.value();
41952 x = x_init;
41953
41954 return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
41955 }
41956
41957 template <typename T>
41958 inline T third_derivative(const expression<T>& e,
41959 T& x,
41960 const T& h = T(0.0001))
41961 {
41962 const T x_init = x;
41963 const T _2h = T(2) * h;
41964
41965 x = x_init + _2h;
41966 const T y0 = e.value();
41967 x = x_init + h;
41968 const T y1 = e.value();
41969 x = x_init - h;
41970 const T y2 = e.value();
41971 x = x_init - _2h;
41972 const T y3 = e.value();
41973 x = x_init;
41974
41975 return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
41976 }
41977
41978 template <typename T>
41979 inline T derivative(const expression<T>& e,
41980 const std::string& variable_name,
41981 const T& h = T(0.00000001))
41982 {
41983 const symbol_table<T>& sym_table = e.get_symbol_table();
41984
41985 if (!sym_table.valid())
41986 {
41987 return std::numeric_limits<T>::quiet_NaN();
41988 }
41989
41990 details::variable_node<T>* var = sym_table.get_variable(variable_name);
41991
41992 if (var)
41993 {
41994 T& x = var->ref();
41995 const T x_original = x;
41996 const T result = derivative(e, x, h);
41997 x = x_original;
41998
41999 return result;
42000 }
42001
42002 return std::numeric_limits<T>::quiet_NaN();
42003 }
42004
42005 template <typename T>
42006 inline T second_derivative(const expression<T>& e,
42007 const std::string& variable_name,
42008 const T& h = T(0.00001))
42009 {
42010 const symbol_table<T>& sym_table = e.get_symbol_table();
42011
42012 if (!sym_table.valid())
42013 {
42014 return std::numeric_limits<T>::quiet_NaN();
42015 }
42016
42017 details::variable_node<T>* var = sym_table.get_variable(variable_name);
42018
42019 if (var)
42020 {
42021 T& x = var->ref();
42022 const T x_original = x;
42023 const T result = second_derivative(e, x, h);
42024 x = x_original;
42025
42026 return result;
42027 }
42028
42029 return std::numeric_limits<T>::quiet_NaN();
42030 }
42031
42032 template <typename T>
42033 inline T third_derivative(const expression<T>& e,
42034 const std::string& variable_name,
42035 const T& h = T(0.0001))
42036 {
42037 const symbol_table<T>& sym_table = e.get_symbol_table();
42038
42039 if (!sym_table.valid())
42040 {
42041 return std::numeric_limits<T>::quiet_NaN();
42042 }
42043
42044 details::variable_node<T>* var = sym_table.get_variable(variable_name);
42045
42046 if (var)
42047 {
42048 T& x = var->ref();
42049 const T x_original = x;
42050 const T result = third_derivative(e, x, h);
42051 x = x_original;
42052
42053 return result;
42054 }
42055
42056 return std::numeric_limits<T>::quiet_NaN();
42057 }
42058
42059 /*
42060 Note: The following 'compute' routines are simple helpers,
42061 for quickly setting up the required pieces of code in order
42062 to evaluate an expression. By virtue of how they operate
42063 there will be an overhead with regards to their setup and
42064 teardown and hence should not be used in time critical
42065 sections of code.
42066 Furthermore they only assume a small sub set of variables,
42067 no string variables or user defined functions.
42068 */
42069 template <typename T>
42070 inline bool compute(const std::string& expression_string, T& result)
42071 {
42072 // No variables
42073 symbol_table<T> symbol_table;
42074 symbol_table.add_constants();
42075
42076 expression<T> expression;
42077 expression.register_symbol_table(symbol_table);
42078
42079 parser<T> parser;
42080
42081 if (parser.compile(expression_string,expression))
42082 {
42083 result = expression.value();
42084
42085 return true;
42086 }
42087 else
42088 return false;
42089 }
42090
42091 template <typename T>
42092 inline bool compute(const std::string& expression_string,
42093 const T& x,
42094 T& result)
42095 {
42096 // Only 'x'
42097 static const std::string x_var("x");
42098
42099 symbol_table<T> symbol_table;
42100 symbol_table.add_constants();
42101 symbol_table.add_constant(x_var,x);
42102
42103 expression<T> expression;
42104 expression.register_symbol_table(symbol_table);
42105
42106 parser<T> parser;
42107
42108 if (parser.compile(expression_string,expression))
42109 {
42110 result = expression.value();
42111
42112 return true;
42113 }
42114 else
42115 return false;
42116 }
42117
42118 template <typename T>
42119 inline bool compute(const std::string& expression_string,
42120 const T&x, const T& y,
42121 T& result)
42122 {
42123 // Only 'x' and 'y'
42124 static const std::string x_var("x");
42125 static const std::string y_var("y");
42126
42127 symbol_table<T> symbol_table;
42128 symbol_table.add_constants();
42129 symbol_table.add_constant(x_var,x);
42130 symbol_table.add_constant(y_var,y);
42131
42132 expression<T> expression;
42133 expression.register_symbol_table(symbol_table);
42134
42135 parser<T> parser;
42136
42137 if (parser.compile(expression_string,expression))
42138 {
42139 result = expression.value();
42140
42141 return true;
42142 }
42143 else
42144 return false;
42145 }
42146
42147 template <typename T>
42148 inline bool compute(const std::string& expression_string,
42149 const T& x, const T& y, const T& z,
42150 T& result)
42151 {
42152 // Only 'x', 'y' or 'z'
42153 static const std::string x_var("x");
42154 static const std::string y_var("y");
42155 static const std::string z_var("z");
42156
42157 symbol_table<T> symbol_table;
42158 symbol_table.add_constants();
42159 symbol_table.add_constant(x_var,x);
42160 symbol_table.add_constant(y_var,y);
42161 symbol_table.add_constant(z_var,z);
42162
42163 expression<T> expression;
42164 expression.register_symbol_table(symbol_table);
42165
42166 parser<T> parser;
42167
42168 if (parser.compile(expression_string,expression))
42169 {
42170 result = expression.value();
42171
42172 return true;
42173 }
42174 else
42175 return false;
42176 }
42177
42178 template <typename T, std::size_t N>
42179 class polynomial : public ifunction<T>
42180 {
42181 private:
42182
42183 template <typename Type, std::size_t NumberOfCoefficients>
42184 struct poly_impl { };
42185
42186 template <typename Type>
42187 struct poly_impl <Type,12>
42188 {
42189 static inline T evaluate(const Type x,
42190 const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
42191 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
42192 const Type c2, const Type c1, const Type c0)
42193 {
42194 // p(x) = c_12x^12 + c_11x^11 + c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42195 return ((((((((((((c12 * x + c11) * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42196 }
42197 };
42198
42199 template <typename Type>
42200 struct poly_impl <Type,11>
42201 {
42202 static inline T evaluate(const Type x,
42203 const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
42204 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
42205 const Type c1, const Type c0)
42206 {
42207 // p(x) = c_11x^11 + c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42208 return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42209 }
42210 };
42211
42212 template <typename Type>
42213 struct poly_impl <Type,10>
42214 {
42215 static inline T evaluate(const Type x,
42216 const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
42217 const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
42218 const Type c0)
42219 {
42220 // p(x) = c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42221 return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42222 }
42223 };
42224
42225 template <typename Type>
42226 struct poly_impl <Type,9>
42227 {
42228 static inline T evaluate(const Type x,
42229 const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
42230 const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
42231 {
42232 // p(x) = c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42233 return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42234 }
42235 };
42236
42237 template <typename Type>
42238 struct poly_impl <Type,8>
42239 {
42240 static inline T evaluate(const Type x,
42241 const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
42242 const Type c3, const Type c2, const Type c1, const Type c0)
42243 {
42244 // p(x) = c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42245 return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42246 }
42247 };
42248
42249 template <typename Type>
42250 struct poly_impl <Type,7>
42251 {
42252 static inline T evaluate(const Type x,
42253 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
42254 const Type c2, const Type c1, const Type c0)
42255 {
42256 // p(x) = c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42257 return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42258 }
42259 };
42260
42261 template <typename Type>
42262 struct poly_impl <Type,6>
42263 {
42264 static inline T evaluate(const Type x,
42265 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
42266 const Type c1, const Type c0)
42267 {
42268 // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42269 return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42270 }
42271 };
42272
42273 template <typename Type>
42274 struct poly_impl <Type,5>
42275 {
42276 static inline T evaluate(const Type x,
42277 const Type c5, const Type c4, const Type c3, const Type c2,
42278 const Type c1, const Type c0)
42279 {
42280 // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42281 return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42282 }
42283 };
42284
42285 template <typename Type>
42286 struct poly_impl <Type,4>
42287 {
42288 static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
42289 {
42290 // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42291 return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
42292 }
42293 };
42294
42295 template <typename Type>
42296 struct poly_impl <Type,3>
42297 {
42298 static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
42299 {
42300 // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42301 return (((c3 * x + c2) * x + c1) * x + c0);
42302 }
42303 };
42304
42305 template <typename Type>
42306 struct poly_impl <Type,2>
42307 {
42308 static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
42309 {
42310 // p(x) = c_2x^2 + c_1x^1 + c_0x^0
42311 return ((c2 * x + c1) * x + c0);
42312 }
42313 };
42314
42315 template <typename Type>
42316 struct poly_impl <Type,1>
42317 {
42318 static inline T evaluate(const Type x, const Type c1, const Type c0)
42319 {
42320 // p(x) = c_1x^1 + c_0x^0
42321 return (c1 * x + c0);
42322 }
42323 };
42324
42325 public:
42326
42327 using ifunction<T>::operator();
42328
42329 polynomial()
42330 : ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max())
42331 {
42333 }
42334
42335 virtual ~polynomial()
42336 {}
42337
42338 #define poly_rtrn(NN) \
42339 return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
42340
42341 inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override
42342 {
42343 poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0));
42344 }
42345
42346 inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override
42347 {
42348 poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0));
42349 }
42350
42351 inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42352 {
42353 poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0));
42354 }
42355
42356 inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1,
42357 const T& c0) exprtk_override
42358 {
42359 poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0));
42360 }
42361
42362 inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2,
42363 const T& c1, const T& c0) exprtk_override
42364 {
42365 poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0));
42366 }
42367
42368 inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3,
42369 const T& c2, const T& c1, const T& c0) exprtk_override
42370 {
42371 poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0));
42372 }
42373
42374 inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4,
42375 const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42376 {
42377 poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0));
42378 }
42379
42380 inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5,
42381 const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42382 {
42383 poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42384 }
42385
42386 inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6,
42387 const T& c5, const T& c4, const T& c3, const T& c2, const T& c1,
42388 const T& c0) exprtk_override
42389 {
42390 poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42391 }
42392
42393 inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7,
42394 const T& c6, const T& c5, const T& c4, const T& c3, const T& c2,
42395 const T& c1, const T& c0) exprtk_override
42396 {
42397 poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42398 }
42399
42400 inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8,
42401 const T& c7, const T& c6, const T& c5, const T& c4, const T& c3,
42402 const T& c2, const T& c1, const T& c0) exprtk_override
42403 {
42404 poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42405 }
42406
42407 inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9,
42408 const T& c8, const T& c7, const T& c6, const T& c5, const T& c4,
42409 const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42410 {
42411 poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42412 }
42413
42414 #undef poly_rtrn
42415
42416 inline virtual T operator() () exprtk_override
42417 {
42418 return std::numeric_limits<T>::quiet_NaN();
42419 }
42420
42421 inline virtual T operator() (const T&) exprtk_override
42422 {
42423 return std::numeric_limits<T>::quiet_NaN();
42424 }
42425
42426 inline virtual T operator() (const T&, const T&) exprtk_override
42427 {
42428 return std::numeric_limits<T>::quiet_NaN();
42429 }
42430 };
42431
42432 template <typename T>
42433 class function_compositor
42434 {
42435 public:
42436
42437 typedef exprtk::expression<T> expression_t;
42438 typedef exprtk::symbol_table<T> symbol_table_t;
42439 typedef exprtk::parser<T> parser_t;
42440 typedef typename parser_t::settings_store settings_t;
42441
42442 struct function
42443 {
42444 function()
42445 {}
42446
42447 function(const std::string& n)
42448 : name_(n)
42449 {}
42450
42451 function(const std::string& name,
42452 const std::string& expression)
42453 : name_(name)
42454 , expression_(expression)
42455 {}
42456
42457 function(const std::string& name,
42458 const std::string& expression,
42459 const std::string& v0)
42460 : name_(name)
42461 , expression_(expression)
42462 {
42463 v_.push_back(v0);
42464 }
42465
42466 function(const std::string& name,
42467 const std::string& expression,
42468 const std::string& v0, const std::string& v1)
42469 : name_(name)
42470 , expression_(expression)
42471 {
42472 v_.push_back(v0); v_.push_back(v1);
42473 }
42474
42475 function(const std::string& name,
42476 const std::string& expression,
42477 const std::string& v0, const std::string& v1,
42478 const std::string& v2)
42479 : name_(name)
42480 , expression_(expression)
42481 {
42482 v_.push_back(v0); v_.push_back(v1);
42483 v_.push_back(v2);
42484 }
42485
42486 function(const std::string& name,
42487 const std::string& expression,
42488 const std::string& v0, const std::string& v1,
42489 const std::string& v2, const std::string& v3)
42490 : name_(name)
42491 , expression_(expression)
42492 {
42493 v_.push_back(v0); v_.push_back(v1);
42494 v_.push_back(v2); v_.push_back(v3);
42495 }
42496
42497 function(const std::string& name,
42498 const std::string& expression,
42499 const std::string& v0, const std::string& v1,
42500 const std::string& v2, const std::string& v3,
42501 const std::string& v4)
42502 : name_(name)
42503 , expression_(expression)
42504 {
42505 v_.push_back(v0); v_.push_back(v1);
42506 v_.push_back(v2); v_.push_back(v3);
42507 v_.push_back(v4);
42508 }
42509
42510 inline function& name(const std::string& n)
42511 {
42512 name_ = n;
42513 return (*this);
42514 }
42515
42516 inline function& expression(const std::string& e)
42517 {
42518 expression_ = e;
42519 return (*this);
42520 }
42521
42522 inline function& var(const std::string& v)
42523 {
42524 v_.push_back(v);
42525 return (*this);
42526 }
42527
42528 inline function& vars(const std::string& v0,
42529 const std::string& v1)
42530 {
42531 v_.push_back(v0);
42532 v_.push_back(v1);
42533 return (*this);
42534 }
42535
42536 inline function& vars(const std::string& v0,
42537 const std::string& v1,
42538 const std::string& v2)
42539 {
42540 v_.push_back(v0);
42541 v_.push_back(v1);
42542 v_.push_back(v2);
42543 return (*this);
42544 }
42545
42546 inline function& vars(const std::string& v0,
42547 const std::string& v1,
42548 const std::string& v2,
42549 const std::string& v3)
42550 {
42551 v_.push_back(v0);
42552 v_.push_back(v1);
42553 v_.push_back(v2);
42554 v_.push_back(v3);
42555 return (*this);
42556 }
42557
42558 inline function& vars(const std::string& v0,
42559 const std::string& v1,
42560 const std::string& v2,
42561 const std::string& v3,
42562 const std::string& v4)
42563 {
42564 v_.push_back(v0);
42565 v_.push_back(v1);
42566 v_.push_back(v2);
42567 v_.push_back(v3);
42568 v_.push_back(v4);
42569 return (*this);
42570 }
42571
42572 std::string name_;
42573 std::string expression_;
42574 std::deque<std::string> v_;
42575 };
42576
42577 private:
42578
42579 struct base_func : public exprtk::ifunction<T>
42580 {
42581 typedef const T& type;
42582 typedef exprtk::ifunction<T> function_t;
42583 typedef std::vector<T*> varref_t;
42584 typedef std::vector<T> var_t;
42585 typedef std::vector<std::string> str_t;
42586 typedef std::pair<T*,std::size_t> lvarref_t;
42587 typedef std::vector<lvarref_t> lvr_vec_t;
42588 typedef std::vector<std::string*> lstr_vec_t;
42589
42590 using exprtk::ifunction<T>::operator();
42591
42592 base_func(const std::size_t& pc = 0)
42593 : exprtk::ifunction<T>(pc)
42594 , local_var_stack_size(0)
42595 , stack_depth(0)
42596 {
42597 v.resize(pc);
42598 }
42599
42600 virtual ~base_func()
42601 {}
42602
42603 #define exprtk_assign(Index) \
42604 (*v[Index]) = v##Index; \
42605
42606 inline void update(const T& v0)
42607 {
42608 exprtk_assign(0)
42609 }
42610
42611 inline void update(const T& v0, const T& v1)
42612 {
42614 }
42615
42616 inline void update(const T& v0, const T& v1, const T& v2)
42617 {
42619 exprtk_assign(2)
42620 }
42621
42622 inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
42623 {
42626 }
42627
42628 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
42629 {
42632 exprtk_assign(4)
42633 }
42634
42635 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
42636 {
42640 }
42641
42642 #ifdef exprtk_assign
42643 #undef exprtk_assign
42644 #endif
42645
42646 inline function_t& setup(expression_t& expr)
42647 {
42648 expression = expr;
42649
42650 typedef typename expression_t::control_block ctrlblk_t;
42651 typedef typename ctrlblk_t::local_data_list_t ldl_t;
42652 typedef typename ctrlblk_t::data_type data_t;
42653 typedef typename ldl_t::value_type ldl_value_type;
42654
42655 const ldl_t ldl = expr.local_data_list();
42656
42657 std::vector<std::pair<std::size_t,data_t> > index_list;
42658
42659 for (std::size_t i = 0; i < ldl.size(); ++i)
42660 {
42661 exprtk_debug(("base_func::setup() - element[%02d] type: %s size: %d\n",
42662 static_cast<int>(i),
42663 expression_t::control_block::to_str(ldl[i].type).c_str(),
42664 static_cast<int>(ldl[i].size)));
42665
42666 switch (ldl[i].type)
42667 {
42668 case ctrlblk_t::e_unknown : continue;
42669 case ctrlblk_t::e_expr : continue;
42670 case ctrlblk_t::e_vecholder : continue;
42671 default : break;
42672 }
42673
42674 if (ldl[i].size)
42675 {
42676 index_list.push_back(std::make_pair(i,ldl[i].type));
42677 }
42678 }
42679
42680 std::size_t input_param_count = 0;
42681
42682 for (std::size_t i = 0; i < index_list.size(); ++i)
42683 {
42684 const std::size_t index = index_list[i].first;
42685 const ldl_value_type& local_var = ldl[index];
42686
42687 assert(local_var.pointer);
42688
42689 if (i < (index_list.size() - v.size()))
42690 {
42691 if (local_var.type == ctrlblk_t::e_string)
42692 {
42693 local_str_vars.push_back(
42694 reinterpret_cast<std::string*>(local_var.pointer));
42695 }
42696 else if (
42697 (local_var.type == ctrlblk_t::e_data ) ||
42698 (local_var.type == ctrlblk_t::e_vecdata)
42699 )
42700 {
42701 local_vars.push_back(std::make_pair(
42702 reinterpret_cast<T*>(local_var.pointer),
42703 local_var.size));
42704
42705 local_var_stack_size += local_var.size;
42706 }
42707 }
42708 else
42709 {
42710 v[input_param_count++] = reinterpret_cast<T*>(local_var.pointer);
42711 }
42712 }
42713
42714 clear_stack();
42715
42716 return (*this);
42717 }
42718
42719 inline void pre()
42720 {
42721 if (stack_depth++)
42722 {
42723 if (!v.empty())
42724 {
42725 var_t var_stack(v.size(),T(0));
42726 copy(v,var_stack);
42727 input_params_stack.push_back(var_stack);
42728 }
42729
42730 if (!local_vars.empty())
42731 {
42732 var_t local_vec_frame(local_var_stack_size,T(0));
42733 copy(local_vars,local_vec_frame);
42734 local_var_stack.push_back(local_vec_frame);
42735 }
42736
42737 if (!local_str_vars.empty())
42738 {
42739 str_t local_str_frame(local_str_vars.size());
42740 copy(local_str_vars,local_str_frame);
42741 local_str_stack.push_back(local_str_frame);
42742 }
42743 }
42744 }
42745
42746 inline void post()
42747 {
42748 if (--stack_depth)
42749 {
42750 if (!v.empty())
42751 {
42752 copy(input_params_stack.back(), v);
42753 input_params_stack.pop_back();
42754 }
42755
42756 if (!local_vars.empty())
42757 {
42758 copy(local_var_stack.back(), local_vars);
42759 local_var_stack.pop_back();
42760 }
42761
42762 if (!local_str_vars.empty())
42763 {
42764 copy(local_str_stack.back(), local_str_vars);
42765 local_str_stack.pop_back();
42766 }
42767 }
42768 }
42769
42770 void copy(const varref_t& src_v, var_t& dest_v)
42771 {
42772 for (std::size_t i = 0; i < src_v.size(); ++i)
42773 {
42774 dest_v[i] = (*src_v[i]);
42775 }
42776 }
42777
42778 void copy(const lstr_vec_t& src_v, str_t& dest_v)
42779 {
42780 for (std::size_t i = 0; i < src_v.size(); ++i)
42781 {
42782 dest_v[i] = (*src_v[i]);
42783 }
42784 }
42785
42786 void copy(const var_t& src_v, varref_t& dest_v)
42787 {
42788 for (std::size_t i = 0; i < src_v.size(); ++i)
42789 {
42790 (*dest_v[i]) = src_v[i];
42791 }
42792 }
42793
42794 void copy(const lvr_vec_t& src_v, var_t& dest_v)
42795 {
42796 typename var_t::iterator itr = dest_v.begin();
42797 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
42798
42799 for (std::size_t i = 0; i < src_v.size(); ++i)
42800 {
42801 lvarref_t vr = src_v[i];
42802
42803 if (1 == vr.second)
42804 *itr++ = (*vr.first);
42805 else
42806 {
42807 std::copy(vr.first, vr.first + vr.second, itr);
42808 itr += static_cast<diff_t>(vr.second);
42809 }
42810 }
42811 }
42812
42813 void copy(const var_t& src_v, lvr_vec_t& dest_v)
42814 {
42815 typename var_t::const_iterator itr = src_v.begin();
42816 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
42817
42818 for (std::size_t i = 0; i < dest_v.size(); ++i)
42819 {
42820 lvarref_t& vr = dest_v[i];
42821
42822 assert(vr.first != 0);
42823 assert(vr.second > 0);
42824
42825 if (1 == vr.second)
42826 (*vr.first) = *itr++;
42827 else
42828 {
42829 std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first);
42830 itr += static_cast<diff_t>(vr.second);
42831 }
42832 }
42833 }
42834
42835 void copy(const str_t& src_str, lstr_vec_t& dest_str)
42836 {
42837 assert(src_str.size() == dest_str.size());
42838
42839 for (std::size_t i = 0; i < dest_str.size(); ++i)
42840 {
42841 *dest_str[i] = src_str[i];
42842 }
42843 }
42844
42845 inline void clear_stack()
42846 {
42847 for (std::size_t i = 0; i < v.size(); ++i)
42848 {
42849 (*v[i]) = 0;
42850 }
42851 }
42852
42853 inline virtual T value(expression_t& e)
42854 {
42855 return e.value();
42856 }
42857
42858 expression_t expression;
42859 varref_t v;
42860 lvr_vec_t local_vars;
42861 lstr_vec_t local_str_vars;
42862 std::size_t local_var_stack_size;
42863 std::size_t stack_depth;
42864 std::deque<var_t> input_params_stack;
42865 std::deque<var_t> local_var_stack;
42866 std::deque<str_t> local_str_stack;
42867 };
42868
42869 typedef std::map<std::string,base_func*> funcparam_t;
42870
42871 typedef const T& type;
42872
42873 template <typename BaseFuncType>
42874 struct scoped_bft
42875 {
42876 explicit scoped_bft(BaseFuncType& bft)
42877 : bft_(bft)
42878 {
42879 bft_.pre ();
42880 }
42881
42882 ~scoped_bft()
42883 {
42884 bft_.post();
42885 }
42886
42887 BaseFuncType& bft_;
42888
42889 private:
42890
42891 scoped_bft(const scoped_bft&) exprtk_delete;
42892 scoped_bft& operator=(const scoped_bft&) exprtk_delete;
42893 };
42894
42895 struct func_0param : public base_func
42896 {
42897 using exprtk::ifunction<T>::operator();
42898
42899 func_0param() : base_func(0) {}
42900
42901 inline T operator() () exprtk_override
42902 {
42903 scoped_bft<func_0param> sb(*this);
42904 return this->value(base_func::expression);
42905 }
42906 };
42907
42908 struct func_1param : public base_func
42909 {
42910 using exprtk::ifunction<T>::operator();
42911
42912 func_1param() : base_func(1) {}
42913
42914 inline T operator() (type v0) exprtk_override
42915 {
42916 scoped_bft<func_1param> sb(*this);
42917 base_func::update(v0);
42918 return this->value(base_func::expression);
42919 }
42920 };
42921
42922 struct func_2param : public base_func
42923 {
42924 using exprtk::ifunction<T>::operator();
42925
42926 func_2param() : base_func(2) {}
42927
42928 inline T operator() (type v0, type v1) exprtk_override
42929 {
42930 scoped_bft<func_2param> sb(*this);
42931 base_func::update(v0, v1);
42932 return this->value(base_func::expression);
42933 }
42934 };
42935
42936 struct func_3param : public base_func
42937 {
42938 using exprtk::ifunction<T>::operator();
42939
42940 func_3param() : base_func(3) {}
42941
42942 inline T operator() (type v0, type v1, type v2) exprtk_override
42943 {
42944 scoped_bft<func_3param> sb(*this);
42945 base_func::update(v0, v1, v2);
42946 return this->value(base_func::expression);
42947 }
42948 };
42949
42950 struct func_4param : public base_func
42951 {
42952 using exprtk::ifunction<T>::operator();
42953
42954 func_4param() : base_func(4) {}
42955
42956 inline T operator() (type v0, type v1, type v2, type v3) exprtk_override
42957 {
42958 scoped_bft<func_4param> sb(*this);
42959 base_func::update(v0, v1, v2, v3);
42960 return this->value(base_func::expression);
42961 }
42962 };
42963
42964 struct func_5param : public base_func
42965 {
42966 using exprtk::ifunction<T>::operator();
42967
42968 func_5param() : base_func(5) {}
42969
42970 inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override
42971 {
42972 scoped_bft<func_5param> sb(*this);
42973 base_func::update(v0, v1, v2, v3, v4);
42974 return this->value(base_func::expression);
42975 }
42976 };
42977
42978 struct func_6param : public base_func
42979 {
42980 using exprtk::ifunction<T>::operator();
42981
42982 func_6param() : base_func(6) {}
42983
42984 inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override
42985 {
42986 scoped_bft<func_6param> sb(*this);
42987 base_func::update(v0, v1, v2, v3, v4, v5);
42988 return this->value(base_func::expression);
42989 }
42990 };
42991
42992 static T return_value(expression_t& e)
42993 {
42994 typedef exprtk::results_context<T> results_context_t;
42995 typedef typename results_context_t::type_store_t type_t;
42996 typedef typename type_t::scalar_view scalar_t;
42997
42998 const T result = e.value();
42999
43000 if (e.return_invoked())
43001 {
43002 // Due to the post compilation checks, it can be safely
43003 // assumed that there will be at least one parameter
43004 // and that the first parameter will always be scalar.
43005 return scalar_t(e.results()[0])();
43006 }
43007
43008 return result;
43009 }
43010
43011 #define def_fp_retval(N) \
43012 struct func_##N##param_retval exprtk_final : public func_##N##param \
43013 { \
43014 inline T value(expression_t& e) exprtk_override \
43015 { \
43016 return return_value(e); \
43017 } \
43018 }; \
43019
43020 def_fp_retval(0)
43021 def_fp_retval(1)
43022 def_fp_retval(2)
43023 def_fp_retval(3)
43024 def_fp_retval(4)
43025 def_fp_retval(5)
43026 def_fp_retval(6)
43027
43028 #undef def_fp_retval
43029
43030 template <typename Allocator,
43031 template <typename, typename> class Sequence>
43032 inline bool add(const std::string& name,
43033 const std::string& expression,
43034 const Sequence<std::string,Allocator>& var_list,
43035 const bool override = false)
43036 {
43037 const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
43038
43039 if (expr_map_.end() != itr)
43040 {
43041 if (!override)
43042 {
43043 exprtk_debug(("Compositor error(add): function '%s' already defined\n",
43044 name.c_str()));
43045
43046 return false;
43047 }
43048
43049 remove(name, var_list.size());
43050 }
43051
43052 if (compile_expression(name, expression, var_list))
43053 {
43054 const std::size_t n = var_list.size();
43055
43056 fp_map_[n][name]->setup(expr_map_[name]);
43057
43058 return true;
43059 }
43060 else
43061 {
43062 exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n",
43063 name.c_str()));
43064
43065 return false;
43066 }
43067 }
43068
43069 public:
43070
43071 function_compositor()
43072 : parser_(settings_t::default_compile_all_opts +
43073 settings_t::e_disable_zero_return)
43074 , fp_map_(7)
43075 , load_variables_(false)
43076 , load_vectors_(false)
43077 {}
43078
43079 explicit function_compositor(const symbol_table_t& st)
43080 : symbol_table_(st)
43081 , parser_(settings_t::default_compile_all_opts +
43082 settings_t::e_disable_zero_return)
43083 , fp_map_(7)
43084 , load_variables_(false)
43085 , load_vectors_(false)
43086 {}
43087
43088 ~function_compositor()
43089 {
43090 clear();
43091 }
43092
43093 inline symbol_table_t& symbol_table()
43094 {
43095 return symbol_table_;
43096 }
43097
43098 inline const symbol_table_t& symbol_table() const
43099 {
43100 return symbol_table_;
43101 }
43102
43103 inline void add_auxiliary_symtab(symbol_table_t& symtab)
43104 {
43105 auxiliary_symtab_list_.push_back(&symtab);
43106 }
43107
43108 void load_variables(const bool load = true)
43109 {
43110 load_variables_ = load;
43111 }
43112
43113 void load_vectors(const bool load = true)
43114 {
43115 load_vectors_ = load;
43116 }
43117
43118 inline void register_loop_runtime_check(loop_runtime_check& lrtchk)
43119 {
43120 parser_.register_loop_runtime_check(lrtchk);
43121 }
43122
43123 inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk)
43124 {
43125 parser_.register_vector_access_runtime_check(vartchk);
43126 }
43127
43128 inline void register_compilation_timeout_check(compilation_check& compchk)
43129 {
43130 parser_.register_compilation_timeout_check(compchk);
43131 }
43132
43133 inline void clear_loop_runtime_check()
43134 {
43135 parser_.clear_loop_runtime_check();
43136 }
43137
43138 inline void clear_vector_access_runtime_check()
43139 {
43140 parser_.clear_vector_access_runtime_check();
43141 }
43142
43143 inline void clear_compilation_timeout_check()
43144 {
43145 parser_.clear_compilation_timeout_check();
43146 }
43147
43148 void clear()
43149 {
43150 symbol_table_.clear();
43151 expr_map_ .clear();
43152
43153 for (std::size_t i = 0; i < fp_map_.size(); ++i)
43154 {
43155 typename funcparam_t::iterator itr = fp_map_[i].begin();
43156 typename funcparam_t::iterator end = fp_map_[i].end ();
43157
43158 while (itr != end)
43159 {
43160 delete itr->second;
43161 ++itr;
43162 }
43163
43164 fp_map_[i].clear();
43165 }
43166
43167 clear_loop_runtime_check ();
43168 clear_vector_access_runtime_check();
43169 clear_compilation_timeout_check ();
43170 }
43171
43172 inline bool add(const function& f, const bool override = false)
43173 {
43174 return add(f.name_, f.expression_, f.v_,override);
43175 }
43176
43177 inline std::string error() const
43178 {
43179 if (!error_list_.empty())
43180 {
43181 return error_list_[0].diagnostic;
43182 }
43183 else
43184 return std::string("No Error");
43185 }
43186
43187 inline std::size_t error_count() const
43188 {
43189 return error_list_.size();
43190 }
43191
43192 inline parser_error::type get_error(const std::size_t& index) const
43193 {
43194 if (index < error_list_.size())
43195 {
43196 return error_list_[index];
43197 }
43198
43199 throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
43200 }
43201
43202 private:
43203
43204 template <typename Allocator,
43205 template <typename, typename> class Sequence>
43206 bool compile_expression(const std::string& name,
43207 const std::string& expression,
43208 const Sequence<std::string,Allocator>& input_var_list,
43209 bool return_present = false)
43210 {
43211 expression_t compiled_expression;
43212 symbol_table_t local_symbol_table;
43213
43214 local_symbol_table.load_from(symbol_table_);
43215 local_symbol_table.add_constants();
43216
43217 if (load_variables_)
43218 {
43219 local_symbol_table.load_variables_from(symbol_table_);
43220 }
43221
43222 if (load_vectors_)
43223 {
43224 local_symbol_table.load_vectors_from(symbol_table_);
43225 }
43226
43227 error_list_.clear();
43228
43229 if (!valid(name,input_var_list.size()))
43230 {
43231 parser_error::type error =
43232 parser_error::make_error(
43233 parser_error::e_parser,
43234 lexer::token(),
43235 "ERR274 - Function '" + name + "' is an invalid overload",
43237
43238 error_list_.push_back(error);
43239 return false;
43240 }
43241
43242 if (!forward(name,
43243 input_var_list.size(),
43244 local_symbol_table,
43245 return_present))
43246 return false;
43247
43248 compiled_expression.register_symbol_table(local_symbol_table);
43249
43250 for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i)
43251 {
43252 compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i]));
43253 }
43254
43255 std::string mod_expression;
43256
43257 for (std::size_t i = 0; i < input_var_list.size(); ++i)
43258 {
43259 mod_expression += " var " + input_var_list[i] + "{};\n";
43260 }
43261
43262 if (
43263 ('{' == details::front(expression)) &&
43264 ('}' == details::back (expression))
43265 )
43266 mod_expression += "~" + expression + ";";
43267 else
43268 mod_expression += "~{" + expression + "};";
43269
43270 if (!parser_.compile(mod_expression,compiled_expression))
43271 {
43272 exprtk_debug(("Compositor Error: %s\n", parser_.error().c_str()));
43273 exprtk_debug(("Compositor modified expression: \n%s\n", mod_expression.c_str()));
43274
43275 remove(name,input_var_list.size());
43276
43277 for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index)
43278 {
43279 error_list_.push_back(parser_.get_error(err_index));
43280 }
43281
43282 return false;
43283 }
43284
43285 if (!return_present && parser_.dec().return_present())
43286 {
43287 remove(name,input_var_list.size());
43288 return compile_expression(name, expression, input_var_list, true);
43289 }
43290
43291 // Make sure every return point has a scalar as its first parameter
43292 if (parser_.dec().return_present())
43293 {
43294 typedef std::vector<std::string> str_list_t;
43295
43296 str_list_t ret_param_list = parser_.dec().return_param_type_list();
43297
43298 for (std::size_t i = 0; i < ret_param_list.size(); ++i)
43299 {
43300 const std::string& params = ret_param_list[i];
43301
43302 if (params.empty() || ('T' != params[0]))
43303 {
43304 exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n",
43305 name.c_str()));
43306
43307 remove(name,input_var_list.size());
43308
43309 return false;
43310 }
43311 }
43312 }
43313
43314 expr_map_[name] = compiled_expression;
43315
43316 exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
43317
43318 if (symbol_table_.add_function(name,ifunc))
43319 return true;
43320 else
43321 {
43322 exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n",
43323 name.c_str()));
43324 return false;
43325 }
43326 }
43327
43328 inline bool symbol_used(const std::string& symbol) const
43329 {
43330 return (
43331 symbol_table_.is_variable (symbol) ||
43332 symbol_table_.is_stringvar (symbol) ||
43333 symbol_table_.is_function (symbol) ||
43334 symbol_table_.is_vector (symbol) ||
43335 symbol_table_.is_vararg_function(symbol)
43336 );
43337 }
43338
43339 inline bool valid(const std::string& name,
43340 const std::size_t& arg_count) const
43341 {
43342 if (arg_count > 6)
43343 return false;
43344 else if (symbol_used(name))
43345 return false;
43346 else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
43347 return false;
43348 else
43349 return true;
43350 }
43351
43352 inline bool forward(const std::string& name,
43353 const std::size_t& arg_count,
43354 symbol_table_t& sym_table,
43355 const bool ret_present = false)
43356 {
43357 switch (arg_count)
43358 {
43359 #define case_stmt(N) \
43360 case N : (fp_map_[arg_count])[name] = \
43361 (!ret_present) ? static_cast<base_func*> \
43362 (new func_##N##param) : \
43363 static_cast<base_func*> \
43364 (new func_##N##param_retval) ; \
43365 break; \
43366
43369 case_stmt(6)
43370 #undef case_stmt
43371 }
43372
43373 exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
43374
43375 return sym_table.add_function(name,ifunc);
43376 }
43377
43378 inline void remove(const std::string& name, const std::size_t& arg_count)
43379 {
43380 if (arg_count > 6)
43381 return;
43382
43383 const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
43384
43385 if (expr_map_.end() != em_itr)
43386 {
43387 expr_map_.erase(em_itr);
43388 }
43389
43390 const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
43391
43392 if (fp_map_[arg_count].end() != fp_itr)
43393 {
43394 delete fp_itr->second;
43395 fp_map_[arg_count].erase(fp_itr);
43396 }
43397
43398 symbol_table_.remove_function(name);
43399 }
43400
43401 private:
43402
43403 symbol_table_t symbol_table_;
43404 parser_t parser_;
43405 std::map<std::string,expression_t> expr_map_;
43406 std::vector<funcparam_t> fp_map_;
43407 std::vector<symbol_table_t*> auxiliary_symtab_list_;
43408 std::deque<parser_error::type> error_list_;
43409 bool load_variables_;
43410 bool load_vectors_;
43411 }; // class function_compositor
43412
43413} // namespace exprtk
43414
43415#if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43416# ifndef NOMINMAX
43417# define NOMINMAX
43418# endif
43419# ifndef WIN32_LEAN_AND_MEAN
43420# define WIN32_LEAN_AND_MEAN
43421# endif
43422# include <windows.h>
43423# include <ctime>
43424#else
43425# include <ctime>
43426# include <sys/time.h>
43427# include <sys/types.h>
43428#endif
43429
43430namespace exprtk
43431{
43432 class timer
43433 {
43434 public:
43435
43436 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43437 timer()
43438 : in_use_(false)
43439 , start_time_{ 0 }
43440 , stop_time_ { 0 }
43441 {
43442 QueryPerformanceFrequency(&clock_frequency_);
43443 }
43444
43445 inline void start()
43446 {
43447 in_use_ = true;
43448 QueryPerformanceCounter(&start_time_);
43449 }
43450
43451 inline void stop()
43452 {
43453 QueryPerformanceCounter(&stop_time_);
43454 in_use_ = false;
43455 }
43456
43457 inline double time() const
43458 {
43459 return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
43460 }
43461
43462 #else
43463
43464 timer()
43465 : in_use_(false)
43466 {
43467 start_time_.tv_sec = 0;
43468 start_time_.tv_usec = 0;
43469
43470 stop_time_.tv_sec = 0;
43471 stop_time_.tv_usec = 0;
43472 }
43473
43474 inline void start()
43475 {
43476 in_use_ = true;
43477 gettimeofday(&start_time_,0);
43478 }
43479
43480 inline void stop()
43481 {
43482 gettimeofday(&stop_time_, 0);
43483 in_use_ = false;
43484 }
43485
43486 inline unsigned long long int usec_time() const
43487 {
43488 if (!in_use_)
43489 {
43490 if (stop_time_.tv_sec >= start_time_.tv_sec)
43491 {
43492 return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec - start_time_.tv_sec ) +
43493 static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ;
43494 }
43495 else
43496 return std::numeric_limits<details::_uint64_t>::max();
43497 }
43498 else
43499 return std::numeric_limits<details::_uint64_t>::max();
43500 }
43501
43502 inline double time() const
43503 {
43504 return usec_time() * 0.000001;
43505 }
43506
43507 #endif
43508
43509 inline bool in_use() const
43510 {
43511 return in_use_;
43512 }
43513
43514 private:
43515
43516 bool in_use_;
43517
43518 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43519 LARGE_INTEGER start_time_;
43520 LARGE_INTEGER stop_time_;
43521 LARGE_INTEGER clock_frequency_;
43522 #else
43523 struct timeval start_time_;
43524 struct timeval stop_time_;
43525 #endif
43526 };
43527
43528 template <typename T>
43529 struct type_defs
43530 {
43531 typedef symbol_table<T> symbol_table_t;
43532 typedef expression<T> expression_t;
43533 typedef parser<T> parser_t;
43534 typedef parser_error::type error_t;
43535 typedef function_compositor<T> compositor_t;
43536 typedef typename compositor_t::function function_t;
43537 };
43538
43539} // namespace exprtk
43540
43541#ifndef exprtk_disable_rtl_io
43542namespace exprtk
43543{
43544 namespace rtl { namespace io { namespace details
43545 {
43546 template <typename T>
43547 inline void print_type(const std::string& fmt,
43548 const T v,
43550 {
43551 #if defined(__clang__)
43552 #pragma clang diagnostic push
43553 #pragma clang diagnostic ignored "-Wformat-nonliteral"
43554 #elif defined(__GNUC__) || defined(__GNUG__)
43555 #pragma GCC diagnostic push
43556 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
43557 #elif defined(_MSC_VER)
43558 #endif
43559
43560 printf(fmt.c_str(), v);
43561
43562 #if defined(__clang__)
43563 #pragma clang diagnostic pop
43564 #elif defined(__GNUC__) || defined(__GNUG__)
43565 #pragma GCC diagnostic pop
43566 #elif defined(_MSC_VER)
43567 #endif
43568 }
43569
43570 template <typename T>
43571 struct print_impl
43572 {
43573 typedef typename igeneric_function<T>::generic_type generic_type;
43574 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
43575 typedef typename generic_type::scalar_view scalar_t;
43576 typedef typename generic_type::vector_view vector_t;
43577 typedef typename generic_type::string_view string_t;
43579
43580 static void process(const std::string& scalar_format, parameter_list_t parameters)
43581 {
43582 for (std::size_t i = 0; i < parameters.size(); ++i)
43583 {
43584 generic_type& gt = parameters[i];
43585
43586 switch (gt.type)
43587 {
43588 case generic_type::e_scalar : print(scalar_format,scalar_t(gt));
43589 break;
43590
43591 case generic_type::e_vector : print(scalar_format,vector_t(gt));
43592 break;
43593
43594 case generic_type::e_string : print(string_t(gt));
43595 break;
43596
43597 default : continue;
43598 }
43599 }
43600 }
43601
43602 static inline void print(const std::string& scalar_format, const scalar_t& s)
43603 {
43604 print_type(scalar_format,s(),num_type());
43605 }
43606
43607 static inline void print(const std::string& scalar_format, const vector_t& v)
43608 {
43609 for (std::size_t i = 0; i < v.size(); ++i)
43610 {
43611 print_type(scalar_format,v[i],num_type());
43612
43613 if ((i + 1) < v.size())
43614 printf(" ");
43615 }
43616 }
43617
43618 static inline void print(const string_t& s)
43619 {
43620 printf("%s",to_str(s).c_str());
43621 }
43622 };
43623
43624 } // namespace exprtk::rtl::io::details
43625
43626 template <typename T>
43627 struct print exprtk_final : public exprtk::igeneric_function<T>
43628 {
43629 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
43630
43631 using exprtk::igeneric_function<T>::operator();
43632
43633 explicit print(const std::string& scalar_format = "%10.5f")
43634 : scalar_format_(scalar_format)
43635 {
43637 }
43638
43639 inline T operator() (parameter_list_t parameters) exprtk_override
43640 {
43641 details::print_impl<T>::process(scalar_format_,parameters);
43642 return T(0);
43643 }
43644
43645 std::string scalar_format_;
43646 };
43647
43648 template <typename T>
43649 struct println exprtk_final : public exprtk::igeneric_function<T>
43650 {
43651 typedef typename igeneric_function<T>::parameter_list_t parameter_list_t;
43652
43653 using exprtk::igeneric_function<T>::operator();
43654
43655 explicit println(const std::string& scalar_format = "%10.5f")
43656 : scalar_format_(scalar_format)
43657 {
43659 }
43660
43661 inline T operator() (parameter_list_t parameters) exprtk_override
43662 {
43663 details::print_impl<T>::process(scalar_format_,parameters);
43664 printf("\n");
43665 return T(0);
43666 }
43667
43668 std::string scalar_format_;
43669 };
43670
43671 template <typename T>
43672 struct package
43673 {
43674 print <T> p;
43675 println<T> pl;
43676
43677 bool register_package(exprtk::symbol_table<T>& symtab)
43678 {
43679 #define exprtk_register_function(FunctionName, FunctionType) \
43680 if (!symtab.add_function(FunctionName,FunctionType)) \
43681 { \
43682 exprtk_debug(( \
43683 "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
43684 FunctionName)); \
43685 return false; \
43686 } \
43687
43688 exprtk_register_function("print" , p )
43689 exprtk_register_function("println", pl)
43690 #undef exprtk_register_function
43691
43692 return true;
43693 }
43694 };
43695
43696 } // namespace exprtk::rtl::io
43697 } // namespace exprtk::rtl
43698} // namespace exprtk
43699#endif
43700
43701#ifndef exprtk_disable_rtl_io_file
43702#include <fstream>
43703namespace exprtk
43704{
43705 namespace rtl { namespace io { namespace file { namespace details
43706 {
43707 using ::exprtk::details::char_ptr;
43708 using ::exprtk::details::char_cptr;
43709
43710 enum file_mode
43711 {
43712 e_error = 0,
43713 e_read = 1,
43714 e_write = 2,
43715 e_rdwrt = 4
43716 };
43717
43718 struct file_descriptor
43719 {
43720 file_descriptor(const std::string& fname, const std::string& access)
43721 : stream_ptr(0)
43722 , mode(get_file_mode(access))
43723 , file_name(fname)
43724 {}
43725
43726 void* stream_ptr;
43727 file_mode mode;
43728 std::string file_name;
43729
43730 bool open()
43731 {
43732 if (e_read == mode)
43733 {
43734 std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary);
43735
43736 if (!(*stream))
43737 {
43738 file_name.clear();
43739 delete stream;
43740
43741 return false;
43742 }
43743
43744 stream_ptr = stream;
43745
43746 return true;
43747 }
43748 else if (e_write == mode)
43749 {
43750 std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary);
43751
43752 if (!(*stream))
43753 {
43754 file_name.clear();
43755 delete stream;
43756
43757 return false;
43758 }
43759
43760 stream_ptr = stream;
43761
43762 return true;
43763 }
43764 else if (e_rdwrt == mode)
43765 {
43766 std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary);
43767
43768 if (!(*stream))
43769 {
43770 file_name.clear();
43771 delete stream;
43772
43773 return false;
43774 }
43775
43776 stream_ptr = stream;
43777
43778 return true;
43779 }
43780
43781 return false;
43782 }
43783
43784 template <typename Stream, typename Ptr>
43785 void close(Ptr& p)
43786 {
43787 Stream* stream = reinterpret_cast<Stream*>(p);
43788 stream->close();
43789 delete stream;
43790 p = reinterpret_cast<Ptr>(0);
43791 }
43792
43793 bool close()
43794 {
43795 switch (mode)
43796 {
43797 case e_read : close<std::ifstream>(stream_ptr);
43798 break;
43799
43800 case e_write : close<std::ofstream>(stream_ptr);
43801 break;
43802
43803 case e_rdwrt : close<std::fstream> (stream_ptr);
43804 break;
43805
43806 default : return false;
43807 }
43808
43809 return true;
43810 }
43811
43812 template <typename View>
43813 bool write(const View& view, const std::size_t amount, const std::size_t offset = 0)
43814 {
43815 switch (mode)
43816 {
43817 case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)->
43818 write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
43819 break;
43820
43821 case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
43822 write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
43823 break;
43824
43825 default : return false;
43826 }
43827
43828 return true;
43829 }
43830
43831 template <typename View>
43832 bool read(View& view, const std::size_t amount, const std::size_t offset = 0)
43833 {
43834 switch (mode)
43835 {
43836 case e_read : reinterpret_cast<std::ifstream*>(stream_ptr)->
43837 read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
43838 break;
43839
43840 case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
43841 read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
43842 break;
43843
43844 default : return false;
43845 }
43846
43847 return true;
43848 }
43849
43850 bool getline(std::string& s)
43851 {
43852 switch (mode)
43853 {
43854 case e_read : return (!!std::getline(*reinterpret_cast<std::ifstream*>(stream_ptr),s));
43855 case e_rdwrt : return (!!std::getline(*reinterpret_cast<std::fstream* >(stream_ptr),s));
43856 default : return false;
43857 }
43858 }
43859
43860 bool eof() const
43861 {
43862 switch (mode)
43863 {
43864 case e_read : return reinterpret_cast<std::ifstream*>(stream_ptr)->eof();
43865 case e_write : return reinterpret_cast<std::ofstream*>(stream_ptr)->eof();
43866 case e_rdwrt : return reinterpret_cast<std::fstream* >(stream_ptr)->eof();
43867 default : return true;
43868 }
43869 }
43870
43871 file_mode get_file_mode(const std::string& access) const
43872 {
43873 if (access.empty() || access.size() > 2)
43874 return e_error;
43875
43876 std::size_t w_cnt = 0;
43877 std::size_t r_cnt = 0;
43878
43879 for (std::size_t i = 0; i < access.size(); ++i)
43880 {
43881 switch (std::tolower(access[i]))
43882 {
43883 case 'r' : r_cnt++; break;
43884 case 'w' : w_cnt++; break;
43885 default : return e_error;
43886 }
43887 }
43888
43889 if ((0 == r_cnt) && (0 == w_cnt))
43890 return e_error;
43891 else if ((r_cnt > 1) || (w_cnt > 1))
43892 return e_error;
43893 else if ((1 == r_cnt) && (1 == w_cnt))
43894 return e_rdwrt;
43895 else if (1 == r_cnt)
43896 return e_read;
43897 else
43898 return e_write;
43899 }
43900 };
43901
43902 template <typename T>
43903 file_descriptor* make_handle(T v)
43904 {
43905 const std::size_t fd_size = sizeof(details::file_descriptor*);
43906 details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
43907
43908 std::memcpy(reinterpret_cast<char_ptr >(&fd),
43909 reinterpret_cast<char_cptr>(&v ),
43910 fd_size);
43911 return fd;
43912 }
43913
43914 template <typename T>
43915 void perform_check()
43916 {
43917 #ifdef _MSC_VER
43918 #pragma warning(push)
43919 #pragma warning(disable: 4127)
43920 #endif
43921 if (sizeof(T) < sizeof(void*))
43922 {
43923 throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
43924 }
43925 #ifdef _MSC_VER
43926 #pragma warning(pop)
43927 #endif
43928 assert(sizeof(T) <= sizeof(void*));
43929 }
43930
43931 } // namespace exprtk::rtl::io::file::details
43932
43933 template <typename T>
43934 class open exprtk_final : public exprtk::igeneric_function<T>
43935 {
43936 public:
43937
43938 typedef typename exprtk::igeneric_function<T> igfun_t;
43939 typedef typename igfun_t::parameter_list_t parameter_list_t;
43940 typedef typename igfun_t::generic_type generic_type;
43941 typedef typename generic_type::string_view string_t;
43942
43943 using igfun_t::operator();
43944
43945 open()
43946 : exprtk::igeneric_function<T>("S|SS")
43947 { details::perform_check<T>(); }
43948
43949 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43950 {
43951 const std::string file_name = to_str(string_t(parameters[0]));
43952
43953 if (file_name.empty())
43954 {
43955 return T(0);
43956 }
43957
43958 if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
43959 {
43960 return T(0);
43961 }
43962
43963 const std::string access =
43964 (0 == ps_index) ? "r" : to_str(string_t(parameters[1]));
43965
43966 details::file_descriptor* fd = new details::file_descriptor(file_name,access);
43967
43968 if (fd->open())
43969 {
43970 T t = T(0);
43971
43972 const std::size_t fd_size = sizeof(details::file_descriptor*);
43973
43974 std::memcpy(reinterpret_cast<char*>(&t ),
43975 reinterpret_cast<char*>(&fd),
43976 fd_size);
43977 return t;
43978 }
43979 else
43980 {
43981 delete fd;
43982 return T(0);
43983 }
43984 }
43985 };
43986
43987 template <typename T>
43988 struct close exprtk_final : public exprtk::ifunction<T>
43989 {
43990 using exprtk::ifunction<T>::operator();
43991
43992 close()
43993 : exprtk::ifunction<T>(1)
43994 { details::perform_check<T>(); }
43995
43996 inline T operator() (const T& v) exprtk_override
43997 {
43998 details::file_descriptor* fd = details::make_handle(v);
43999
44000 if (!fd->close())
44001 return T(0);
44002
44003 delete fd;
44004
44005 return T(1);
44006 }
44007 };
44008
44009 template <typename T>
44010 class write exprtk_final : public exprtk::igeneric_function<T>
44011 {
44012 public:
44013
44014 typedef typename exprtk::igeneric_function<T> igfun_t;
44015 typedef typename igfun_t::parameter_list_t parameter_list_t;
44016 typedef typename igfun_t::generic_type generic_type;
44017 typedef typename generic_type::string_view string_t;
44018 typedef typename generic_type::scalar_view scalar_t;
44019 typedef typename generic_type::vector_view vector_t;
44020
44021 using igfun_t::operator();
44022
44023 write()
44024 : igfun_t("TS|TST|TV|TVT")
44025 { details::perform_check<T>(); }
44026
44027 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44028 {
44029 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
44030
44031 switch (ps_index)
44032 {
44033 case 0 : {
44034 const string_t buffer(parameters[1]);
44035 const std::size_t amount = buffer.size();
44036 return T(fd->write(buffer, amount) ? 1 : 0);
44037 }
44038
44039 case 1 : {
44040 const string_t buffer(parameters[1]);
44041 const std::size_t amount =
44042 std::min(buffer.size(),
44043 static_cast<std::size_t>(scalar_t(parameters[2])()));
44044 return T(fd->write(buffer, amount) ? 1 : 0);
44045 }
44046
44047 case 2 : {
44048 const vector_t vec(parameters[1]);
44049 const std::size_t amount = vec.size();
44050 return T(fd->write(vec, amount) ? 1 : 0);
44051 }
44052
44053 case 3 : {
44054 const vector_t vec(parameters[1]);
44055 const std::size_t amount =
44056 std::min(vec.size(),
44057 static_cast<std::size_t>(scalar_t(parameters[2])()));
44058 return T(fd->write(vec, amount) ? 1 : 0);
44059 }
44060 }
44061
44062 return T(0);
44063 }
44064 };
44065
44066 template <typename T>
44067 class read exprtk_final : public exprtk::igeneric_function<T>
44068 {
44069 public:
44070
44071 typedef typename exprtk::igeneric_function<T> igfun_t;
44072 typedef typename igfun_t::parameter_list_t parameter_list_t;
44073 typedef typename igfun_t::generic_type generic_type;
44074 typedef typename generic_type::string_view string_t;
44075 typedef typename generic_type::scalar_view scalar_t;
44076 typedef typename generic_type::vector_view vector_t;
44077
44078 using igfun_t::operator();
44079
44080 read()
44081 : igfun_t("TS|TST|TV|TVT")
44082 { details::perform_check<T>(); }
44083
44084 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44085 {
44086 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
44087
44088 switch (ps_index)
44089 {
44090 case 0 : {
44091 string_t buffer(parameters[1]);
44092 const std::size_t amount = buffer.size();
44093 return T(fd->read(buffer,amount) ? 1 : 0);
44094 }
44095
44096 case 1 : {
44097 string_t buffer(parameters[1]);
44098 const std::size_t amount =
44099 std::min(buffer.size(),
44100 static_cast<std::size_t>(scalar_t(parameters[2])()));
44101 return T(fd->read(buffer,amount) ? 1 : 0);
44102 }
44103
44104 case 2 : {
44105 vector_t vec(parameters[1]);
44106 const std::size_t amount = vec.size();
44107 return T(fd->read(vec,amount) ? 1 : 0);
44108 }
44109
44110 case 3 : {
44111 vector_t vec(parameters[1]);
44112 const std::size_t amount =
44113 std::min(vec.size(),
44114 static_cast<std::size_t>(scalar_t(parameters[2])()));
44115 return T(fd->read(vec,amount) ? 1 : 0);
44116 }
44117 }
44118
44119 return T(0);
44120 }
44121 };
44122
44123 template <typename T>
44124 class getline exprtk_final : public exprtk::igeneric_function<T>
44125 {
44126 public:
44127
44128 typedef typename exprtk::igeneric_function<T> igfun_t;
44129 typedef typename igfun_t::parameter_list_t parameter_list_t;
44130 typedef typename igfun_t::generic_type generic_type;
44131 typedef typename generic_type::string_view string_t;
44132 typedef typename generic_type::scalar_view scalar_t;
44133
44134 using igfun_t::operator();
44135
44136 getline()
44137 : igfun_t("T",igfun_t::e_rtrn_string)
44138 { details::perform_check<T>(); }
44139
44140 inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override
44141 {
44142 details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
44143 return T(fd->getline(result) ? 1 : 0);
44144 }
44145 };
44146
44147 template <typename T>
44148 struct eof exprtk_final : public exprtk::ifunction<T>
44149 {
44150 using exprtk::ifunction<T>::operator();
44151
44152 eof()
44153 : exprtk::ifunction<T>(1)
44154 { details::perform_check<T>(); }
44155
44156 inline T operator() (const T& v) exprtk_override
44157 {
44158 details::file_descriptor* fd = details::make_handle(v);
44159 return (fd->eof() ? T(1) : T(0));
44160 }
44161 };
44162
44163 template <typename T>
44164 struct package
44165 {
44166 open <T> o;
44167 close <T> c;
44168 write <T> w;
44169 read <T> r;
44170 getline<T> g;
44171 eof <T> e;
44172
44173 bool register_package(exprtk::symbol_table<T>& symtab)
44174 {
44175 #define exprtk_register_function(FunctionName, FunctionType) \
44176 if (!symtab.add_function(FunctionName,FunctionType)) \
44177 { \
44178 exprtk_debug(( \
44179 "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
44180 FunctionName)); \
44181 return false; \
44182 } \
44183
44184 exprtk_register_function("open" , o)
44185 exprtk_register_function("close" , c)
44186 exprtk_register_function("write" , w)
44187 exprtk_register_function("read" , r)
44188 exprtk_register_function("getline" , g)
44189 exprtk_register_function("eof" , e)
44190 #undef exprtk_register_function
44191
44192 return true;
44193 }
44194 };
44195
44196 } // namespace exprtk::rtl::io::file
44197 } // namespace exprtk::rtl::io
44198 } // namespace exprtk::rtl
44199} // namespace exprtk
44200#endif
44201
44202#ifndef exprtk_disable_rtl_vecops
44203namespace exprtk
44204{
44205 namespace rtl { namespace vecops {
44206
44207 namespace helper
44208 {
44209 template <typename Vector>
44210 inline bool invalid_range(const Vector& v, const std::size_t r0, const std::size_t r1)
44211 {
44212 if (r0 > (v.size() - 1))
44213 return true;
44214 else if (r1 > (v.size() - 1))
44215 return true;
44216 else if (r1 < r0)
44217 return true;
44218 else
44219 return false;
44220 }
44221
44222 template <typename T>
44223 struct load_vector_range
44224 {
44225 typedef typename exprtk::igeneric_function<T> igfun_t;
44226 typedef typename igfun_t::parameter_list_t parameter_list_t;
44227 typedef typename igfun_t::generic_type generic_type;
44228 typedef typename generic_type::scalar_view scalar_t;
44229 typedef typename generic_type::vector_view vector_t;
44230
44231 static inline bool process(parameter_list_t& parameters,
44232 std::size_t& r0, std::size_t& r1,
44233 const std::size_t& r0_prmidx,
44234 const std::size_t& r1_prmidx,
44235 const std::size_t vec_idx = 0)
44236 {
44237 if (r0_prmidx >= parameters.size())
44238 return false;
44239
44240 if (r1_prmidx >= parameters.size())
44241 return false;
44242
44243 if (!scalar_t(parameters[r0_prmidx]).to_uint(r0))
44244 return false;
44245
44246 if (!scalar_t(parameters[r1_prmidx]).to_uint(r1))
44247 return false;
44248
44249 return !invalid_range(vector_t(parameters[vec_idx]), r0, r1);
44250 }
44251 };
44252 }
44253
44254 namespace details
44255 {
44256 template <typename T>
44257 inline void kahan_sum(T& sum, T& error, const T v)
44258 {
44259 const T x = v - error;
44260 const T y = sum + x;
44261 error = (y - sum) - x;
44262 sum = y;
44263 }
44264
44265 } // namespace exprtk::rtl::details
44266
44267 template <typename T>
44268 class all_true exprtk_final : public exprtk::igeneric_function<T>
44269 {
44270 public:
44271
44272 typedef typename exprtk::igeneric_function<T> igfun_t;
44273 typedef typename igfun_t::parameter_list_t parameter_list_t;
44274 typedef typename igfun_t::generic_type generic_type;
44275 typedef typename generic_type::scalar_view scalar_t;
44276 typedef typename generic_type::vector_view vector_t;
44277
44278 using igfun_t::operator();
44279
44280 all_true()
44281 : exprtk::igeneric_function<T>("V|VTT|T*")
44282 /*
44283 Overloads:
44284 0. V - vector
44285 1. VTT - vector, r0, r1
44286 2. T* - T....T
44287 */
44288 {}
44289
44290 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44291 {
44292 if (2 == ps_index)
44293 {
44294 for (std::size_t i = 0; i < parameters.size(); ++i)
44295 {
44296 if (scalar_t(parameters[i])() == T(0))
44297 {
44298 return T(0);
44299 }
44300 }
44301 }
44302 else
44303 {
44304 const vector_t vec(parameters[0]);
44305
44306 std::size_t r0 = 0;
44307 std::size_t r1 = vec.size() - 1;
44308
44309 if (
44310 (1 == ps_index) &&
44311 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44312 )
44313 {
44314 return std::numeric_limits<T>::quiet_NaN();
44315 }
44316
44317 for (std::size_t i = r0; i <= r1; ++i)
44318 {
44319 if (vec[i] == T(0))
44320 {
44321 return T(0);
44322 }
44323 }
44324 }
44325
44326 return T(1);
44327 }
44328 };
44329
44330 template <typename T>
44331 class all_false exprtk_final : public exprtk::igeneric_function<T>
44332 {
44333 public:
44334
44335 typedef typename exprtk::igeneric_function<T> igfun_t;
44336 typedef typename igfun_t::parameter_list_t parameter_list_t;
44337 typedef typename igfun_t::generic_type generic_type;
44338 typedef typename generic_type::scalar_view scalar_t;
44339 typedef typename generic_type::vector_view vector_t;
44340
44341 using igfun_t::operator();
44342
44343 all_false()
44344 : exprtk::igeneric_function<T>("V|VTT|T*")
44345 /*
44346 Overloads:
44347 0. V - vector
44348 1. VTT - vector, r0, r1
44349 2. T* - T....T
44350 */
44351 {}
44352
44353 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44354 {
44355 if (2 == ps_index)
44356 {
44357 for (std::size_t i = 0; i < parameters.size(); ++i)
44358 {
44359 if (scalar_t(parameters[i])() != T(0))
44360 {
44361 return T(0);
44362 }
44363 }
44364 }
44365 else
44366 {
44367 const vector_t vec(parameters[0]);
44368
44369 std::size_t r0 = 0;
44370 std::size_t r1 = vec.size() - 1;
44371
44372 if (
44373 (1 == ps_index) &&
44374 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44375 )
44376 {
44377 return std::numeric_limits<T>::quiet_NaN();
44378 }
44379
44380 for (std::size_t i = r0; i <= r1; ++i)
44381 {
44382 if (vec[i] != T(0))
44383 {
44384 return T(0);
44385 }
44386 }
44387 }
44388
44389 return T(1);
44390 }
44391 };
44392
44393 template <typename T>
44394 class any_true exprtk_final : public exprtk::igeneric_function<T>
44395 {
44396 public:
44397
44398 typedef typename exprtk::igeneric_function<T> igfun_t;
44399 typedef typename igfun_t::parameter_list_t parameter_list_t;
44400 typedef typename igfun_t::generic_type generic_type;
44401 typedef typename generic_type::scalar_view scalar_t;
44402 typedef typename generic_type::vector_view vector_t;
44403
44404 using igfun_t::operator();
44405
44406 any_true()
44407 : exprtk::igeneric_function<T>("V|VTT|T*")
44408 /*
44409 Overloads:
44410 0. V - vector
44411 1. VTT - vector, r0, r1
44412 2. T* - T....T
44413 */
44414 {}
44415
44416 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44417 {
44418 if (2 == ps_index)
44419 {
44420 for (std::size_t i = 0; i < parameters.size(); ++i)
44421 {
44422 if (scalar_t(parameters[i])() != T(0))
44423 {
44424 return T(1);
44425 }
44426 }
44427 }
44428 else
44429 {
44430 const vector_t vec(parameters[0]);
44431
44432 std::size_t r0 = 0;
44433 std::size_t r1 = vec.size() - 1;
44434
44435 if (
44436 (1 == ps_index) &&
44437 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44438 )
44439 {
44440 return std::numeric_limits<T>::quiet_NaN();
44441 }
44442
44443 for (std::size_t i = r0; i <= r1; ++i)
44444 {
44445 if (vec[i] != T(0))
44446 {
44447 return T(1);
44448 }
44449 }
44450 }
44451
44452 return T(0);
44453 }
44454 };
44455
44456 template <typename T>
44457 class any_false exprtk_final : public exprtk::igeneric_function<T>
44458 {
44459 public:
44460
44461 typedef typename exprtk::igeneric_function<T> igfun_t;
44462 typedef typename igfun_t::parameter_list_t parameter_list_t;
44463 typedef typename igfun_t::generic_type generic_type;
44464 typedef typename generic_type::scalar_view scalar_t;
44465 typedef typename generic_type::vector_view vector_t;
44466
44467 using igfun_t::operator();
44468
44469 any_false()
44470 : exprtk::igeneric_function<T>("V|VTT|T*")
44471 /*
44472 Overloads:
44473 0. V - vector
44474 1. VTT - vector, r0, r1
44475 2. T* - T....T
44476 */
44477 {}
44478
44479 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44480 {
44481 if (2 == ps_index)
44482 {
44483 for (std::size_t i = 0; i < parameters.size(); ++i)
44484 {
44485 if (scalar_t(parameters[i])() == T(0))
44486 {
44487 return T(1);
44488 }
44489 }
44490 }
44491 else
44492 {
44493 const vector_t vec(parameters[0]);
44494
44495 std::size_t r0 = 0;
44496 std::size_t r1 = vec.size() - 1;
44497
44498 if (
44499 (1 == ps_index) &&
44500 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44501 )
44502 {
44503 return std::numeric_limits<T>::quiet_NaN();
44504 }
44505
44506 for (std::size_t i = r0; i <= r1; ++i)
44507 {
44508 if (vec[i] == T(0))
44509 {
44510 return T(1);
44511 }
44512 }
44513 }
44514
44515 return T(0);
44516 }
44517 };
44518
44519 template <typename T>
44520 class count exprtk_final : public exprtk::igeneric_function<T>
44521 {
44522 public:
44523
44524 typedef typename exprtk::igeneric_function<T> igfun_t;
44525 typedef typename igfun_t::parameter_list_t parameter_list_t;
44526 typedef typename igfun_t::generic_type generic_type;
44527 typedef typename generic_type::scalar_view scalar_t;
44528 typedef typename generic_type::vector_view vector_t;
44529
44530 using igfun_t::operator();
44531
44532 count()
44533 : exprtk::igeneric_function<T>("V|VTT|T*")
44534 /*
44535 Overloads:
44536 0. V - vector
44537 1. VTT - vector, r0, r1
44538 2. T* - T....T
44539 */
44540 {}
44541
44542 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44543 {
44544 std::size_t cnt = 0;
44545
44546 if (2 == ps_index)
44547 {
44548 for (std::size_t i = 0; i < parameters.size(); ++i)
44549 {
44550 if (scalar_t(parameters[i])() != T(0)) ++cnt;
44551 }
44552 }
44553 else
44554 {
44555 const vector_t vec(parameters[0]);
44556
44557 std::size_t r0 = 0;
44558 std::size_t r1 = vec.size() - 1;
44559
44560 if (
44561 (1 == ps_index) &&
44562 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44563 )
44564 {
44565 return std::numeric_limits<T>::quiet_NaN();
44566 }
44567
44568 for (std::size_t i = r0; i <= r1; ++i)
44569 {
44570 if (vec[i] != T(0)) ++cnt;
44571 }
44572 }
44573
44574 return T(cnt);
44575 }
44576 };
44577
44578 template <typename T>
44579 class copy exprtk_final : public exprtk::igeneric_function<T>
44580 {
44581 public:
44582
44583 typedef typename exprtk::igeneric_function<T> igfun_t;
44584 typedef typename igfun_t::parameter_list_t parameter_list_t;
44585 typedef typename igfun_t::generic_type generic_type;
44586 typedef typename generic_type::scalar_view scalar_t;
44587 typedef typename generic_type::vector_view vector_t;
44588
44589 using igfun_t::operator();
44590
44591 copy()
44592 : exprtk::igeneric_function<T>("VV|VTTVTT")
44593 /*
44594 Overloads:
44595 0. VV - x(vector), y(vector)
44596 1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1,
44597 */
44598 {}
44599
44600 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44601 {
44602 const vector_t x(parameters[0]);
44603 vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
44604
44605 std::size_t xr0 = 0;
44606 std::size_t xr1 = x.size() - 1;
44607
44608 std::size_t yr0 = 0;
44609 std::size_t yr1 = y.size() - 1;
44610
44611 if (1 == ps_index)
44612 {
44613 if (
44614 !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) ||
44615 !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3)
44616 )
44617 return T(0);
44618 }
44619
44620 const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1);
44621
44622 std::copy(
44623 x.begin() + xr0,
44624 x.begin() + xr0 + n,
44625 y.begin() + yr0);
44626
44627 return T(n);
44628 }
44629 };
44630
44631 template <typename T>
44632 class rol exprtk_final : public exprtk::igeneric_function<T>
44633 {
44634 public:
44635
44636 typedef typename exprtk::igeneric_function<T> igfun_t;
44637 typedef typename igfun_t::parameter_list_t parameter_list_t;
44638 typedef typename igfun_t::generic_type generic_type;
44639 typedef typename generic_type::scalar_view scalar_t;
44640 typedef typename generic_type::vector_view vector_t;
44641
44642 using igfun_t::operator();
44643
44644 rol()
44645 : exprtk::igeneric_function<T>("VT|VTTT")
44646 /*
44647 Overloads:
44648 0. VT - vector, N
44649 1. VTTT - vector, N, r0, r1
44650 */
44651 {}
44652
44653 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44654 {
44655 vector_t vec(parameters[0]);
44656
44657 std::size_t n = 0;
44658 std::size_t r0 = 0;
44659 std::size_t r1 = vec.size() - 1;
44660
44661 if (!scalar_t(parameters[1]).to_uint(n))
44662 return T(0);
44663
44664 if (
44665 (1 == ps_index) &&
44666 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44667 )
44668 return T(0);
44669
44670 const std::size_t dist = r1 - r0 + 1;
44671 const std::size_t shift = n % dist;
44672
44673 std::rotate(
44674 vec.begin() + r0,
44675 vec.begin() + r0 + shift,
44676 vec.begin() + r1 + 1);
44677
44678 return T(1);
44679 }
44680 };
44681
44682 template <typename T>
44683 class ror exprtk_final : public exprtk::igeneric_function<T>
44684 {
44685 public:
44686
44687 typedef typename exprtk::igeneric_function<T> igfun_t;
44688 typedef typename igfun_t::parameter_list_t parameter_list_t;
44689 typedef typename igfun_t::generic_type generic_type;
44690 typedef typename generic_type::scalar_view scalar_t;
44691 typedef typename generic_type::vector_view vector_t;
44692
44693 using igfun_t::operator();
44694
44695 ror()
44696 : exprtk::igeneric_function<T>("VT|VTTT")
44697 /*
44698 Overloads:
44699 0. VT - vector, N
44700 1. VTTT - vector, N, r0, r1
44701 */
44702 {}
44703
44704 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44705 {
44706 vector_t vec(parameters[0]);
44707
44708 std::size_t n = 0;
44709 std::size_t r0 = 0;
44710 std::size_t r1 = vec.size() - 1;
44711
44712 if (!scalar_t(parameters[1]).to_uint(n))
44713 return T(0);
44714
44715 if (
44716 (1 == ps_index) &&
44717 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44718 )
44719 return T(0);
44720
44721 const std::size_t dist = r1 - r0 + 1;
44722 const std::size_t shift = (dist - (n % dist)) % dist;
44723
44724 std::rotate(
44725 vec.begin() + r0,
44726 vec.begin() + r0 + shift,
44727 vec.begin() + r1 + 1);
44728
44729 return T(1);
44730 }
44731 };
44732
44733 template <typename T>
44734 class reverse exprtk_final : public exprtk::igeneric_function<T>
44735 {
44736 public:
44737
44738 typedef typename exprtk::igeneric_function<T> igfun_t;
44739 typedef typename igfun_t::parameter_list_t parameter_list_t;
44740 typedef typename igfun_t::generic_type generic_type;
44741 typedef typename generic_type::scalar_view scalar_t;
44742 typedef typename generic_type::vector_view vector_t;
44743
44744 using igfun_t::operator();
44745
44746 reverse()
44747 : exprtk::igeneric_function<T>("V|VTT")
44748 /*
44749 Overloads:
44750 0. V - vector
44751 1. VTT - vector, r0, r1
44752 */
44753 {}
44754
44755 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44756 {
44757 vector_t vec(parameters[0]);
44758
44759 std::size_t r0 = 0;
44760 std::size_t r1 = vec.size() - 1;
44761
44762 if (
44763 (1 == ps_index) &&
44764 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44765 )
44766 return T(0);
44767
44768 std::reverse(vec.begin() + r0, vec.begin() + r1 + 1);
44769
44770 return T(1);
44771 }
44772 };
44773
44774 template <typename T>
44775 class shift_left exprtk_final : public exprtk::igeneric_function<T>
44776 {
44777 public:
44778
44779 typedef typename exprtk::igeneric_function<T> igfun_t;
44780 typedef typename igfun_t::parameter_list_t parameter_list_t;
44781 typedef typename igfun_t::generic_type generic_type;
44782 typedef typename generic_type::scalar_view scalar_t;
44783 typedef typename generic_type::vector_view vector_t;
44784
44785 using igfun_t::operator();
44786
44787 shift_left()
44788 : exprtk::igeneric_function<T>("VT|VTTT")
44789 /*
44790 Overloads:
44791 0. VT - vector, N
44792 1. VTTT - vector, N, r0, r1
44793 */
44794 {}
44795
44796 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44797 {
44798 vector_t vec(parameters[0]);
44799
44800 std::size_t n = 0;
44801 std::size_t r0 = 0;
44802 std::size_t r1 = vec.size() - 1;
44803
44804 if (!scalar_t(parameters[1]).to_uint(n))
44805 return T(0);
44806
44807 if (
44808 (1 == ps_index) &&
44809 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44810 )
44811 return T(0);
44812
44813 const std::size_t dist = r1 - r0 + 1;
44814
44815 if (n > dist)
44816 return T(0);
44817
44818 std::rotate(
44819 vec.begin() + r0,
44820 vec.begin() + r0 + n,
44821 vec.begin() + r1 + 1);
44822
44823 for (std::size_t i = r1 - n + 1; i <= r1; ++i)
44824 {
44825 vec[i] = T(0);
44826 }
44827
44828 return T(1);
44829 }
44830 };
44831
44832 template <typename T>
44833 class shift_right exprtk_final : public exprtk::igeneric_function<T>
44834 {
44835 public:
44836
44837 typedef typename exprtk::igeneric_function<T> igfun_t;
44838 typedef typename igfun_t::parameter_list_t parameter_list_t;
44839 typedef typename igfun_t::generic_type generic_type;
44840 typedef typename generic_type::scalar_view scalar_t;
44841 typedef typename generic_type::vector_view vector_t;
44842
44843 using igfun_t::operator();
44844
44845 shift_right()
44846 : exprtk::igeneric_function<T>("VT|VTTT")
44847 /*
44848 Overloads:
44849 0. VT - vector, N
44850 1. VTTT - vector, N, r0, r1
44851 */
44852 {}
44853
44854 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44855 {
44856 vector_t vec(parameters[0]);
44857
44858 std::size_t n = 0;
44859 std::size_t r0 = 0;
44860 std::size_t r1 = vec.size() - 1;
44861
44862 if (!scalar_t(parameters[1]).to_uint(n))
44863 return T(0);
44864
44865 if (
44866 (1 == ps_index) &&
44867 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44868 )
44869 return T(0);
44870
44871 const std::size_t dist = r1 - r0 + 1;
44872
44873 if (n > dist)
44874 return T(0);
44875
44876 const std::size_t shift = (dist - (n % dist)) % dist;
44877
44878 std::rotate(
44879 vec.begin() + r0,
44880 vec.begin() + r0 + shift,
44881 vec.begin() + r1 + 1);
44882
44883 for (std::size_t i = r0; i < r0 + n; ++i)
44884 {
44885 vec[i] = T(0);
44886 }
44887
44888 return T(1);
44889 }
44890 };
44891
44892 template <typename T>
44893 class sort exprtk_final : public exprtk::igeneric_function<T>
44894 {
44895 public:
44896
44897 typedef typename exprtk::igeneric_function<T> igfun_t;
44898 typedef typename igfun_t::parameter_list_t parameter_list_t;
44899 typedef typename igfun_t::generic_type generic_type;
44900 typedef typename generic_type::string_view string_t;
44901 typedef typename generic_type::vector_view vector_t;
44902
44903 using igfun_t::operator();
44904
44905 sort()
44906 : exprtk::igeneric_function<T>("V|VTT|VS|VSTT")
44907 /*
44908 Overloads:
44909 0. V - vector
44910 1. VTT - vector, r0, r1
44911 2. VS - vector, string
44912 3. VSTT - vector, string, r0, r1
44913 */
44914 {}
44915
44916 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44917 {
44918 vector_t vec(parameters[0]);
44919
44920 std::size_t r0 = 0;
44921 std::size_t r1 = vec.size() - 1;
44922
44923 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
44924 return T(0);
44925 if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
44926 return T(0);
44927
44928 bool ascending = true;
44929
44930 if ((2 == ps_index) || (3 == ps_index))
44931 {
44932 if (exprtk::details::imatch(to_str(string_t(parameters[1])),"ascending"))
44933 ascending = true;
44934 else if (exprtk::details::imatch(to_str(string_t(parameters[1])),"descending"))
44935 ascending = false;
44936 else
44937 return T(0);
44938 }
44939
44940 if (ascending)
44941 std::sort(
44942 vec.begin() + r0,
44943 vec.begin() + r1 + 1,
44944 std::less<T>());
44945 else
44946 std::sort(
44947 vec.begin() + r0,
44948 vec.begin() + r1 + 1,
44949 std::greater<T>());
44950
44951 return T(1);
44952 }
44953 };
44954
44955 template <typename T>
44956 class nthelement exprtk_final : public exprtk::igeneric_function<T>
44957 {
44958 public:
44959
44960 typedef typename exprtk::igeneric_function<T> igfun_t;
44961 typedef typename igfun_t::parameter_list_t parameter_list_t;
44962 typedef typename igfun_t::generic_type generic_type;
44963 typedef typename generic_type::scalar_view scalar_t;
44964 typedef typename generic_type::vector_view vector_t;
44965
44966 using igfun_t::operator();
44967
44968 nthelement()
44969 : exprtk::igeneric_function<T>("VT|VTTT")
44970 /*
44971 Overloads:
44972 0. VT - vector, nth-element
44973 1. VTTT - vector, nth-element, r0, r1
44974 */
44975 {}
44976
44977 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44978 {
44979 vector_t vec(parameters[0]);
44980
44981 std::size_t n = 0;
44982 std::size_t r0 = 0;
44983 std::size_t r1 = vec.size() - 1;
44984
44985 if (!scalar_t(parameters[1]).to_uint(n))
44986 return T(0);
44987
44988 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
44989 {
44990 return std::numeric_limits<T>::quiet_NaN();
44991 }
44992
44993 std::nth_element(
44994 vec.begin() + r0,
44995 vec.begin() + r0 + n ,
44996 vec.begin() + r1 + 1);
44997
44998 return T(1);
44999 }
45000 };
45001
45002 template <typename T>
45003 class assign exprtk_final : public exprtk::igeneric_function<T>
45004 {
45005 public:
45006
45007 typedef typename exprtk::igeneric_function<T> igfun_t;
45008 typedef typename igfun_t::parameter_list_t parameter_list_t;
45009 typedef typename igfun_t::generic_type generic_type;
45010 typedef typename generic_type::scalar_view scalar_t;
45011 typedef typename generic_type::vector_view vector_t;
45012
45013 using igfun_t::operator();
45014
45015 assign()
45016 : exprtk::igeneric_function<T>("VT|VTTT|VTTTT")
45017 /*
45018 Overloads:
45019 0. VT - vector, V
45020 1. VTTT - vector, V, r0, r1
45021 2. VTTTT - vector, V, r0, r1, SS
45022 */
45023 {}
45024
45025 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45026 {
45027 vector_t vec(parameters[0]);
45028
45029 const T assign_value = scalar_t(parameters[1]);
45030
45031 const std::size_t step_size = (2 != ps_index) ? 1 :
45032 static_cast<std::size_t>(scalar_t(parameters.back())());
45033
45034 std::size_t r0 = 0;
45035 std::size_t r1 = vec.size() - 1;
45036
45037 if (
45038 ((ps_index == 1) || (ps_index == 2)) &&
45039 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
45040 )
45041 {
45042 return T(0);
45043 }
45044
45045 for (std::size_t i = r0; i <= r1; i += step_size)
45046 {
45047 vec[i] = assign_value;
45048 }
45049
45050 return T(1);
45051 }
45052 };
45053
45054 template <typename T>
45055 class iota exprtk_final : public exprtk::igeneric_function<T>
45056 {
45057 public:
45058
45059 typedef typename exprtk::igeneric_function<T> igfun_t;
45060 typedef typename igfun_t::parameter_list_t parameter_list_t;
45061 typedef typename igfun_t::generic_type generic_type;
45062 typedef typename generic_type::scalar_view scalar_t;
45063 typedef typename generic_type::vector_view vector_t;
45064
45065 using igfun_t::operator();
45066
45067 iota()
45068 : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT")
45069 /*
45070 Overloads:
45071 0. VTT - vector, SV, SS
45072 1. VT - vector, SV, SS (+1)
45073 2. VTTT - vector, r0, r1, SV, SS
45074 3. VTT - vector, r0, r1, SV, SS (+1)
45075
45076 Where:
45077 1. SV - Start value
45078 2. SS - Step size
45079 */
45080 {}
45081
45082 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45083 {
45084 vector_t vec(parameters[0]);
45085
45086 const T start_value = (ps_index <= 1) ?
45087 scalar_t(parameters[1]) :
45088 scalar_t(parameters[3]) ;
45089
45090 const T step_size = ((0 == ps_index) || (2 == ps_index)) ?
45091 scalar_t(parameters.back())() :
45092 T(1) ;
45093
45094 std::size_t r0 = 0;
45095 std::size_t r1 = vec.size() - 1;
45096
45097 if (
45098 ((ps_index == 2) || (ps_index == 3)) &&
45099 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45100 )
45101 {
45102 return T(0);
45103 }
45104
45105 for (std::size_t i = r0; i <= r1; ++i)
45106 {
45107 vec[i] = start_value + ((i - r0) * step_size);
45108 }
45109
45110 return T(1);
45111 }
45112 };
45113
45114 template <typename T>
45115 class sumk exprtk_final : public exprtk::igeneric_function<T>
45116 {
45117 public:
45118
45119 typedef typename exprtk::igeneric_function<T> igfun_t;
45120 typedef typename igfun_t::parameter_list_t parameter_list_t;
45121 typedef typename igfun_t::generic_type generic_type;
45122 typedef typename generic_type::scalar_view scalar_t;
45123 typedef typename generic_type::vector_view vector_t;
45124
45125 using igfun_t::operator();
45126
45127 sumk()
45128 : exprtk::igeneric_function<T>("V|VTT|VTTT")
45129 /*
45130 Overloads:
45131 0. V - vector
45132 1. VTT - vector, r0, r1
45133 2. VTTT - vector, r0, r1, stride
45134 */
45135 {}
45136
45137 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45138 {
45139 const vector_t vec(parameters[0]);
45140
45141 const std::size_t stride = (2 != ps_index) ? 1 :
45142 static_cast<std::size_t>(scalar_t(parameters[3])());
45143
45144 std::size_t r0 = 0;
45145 std::size_t r1 = vec.size() - 1;
45146
45147 if (
45148 ((1 == ps_index) || (2 == ps_index)) &&
45149 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45150 )
45151 {
45152 return std::numeric_limits<T>::quiet_NaN();
45153 }
45154
45155 T result = T(0);
45156 T error = T(0);
45157
45158 for (std::size_t i = r0; i <= r1; i += stride)
45159 {
45160 details::kahan_sum(result, error, vec[i]);
45161 }
45162
45163 return result;
45164 }
45165 };
45166
45167 template <typename T>
45168 class axpy exprtk_final : public exprtk::igeneric_function<T>
45169 {
45170 public:
45171
45172 typedef typename exprtk::igeneric_function<T> igfun_t;
45173 typedef typename igfun_t::parameter_list_t parameter_list_t;
45174 typedef typename igfun_t::generic_type generic_type;
45175 typedef typename generic_type::scalar_view scalar_t;
45176 typedef typename generic_type::vector_view vector_t;
45177
45178 using igfun_t::operator();
45179
45180 axpy()
45181 : exprtk::igeneric_function<T>("TVV|TVVTT")
45182 /*
45183 y <- ax + y
45184 Overloads:
45185 0. TVV - a, x(vector), y(vector)
45186 1. TVVTT - a, x(vector), y(vector), r0, r1
45187 */
45188 {}
45189
45190 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45191 {
45192 const vector_t x(parameters[1]);
45193 vector_t y(parameters[2]);
45194
45195 std::size_t r0 = 0;
45196 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45197
45198 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
45199 return std::numeric_limits<T>::quiet_NaN();
45200 else if (helper::invalid_range(y, r0, r1))
45201 return std::numeric_limits<T>::quiet_NaN();
45202
45203 const T a = scalar_t(parameters[0])();
45204
45205 for (std::size_t i = r0; i <= r1; ++i)
45206 {
45207 y[i] = (a * x[i]) + y[i];
45208 }
45209
45210 return T(1);
45211 }
45212 };
45213
45214 template <typename T>
45215 class axpby exprtk_final : public exprtk::igeneric_function<T>
45216 {
45217 public:
45218
45219 typedef typename exprtk::igeneric_function<T> igfun_t;
45220 typedef typename igfun_t::parameter_list_t parameter_list_t;
45221 typedef typename igfun_t::generic_type generic_type;
45222 typedef typename generic_type::scalar_view scalar_t;
45223 typedef typename generic_type::vector_view vector_t;
45224
45225 using igfun_t::operator();
45226
45227 axpby()
45228 : exprtk::igeneric_function<T>("TVTV|TVTVTT")
45229 /*
45230 y <- ax + by
45231 Overloads:
45232 0. TVTV - a, x(vector), b, y(vector)
45233 1. TVTVTT - a, x(vector), b, y(vector), r0, r1
45234 */
45235 {}
45236
45237 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45238 {
45239 const vector_t x(parameters[1]);
45240 vector_t y(parameters[3]);
45241
45242 std::size_t r0 = 0;
45243 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45244
45245 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45246 return std::numeric_limits<T>::quiet_NaN();
45247 else if (helper::invalid_range(y, r0, r1))
45248 return std::numeric_limits<T>::quiet_NaN();
45249
45250 const T a = scalar_t(parameters[0])();
45251 const T b = scalar_t(parameters[2])();
45252
45253 for (std::size_t i = r0; i <= r1; ++i)
45254 {
45255 y[i] = (a * x[i]) + (b * y[i]);
45256 }
45257
45258 return T(1);
45259 }
45260 };
45261
45262 template <typename T>
45263 class axpyz exprtk_final : public exprtk::igeneric_function<T>
45264 {
45265 public:
45266
45267 typedef typename exprtk::igeneric_function<T> igfun_t;
45268 typedef typename igfun_t::parameter_list_t parameter_list_t;
45269 typedef typename igfun_t::generic_type generic_type;
45270 typedef typename generic_type::scalar_view scalar_t;
45271 typedef typename generic_type::vector_view vector_t;
45272
45273 using igfun_t::operator();
45274
45275 axpyz()
45276 : exprtk::igeneric_function<T>("TVVV|TVVVTT")
45277 /*
45278 z <- ax + y
45279 Overloads:
45280 0. TVVV - a, x(vector), y(vector), z(vector)
45281 1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1
45282 */
45283 {}
45284
45285 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45286 {
45287 const vector_t x(parameters[1]);
45288 const vector_t y(parameters[2]);
45289 vector_t z(parameters[3]);
45290
45291 std::size_t r0 = 0;
45292 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45293
45294 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45295 return std::numeric_limits<T>::quiet_NaN();
45296 else if (helper::invalid_range(y, r0, r1))
45297 return std::numeric_limits<T>::quiet_NaN();
45298 else if (helper::invalid_range(z, r0, r1))
45299 return std::numeric_limits<T>::quiet_NaN();
45300
45301 const T a = scalar_t(parameters[0])();
45302
45303 for (std::size_t i = r0; i <= r1; ++i)
45304 {
45305 z[i] = (a * x[i]) + y[i];
45306 }
45307
45308 return T(1);
45309 }
45310 };
45311
45312 template <typename T>
45313 class axpbyz exprtk_final : public exprtk::igeneric_function<T>
45314 {
45315 public:
45316
45317 typedef typename exprtk::igeneric_function<T> igfun_t;
45318 typedef typename igfun_t::parameter_list_t parameter_list_t;
45319 typedef typename igfun_t::generic_type generic_type;
45320 typedef typename generic_type::scalar_view scalar_t;
45321 typedef typename generic_type::vector_view vector_t;
45322
45323 using igfun_t::operator();
45324
45325 axpbyz()
45326 : exprtk::igeneric_function<T>("TVTVV|TVTVVTT")
45327 /*
45328 z <- ax + by
45329 Overloads:
45330 0. TVTVV - a, x(vector), b, y(vector), z(vector)
45331 1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1
45332 */
45333 {}
45334
45335 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45336 {
45337 const vector_t x(parameters[1]);
45338 const vector_t y(parameters[3]);
45339 vector_t z(parameters[4]);
45340
45341 std::size_t r0 = 0;
45342 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45343
45344 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
45345 return std::numeric_limits<T>::quiet_NaN();
45346 else if (helper::invalid_range(y, r0, r1))
45347 return std::numeric_limits<T>::quiet_NaN();
45348 else if (helper::invalid_range(z, r0, r1))
45349 return std::numeric_limits<T>::quiet_NaN();
45350
45351 const T a = scalar_t(parameters[0])();
45352 const T b = scalar_t(parameters[2])();
45353
45354 for (std::size_t i = r0; i <= r1; ++i)
45355 {
45356 z[i] = (a * x[i]) + (b * y[i]);
45357 }
45358
45359 return T(1);
45360 }
45361 };
45362
45363 template <typename T>
45364 class axpbsy exprtk_final : public exprtk::igeneric_function<T>
45365 {
45366 public:
45367
45368 typedef typename exprtk::igeneric_function<T> igfun_t;
45369 typedef typename igfun_t::parameter_list_t parameter_list_t;
45370 typedef typename igfun_t::generic_type generic_type;
45371 typedef typename generic_type::scalar_view scalar_t;
45372 typedef typename generic_type::vector_view vector_t;
45373
45374 using igfun_t::operator();
45375
45376 axpbsy()
45377 : exprtk::igeneric_function<T>("TVTTV|TVTTVTT")
45378 /*
45379 y <- ax + by
45380 Overloads:
45381 0. TVTVV - a, x(vector), b, shift, y(vector), z(vector)
45382 1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
45383 */
45384 {}
45385
45386 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45387 {
45388 const vector_t x(parameters[1]);
45389 vector_t y(parameters[4]);
45390
45391 std::size_t r0 = 0;
45392 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45393
45394 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
45395 return std::numeric_limits<T>::quiet_NaN();
45396 else if (helper::invalid_range(y, r0, r1))
45397 return std::numeric_limits<T>::quiet_NaN();
45398
45399 const T a = scalar_t(parameters[0])();
45400 const T b = scalar_t(parameters[2])();
45401
45402 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
45403
45404 for (std::size_t i = r0; i <= r1; ++i)
45405 {
45406 y[i] = (a * x[i]) + (b * y[i + s]);
45407 }
45408
45409 return T(1);
45410 }
45411 };
45412
45413 template <typename T>
45414 class axpbsyz exprtk_final : public exprtk::igeneric_function<T>
45415 {
45416 public:
45417
45418 typedef typename exprtk::igeneric_function<T> igfun_t;
45419 typedef typename igfun_t::parameter_list_t parameter_list_t;
45420 typedef typename igfun_t::generic_type generic_type;
45421 typedef typename generic_type::scalar_view scalar_t;
45422 typedef typename generic_type::vector_view vector_t;
45423
45424 using igfun_t::operator();
45425
45426 axpbsyz()
45427 : exprtk::igeneric_function<T>("TVTTVV|TVTTVVTT")
45428 /*
45429 z <- ax + by
45430 Overloads:
45431 0. TVTVV - a, x(vector), b, shift, y(vector), z(vector)
45432 1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
45433 */
45434 {}
45435
45436 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45437 {
45438 const vector_t x(parameters[1]);
45439 const vector_t y(parameters[4]);
45440 vector_t z(parameters[5]);
45441
45442 std::size_t r0 = 0;
45443 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45444
45445 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1))
45446 return std::numeric_limits<T>::quiet_NaN();
45447 else if (helper::invalid_range(y, r0, r1))
45448 return std::numeric_limits<T>::quiet_NaN();
45449 else if (helper::invalid_range(z, r0, r1))
45450 return std::numeric_limits<T>::quiet_NaN();
45451
45452 const T a = scalar_t(parameters[0])();
45453 const T b = scalar_t(parameters[2])();
45454
45455 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
45456
45457 for (std::size_t i = r0; i <= r1; ++i)
45458 {
45459 z[i] = (a * x[i]) + (b * y[i + s]);
45460 }
45461
45462 return T(1);
45463 }
45464 };
45465
45466 template <typename T>
45467 class axpbz exprtk_final : public exprtk::igeneric_function<T>
45468 {
45469 public:
45470
45471 typedef typename exprtk::igeneric_function<T> igfun_t;
45472 typedef typename igfun_t::parameter_list_t parameter_list_t;
45473 typedef typename igfun_t::generic_type generic_type;
45474 typedef typename generic_type::scalar_view scalar_t;
45475 typedef typename generic_type::vector_view vector_t;
45476
45477 using igfun_t::operator();
45478
45479 axpbz()
45480 : exprtk::igeneric_function<T>("TVTV|TVTVTT")
45481 /*
45482 z <- ax + b
45483 Overloads:
45484 0. TVTV - a, x(vector), b, z(vector)
45485 1. TVTVTT - a, x(vector), b, z(vector), r0, r1
45486 */
45487 {}
45488
45489 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45490 {
45491 const vector_t x(parameters[1]);
45492 vector_t z(parameters[3]);
45493
45494 std::size_t r0 = 0;
45495 std::size_t r1 = x.size() - 1;
45496
45497 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45498 return std::numeric_limits<T>::quiet_NaN();
45499 else if (helper::invalid_range(z, r0, r1))
45500 return std::numeric_limits<T>::quiet_NaN();
45501
45502 const T a = scalar_t(parameters[0])();
45503 const T b = scalar_t(parameters[2])();
45504
45505 for (std::size_t i = r0; i <= r1; ++i)
45506 {
45507 z[i] = (a * x[i]) + b;
45508 }
45509
45510 return T(1);
45511 }
45512 };
45513
45514 template <typename T>
45515 class diff exprtk_final : public exprtk::igeneric_function<T>
45516 {
45517 public:
45518
45519 typedef typename exprtk::igeneric_function<T> igfun_t;
45520 typedef typename igfun_t::parameter_list_t parameter_list_t;
45521 typedef typename igfun_t::generic_type generic_type;
45522 typedef typename generic_type::scalar_view scalar_t;
45523 typedef typename generic_type::vector_view vector_t;
45524
45525 using igfun_t::operator();
45526
45527 diff()
45528 : exprtk::igeneric_function<T>("VV|VVT")
45529 /*
45530 x_(i - stride) - x_i
45531 Overloads:
45532 0. VV - x(vector), y(vector)
45533 1. VVT - x(vector), y(vector), stride
45534 */
45535 {}
45536
45537 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45538 {
45539 const vector_t x(parameters[0]);
45540 vector_t y(parameters[1]);
45541
45542 const std::size_t r0 = 0;
45543 const std::size_t r1 = std::min(x.size(),y.size()) - 1;
45544
45545 const std::size_t stride = (1 != ps_index) ? 1 :
45546 std::min(r1,static_cast<std::size_t>(scalar_t(parameters[2])()));
45547
45548 for (std::size_t i = 0; i < stride; ++i)
45549 {
45550 y[i] = std::numeric_limits<T>::quiet_NaN();
45551 }
45552
45553 for (std::size_t i = (r0 + stride); i <= r1; ++i)
45554 {
45555 y[i] = x[i] - x[i - stride];
45556 }
45557
45558 return T(1);
45559 }
45560 };
45561
45562 template <typename T>
45563 class dot exprtk_final : public exprtk::igeneric_function<T>
45564 {
45565 public:
45566
45567 typedef typename exprtk::igeneric_function<T> igfun_t;
45568 typedef typename igfun_t::parameter_list_t parameter_list_t;
45569 typedef typename igfun_t::generic_type generic_type;
45570 typedef typename generic_type::scalar_view scalar_t;
45571 typedef typename generic_type::vector_view vector_t;
45572
45573 using igfun_t::operator();
45574
45575 dot()
45576 : exprtk::igeneric_function<T>("VV|VVTT")
45577 /*
45578 Overloads:
45579 0. VV - x(vector), y(vector)
45580 1. VVTT - x(vector), y(vector), r0, r1
45581 */
45582 {}
45583
45584 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45585 {
45586 const vector_t x(parameters[0]);
45587 const vector_t y(parameters[1]);
45588
45589 std::size_t r0 = 0;
45590 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45591
45592 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
45593 return std::numeric_limits<T>::quiet_NaN();
45594 else if (helper::invalid_range(y, r0, r1))
45595 return std::numeric_limits<T>::quiet_NaN();
45596
45597 T result = T(0);
45598
45599 for (std::size_t i = r0; i <= r1; ++i)
45600 {
45601 result += (x[i] * y[i]);
45602 }
45603
45604 return result;
45605 }
45606 };
45607
45608 template <typename T>
45609 class dotk exprtk_final : public exprtk::igeneric_function<T>
45610 {
45611 public:
45612
45613 typedef typename exprtk::igeneric_function<T> igfun_t;
45614 typedef typename igfun_t::parameter_list_t parameter_list_t;
45615 typedef typename igfun_t::generic_type generic_type;
45616 typedef typename generic_type::scalar_view scalar_t;
45617 typedef typename generic_type::vector_view vector_t;
45618
45619 using igfun_t::operator();
45620
45621 dotk()
45622 : exprtk::igeneric_function<T>("VV|VVTT")
45623 /*
45624 Overloads:
45625 0. VV - x(vector), y(vector)
45626 1. VVTT - x(vector), y(vector), r0, r1
45627 */
45628 {}
45629
45630 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45631 {
45632 const vector_t x(parameters[0]);
45633 const vector_t y(parameters[1]);
45634
45635 std::size_t r0 = 0;
45636 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45637
45638 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
45639 return std::numeric_limits<T>::quiet_NaN();
45640 else if (helper::invalid_range(y, r0, r1))
45641 return std::numeric_limits<T>::quiet_NaN();
45642
45643 T result = T(0);
45644 T error = T(0);
45645
45646 for (std::size_t i = r0; i <= r1; ++i)
45647 {
45648 details::kahan_sum(result, error, (x[i] * y[i]));
45649 }
45650
45651 return result;
45652 }
45653 };
45654
45655 template <typename T>
45656 class threshold_below exprtk_final : public exprtk::igeneric_function<T>
45657 {
45658 public:
45659
45660 typedef typename exprtk::igeneric_function<T> igfun_t;
45661 typedef typename igfun_t::parameter_list_t parameter_list_t;
45662 typedef typename igfun_t::generic_type generic_type;
45663 typedef typename generic_type::scalar_view scalar_t;
45664 typedef typename generic_type::vector_view vector_t;
45665
45666 using igfun_t::operator();
45667
45668 threshold_below()
45669 : exprtk::igeneric_function<T>("VTT|VTTTT")
45670 /*
45671 Overloads:
45672 0. VTT - vector, TV, SV
45673 1. VTTTT - vector, r0, r1, TV, SV
45674
45675 Where:
45676 TV - Threshold value
45677 SV - Snap-to value
45678 */
45679 {}
45680
45681 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45682 {
45683 vector_t vec(parameters[0]);
45684
45685 const T threshold_value = (0 == ps_index) ?
45686 scalar_t(parameters[1]) :
45687 scalar_t(parameters[3]) ;
45688
45689 const T snap_value = scalar_t(parameters.back());
45690
45691 std::size_t r0 = 0;
45692 std::size_t r1 = vec.size() - 1;
45693
45694 if (
45695 (1 == ps_index) &&
45696 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45697 )
45698 {
45699 return T(0);
45700 }
45701
45702 for (std::size_t i = r0; i <= r1; ++i)
45703 {
45704 if (vec[i] < threshold_value)
45705 {
45706 vec[i] = snap_value;
45707 }
45708 }
45709
45710 return T(1);
45711 }
45712 };
45713
45714 template <typename T>
45715 class threshold_above exprtk_final : public exprtk::igeneric_function<T>
45716 {
45717 public:
45718
45719 typedef typename exprtk::igeneric_function<T> igfun_t;
45720 typedef typename igfun_t::parameter_list_t parameter_list_t;
45721 typedef typename igfun_t::generic_type generic_type;
45722 typedef typename generic_type::scalar_view scalar_t;
45723 typedef typename generic_type::vector_view vector_t;
45724
45725 using igfun_t::operator();
45726
45727 threshold_above()
45728 : exprtk::igeneric_function<T>("VTT|VTTTT")
45729 /*
45730 Overloads:
45731 0. VTT - vector, TV, SV
45732 1. VTTTT - vector, r0, r1, TV, SV
45733
45734 Where:
45735 TV - Threshold value
45736 SV - Snap-to value
45737 */
45738 {}
45739
45740 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45741 {
45742 vector_t vec(parameters[0]);
45743
45744 const T threshold_value = (0 == ps_index) ?
45745 scalar_t(parameters[1]) :
45746 scalar_t(parameters[3]) ;
45747
45748 const T snap_value = scalar_t(parameters.back());
45749
45750 std::size_t r0 = 0;
45751 std::size_t r1 = vec.size() - 1;
45752
45753 if (
45754 (1 == ps_index) &&
45755 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45756 )
45757 {
45758 return T(0);
45759 }
45760
45761 for (std::size_t i = r0; i <= r1; ++i)
45762 {
45763 if (vec[i] > threshold_value)
45764 {
45765 vec[i] = snap_value;
45766 }
45767 }
45768
45769 return T(1);
45770 }
45771 };
45772
45773 template <typename T>
45774 struct package
45775 {
45776 all_true <T> at;
45777 all_false <T> af;
45778 any_true <T> nt;
45779 any_false <T> nf;
45780 count <T> c;
45781 copy <T> cp;
45782 rol <T> rl;
45783 ror <T> rr;
45784 reverse <T> rev;
45785 shift_left <T> sl;
45786 shift_right <T> sr;
45787 sort <T> st;
45788 nthelement <T> ne;
45789 assign <T> an;
45790 iota <T> ia;
45791 sumk <T> sk;
45792 axpy <T> b1_axpy;
45793 axpby <T> b1_axpby;
45794 axpyz <T> b1_axpyz;
45795 axpbyz <T> b1_axpbyz;
45796 axpbsy <T> b1_axpbsy;
45797 axpbsyz <T> b1_axpbsyz;
45798 axpbz <T> b1_axpbz;
45799 diff <T> df;
45800 dot <T> dt;
45801 dotk <T> dtk;
45802 threshold_above<T> ta;
45803 threshold_below<T> tb;
45804
45805 bool register_package(exprtk::symbol_table<T>& symtab)
45806 {
45807 #define exprtk_register_function(FunctionName, FunctionType) \
45808 if (!symtab.add_function(FunctionName,FunctionType)) \
45809 { \
45810 exprtk_debug(( \
45811 "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
45812 FunctionName)); \
45813 return false; \
45814 } \
45815
45816 exprtk_register_function("all_true" , at )
45817 exprtk_register_function("all_false" , af )
45818 exprtk_register_function("any_true" , nt )
45819 exprtk_register_function("any_false" , nf )
45820 exprtk_register_function("count" , c )
45821 exprtk_register_function("copy" , cp )
45822 exprtk_register_function("rotate_left" , rl )
45823 exprtk_register_function("rol" , rl )
45824 exprtk_register_function("rotate_right" , rr )
45825 exprtk_register_function("ror" , rr )
45826 exprtk_register_function("reverse" , rev )
45827 exprtk_register_function("shftl" , sl )
45828 exprtk_register_function("shftr" , sr )
45829 exprtk_register_function("sort" , st )
45830 exprtk_register_function("nth_element" , ne )
45831 exprtk_register_function("assign" , an )
45832 exprtk_register_function("iota" , ia )
45833 exprtk_register_function("sumk" , sk )
45834 exprtk_register_function("axpy" , b1_axpy )
45835 exprtk_register_function("axpby" , b1_axpby )
45836 exprtk_register_function("axpyz" , b1_axpyz )
45837 exprtk_register_function("axpbyz" , b1_axpbyz )
45838 exprtk_register_function("axpbsy" , b1_axpbsy )
45839 exprtk_register_function("axpbsyz" , b1_axpbsyz)
45840 exprtk_register_function("axpbz" , b1_axpbz )
45841 exprtk_register_function("diff" , df )
45842 exprtk_register_function("dot" , dt )
45843 exprtk_register_function("dotk" , dtk )
45844 exprtk_register_function("threshold_above" , ta )
45845 exprtk_register_function("threshold_below" , tb )
45846 #undef exprtk_register_function
45847
45848 return true;
45849 }
45850 };
45851
45852 } // namespace exprtk::rtl::vecops
45853 } // namespace exprtk::rtl
45854} // namespace exprtk
45855#endif
45856
45857namespace exprtk
45858{
45859 namespace information
45860 {
45861 using ::exprtk::details::char_cptr;
45862
45863 static char_cptr library = "Mathematical Expression Toolkit";
45864 static char_cptr version = "2.7182818284590452353602874713526624977"
45865 "572470936999595749669676277240766303535"
45866 "475945713821785251664274274663919320030"
45867 "599218174135966290435729003342952605956";
45868 static char_cptr date = "20240101";
45869 static char_cptr min_cpp = "199711L";
45870
45871 static inline std::string data()
45872 {
45873 static const std::string info_str = std::string(library) +
45874 std::string(" v") + std::string(version) +
45875 std::string(" (") + date + std::string(")") +
45876 std::string(" (") + min_cpp + std::string(")");
45877 return info_str;
45878 }
45879
45880 } // namespace information
45881
45882 #ifdef exprtk_debug
45883 #undef exprtk_debug
45884 #endif
45885
45886 #ifdef exprtk_error_location
45887 #undef exprtk_error_location
45888 #endif
45889
45890 #ifdef exprtk_fallthrough
45891 #undef exprtk_fallthrough
45892 #endif
45893
45894 #ifdef exprtk_override
45895 #undef exprtk_override
45896 #endif
45897
45898 #ifdef exprtk_final
45899 #undef exprtk_final
45900 #endif
45901
45902 #ifdef exprtk_delete
45903 #undef exprtk_delete
45904 #endif
45905
45906} // namespace exprtk
45907
45908#endif
#define register_sf4(Op)
#define basic_opr_switch_statements
Definition exprtk.hpp:34691
#define register_binary_op(Op, BinaryFunctor)
#define exprtk_final
Definition exprtk.hpp:76
#define exprtk_register_function(FunctionName, FunctionType)
#define case_stmt1(op)
#define register_unary_op(Op, UnaryFunctor)
#define case_stmt0(op)
#define poly_rtrn(NN)
Definition exprtk.hpp:42338
#define register_sf4ext(Op)
#define def_fp_retval(N)
Definition exprtk.hpp:43011
#define extended_opr_switch_statements
Definition exprtk.hpp:34699
#define exprtk_override
Definition exprtk.hpp:75
#define exprtk_debug(params)
Definition exprtk.hpp:64
#define exprtk_error_location
Definition exprtk.hpp:67
#define string_opr_switch_statements
Definition exprtk.hpp:40604
#define exprtk_assign(Index)
Definition exprtk.hpp:42603
#define register_sf3_extid(Id, Op)
#define register_sf3(Op)
#define exprtk_delete
Definition exprtk.hpp:77
void polynomial()
complex_t min(const complex_t v0, const complex_t v1)
complex_t max(const complex_t v0, const complex_t v1)
T process(const operator_type operation, const T arg)
Definition exprtk.hpp:5504
bool imatch(const char_t c1, const char_t c2)
Definition exprtk.hpp:190
const char_t & back(const std::string &s)
Definition exprtk.hpp:272
T value(details::expression_node< T > *n)
Definition exprtk.hpp:15749
std::string to_str(int i)
Definition exprtk.hpp:277
void free_node(NodeAllocator &, expression_node< T > *&node)
Definition exprtk.hpp:6007
char_t const * char_cptr
Definition exprtk.hpp:96
char_t * char_ptr
Definition exprtk.hpp:95
void free_all_nodes(NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
Definition exprtk.hpp:5984
bool is_neg_unary_node(const expression_node< T > *node)
Definition exprtk.hpp:5667
static char_cptr date
Definition exprtk.hpp:45868
static char_cptr min_cpp
Definition exprtk.hpp:45869
static std::string data()
Definition exprtk.hpp:45871
static char_cptr version
Definition exprtk.hpp:45864
static char_cptr library
Definition exprtk.hpp:45863
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
Definition exprtk.hpp:43547
file_descriptor * make_handle(T v)
Definition exprtk.hpp:43903
void kahan_sum(T &sum, T &error, const T v)
Definition exprtk.hpp:44257
bool invalid_range(const Vector &v, const std::size_t r0, const std::size_t r1)
Definition exprtk.hpp:44210
void enable_zero_parameters(FunctionType &func)
Definition exprtk.hpp:19497
bool collect_variables(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
Definition exprtk.hpp:41742
vector_access_runtime_check * vector_access_runtime_check_ptr
Definition exprtk.hpp:2192
void disable_has_side_effects(FunctionType &func)
Definition exprtk.hpp:19520
compilation_check * compilation_check_ptr
Definition exprtk.hpp:2227
assert_check * assert_check_ptr
Definition exprtk.hpp:2212
T third_derivative(const expression< T > &e, T &x, const T &h=T(0.0001))
Definition exprtk.hpp:41958
bool collect_functions(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
Definition exprtk.hpp:41803
loop_runtime_check * loop_runtime_check_ptr
Definition exprtk.hpp:2168
bool compute(const std::string &expression_string, T &result)
Definition exprtk.hpp:42070
T derivative(const expression< T > &e, T &x, const T &h=T(0.00000001))
Definition exprtk.hpp:41915
T second_derivative(const expression< T > &e, T &x, const T &h=T(0.00001))
Definition exprtk.hpp:41936
T integrate(const expression< T > &e, T &x, const T &r0, const T &r1, const std::size_t number_of_intervals=1000000)
Definition exprtk.hpp:41863

◆ batch_eqineq_logic_case

#define batch_eqineq_logic_case
Value:
case_stmt(details::e_lt , details::lt_op ) \
case_stmt(details::e_lte , details::lte_op ) \
case_stmt(details::e_gt , details::gt_op ) \
case_stmt(details::e_gte , details::gte_op ) \
case_stmt(details::e_eq , details::eq_op ) \
case_stmt(details::e_ne , details::ne_op ) \
case_stmt(details::e_equal , details::equal_op) \
case_stmt(details::e_and , details::and_op ) \
case_stmt(details::e_nand , details::nand_op ) \
case_stmt(details::e_or , details::or_op ) \
case_stmt(details::e_nor , details::nor_op ) \
case_stmt(details::e_xor , details::xor_op ) \
case_stmt(details::e_xnor , details::xnor_op ) \

◆ case_stmt [1/60]

#define case_stmt (   cp)
Value:
case cp : return node_allocator_-> \
allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [2/60]

#define case_stmt (   N)
Value:
case N : { std::swap(s0[i], s1[i]); ++i; } \
#define exprtk_fallthrough
Definition exprtk.hpp:86

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [3/60]

#define case_stmt (   N)
Value:
case N : *vec++ = v; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [4/60]

#define case_stmt (   N)
Value:
case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [5/60]

#define case_stmt (   N)
Value:
case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [6/60]

#define case_stmt (   N)     if (is_true(arg[(2 * N)].first)) { return arg[(2 * N) + 1].first->value(); } \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [7/60]

#define case_stmt (   N)
Value:
case N : \
return node_allocator_-> \
allocate<details::switch_n_node \
<Type,typename switch_nodes::switch_impl_##N > >(arg_list); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [8/60]

#define case_stmt (   N)
Value:
case N : (fp_map_[arg_count])[name] = \
(!ret_present) ? static_cast<base_func*> \
(new func_##N##param) : \
static_cast<base_func*> \
(new func_##N##param_retval) ; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [9/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : *vec0++ = *vec1++; \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [10/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : Operation::assign(*vec++,v); \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [11/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [12/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [13/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [14/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : result += vec[i++]; \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [15/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : r[0] += vec[i++]; \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [16/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : result *= vec[i++]; \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [17/60]

#define case_stmt (   N,
  fall_through 
)
Value:
case N : r[0] *= vec[i++]; \
fall_through \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [18/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : temp_node = node_allocator_-> \
allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
(operation, branch); \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [19/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : return node_allocator_-> \
allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \
(v0, v1, v2); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [20/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : return node_allocator_-> \
allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
(operation, branch); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [21/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : temp_node = node_allocator_-> \
allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
(operation, branch); \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [22/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : return node_allocator_-> \
allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \
(v0, v1, v2, v3); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [23/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : return node_allocator_-> \
allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
(operation, branch); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [24/60]

#define case_stmt (   op)
Value:
case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
allocate(*(expr_gen.node_allocator_), t0, t1, t2); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [25/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [26/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate<typename details::unary_vector_node<Type,op1<Type> > > \
(operation, branch[0]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [27/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [28/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : temp_node = node_allocator_-> \
allocate<details::vararg_node<Type,op1<Type> > > \
(arg_list); \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [29/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [30/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [31/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [32/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_op_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [33/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_vec_elem_op_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [34/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_vec_elem_op_rtc_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_vec_elem_op_rtc_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [35/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_vec_celem_op_rtc_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_vec_celem_op_rtc_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [36/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_rebasevec_elem_op_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [37/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_rebasevec_celem_op_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [38/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_rebasevec_elem_op_rtc_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_rebasevec_elem_op_rtc_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [39/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_rebasevec_celem_op_rtc_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_rebasevec_celem_op_rtc_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [40/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_rebasevec_celem_op_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [41/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "assignment_vec_op_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [42/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "vec_binop_vecvec_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [43/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "vec_binop_vecval_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [44/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "vec_binop_valvec_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [45/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "vec_binop_vecvec_node"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [46/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [47/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : result = node_allocator_-> \
template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
(operation, branch[0], branch[1]); \
node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)"; \
break; \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [48/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
(branch[0], branch[1]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [49/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
(v, branch[1]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [50/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
(branch[0], v); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [51/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
(c, branch[1]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [52/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
(branch[0], c); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [53/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
(v1, v2); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [54/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
(c, v); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [55/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return expr_gen.node_allocator_-> \
template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
(v, c); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [56/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
(s0, s1, rp0); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [57/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
(s0, s1, rp1); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [58/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
(s0, s1, rp0, rp1); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [59/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt [60/60]

#define case_stmt (   op0,
  op1 
)
Value:
case op0 : return node_allocator_-> \
allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
(opr, branch[0], branch[1]); \

Definition at line 32731 of file exprtk.hpp.

32732 { return arg[(2 * N) + 1].first->value(); } \
32733

◆ case_stmt0

#define case_stmt0 (   op)
Value:
case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \

◆ case_stmt1

#define case_stmt1 (   op)
Value:
case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \

◆ def_fp_retval

#define def_fp_retval (   N)
Value:
struct func_##N##param_retval exprtk_final : public func_##N##param \
{ \
inline T value(expression_t& e) exprtk_override \
{ \
return return_value(e); \
} \
}; \

Definition at line 43011 of file exprtk.hpp.

43012 : public func_##N##param \
43013 { \
43014 inline T value(expression_t& e) exprtk_override \
43015 { \
43016 return return_value(e); \
43017 } \
43018 }; \
43019

◆ define_sfop3

#define define_sfop3 (   NN,
  OP0,
  OP1 
)
Value:
template <typename T> \
struct sf##NN##_op : public sf_base<T> \
{ \
typedef typename sf_base<T>::Type const Type; \
static inline T process(Type x, Type y, Type z) \
{ \
return (OP0); \
} \
static inline std::string id() \
{ \
return (OP1); \
} \
}; \

Definition at line 11793 of file exprtk.hpp.

11795 : public sf_base<T> \
11796 { \
11797 typedef typename sf_base<T>::Type const Type; \
11798 static inline T process(Type x, Type y, Type z) \
11799 { \
11800 return (OP0); \
11801 } \
11802 static inline std::string id() \
11803 { \
11804 return (OP1); \
11805 } \
11806 }; \
11807

◆ define_sfop4

#define define_sfop4 (   NN,
  OP0,
  OP1 
)
Value:
template <typename T> \
struct sf##NN##_op : public sf_base<T> \
{ \
typedef typename sf_base<T>::Type const Type; \
static inline T process(Type x, Type y, Type z, Type w) \
{ \
return (OP0); \
} \
static inline std::string id() \
{ \
return (OP1); \
} \
}; \

Definition at line 11857 of file exprtk.hpp.

11859 : public sf_base<T> \
11860 { \
11861 typedef typename sf_base<T>::Type const Type; \
11862 static inline T process(Type x, Type y, Type z, Type w) \
11863 { \
11864 return (OP0); \
11865 } \
11866 static inline std::string id() \
11867 { \
11868 return (OP1); \
11869 } \
11870 }; \
11871

◆ empty_method_body

#define empty_method_body (   N)
Value:
{ \
exprtk_debug(("ifunction::operator() - Operator(" #N ") has not been overridden\n")); \
return std::numeric_limits<T>::quiet_NaN(); \
} \

Definition at line 19552 of file exprtk.hpp.

19553 { \
19554 exprtk_debug(("ifunction::operator() - Operator(" #N ") has not been overridden\n")); \
19555 return std::numeric_limits<T>::quiet_NaN(); \
19556 } \
19557

◆ exprtk_assign

#define exprtk_assign (   Index)     (*v[Index]) = v##Index; \

Definition at line 42603 of file exprtk.hpp.

◆ exprtk_crtype

#define exprtk_crtype (   Type)     param_to_str<is_const_ref< Type >::result>::result() \

Definition at line 16997 of file exprtk.hpp.

◆ exprtk_debug

#define exprtk_debug (   params)    (void)0

Definition at line 64 of file exprtk.hpp.

◆ exprtk_define_epsilon_type

#define exprtk_define_epsilon_type (   Type,
  Epsilon 
)
Value:
template <> struct epsilon_type<Type> \
{ \
static inline Type value() \
{ \
const Type epsilon = static_cast<Type>(Epsilon); \
return epsilon; \
} \
}; \

Definition at line 862 of file exprtk.hpp.

864 { \
865 static inline Type value() \
866 { \
867 const Type epsilon = static_cast<Type>(Epsilon); \
868 return epsilon; \
869 } \
870 }; \
871

◆ exprtk_define_erf

#define exprtk_define_erf (   TT,
  impl 
)     inline TT erf_impl(const TT v) { return impl(v); } \

Definition at line 1244 of file exprtk.hpp.

1245 { return impl(v); } \
1246

◆ exprtk_define_erfc

#define exprtk_define_erfc (   TT,
  impl 
)     inline TT erfc_impl(const TT v) { return impl(v); } \

Definition at line 1289 of file exprtk.hpp.

1290 { return impl(v); } \
1291

◆ exprtk_define_freefunction

#define exprtk_define_freefunction (   NN)
Value:
inline bool add_function(const std::string& function_name, ff##NN##_functor function) \
{ \
if (!valid()) \
{ return false; } \
if (!valid_symbol(function_name)) \
{ return false; } \
if (symbol_exists(function_name)) \
{ return false; } \
\
exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
\
local_data().free_function_list_.push_back(ifunc); \
\
return add_function(function_name,(*local_data().free_function_list_.back())); \
} \

Definition at line 20864 of file exprtk.hpp.

20866 { \
20867 if (!valid()) \
20868 { return false; } \
20869 if (!valid_symbol(function_name)) \
20870 { return false; } \
20871 if (symbol_exists(function_name)) \
20872 { return false; } \
20873 \
20874 exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
20875 \
20876 local_data().free_function_list_.push_back(ifunc); \
20877 \
20878 return add_function(function_name,(*local_data().free_function_list_.back())); \
20879 } \
20880

◆ exprtk_define_process

#define exprtk_define_process (   Type)
Value:
static inline void process(std::pair<bool,Type*>& n) \
{ \
delete n.second; \
} \

Definition at line 19978 of file exprtk.hpp.

19980 { \
19981 delete n.second; \
19982 } \
19983

◆ exprtk_define_reserved_function

#define exprtk_define_reserved_function (   NN)
Value:
inline bool add_reserved_function(const std::string& function_name, ff##NN##_functor function) \
{ \
if (!valid()) \
{ return false; } \
if (!valid_symbol(function_name,false)) \
{ return false; } \
if (symbol_exists(function_name,false)) \
{ return false; } \
\
exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
\
local_data().free_function_list_.push_back(ifunc); \
\
return add_reserved_function(function_name,(*local_data().free_function_list_.back())); \
} \

Definition at line 20945 of file exprtk.hpp.

20947 { \
20948 if (!valid()) \
20949 { return false; } \
20950 if (!valid_symbol(function_name,false)) \
20951 { return false; } \
20952 if (symbol_exists(function_name,false)) \
20953 { return false; } \
20954 \
20955 exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
20956 \
20957 local_data().free_function_list_.push_back(ifunc); \
20958 \
20959 return add_reserved_function(function_name,(*local_data().free_function_list_.back())); \
20960 } \
20961

◆ exprtk_define_unary_function

#define exprtk_define_unary_function (   FunctionName)
Value:
template <typename T> \
inline T FunctionName (const T v) \
{ \
const typename details::number_type<T>::type num_type; \
return FunctionName##_impl(v,num_type); \
} \

Definition at line 1667 of file exprtk.hpp.

1670 { \
1671 const typename details::number_type<T>::type num_type; \
1672 return FunctionName##_impl(v,num_type); \
1673 } \
1674

◆ exprtk_define_unary_op

#define exprtk_define_unary_op (   OpName)
Value:
template <typename T> \
struct OpName##_op \
{ \
typedef typename functor_t<T>::Type Type; \
typedef typename expression_node<T>::node_type node_t; \
\
static inline T process(Type v) \
{ \
return numeric:: OpName (v); \
} \
\
static inline node_t type() \
{ \
return expression_node<T>::e_##OpName; \
} \
\
static inline details::operator_type operation() \
{ \
return details::e_##OpName; \
} \
}; \

Definition at line 15412 of file exprtk.hpp.

15415 { \
15416 typedef typename functor_t<T>::Type Type; \
15417 typedef typename expression_node<T>::node_type node_t; \
15418 \
15419 static inline T process(Type v) \
15420 { \
15421 return numeric:: OpName (v); \
15422 } \
15423 \
15424 static inline node_t type() \
15425 { \
15426 return expression_node<T>::e_##OpName; \
15427 } \
15428 \
15429 static inline details::operator_type operation() \
15430 { \
15431 return details::e_##OpName; \
15432 } \
15433 }; \
15434

◆ exprtk_delete

#define exprtk_delete

Definition at line 77 of file exprtk.hpp.

◆ exprtk_error_location

#define exprtk_error_location    "exprtk.hpp:" + details::to_str(__LINE__) \

Definition at line 67 of file exprtk.hpp.

68 :" + details::to_str(__LINE__) \
69

◆ exprtk_fallthrough

#define exprtk_fallthrough   __attribute__ ((fallthrough));

Definition at line 86 of file exprtk.hpp.

◆ exprtk_final

#define exprtk_final

Definition at line 76 of file exprtk.hpp.

◆ exprtk_loop [1/11]

#define exprtk_loop (   N)     std::swap(s0[N], s1[N]); \

◆ exprtk_loop [2/11]

#define exprtk_loop (   N)     vec[N] = v; \

◆ exprtk_loop [3/11]

#define exprtk_loop (   N)     vec0[N] = vec1[N]; \

◆ exprtk_loop [4/11]

#define exprtk_loop (   N)     Operation::assign(vec[N],v); \

◆ exprtk_loop [5/11]

#define exprtk_loop (   N)     vec0[N] = Operation::process(vec0[N], vec1[N]); \

◆ exprtk_loop [6/11]

#define exprtk_loop (   N)     vec2[N] = Operation::process(vec0[N], vec1[N]); \

◆ exprtk_loop [7/11]

#define exprtk_loop (   N)     vec1[N] = Operation::process(vec0[N], v); \

◆ exprtk_loop [8/11]

#define exprtk_loop (   N)     vec0[N] = Operation::process(v, vec1[N]); \

◆ exprtk_loop [9/11]

#define exprtk_loop (   N)     vec1[N] = Operation::process(vec0[N]); \

◆ exprtk_loop [10/11]

#define exprtk_loop (   N)     r[N] += vec[N]; \

◆ exprtk_loop [11/11]

#define exprtk_loop (   N)     r[N] *= vec[N]; \

◆ exprtk_override

#define exprtk_override

Definition at line 75 of file exprtk.hpp.

◆ exprtk_process_digit

#define exprtk_process_digit
Value:
if ((digit = (*itr++ - zero)) < 10) \
result = result * T(10) + digit; \
else \
{ \
return_result = false; \
break; \
} \

◆ exprtk_register_function [1/3]

#define exprtk_register_function (   FunctionName,
  FunctionType 
)
Value:
if (!symtab.add_function(FunctionName,FunctionType)) \
{ \
exprtk_debug(( \
"exprtk::rtl::io::register_package - Failed to add function: %s\n", \
FunctionName)); \
return false; \
} \

◆ exprtk_register_function [2/3]

#define exprtk_register_function (   FunctionName,
  FunctionType 
)
Value:
if (!symtab.add_function(FunctionName,FunctionType)) \
{ \
exprtk_debug(( \
"exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
FunctionName)); \
return false; \
} \

◆ exprtk_register_function [3/3]

#define exprtk_register_function (   FunctionName,
  FunctionType 
)
Value:
if (!symtab.add_function(FunctionName,FunctionType)) \
{ \
exprtk_debug(( \
"exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
FunctionName)); \
return false; \
} \

◆ exprtk_register_int_type_tag

#define exprtk_register_int_type_tag (   T)
Value:
template <> struct number_type<T> \
{ typedef int_type_tag type; number_type() {} }; \

Definition at line 841 of file exprtk.hpp.

843 { typedef int_type_tag type; number_type() {} }; \
844

◆ exprtk_register_real_type_tag

#define exprtk_register_real_type_tag (   T)
Value:
template <> struct number_type<T> \
{ typedef real_type_tag type; number_type() {} }; \

Definition at line 837 of file exprtk.hpp.

839 { typedef real_type_tag type; number_type() {} }; \
840

◆ extended_opr_switch_statements

#define extended_opr_switch_statements
Value:
case_stmt(details::e_lt , details::lt_op ) \
case_stmt(details::e_lte , details::lte_op ) \
case_stmt(details::e_gt , details::gt_op ) \
case_stmt(details::e_gte , details::gte_op ) \
case_stmt(details::e_eq , details::eq_op ) \
case_stmt(details::e_ne , details::ne_op ) \
case_stmt(details::e_and , details::and_op ) \
case_stmt(details::e_nand , details::nand_op) \
case_stmt(details::e_or , details::or_op ) \
case_stmt(details::e_nor , details::nor_op ) \
case_stmt(details::e_xor , details::xor_op ) \
case_stmt(details::e_xnor , details::xnor_op) \

Definition at line 34699 of file exprtk.hpp.

◆ igeneric_function_empty_body

#define igeneric_function_empty_body (   N)
Value:
{ \
exprtk_debug(("igeneric_function::operator() - Operator(" #N ") has not been overridden\n")); \
return std::numeric_limits<T>::quiet_NaN(); \
} \

Definition at line 19675 of file exprtk.hpp.

19676 { \
19677 exprtk_debug(("igeneric_function::operator() - Operator(" #N ") has not been overridden\n")); \
19678 return std::numeric_limits<T>::quiet_NaN(); \
19679 } \
19680

◆ parse_digit_1

#define parse_digit_1 (   d)
Value:
if ((digit = (*itr - zero)) < 10) \
{ d = d * T(10) + digit; } \
else \
{ break; } \
if (end == ++itr) break; \

◆ parse_digit_2

#define parse_digit_2 (   d)
Value:
if ((digit = (*itr - zero)) < 10) \
{ d = d * T(10) + digit; } \
else \
{ break; } \
++itr; \

◆ pod_set_zero_value

#define pod_set_zero_value (   T)
Value:
template <> \
struct set_zero_value_impl<T> \
{ \
static inline void process(T* base_ptr, const std::size_t size) \
{ std::memset(base_ptr, 0x00, size * sizeof(T)); } \
}; \

Definition at line 769 of file exprtk.hpp.

772 { \
773 static inline void process(T* base_ptr, const std::size_t size) \
774 { std::memset(base_ptr, 0x00, size * sizeof(T)); } \
775 }; \
776

◆ poly_rtrn

#define poly_rtrn (   NN)     return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :

Definition at line 42338 of file exprtk.hpp.

42339 :
42340

◆ register_binary_op [1/2]

#define register_binary_op (   Op,
  BinaryFunctor 
)     m.insert(value_type(Op,BinaryFunctor<T>::process)); \

◆ register_binary_op [2/2]

#define register_binary_op (   Op,
  BinaryFunctor 
)     m.insert(value_type(BinaryFunctor<T>::process,Op)); \

◆ register_op

#define register_op (   Symbol,
  Type,
  Args 
)     m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \

◆ register_sf3

#define register_sf3 (   Op)     sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \

◆ register_sf3_extid

#define register_sf3_extid (   Id,
  Op 
)     sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \

◆ register_sf4

#define register_sf4 (   Op)     sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \

◆ register_sf4ext

#define register_sf4ext (   Op)     sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \

◆ register_synthezier

#define register_synthezier (   S)     synthesize_map_[S ::node_type::id()] = S ::process; \

◆ register_unary_op

#define register_unary_op (   Op,
  UnaryFunctor 
)     m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \

◆ string_opr_switch_statements

#define string_opr_switch_statements
Value:
case_stmt(details::e_lt , details::lt_op ) \
case_stmt(details::e_lte , details::lte_op ) \
case_stmt(details::e_gt , details::gt_op ) \
case_stmt(details::e_gte , details::gte_op ) \
case_stmt(details::e_eq , details::eq_op ) \
case_stmt(details::e_ne , details::ne_op ) \
case_stmt(details::e_in , details::in_op ) \
case_stmt(details::e_like , details::like_op ) \
case_stmt(details::e_ilike , details::ilike_op) \

Definition at line 40604 of file exprtk.hpp.

◆ synthesis_node_type_define [1/3]

#define synthesis_node_type_define (   T0_,
  T1_,
  T2_,
  T3_,
  v_ 
)
Value:
template <typename T, typename T0, typename T1, typename T2, typename T3> \
struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
template <typename T, typename T0, typename T1, typename T2, typename T3> \
const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \

Definition at line 17161 of file exprtk.hpp.

17163 { static const typename expression_node<T>::node_type result; }; \
17164 template <typename T, typename T0, typename T1> \
17165 const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
17166

◆ synthesis_node_type_define [2/3]

#define synthesis_node_type_define (   T0_,
  T1_,
  T2_,
  v_ 
)
Value:
template <typename T, typename T0, typename T1, typename T2> \
struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
template <typename T, typename T0, typename T1, typename T2> \
const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \

Definition at line 17161 of file exprtk.hpp.

17163 { static const typename expression_node<T>::node_type result; }; \
17164 template <typename T, typename T0, typename T1> \
17165 const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
17166

◆ synthesis_node_type_define [3/3]

#define synthesis_node_type_define (   T0_,
  T1_,
  v_ 
)
Value:
template <typename T, typename T0, typename T1> \
struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
template <typename T, typename T0, typename T1> \
const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \

Definition at line 17161 of file exprtk.hpp.

17163 { static const typename expression_node<T>::node_type result; }; \
17164 template <typename T, typename T0, typename T1> \
17165 const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
17166

◆ token_inserter_empty_body

#define token_inserter_empty_body
Value:
{ \
return -1; \
} \

Definition at line 3320 of file exprtk.hpp.

3321 { \
3322 return -1; \
3323 } \
3324

◆ unary_opr_switch_statements

#define unary_opr_switch_statements

Definition at line 32907 of file exprtk.hpp.

◆ vector_ops

#define vector_ops
Value:
case_stmt(details::e_add , details::add_op) \
case_stmt(details::e_sub , details::sub_op) \
case_stmt(details::e_mul , details::mul_op) \
case_stmt(details::e_div , details::div_op) \
case_stmt(details::e_mod , details::mod_op) \