]> git.tdb.fi Git - poefilter.git/blobdiff - source/condition.cpp
Further merge conditions while flattening
[poefilter.git] / source / condition.cpp
index 42e9ee8f3f1360829d2b518d9d22e99a569f0a69..a8a5a90d9c8b6ce1c87f542dad8422a0063d121d 100644 (file)
@@ -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<Condition *> 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<Condition *>::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<Condition *>::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; i<count2; ++i)
-               cond1->add(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; i<count2; ++i)
-               cond1->add(cond2->get(i)->clone());
-       delete cond2;
-       return cond1;
+       return merge_contents_to(cond2, cond1);
 }
 
 void OrCondition::add_lines(list<FilterStatement> &st) const