From 552d75682b9c3f8b1bb7fb009e0d11f0dfea66c0 Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Fri, 5 Dec 2014 05:56:58 +1100 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 160 ++++++++++++++++++++++++++--------------------------- 1 file changed, 78 insertions(+), 82 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index ef17d05..b50ca76 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -4217,21 +4217,10 @@ namespace exprtk }; template - class string_base_node - { - public: - - virtual std::string str() const = 0; - - virtual const char* base() const = 0; - - virtual void register_base(void*&) {} - - virtual void update_base() {} - }; + struct range_pack; template - struct range_pack; + struct range_data_type; template class range_interface @@ -4245,6 +4234,18 @@ namespace exprtk virtual const range_t& range_ref() const = 0; }; + template + class string_base_node + { + public: + + typedef range_data_type range_data_type_t; + + virtual std::string str() const = 0; + + virtual const char* base() const = 0; + }; + template class string_literal_node : public expression_node , public string_base_node, @@ -5676,6 +5677,30 @@ namespace exprtk mutable cached_range_t cache; }; + template + class string_base_node; + + template + struct range_data_type + { + typedef range_pack range_pack_t; + typedef string_base_node* strbase_ptr_t; + + range_data_type() + : range(0), + data (0), + size (0), + type_size(0), + str_node (0) + {} + + range_pack_t* range; + void* data; + std::size_t size; + std::size_t type_size; + strbase_ptr_t str_node; + }; + template class vector_node; template @@ -6032,6 +6057,7 @@ namespace exprtk public: typedef range_pack range_t; + typedef range_data_type range_data_type_t; static std::string null_value; @@ -6093,27 +6119,10 @@ namespace exprtk return (*value_).data(); } - void register_base(void*& ptr) - { - base_list_.push_back(&ptr); - } - - void update_base() - { - if (!base_list_.empty()) - { - for (std::size_t i = 0; i < base_list_.size(); ++i) - { - (*base_list_[i]) = reinterpret_cast(const_cast(base())); - } - } - } - private: std::string* value_; range_t rp_; - std::vector base_list_; }; template @@ -6869,10 +6878,6 @@ namespace exprtk str1_range_ptr_ = &(range_ptr->range_ref()); } - - rp_.n0_c = std::make_pair(true ,0); - rp_.n1_c = std::make_pair(false,0); - rp_.cache = cached_range_t(0,0); } inline T value() const @@ -6893,10 +6898,14 @@ namespace exprtk if (range(r0,r1,str1_base_ptr_->str().size())) { + range_t& rp = const_cast(range_ref()); + str0_node_ptr_->ref().assign(str1_base_ptr_->str().data() + r0, (r1 - r0) + 1); - rp_.n1_c = std::make_pair(true,str0_node_ptr_->ref().size() - 1); - rp_.cache = cached_range_t(0,rp_.n1_c.second); - str0_node_ptr_->update_base(); + + const std::size_t size = str0_node_ptr_->ref().size(); + + rp.n1_c = std::make_pair(true,size - 1); + rp.cache = cached_range_t( 0,size - 1); } } @@ -6915,12 +6924,12 @@ namespace exprtk range_t& range_ref() { - return rp_; + return str0_node_ptr_->range_ref(); } const range_t& range_ref() const { - return rp_; + return str0_node_ptr_->range_ref(); } inline typename expression_node::node_type type() const @@ -6928,23 +6937,12 @@ namespace exprtk return expression_node::e_strass; } - void register_base(void*& ptr) - { - str0_node_ptr_->register_base(ptr); - } - - void update_base() - { - str0_node_ptr_->update_base(); - } - private: str_base_ptr str0_base_ptr_; str_base_ptr str1_base_ptr_; strvar_node_ptr str0_node_ptr_; range_ptr str1_range_ptr_; - mutable range_t rp_; }; template @@ -8533,21 +8531,6 @@ namespace exprtk typedef range_pack range_pack_t; - struct range_type - { - range_type() - : range(0), - data (0), - size (0), - type_size(0) - {} - - range_pack_t* range; - void* data; - std::size_t size; - std::size_t type_size; - }; - typedef type_store type_store_t; typedef expression_node* expression_ptr; typedef variable_node variable_node_t; @@ -8557,11 +8540,12 @@ namespace exprtk typedef vector_elem_node_t* vector_elem_node_ptr_t; typedef vector_node_t* vector_node_ptr_t; typedef range_interface range_interface_t; + typedef range_data_type range_data_type_t; typedef std::pair branch_t; typedef std::pair void_t; typedef std::vector tmp_vs_t; typedef std::vector typestore_list_t; - typedef std::vector range_list_t; + typedef std::vector range_list_t; generic_function_node(GenericFunction* func, const std::vector& arg_list) @@ -8583,11 +8567,10 @@ namespace exprtk bool init_branches() { - expr_as_vec1_store_.resize(arg_list_.size(),T(0)); - - range_list_.resize(arg_list_.size(),range_type()); - - typestore_list_.resize(arg_list_.size(),type_store_t()); + expr_as_vec1_store_.resize(arg_list_.size(),T(0) ); + typestore_list_ .resize(arg_list_.size(),type_store_t() ); + range_list_ .resize(arg_list_.size(),range_data_type_t()); + branch_ .resize(arg_list_.size(),branch_t((expression_ptr)0,false)); for (std::size_t i = 0; i < arg_list_.size(); ++i) { @@ -8617,11 +8600,10 @@ namespace exprtk ts.data = reinterpret_cast(const_cast(sbn->base())); ts.type = type_store_t::e_string; - range_list_[i].data = ts.data; - range_list_[i].size = ts.size; + range_list_[i].data = ts.data; + range_list_[i].size = ts.size; range_list_[i].type_size = sizeof(char); - - sbn->register_base(range_list_[i].data); + range_list_[i].str_node = sbn; if ( is_string_range_node (arg_list_[i]) || @@ -8636,7 +8618,10 @@ namespace exprtk range_pack_t& rp = ri->range_ref(); - if (rp.const_range()) + if ( + rp.const_range() && + is_const_string_range_node(arg_list_[i]) + ) { ts.size = rp.const_size(); ts.data = static_cast(ts.data) + rp.n0_c.second; @@ -8675,7 +8660,7 @@ namespace exprtk ts.type = type_store_t::e_scalar; } - branch_.push_back(std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]))); + branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i])); } return true; @@ -8711,17 +8696,28 @@ namespace exprtk for (std::size_t i = 0; i < branch_.size(); ++i) { expr_as_vec1_store_[i] = branch_[i].first->value(); + } - if (range_list_[i].range) + for (std::size_t i = 0; i < branch_.size(); ++i) + { + range_data_type_t& rdt = range_list_[i]; + + if (rdt.range) { - range_pack_t& rp = (*range_list_[i].range); + range_pack_t& rp = (*rdt.range); std::size_t r0 = 0; std::size_t r1 = 0; - if (rp(r0,r1,range_list_[i].size)) + if (rp(r0,r1,rdt.size)) { - typestore_list_[i].size = rp.cache_size(); - typestore_list_[i].data = static_cast(range_list_[i].data) + (rp.cache.first * range_list_[i].type_size); + type_store_t& ts = typestore_list_[i]; + + ts.size = rp.cache_size(); + + if (ts.type == type_store_t::e_string) + ts.data = const_cast(rdt.str_node->base()) + rp.cache.first; + else + ts.data = static_cast(rdt.data) + (rp.cache.first * rdt.type_size); } else return false;