From: Mikko Rasa Date: Wed, 15 Aug 2018 22:08:46 +0000 (+0300) Subject: Further merge conditions while flattening X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=694d2890065b1555a01a81994cb80f106ca577ee;p=poefilter.git Further merge conditions while flattening --- diff --git a/source/condition.cpp b/source/condition.cpp index 42e9ee8..a8a5a90 100644 --- a/source/condition.cpp +++ b/source/condition.cpp @@ -91,6 +91,47 @@ Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond throw logic_error("CompoundCondition::dispatch_flatten"); } +Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const +{ + vector parts; + parts.reserve(2); + parts.push_back(cond1); + parts.push_back(cond2); + Condition *result = cond1->merge(parts, *this); + if(del) + { + delete cond1; + delete cond2; + } + return result; +} + +Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const +{ + for(vector::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i) + if((*i)->can_merge(*cond, *target)) + { + Condition *m = merge_two(cond, *i, false); + delete *i; + if(del) + delete cond; + *i = m; + return target; + } + + target->add(del ? cond : cond->clone()); + return target; +} + +Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) const +{ + for(vector::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i) + add_merged_to(*i, target, false); + + delete cond; + return target; +} + AndCondition *AndCondition::clone() const { @@ -101,6 +142,9 @@ AndCondition *AndCondition::clone() const Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const { + if(cond1->can_merge(*cond2, *this)) + return merge_two(cond1, cond2, true); + AndCondition *result = new AndCondition; result->add(cond1); result->add(cond2); @@ -109,17 +153,12 @@ Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const { - cond1->add(cond2); - return cond1; + return add_merged_to(cond2, cond1, true); } Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const { - unsigned count2 = cond2->count(); - for(unsigned i=0; iadd(cond2->get(i)->clone()); - delete cond2; - return cond1; + return merge_contents_to(cond2, cond1); } Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const @@ -166,6 +205,9 @@ OrCondition *OrCondition::clone() const Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const { + if(cond1->can_merge(*cond2, *this)) + return merge_two(cond1, cond2, true); + OrCondition *result = new OrCondition; result->add(cond1); result->add(cond2); @@ -184,8 +226,7 @@ Condition *OrCondition::flatten(AndCondition *cond1, AndCondition *cond2) const Condition *OrCondition::flatten(OrCondition *cond1, Condition *cond2) const { - cond1->add(cond2); - return cond1; + return add_merged_to(cond2, cond1, true); } Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const @@ -195,11 +236,7 @@ Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const { - unsigned count2 = cond2->count(); - for(unsigned i=0; iadd(cond2->get(i)->clone()); - delete cond2; - return cond1; + return merge_contents_to(cond2, cond1); } void OrCondition::add_lines(list &st) const diff --git a/source/condition.h b/source/condition.h index 141e570..979f1e9 100644 --- a/source/condition.h +++ b/source/condition.h @@ -47,6 +47,9 @@ public: virtual Condition *flatten() const; protected: Condition *dispatch_flatten(Condition *, Condition *) const; + Condition *merge_two(Condition *, Condition *, bool) const; + Condition *add_merged_to(Condition *, CompoundCondition *, bool) const; + Condition *merge_contents_to(CompoundCondition *, CompoundCondition *) const; virtual Condition *flatten(Condition *, Condition *) const = 0; virtual Condition *flatten(AndCondition *, Condition *) const = 0; virtual Condition *flatten(AndCondition *, AndCondition *) const = 0;