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 void CompoundCondition::add(Condition *cond)
22 throw invalid_argument("CompoundCondition::add");
23 conditions.push_back(cond);
26 const Condition &CompoundCondition::get(unsigned i) const
28 if(i>=conditions.size())
29 throw out_of_range("CompoundCondition::get");
30 return *conditions[i];
33 Condition *CompoundCondition::flatten() const
35 if(conditions.empty())
37 else if(conditions.size()==1)
38 return conditions.front()->clone();
41 for(vector<Condition *>::const_iterator i=conditions.begin(); (merge && ++i!=conditions.end()); )
42 merge = conditions.front()->can_merge(**i, *this);
46 vector<const Condition *> merge_conds(conditions.begin(), conditions.end());
47 return conditions.front()->merge(merge_conds, *this);
51 Condition *result = 0;
52 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
54 Condition *sub = (*i)->flatten();
58 result = dispatch_flatten(result, sub);
61 if(result && result->is_viable())
69 Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond2) const
71 OrCondition *or1 = dynamic_cast<OrCondition *>(cond1);
72 AndCondition *and1 = dynamic_cast<AndCondition *>(cond1);
73 OrCondition *or2 = dynamic_cast<OrCondition *>(cond2);
74 AndCondition *and2 = dynamic_cast<AndCondition *>(cond2);
78 return flatten(or1, or2);
80 return flatten(or1, and2);
82 return flatten(or2, and1);
84 return flatten(or1, cond2);
86 return flatten(or2, cond1);
91 return flatten(and1, and2);
93 return flatten(and1, cond2);
95 return flatten(and2, cond1);
98 return flatten(cond1, cond2);
100 throw logic_error("CompoundCondition::dispatch_flatten");
103 Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const
105 vector<const Condition *> parts(2);
108 Condition *result = cond1->merge(parts, *this);
115 if(!result->is_viable())
125 Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const
128 for(vector<Condition *>::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i)
129 if((*i)->can_merge(*cond, *target))
131 Condition *m = merge_two(cond, *i, false);
141 target->add(del ? cond : cond->clone());
143 if(del && !target->is_viable())
152 Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) const
154 for(vector<Condition *>::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i)
155 add_merged_to(*i, target, false);
159 if(target->is_viable())
167 AndCondition *AndCondition::clone() const
169 AndCondition *result = new AndCondition;
174 Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const
176 if(cond1->can_merge(*cond2, *this))
177 return merge_two(cond1, cond2, true);
179 AndCondition *result = new AndCondition;
185 Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const
187 return add_merged_to(cond2, cond1, true);
190 Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
192 return merge_contents_to(cond2, cond1);
195 Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const
197 OrCondition *result = new OrCondition;
198 unsigned count = cond1->count();
199 for(unsigned i=0; i<count; ++i)
200 if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), (i+1<count ? cond2->clone() : cond2)))
204 if(result->is_viable())
211 Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
213 return flatten(cond1, static_cast<Condition *>(cond2));
216 Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
218 unsigned count1 = cond1->count();
219 unsigned count2 = cond2->count();
220 OrCondition *result = new OrCondition;
221 for(unsigned i=0; i<count1; ++i)
222 for(unsigned j=0; j<count2; ++j)
223 if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), cond2->get(j).clone()))
229 if(result->is_viable())
236 bool AndCondition::is_viable() const
238 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
239 if(!(*i)->is_viable())
241 return !conditions.empty();
244 void AndCondition::add_lines(list<FilterStatement> &st) const
246 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
251 OrCondition *OrCondition::clone() const
253 OrCondition *result = new OrCondition;
258 Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const
260 if(cond1->can_merge(*cond2, *this))
261 return merge_two(cond1, cond2, true);
263 OrCondition *result = new OrCondition;
269 Condition *OrCondition::flatten(AndCondition *cond1, Condition *cond2) const
271 return flatten(static_cast<Condition *>(cond1), cond2);
274 Condition *OrCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
276 return flatten(static_cast<Condition *>(cond1), static_cast<Condition *>(cond2));
279 Condition *OrCondition::flatten(OrCondition *cond1, Condition *cond2) const
281 return add_merged_to(cond2, cond1, true);
284 Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
286 return flatten(cond1, static_cast<Condition *>(cond2));
289 Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
291 return merge_contents_to(cond2, cond1);
294 bool OrCondition::is_viable() const
296 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
297 if((*i)->is_viable())
302 void OrCondition::add_lines(list<FilterStatement> &st) const
304 list<FilterStatement> result;
305 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
307 list<FilterStatement> sub_result = st;
308 (*i)->add_lines(sub_result);
309 result.splice(result.end(), sub_result);
315 LinkedColorsCondition::LinkedColorsCondition(const Colors &c):
319 LinkedColorsCondition *LinkedColorsCondition::clone() const
321 return new LinkedColorsCondition(colors);
324 void LinkedColorsCondition::add_lines(list<FilterStatement> &st) const
326 FilterStatement::add_line(st, format("SocketGroup %s", colors.colors));
330 void operator>>(const LexicalConverter &conv, LinkedColorsCondition::Colors &colors)
332 const string &str = conv.get();
334 for(string::const_iterator i=str.begin(); (rgb && i!=str.end()); ++i)
335 rgb = (*i=='R' || *i=='G' || *i=='B');
336 if(str.size()>6 || !rgb)
337 throw lexical_error(format("conversion of '%s' to LinkedColorsCondition::Colors", str));
339 fill(colors.colors, colors.colors+7, '\0');
340 copy(str.begin(), str.end(), colors.colors);