other.add((*i)->clone());
}
+bool CompoundCondition::sub_equals(const CompoundCondition &other) const
+{
+ if(other.count()!=conditions.size())
+ return false;
+
+ for(unsigned i=0; i<conditions.size(); ++i)
+ if(!conditions[i]->equals(other.get(i)))
+ return false;
+
+ return true;
+}
+
void CompoundCondition::add(Condition *cond)
{
+ if(!cond)
+ throw invalid_argument("CompoundCondition::add");
conditions.push_back(cond);
}
-const Condition *CompoundCondition::get(unsigned i) const
+const Condition &CompoundCondition::get(unsigned i) const
{
if(i>=conditions.size())
throw out_of_range("CompoundCondition::get");
- return conditions[i];
+ return *conditions[i];
}
Condition *CompoundCondition::flatten() const
merge = conditions.front()->can_merge(**i, *this);
if(merge)
- return conditions.front()->merge(conditions, *this);
+ {
+ vector<const Condition *> merge_conds(conditions.begin(), conditions.end());
+ return conditions.front()->merge(merge_conds, *this);
+ }
else
{
Condition *result = 0;
throw logic_error("CompoundCondition::dispatch_flatten");
}
-Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const
+Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, const CompoundCondition &parent, bool del)
{
- vector<Condition *> parts;
- parts.reserve(2);
- parts.push_back(cond1);
- parts.push_back(cond2);
- Condition *result = cond1->merge(parts, *this);
+ vector<const Condition *> parts(2);
+ parts[0] = cond1;
+ parts[1] = cond2;
+ Condition *result = cond1->merge(parts, parent);
if(del)
{
return result;
}
-Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const
+Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del)
{
bool merged = false;
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);
+ Condition *m = merge_two(cond, *i, *target, false);
delete *i;
if(del)
delete cond;
return target;
}
-Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) const
+Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target)
{
for(vector<Condition *>::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i)
add_merged_to(*i, target, false);
return result;
}
+bool AndCondition::equals(const Condition &other) const
+{
+ const AndCondition *other_and = dynamic_cast<const AndCondition *>(&other);
+ return (other_and ? sub_equals(*other_and) : false);
+}
+
Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const
{
if(cond1->can_merge(*cond2, *this))
- return merge_two(cond1, cond2, true);
+ return merge_two(cond1, cond2, *this, true);
AndCondition *result = new AndCondition;
result->add(cond1);
OrCondition *result = new OrCondition;
unsigned count = cond1->count();
for(unsigned i=0; i<count; ++i)
- if(Condition *sub = dispatch_flatten(cond1->get(i)->clone(), (i+1<count ? cond2->clone() : cond2)))
+ if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), (i+1<count ? cond2->clone() : cond2)))
result->add(sub);
delete cond1;
OrCondition *result = new OrCondition;
for(unsigned i=0; i<count1; ++i)
for(unsigned j=0; j<count2; ++j)
- if(Condition *sub = dispatch_flatten(cond1->get(i)->clone(), cond2->get(j)->clone()))
+ if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), cond2->get(j).clone()))
result->add(sub);
delete cond1;
return result;
}
+bool OrCondition::equals(const Condition &other) const
+{
+ const OrCondition *other_or = dynamic_cast<const OrCondition *>(&other);
+ return (other_or ? sub_equals(*other_or) : false);
+}
+
Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const
{
if(cond1->can_merge(*cond2, *this))
- return merge_two(cond1, cond2, true);
+ return merge_two(cond1, cond2, *this, true);
OrCondition *result = new OrCondition;
result->add(cond1);
return new LinkedColorsCondition(colors);
}
+bool LinkedColorsCondition::equals(const Condition &other) const
+{
+ const LinkedColorsCondition *other_linked = dynamic_cast<const LinkedColorsCondition *>(&other);
+ if(!other_linked)
+ return false;
+
+ for(unsigned i=0; i<7; ++i)
+ {
+ if(colors.colors[i]!=other_linked->colors.colors[i])
+ return false;
+ if(!colors.colors[i])
+ break;
+ }
+
+ return true;
+}
+
void LinkedColorsCondition::add_lines(list<FilterStatement> &st) const
{
FilterStatement::add_line(st, format("SocketGroup %s", colors.colors));