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);
60 Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond2) const
62 OrCondition *or1 = dynamic_cast<OrCondition *>(cond1);
63 AndCondition *and1 = dynamic_cast<AndCondition *>(cond1);
64 OrCondition *or2 = dynamic_cast<OrCondition *>(cond2);
65 AndCondition *and2 = dynamic_cast<AndCondition *>(cond2);
69 return flatten(or1, or2);
71 return flatten(or1, and2);
73 return flatten(or2, and1);
75 return flatten(or1, cond2);
77 return flatten(or2, cond1);
82 return flatten(and1, and2);
84 return flatten(and1, cond2);
86 return flatten(and2, cond1);
89 return flatten(cond1, cond2);
91 throw logic_error("CompoundCondition::dispatch_flatten");
94 Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const
96 vector<Condition *> parts;
98 parts.push_back(cond1);
99 parts.push_back(cond2);
100 Condition *result = cond1->merge(parts, *this);
109 Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const
111 for(vector<Condition *>::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i)
112 if((*i)->can_merge(*cond, *target))
114 Condition *m = merge_two(cond, *i, false);
122 target->add(del ? cond : cond->clone());
126 Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, CompoundCondition *target) const
128 for(vector<Condition *>::iterator i=cond->conditions.begin(); i!=cond->conditions.end(); ++i)
129 add_merged_to(*i, target, false);
136 AndCondition *AndCondition::clone() const
138 AndCondition *result = new AndCondition;
143 Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const
145 if(cond1->can_merge(*cond2, *this))
146 return merge_two(cond1, cond2, true);
148 AndCondition *result = new AndCondition;
154 Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const
156 return add_merged_to(cond2, cond1, true);
159 Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
161 return merge_contents_to(cond2, cond1);
164 Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const
166 OrCondition *result = new OrCondition;
167 unsigned count = cond1->count();
168 for(unsigned i=0; i<count; ++i)
169 result->add(dispatch_flatten(cond1->get(i)->clone(), (i+1<count ? cond2->clone() : cond2)));
174 Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
176 return flatten(cond1, static_cast<Condition *>(cond2));
179 Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
181 unsigned count1 = cond1->count();
182 unsigned count2 = cond2->count();
183 OrCondition *result = new OrCondition;
184 for(unsigned i=0; i<count1; ++i)
185 for(unsigned j=0; j<count2; ++j)
186 result->add(dispatch_flatten(cond1->get(i)->clone(), cond2->get(j)->clone()));
192 void AndCondition::add_lines(list<FilterStatement> &st) const
194 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
199 OrCondition *OrCondition::clone() const
201 OrCondition *result = new OrCondition;
206 Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const
208 if(cond1->can_merge(*cond2, *this))
209 return merge_two(cond1, cond2, true);
211 OrCondition *result = new OrCondition;
217 Condition *OrCondition::flatten(AndCondition *cond1, Condition *cond2) const
219 return flatten(static_cast<Condition *>(cond1), cond2);
222 Condition *OrCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
224 return flatten(static_cast<Condition *>(cond1), static_cast<Condition *>(cond2));
227 Condition *OrCondition::flatten(OrCondition *cond1, Condition *cond2) const
229 return add_merged_to(cond2, cond1, true);
232 Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
234 return flatten(cond1, static_cast<Condition *>(cond2));
237 Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
239 return merge_contents_to(cond2, cond1);
242 void OrCondition::add_lines(list<FilterStatement> &st) const
244 list<FilterStatement> result;
245 for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
247 list<FilterStatement> sub_result = st;
248 (*i)->add_lines(sub_result);
249 result.splice(result.end(), sub_result);
255 LinkedColorsCondition::LinkedColorsCondition(const Colors &c):
259 LinkedColorsCondition *LinkedColorsCondition::clone() const
261 return new LinkedColorsCondition(colors);
264 void LinkedColorsCondition::add_lines(list<FilterStatement> &st) const
266 FilterStatement::add_line(st, format("SocketGroup %s", colors.colors));
270 void operator>>(const LexicalConverter &conv, LinkedColorsCondition::Colors &colors)
272 const string &str = conv.get();
274 for(string::const_iterator i=str.begin(); (rgb && i!=str.end()); ++i)
275 rgb = (*i=='R' || *i=='G' || *i=='B');
276 if(str.size()>6 || !rgb)
277 throw lexical_error(format("conversion of '%s' to LinkedColorsCondition::Colors", str));
279 fill(colors.colors, colors.colors+7, '\0');
280 copy(str.begin(), str.end(), colors.colors);