7 CompoundCondition::~CompoundCondition()
9 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
13 void CompoundCondition::clone_to(CompoundCondition &other) const
15 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
16 other.add((*i)->clone());
19 bool CompoundCondition::sub_equals(const CompoundCondition &other) const
21 if(other.count()!=conditions.size())
24 for(unsigned i=0; i<conditions.size(); ++i)
25 if(!conditions[i]->equals(other.get(i)))
31 void CompoundCondition::add(Condition *cond)
34 throw invalid_argument("CompoundCondition::add");
35 conditions.push_back(cond);
38 const Condition &CompoundCondition::get(unsigned i) const
40 if(i>=conditions.size())
41 throw out_of_range("CompoundCondition::get");
42 return *conditions[i];
45 Condition *CompoundCondition::flatten() const
47 if(conditions.empty())
49 else if(conditions.size()==1)
50 return conditions.front()->clone();
53 for(vector<Condition *>::const_iterator i=conditions.begin(); (merge && ++i!=conditions.end()); )
54 merge = conditions.front()->can_merge(**i, *this);
58 vector<const Condition *> merge_conds(conditions.begin(), conditions.end());
59 return conditions.front()->merge(merge_conds, *this);
63 Condition *result = 0;
64 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
66 Condition *sub = (*i)->flatten();
70 result = dispatch_flatten(result, sub);
73 if(result && result->is_viable())
81 Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond2) const
83 OrCondition *or1 = dynamic_cast<OrCondition *>(cond1);
84 AndCondition *and1 = dynamic_cast<AndCondition *>(cond1);
85 OrCondition *or2 = dynamic_cast<OrCondition *>(cond2);
86 AndCondition *and2 = dynamic_cast<AndCondition *>(cond2);
90 return flatten(or1, or2);
92 return flatten(or1, and2);
94 return flatten(or2, and1);
96 return flatten(or1, cond2);
98 return flatten(or2, cond1);
100 else if(and1 || and2)
103 return flatten(and1, and2);
105 return flatten(and1, cond2);
107 return flatten(and2, cond1);
110 return flatten(cond1, cond2);
112 throw logic_error("CompoundCondition::dispatch_flatten");
115 Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, const CompoundCondition &parent, bool del)
117 vector<const Condition *> parts(2);
120 Condition *result = cond1->merge(parts, parent);
127 if(!result->is_viable())
137 Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del)
140 for(vector<Condition *>::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i)
141 if((*i)->can_merge(*cond, *target))
143 Condition *m = merge_two(cond, *i, *target, false);
153 target->add(del ? cond : cond->clone());
155 if(del && !target->is_viable())
164 Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target)
166 for(vector<Condition *>::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i)
167 add_merged_to(*i, target, false);
171 if(target->is_viable())
179 AndCondition *AndCondition::clone() const
181 AndCondition *result = new AndCondition;
186 bool AndCondition::equals(const Condition &other) const
188 const AndCondition *other_and = dynamic_cast<const AndCondition *>(&other);
189 return (other_and ? sub_equals(*other_and) : false);
192 Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const
194 if(cond1->can_merge(*cond2, *this))
195 return merge_two(cond1, cond2, *this, true);
197 AndCondition *result = new AndCondition;
203 Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const
205 return add_merged_to(cond2, cond1, true);
208 Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
210 return merge_contents_to(cond2, cond1);
213 Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const
215 OrCondition *result = new OrCondition;
216 unsigned count = cond1->count();
217 for(unsigned i=0; i<count; ++i)
218 if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), (i+1<count ? cond2->clone() : cond2)))
219 add_merged_to(sub, result, true);
222 if(result->is_viable())
229 Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
231 return flatten(cond1, static_cast<Condition *>(cond2));
234 Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
236 unsigned count1 = cond1->count();
237 unsigned count2 = cond2->count();
238 OrCondition *result = new OrCondition;
239 for(unsigned i=0; i<count1; ++i)
240 for(unsigned j=0; j<count2; ++j)
241 if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), cond2->get(j).clone()))
242 add_merged_to(sub, result, true);
247 if(result->is_viable())
254 bool AndCondition::can_merge(const Condition &other, const CompoundCondition &parent) const
256 const AndCondition *other_and = dynamic_cast<const AndCondition *>(&other);
257 if(!other_and || !dynamic_cast<const OrCondition *>(&parent))
260 return merge(*this, *other_and, parent, 0);
263 AndCondition *AndCondition::merge(const vector<const Condition *> &conds, const CompoundCondition &parent) const
268 const AndCondition *and1 = dynamic_cast<const AndCondition *>(conds[0]);
269 const AndCondition *and2 = dynamic_cast<const AndCondition *>(conds[1]);
270 if(!and1 || !and2 || !dynamic_cast<const OrCondition *>(&parent))
273 AndCondition *result = 0;
274 merge(*and1, *and2, parent, &result);
278 bool AndCondition::merge(const AndCondition &cond1, const AndCondition &cond2, const CompoundCondition &parent, AndCondition **result)
280 if(cond1.count()!=cond2.count())
284 vector<bool> used(cond1.count(), false);
285 for(unsigned i=0; i<cond1.count(); ++i)
288 for(unsigned j=0; (match<0 && j<cond2.count()); ++j)
289 if(!used[j] && cond1.get(i).equals(cond2.get(j)))
302 vector<const Condition *> merge_conds(2, 0);
303 merge_conds[0] = &cond1.get(merge1);
304 for(unsigned i=0; (!merge_conds[1] && i<cond2.count()); ++i)
306 merge_conds[1] = &cond2.get(i);
308 if(!merge_conds[1] || !merge_conds[0]->can_merge(*merge_conds[1], parent))
313 *result = new AndCondition;
314 (*result)->add(merge_conds[0]->merge(merge_conds, parent));
318 *result = new AndCondition;
322 for(unsigned i=0; i<cond2.count(); ++i)
324 (*result)->add(cond2.get(i).clone());
330 bool AndCondition::is_viable() const
332 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
333 if(!(*i)->is_viable())
335 return !conditions.empty();
338 void AndCondition::add_lines(list<FilterStatement> &st) const
340 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
345 OrCondition *OrCondition::clone() const
347 OrCondition *result = new OrCondition;
352 bool OrCondition::equals(const Condition &other) const
354 const OrCondition *other_or = dynamic_cast<const OrCondition *>(&other);
355 return (other_or ? sub_equals(*other_or) : false);
358 Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const
360 if(cond1->can_merge(*cond2, *this))
361 return merge_two(cond1, cond2, *this, true);
363 OrCondition *result = new OrCondition;
369 Condition *OrCondition::flatten(AndCondition *cond1, Condition *cond2) const
371 return flatten(static_cast<Condition *>(cond1), cond2);
374 Condition *OrCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
376 return flatten(static_cast<Condition *>(cond1), static_cast<Condition *>(cond2));
379 Condition *OrCondition::flatten(OrCondition *cond1, Condition *cond2) const
381 return add_merged_to(cond2, cond1, true);
384 Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
386 return flatten(cond1, static_cast<Condition *>(cond2));
389 Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
391 return merge_contents_to(cond2, cond1);
394 bool OrCondition::is_viable() const
396 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
397 if((*i)->is_viable())
402 void OrCondition::add_lines(list<FilterStatement> &st) const
404 list<FilterStatement> result;
405 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
407 list<FilterStatement> sub_result = st;
408 (*i)->add_lines(sub_result);
409 result.splice(result.end(), sub_result);
415 LinkedColorsCondition::LinkedColorsCondition(const Colors &c):
419 LinkedColorsCondition *LinkedColorsCondition::clone() const
421 return new LinkedColorsCondition(colors);
424 bool LinkedColorsCondition::equals(const Condition &other) const
426 const LinkedColorsCondition *other_linked = dynamic_cast<const LinkedColorsCondition *>(&other);
430 for(unsigned i=0; i<7; ++i)
432 if(colors.colors[i]!=other_linked->colors.colors[i])
434 if(!colors.colors[i])
441 void LinkedColorsCondition::add_lines(list<FilterStatement> &st) const
443 FilterStatement::add_line(st, format("SocketGroup %s", colors.colors));
447 void operator>>(const LexicalConverter &conv, LinkedColorsCondition::Colors &colors)
449 const string &str = conv.get();
451 for(string::const_iterator i=str.begin(); (rgb && i!=str.end()); ++i)
452 rgb = (*i=='R' || *i=='G' || *i=='B');
453 if(str.size()>6 || !rgb)
454 throw lexical_error(format("conversion of '%s' to LinkedColorsCondition::Colors", str));
456 fill(colors.colors, colors.colors+7, '\0');
457 copy(str.begin(), str.end(), colors.colors);