@@ -6,10 +6,10 @@ namespace mexpr
66inline namespace
77{
88Expression diff_sum_sub_impl (
9- const std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
9+ std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
1010 const std::string_view var) {
1111
12- const auto & [type, lhs, rhs] = bexpr;
12+ auto & [type, lhs, rhs] = bexpr;
1313 bool lhs_contains_var = lhs->contains_var (var);
1414 bool rhs_contains_var = rhs->contains_var (var);
1515
@@ -23,10 +23,10 @@ Expression diff_sum_sub_impl(
2323}
2424
2525Expression diff_mul_impl (
26- const std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
26+ std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
2727 const std::string_view var) {
2828
29- const auto & [type, lhs, rhs] = bexpr;
29+ auto & [type, lhs, rhs] = bexpr;
3030 bool lhs_contains_var = lhs->contains_var (var);
3131 bool rhs_contains_var = rhs->contains_var (var);
3232 if (not (lhs_contains_var or rhs_contains_var)) {
@@ -53,10 +53,10 @@ Expression diff_mul_impl(
5353}
5454
5555Expression diff_div_impl (
56- const std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
56+ std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
5757 const std::string_view var) {
5858
59- const auto & [type, lhs, rhs] = bexpr;
59+ auto & [type, lhs, rhs] = bexpr;
6060 bool lhs_contains_var = lhs->contains_var (var);
6161 bool rhs_contains_var = rhs->contains_var (var);
6262
@@ -105,31 +105,35 @@ Expression diff_div_impl(
105105}
106106} // namespace
107107
108- Expression::Expression (int val) : value_{val} {
108+ Expression::Expression (int val) : variable_lookup_cache_{}, value_{val} {
109109}
110110
111111
112- Expression::Expression (std::string name) : value_{name} {
112+ Expression::Expression (std::string name) : variable_lookup_cache_{{name, true }}, value_{name} {
113113}
114114
115115
116116Expression::Expression (unary_expr_type expr_type, std::unique_ptr<Expression> expr)
117- : value_{std::make_tuple (expr_type, std::move (expr))} {
117+ : variable_lookup_cache_{}
118+ , value_{std::make_tuple (expr_type, std::move (expr))} {
118119}
119120
120121
121122Expression::Expression (unary_expr_type expr_type, Expression&& expr)
122- : value_{std::make_tuple (expr_type, std::make_unique<Expression>(std::move (expr)))} {
123+ : variable_lookup_cache_{}
124+ , value_{std::make_tuple (expr_type, std::make_unique<Expression>(std::move (expr)))} {
123125}
124126
125127
126128Expression::Expression (binary_expr_type expr_type, std::unique_ptr<Expression> lhs, std::unique_ptr<Expression> rhs)
127- : value_{std::make_tuple (expr_type, std::move (lhs), std::move (rhs))} {
129+ : variable_lookup_cache_{}
130+ , value_{std::make_tuple (expr_type, std::move (lhs), std::move (rhs))} {
128131}
129132
130133
131134Expression::Expression (binary_expr_type expr_type, Expression&& lhs, Expression&& rhs)
132- : value_{std::make_tuple (
135+ : variable_lookup_cache_{}
136+ , value_{std::make_tuple (
133137 expr_type,
134138 std::make_unique<Expression>(std::move (lhs)),
135139 std::make_unique<Expression>(std::move (rhs)))} {
@@ -151,11 +155,11 @@ Expression Expression::clone() const {
151155}
152156
153157
154- Expression Expression::diff (const std::string_view var) const {
158+ Expression Expression::diff (const std::string_view var) {
155159
156160 if (std::holds_alternative<binary_expr>(value_)) {
157161 // first unpack variant value
158- const auto & bexpr = std::get<binary_expr>(value_);
162+ auto & bexpr = std::get<binary_expr>(value_);
159163 // then unpack tuple from variant value
160164 const auto & type = std::get<0 >(bexpr);
161165 switch (type) {
@@ -165,8 +169,8 @@ Expression Expression::diff(const std::string_view var) const {
165169 case binary_expr_type::div: return diff_div_impl (bexpr, var);
166170 }
167171 } else if (std::holds_alternative<unary_expr>(value_)) {
168- const auto & uexpr = std::get<unary_expr>(value_);
169- const auto & [type, value] = uexpr;
172+ auto & uexpr = std::get<unary_expr>(value_);
173+ auto & [type, value] = uexpr;
170174 switch (type) {
171175 case unary_expr_type::unary_minus:
172176 return value->contains_var (var) //
@@ -251,18 +255,29 @@ std::string Expression::to_string() const {
251255}
252256
253257
254- bool Expression::contains_var (const std::string_view var) const {
258+ bool Expression::contains_var (const std::string_view var) {
259+ const auto cache_hit = variable_lookup_cache_.find (var);
260+ if (cache_hit != variable_lookup_cache_.end ()) {
261+ return cache_hit->second ;
262+ }
263+
255264 if (std::holds_alternative<binary_expr>(value_)) {
256265 const auto & bexpr = std::get<binary_expr>(value_);
257- return std::get<1 >(bexpr)->contains_var (var) or std::get<2 >(bexpr)->contains_var (var);
266+ bool result = std::get<1 >(bexpr)->contains_var (var) or std::get<2 >(bexpr)->contains_var (var);
267+ variable_lookup_cache_.emplace (var, result);
268+ return result;
258269 } else if (std::holds_alternative<unary_expr>(value_)) {
259270 const auto & uexpr = std::get<unary_expr>(value_);
260- return std::get<1 >(uexpr)->contains_var (var);
271+ bool result = std::get<1 >(uexpr)->contains_var (var);
272+ variable_lookup_cache_.emplace (var, result);
273+ return result;
261274 } else if (std::holds_alternative<std::string>(value_)) {
262- return std::get<std::string>(value_) == var;
263- } else {
264- return false ;
275+ bool result = std::get<std::string>(value_) == var;
276+ variable_lookup_cache_.emplace (var, result);
265277 }
278+
279+ variable_lookup_cache_.emplace (var, false );
280+ return false ;
266281}
267282
268283
0 commit comments