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
{
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);
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
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);
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
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
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;