From 1b32ca4bbbba9a4a8aa40bb8b5b045de855142d7 Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Fri, 6 Apr 2012 19:26:00 +1000 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 34 +++++++++- exprtk_test.cpp | 167 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 170 insertions(+), 31 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index 7617c10..e713c69 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -3843,7 +3843,7 @@ namespace exprtk } else { - vm_itr_t itr = function_map_.find(function_name); + fm_itr_t itr = function_map_.find(function_name); if (function_map_.end() != itr) { function_map_.erase(itr); @@ -3855,6 +3855,34 @@ namespace exprtk } } + inline bool remove_stringvar(const std::string& string_name) + { + if (1 == string_name.size()) + { + stringvar_pair_t& svp = short_stringvar_lut_[static_cast(string_name[0])]; + if (0 == svp.second) + return false; + delete svp.second; + svp.first = false; + svp.second = 0; + --stringvar_count_; + return true; + } + else + { + svm_itr_t itr = stringvar_map_.find(string_name); + if (stringvar_map_.end() != itr) + { + delete (*itr).second.second; + stringvar_map_.erase(itr); + --stringvar_count_; + return true; + } + else + return false; + } + } + inline void add_constants() { add_pi(); @@ -4229,7 +4257,7 @@ namespace exprtk template class Sequence> inline std::size_t expression_symbols(Sequence& symbols_list) { - if (!symbol_name_cache_) + if (!symbol_name_caching_) return 0; if (symbol_name_cache_.empty()) return 0; @@ -6345,7 +6373,7 @@ namespace exprtk namespace information { static const char* library = "Mathematical Expression Toolkit"; - static const char* version = "2.718281828459"; + static const char* version = "2.718281828459045235"; static const char* date = "20111111"; static inline std::string data() diff --git a/exprtk_test.cpp b/exprtk_test.cpp index b45ccb7..c314c83 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -933,7 +933,7 @@ inline bool run_test02() exprtk::parser parser; if (!parser.compile(test.expr,expression)) { - std::cout << "test_expression() - Error: " << parser.error() << "\tExpression: " << test.expr << std::endl; + std::cout << "run_test02() - Error: " << parser.error() << "\tExpression: " << test.expr << std::endl; return false; } } @@ -941,7 +941,7 @@ inline bool run_test02() T result = expression.value(); if (not_equal(result,test.result)) { - printf("Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", + printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", test.expr.c_str(), test.result, result); @@ -1015,7 +1015,7 @@ inline bool run_test03() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test01() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test03() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } expression.value(); @@ -1051,7 +1051,7 @@ inline bool run_test04() if (!parser.compile(expression_string,expression)) { - std::cout << "run_test02() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test04() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } @@ -1065,7 +1065,7 @@ inline bool run_test04() T result2 = clamp(-1.0,std::sin(2 * pi * x) + std::cos(y / 2 * pi),+1.0); if (not_equal(result1,result2)) { - printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n", + printf("run_test04() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n", expression_string.c_str(), result1, result2, @@ -1104,7 +1104,7 @@ inline bool run_test05() if (!parser.compile(expression_string,e)) { - std::cout << "run_test03() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; + std::cout << "run_test05() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } expression_list.push_back(e); @@ -1123,7 +1123,7 @@ inline bool run_test05() T result = expr.value(); if (not_equal(result,real_result)) { - printf("run_test03() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n", + printf("run_test05() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n", expression_string.c_str(), real_result, result, @@ -1216,7 +1216,7 @@ inline bool run_test07() } if (not_equal(result1,real_result,0.000000001)) { - printf("run_test05() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n", + printf("run_test07() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n", x, real_result, result1); @@ -1440,6 +1440,27 @@ inline bool run_test10() exprtk::symbol_table symbol_table; + struct test + { + static inline bool variable(exprtk::symbol_table& symbol_table, const std::string& variable_name, const T& value) + { + exprtk::details::variable_node* var = symbol_table.get_variable(variable_name); + if (var) + return (!not_equal(var->ref(),value)); + else + return false; + } + + static inline bool string(exprtk::symbol_table& symbol_table, const std::string& string_name, const std::string& str) + { + exprtk::details::stringvar_node* str_node = symbol_table.get_stringvar(string_name); + if (str_node) + return (str_node->ref() == str); + else + return false; + } + }; + { symbol_table.add_variable("x", x); symbol_table.add_variable("y", y); @@ -1466,22 +1487,7 @@ inline bool run_test10() std::cout << "run_test10() - Symbol 'yy' does not exist!\n"; return false; } - - struct test - { - static inline bool variable(exprtk::symbol_table& symbol_table, const std::string& variable_name, const T& value) - { - exprtk::details::variable_node* var = symbol_table.get_variable(variable_name); - if (var) - { - return (!not_equal(var->ref(),value)); - } - else - return false; - } - }; - - if (!test::variable(symbol_table,"x",x)) + else if (!test::variable(symbol_table,"x",x)) { std::cout << "run_test10() - Symbol 'x' value failure!\n"; return false; @@ -1502,25 +1508,130 @@ inline bool run_test10() return false; } - if (symbol_table.remove_variable("x")) + if (!symbol_table.remove_variable("x")) { + std::cout << "run_test10() - Failed to remove symbol 'x'!\n"; return false; } - else if (symbol_table.remove_variable("y")) + else if (!symbol_table.remove_variable("y")) { + std::cout << "run_test10() - Failed to remove symbol 'y'!\n"; return false; } - else if (symbol_table.remove_variable("xx")) + else if (!symbol_table.remove_variable("xx")) { + std::cout << "run_test10() - Failed to remove symbol 'xx'!\n"; return false; } - else if (symbol_table.remove_variable("yy")) + else if (!symbol_table.remove_variable("yy")) { + std::cout << "run_test10() - Failed to remove symbol 'yy'!\n"; return false; } } { + myfunc mf; + + symbol_table.add_function("f",mf); + symbol_table.add_function("f1",mf); + + if (!symbol_table.symbol_exists("f")) + { + std::cout << "run_test10() - function 'f' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("f1")) + { + std::cout << "run_test10() - function 'f1' does not exist!\n"; + return false; + } + + if (!symbol_table.remove_function("f")) + { + std::cout << "run_test10() - Failed to remove function 'f'!\n"; + return false; + } + else if (!symbol_table.remove_function("f1")) + { + std::cout << "run_test10() - Failed to remove function 'f1'!\n"; + return false; + } + } + + { + std::string i = "A String"; + std::string j = "Another String"; + + std::string ii = "A String"; + std::string jj = "Another String"; + + symbol_table.add_stringvar("i",i); + symbol_table.add_stringvar("j",j); + + symbol_table.add_stringvar("ii",ii); + symbol_table.add_stringvar("jj",jj); + + if (!symbol_table.symbol_exists("i")) + { + std::cout << "run_test10() - String 'i' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("j")) + { + std::cout << "run_test10() - String 'j' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("ii")) + { + std::cout << "run_test10() - String 'ii' does not exist!\n"; + return false; + } + else if (!symbol_table.symbol_exists("jj")) + { + std::cout << "run_test10() - String 'jj' does not exist!\n"; + return false; + } + else if (!test::string(symbol_table,"i",i)) + { + std::cout << "run_test10() - String 'i' value failure!\n"; + return false; + } + else if (!test::string(symbol_table,"j",j)) + { + std::cout << "run_test10() - String 'j' value failure!\n"; + return false; + } + else if (!test::string(symbol_table,"ii",ii)) + { + std::cout << "run_test10() - String 'ii' value failure!\n"; + return false; + } + else if (!test::string(symbol_table,"jj",jj)) + { + std::cout << "run_test10() - String 'jj' value failure!\n"; + return false; + } + else if (!symbol_table.remove_stringvar("i")) + { + std::cout << "run_test10() - Failed to remove String 'i'!\n"; + return false; + } + else if (!symbol_table.remove_stringvar("j")) + { + std::cout << "run_test10() - Failed to remove String 'j'!\n"; + return false; + } + else if (!symbol_table.remove_stringvar("ii")) + { + std::cout << "run_test10() - Failed to remove String 'ii'!\n"; + return false; + } + else if (!symbol_table.remove_stringvar("jj")) + { + std::cout << "run_test10() - Failed to remove String 'jj'!\n"; + return false; + } } return true;