From d26bb0eafc3541e5a99855ce0dd952ef7317e5df Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Tue, 10 Apr 2012 23:10:00 +1000 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 162 +++++++++++++++++++++++++++++++++++++++-- exprtk_test.cpp | 187 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 336 insertions(+), 13 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index e713c69..0a2e541 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -311,7 +311,7 @@ namespace exprtk exprtk_register_int_type_tag(unsigned long long int) #undef exprtk_register_real_type_tag - #undef exprtk_register_real_type_tag + #undef exprtk_register_int_type_tag template inline T equal_impl(const T& v0, const T& v1, real_type_tag) @@ -3661,6 +3661,29 @@ namespace exprtk } } + inline std::string& stringvar_ref(const std::string& symbol_name) + { + static std::string null_stringvar; + if (!valid_symbol(symbol_name)) + return null_var; + else if (1 == symbol_name.size()) + { + stringvar_pair_t& svp = short_stringvar_lut_[static_cast(symbol_name[0])]; + if (svp.second) + return svp->second.ref(); + else + return null_stringvar; + } + else + { + svm_const_itr_t itr = stringvar_map_.find(symbol_name); + if (stringvar_map_.end() == itr) + return null_var; + else + return itr->second.second->ref(); + } + } + inline bool is_constant_node(const std::string& symbol_name) const { if (1 == symbol_name.size()) @@ -3704,6 +3727,17 @@ namespace exprtk return add_variable(variable_name,t); } + inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string("")) + { + if (!valid_symbol(stringvar_name)) + return false; + else if (symbol_exists(stringvar_name)) + return false; + local_stringvar_list_.push_back(value); + std::string& s = local_stringvar_list_.back(); + return add_stringvar(stringvar_name,s); + } + inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false) { if (!valid_symbol(variable_name)) @@ -3936,6 +3970,90 @@ namespace exprtk return count; } + template class Sequence> + inline std::size_t get_variable_list(Sequence& vlist) const + { + std::size_t count = 0; + for (std::size_t i = 0; i < lut_size; ++i) + { + const variable_pair_t& vp = short_variable_lut_[static_cast(i)]; + if (0 != vp.second) + { + vlist.push_back(std::string("") + static_cast(i)); + ++count; + } + } + if (!variable_map_.empty()) + { + vm_const_itr_t itr = variable_map_.begin(); + vm_const_itr_t end = variable_map_.end(); + while (end != itr) + { + vlist.push_back((*itr).first); + ++itr; + ++count; + } + } + return count; + } + + template class Sequence> + inline std::size_t get_stringvar_list(Sequence,Allocator>& svlist) const + { + std::size_t count = 0; + for (std::size_t i = 0; i < lut_size; ++i) + { + const stringvar_pair_t& svp = short_stringvar_lut_[static_cast(i)]; + if (0 != svp.second) + { + svlist.push_back(std::make_pair(std::string("") + static_cast(i),svp.second->ref())); + ++count; + } + } + if (!stringvar_map_.empty()) + { + svm_const_itr_t itr = stringvar_map_.begin(); + svm_const_itr_t end = stringvar_map_.end(); + while (end != itr) + { + svlist.push_back(std::make_pair((*itr).first,itr->second.second->ref())); + ++itr; + ++count; + } + } + return count; + } + + template class Sequence> + inline std::size_t get_stringvar_list(Sequence& svlist) const + { + std::size_t count = 0; + for (std::size_t i = 0; i < lut_size; ++i) + { + const stringvar_pair_t& svp = short_stringvar_lut_[static_cast(i)]; + if (0 != svp.second) + { + svlist.push_back(std::string("") + static_cast(i)); + ++count; + } + } + if (!stringvar_map_.empty()) + { + svm_const_itr_t itr = stringvar_map_.begin(); + svm_const_itr_t end = stringvar_map_.end(); + while (end != itr) + { + svlist.push_back((*itr).first); + ++itr; + ++count; + } + } + return count; + } + inline bool symbol_exists(const std::string& symbol_name) const { /* @@ -3944,7 +4062,7 @@ namespace exprtk */ if ((1 == symbol_name.size()) && short_variable_lut_[static_cast(symbol_name[0])].second) return true; - if ((1 == symbol_name.size()) && short_stringvar_lut_[static_cast(symbol_name[0])].second) + else if ((1 == symbol_name.size()) && short_stringvar_lut_[static_cast(symbol_name[0])].second) return true; else if ((1 == symbol_name.size()) && short_function_lut_[static_cast(symbol_name[0])]) return true; @@ -3958,6 +4076,36 @@ namespace exprtk return false; } + inline bool is_variable(const std::string& variable_name) const + { + if ((1 == variable_name.size()) && short_variable_lut_[static_cast(variable_name[0])].second) + return true; + else if (variable_map_.end() != variable_map_.find(variable_name)) + return true; + else + return false; + } + + inline bool is_stringvar(const std::string& stringvar_name) const + { + if ((1 == stringvar_name.size()) && short_stringvar_lut_[static_cast(stringvar_name[0])].second) + return true; + else if (stringvar_map_.end() != stringvar_map_.find(stringvar_name)) + return true; + else + return false; + } + + inline bool is_function(const std::string& function_name) const + { + if ((1 == function_name.size()) && short_function_lut_[static_cast(function_name[0])].second) + return true; + else if (function_map_.end() != function_map_.find(function_name)) + return true; + else + return false; + } + private: symbol_table(const symbol_table&); @@ -4097,11 +4245,6 @@ namespace exprtk } } - inline T operator()() const - { - return value(); - } - inline T value() const { if (expression_holder_ && expression_holder_->expr) @@ -4110,6 +4253,11 @@ namespace exprtk return std::numeric_limits::quiet_NaN(); } + inline T operator()() const + { + return value(); + } + inline operator T() const { return value(); diff --git a/exprtk_test.cpp b/exprtk_test.cpp index c314c83..2182878 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -1438,6 +1438,11 @@ inline bool run_test10() T xx = T(3.3); T yy = T(4.4); + std::string i = "A String"; + std::string j = "Another String"; + std::string ii = "A String"; + std::string jj = "Another String"; + exprtk::symbol_table symbol_table; struct test @@ -1560,12 +1565,6 @@ inline bool run_test10() } { - 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); @@ -1634,6 +1633,182 @@ inline bool run_test10() } } + { + symbol_table.add_variable("x", x); + symbol_table.add_variable("y", y); + symbol_table.add_variable("xx",xx); + symbol_table.add_variable("yy",yy); + + std::vector expected_var_list; + + expected_var_list.push_back( "x"); + expected_var_list.push_back( "y"); + expected_var_list.push_back("xx"); + expected_var_list.push_back("yy"); + + std::deque > variable_list; + + symbol_table.get_variable_list(variable_list); + + if (variable_list.size() != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get variable list (1)\n"; + return false; + } + + std::size_t found_count = 0; + + for (std::size_t i = 0; i < variable_list.size(); ++i) + { + for (std::size_t j = 0; j < expected_var_list.size(); ++j) + { + if (variable_list[i].first == expected_var_list[j]) + { + ++found_count; + break; + } + } + } + + if (found_count != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get variable list (2)\n"; + return false; + } + } + + { + symbol_table.add_variable("x", x); + symbol_table.add_variable("y", y); + symbol_table.add_variable("xx",xx); + symbol_table.add_variable("yy",yy); + + std::vector expected_var_list; + + expected_var_list.push_back( "x"); + expected_var_list.push_back( "y"); + expected_var_list.push_back("xx"); + expected_var_list.push_back("yy"); + + std::deque variable_list; + + symbol_table.get_variable_list(variable_list); + + if (variable_list.size() != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get variable list (3)\n"; + return false; + } + + std::size_t found_count = 0; + + for (std::size_t i = 0; i < variable_list.size(); ++i) + { + for (std::size_t j = 0; j < expected_var_list.size(); ++j) + { + if (variable_list[i] == expected_var_list[j]) + { + ++found_count; + break; + } + } + } + + if (found_count != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get variable list (4)\n"; + return false; + } + } + + { + symbol_table.add_stringvar( "i", i); + symbol_table.add_stringvar( "j", j); + symbol_table.add_stringvar("ii",ii); + symbol_table.add_stringvar("jj",jj); + + std::vector expected_var_list; + + expected_var_list.push_back( "i"); + expected_var_list.push_back( "j"); + expected_var_list.push_back("ii"); + expected_var_list.push_back("jj"); + + std::deque > stringvar_list; + + symbol_table.get_stringvar_list(stringvar_list); + + if (stringvar_list.size() != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get stringvar list (1)\n"; + return false; + } + + std::size_t found_count = 0; + + for (std::size_t i = 0; i < stringvar_list.size(); ++i) + { + for (std::size_t j = 0; j < expected_var_list.size(); ++j) + { + if (stringvar_list[i].first == expected_var_list[j]) + { + ++found_count; + break; + } + } + } + + if (found_count != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get stringvar list (2)\n"; + return false; + } + } + + { + symbol_table.add_stringvar("i", i); + symbol_table.add_stringvar("j", j); + symbol_table.add_stringvar("ii",ii); + symbol_table.add_stringvar("jj",jj); + + std::vector expected_var_list; + + expected_var_list.push_back( "i"); + expected_var_list.push_back( "j"); + expected_var_list.push_back("ii"); + expected_var_list.push_back("jj"); + + std::deque stringvar_list; + + symbol_table.get_stringvar_list(stringvar_list); + + if (stringvar_list.size() != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get stringvar list (3)\n"; + return false; + } + + std::size_t found_count = 0; + + for (std::size_t i = 0; i < stringvar_list.size(); ++i) + { + for (std::size_t j = 0; j < expected_var_list.size(); ++j) + { + if (stringvar_list[i] == expected_var_list[j]) + { + ++found_count; + break; + } + } + } + + if (found_count != expected_var_list.size()) + { + std::cout << "run_test10() - Failed to get stringvar list (4)\n"; + return false; + } + } + return true; }