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)
21 conditions.push_back(cond);
24 const Condition *CompoundCondition::get(unsigned i) const
26 if(i>=conditions.size())
27 throw out_of_range("CompoundCondition::get");
31 Condition *CompoundCondition::flatten() const
33 if(conditions.empty())
35 else if(conditions.size()==1)
36 return conditions.front()->clone();
39 for(vector<Condition *>::const_iterator i=conditions.begin(); (merge && ++i!=conditions.end()); )
40 merge = conditions.front()->can_merge(**i, *this);
43 return conditions.front()->merge(conditions, *this);
46 Condition *result = 0;
47 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
49 Condition *sub = (*i)->flatten();
53 result = dispatch_flatten(result, sub);
56 if(result && result->is_viable())
64 Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond2) const
66 OrCondition *or1 = dynamic_cast<OrCondition *>(cond1);
67 AndCondition *and1 = dynamic_cast<AndCondition *>(cond1);
68 OrCondition *or2 = dynamic_cast<OrCondition *>(cond2);
69 AndCondition *and2 = dynamic_cast<AndCondition *>(cond2);
73 return flatten(or1, or2);
75 return flatten(or1, and2);
77 return flatten(or2, and1);
79 return flatten(or1, cond2);
81 return flatten(or2, cond1);
86 return flatten(and1, and2);
88 return flatten(and1, cond2);
90 return flatten(and2, cond1);
93 return flatten(cond1, cond2);
95 throw logic_error("CompoundCondition::dispatch_flatten");
98 Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const
100 vector<Condition *> parts;
102 parts.push_back(cond1);
103 parts.push_back(cond2);
104 Condition *result = cond1->merge(parts, *this);
111 if(!result->is_viable())
121 Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const
124 for(vector<Condition *>::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i)
125 if((*i)->can_merge(*cond, *target))
127 Condition *m = merge_two(cond, *i, false);
137 target->add(del ? cond : cond->clone());
139 if(del && !target->is_viable())
148 Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) const
150 for(vector<Condition *>::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i)
151 add_merged_to(*i, target, false);
155 if(target->is_viable())
163 AndCondition *AndCondition::clone() const
165 AndCondition *result = new AndCondition;
170 Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const
172 if(cond1->can_merge(*cond2, *this))
173 return merge_two(cond1, cond2, true);
175 AndCondition *result = new AndCondition;
181 Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const
183 return add_merged_to(cond2, cond1, true);
186 Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
188 return merge_contents_to(cond2, cond1);
191 Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const
193 OrCondition *result = new OrCondition;
194 unsigned count = cond1->count();
195 for(unsigned i=0; i<count; ++i)
196 if(Condition *sub = dispatch_flatten(cond1->get(i)->clone(), (i+1<count ? cond2->clone() : cond2)))
200 if(result->is_viable())
207 Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
209 return flatten(cond1, static_cast<Condition *>(cond2));
212 Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
214 unsigned count1 = cond1->count();
215 unsigned count2 = cond2->count();
216 OrCondition *result = new OrCondition;
217 for(unsigned i=0; i<count1; ++i)
218 for(unsigned j=0; j<count2; ++j)
219 if(Condition *sub = dispatch_flatten(cond1->get(i)->clone(), cond2->get(j)->clone()))
225 if(result->is_viable())
232 bool AndCondition::is_viable() const
234 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
235 if(!(*i)->is_viable())
237 return !conditions.empty();
240 void AndCondition::add_lines(list<FilterStatement> &st) const
242 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
247 OrCondition *OrCondition::clone() const
249 OrCondition *result = new OrCondition;
254 Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const
256 if(cond1->can_merge(*cond2, *this))
257 return merge_two(cond1, cond2, true);
259 OrCondition *result = new OrCondition;
265 Condition *OrCondition::flatten(AndCondition *cond1, Condition *cond2) const
267 return flatten(static_cast<Condition *>(cond1), cond2);
270 Condition *OrCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
272 return flatten(static_cast<Condition *>(cond1), static_cast<Condition *>(cond2));
275 Condition *OrCondition::flatten(OrCondition *cond1, Condition *cond2) const
277 return add_merged_to(cond2, cond1, true);
280 Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
282 return flatten(cond1, static_cast<Condition *>(cond2));
285 Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
287 return merge_contents_to(cond2, cond1);
290 bool OrCondition::is_viable() const
292 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
293 if((*i)->is_viable())
298 void OrCondition::add_lines(list<FilterStatement> &st) const
300 list<FilterStatement> result;
301 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
303 list<FilterStatement> sub_result = st;
304 (*i)->add_lines(sub_result);
305 result.splice(result.end(), sub_result);
311 LinkedColorsCondition::LinkedColorsCondition(const Colors &c):
315 LinkedColorsCondition *LinkedColorsCondition::clone() const
317 return new LinkedColorsCondition(colors);
320 void LinkedColorsCondition::add_lines(list<FilterStatement> &st) const
322 FilterStatement::add_line(st, format("SocketGroup %s", colors.colors));
326 void operator>>(const LexicalConverter &conv, LinkedColorsCondition::Colors &colors)
328 const string &str = conv.get();
330 for(string::const_iterator i=str.begin(); (rgb && i!=str.end()); ++i)
331 rgb = (*i=='R' || *i=='G' || *i=='B');
332 if(str.size()>6 || !rgb)
333 throw lexical_error(format("conversion of '%s' to LinkedColorsCondition::Colors", str));
335 fill(colors.colors, colors.colors+7, '\0');
336 copy(str.begin(), str.end(), colors.colors);