X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcondition.cpp;h=42e9ee8f3f1360829d2b518d9d22e99a569f0a69;hb=8b9d1f472e7bfbb1e097bb6d8bcad026e9636822;hp=9ff02aa322db9f93bbf8ce6f623a1471666d51cd;hpb=d0663f70ea5caea2db3c6d3c846ec67410db3498;p=poefilter.git diff --git a/source/condition.cpp b/source/condition.cpp index 9ff02aa..42e9ee8 100644 --- a/source/condition.cpp +++ b/source/condition.cpp @@ -21,14 +21,135 @@ void CompoundCondition::add(Condition *cond) conditions.push_back(cond); } +const Condition *CompoundCondition::get(unsigned i) const +{ + if(i>=conditions.size()) + throw out_of_range("CompoundCondition::get"); + return conditions[i]; +} + +Condition *CompoundCondition::flatten() const +{ + if(conditions.empty()) + return 0; + else if(conditions.size()==1) + return conditions.front()->clone(); + + bool merge = true; + for(vector::const_iterator i=conditions.begin(); (merge && ++i!=conditions.end()); ) + merge = conditions.front()->can_merge(**i, *this); + + if(merge) + return conditions.front()->merge(conditions, *this); + else + { + Condition *result = 0; + for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) + { + Condition *sub = (*i)->flatten(); + if(!result) + result = sub; + else + result = dispatch_flatten(result, sub); + } + + return result; + } +} + +Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond2) const +{ + OrCondition *or1 = dynamic_cast(cond1); + AndCondition *and1 = dynamic_cast(cond1); + OrCondition *or2 = dynamic_cast(cond2); + AndCondition *and2 = dynamic_cast(cond2); + if(or1 || or2) + { + if(or1 && or2) + return flatten(or1, or2); + else if(or1 && and2) + return flatten(or1, and2); + else if(or2 && and1) + return flatten(or2, and1); + else if(or1) + return flatten(or1, cond2); + else if(or2) + return flatten(or2, cond1); + } + else if(and1 || and2) + { + if(and1 && and2) + return flatten(and1, and2); + else if(and1) + return flatten(and1, cond2); + else if(and2) + return flatten(and2, cond1); + } + else + return flatten(cond1, cond2); + + throw logic_error("CompoundCondition::dispatch_flatten"); +} + -Condition *AndCondition::clone() const +AndCondition *AndCondition::clone() const { AndCondition *result = new AndCondition; clone_to(*result); return result; } +Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const +{ + AndCondition *result = new AndCondition; + result->add(cond1); + result->add(cond2); + return result; +} + +Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const +{ + cond1->add(cond2); + return cond1; +} + +Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const +{ + unsigned count2 = cond2->count(); + for(unsigned i=0; iadd(cond2->get(i)->clone()); + delete cond2; + return cond1; +} + +Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const +{ + OrCondition *result = new OrCondition; + unsigned count = cond1->count(); + for(unsigned i=0; iadd(dispatch_flatten(cond1->get(i)->clone(), (i+1clone() : cond2))); + delete cond1; + return result; +} + +Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const +{ + return flatten(cond1, static_cast(cond2)); +} + +Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const +{ + unsigned count1 = cond1->count(); + unsigned count2 = cond2->count(); + OrCondition *result = new OrCondition; + for(unsigned i=0; iadd(dispatch_flatten(cond1->get(i)->clone(), cond2->get(j)->clone())); + delete cond1; + delete cond2; + return result; +} + void AndCondition::add_lines(list &st) const { for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) @@ -36,32 +157,61 @@ void AndCondition::add_lines(list &st) const } -Condition *OrCondition::clone() const +OrCondition *OrCondition::clone() const { OrCondition *result = new OrCondition; clone_to(*result); return result; } -void OrCondition::add_lines(list &st) const +Condition *OrCondition::flatten(Condition *cond1, Condition *cond2) const { - bool merge = conditions.size()>1; - for(vector::const_iterator i=conditions.begin(); (merge && ++i!=conditions.end()); ) - merge = conditions.front()->can_merge(**i, *this); + OrCondition *result = new OrCondition; + result->add(cond1); + result->add(cond2); + return result; +} - if(merge) - conditions.front()->add_merged_lines(conditions, *this, st); - else +Condition *OrCondition::flatten(AndCondition *cond1, Condition *cond2) const +{ + return flatten(static_cast(cond1), cond2); +} + +Condition *OrCondition::flatten(AndCondition *cond1, AndCondition *cond2) const +{ + return flatten(static_cast(cond1), static_cast(cond2)); +} + +Condition *OrCondition::flatten(OrCondition *cond1, Condition *cond2) const +{ + cond1->add(cond2); + return cond1; +} + +Condition *OrCondition::flatten(OrCondition *cond1, AndCondition *cond2) const +{ + return flatten(cond1, static_cast(cond2)); +} + +Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const +{ + unsigned count2 = cond2->count(); + for(unsigned i=0; iadd(cond2->get(i)->clone()); + delete cond2; + return cond1; +} + +void OrCondition::add_lines(list &st) const +{ + list result; + for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { - list result; - for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) - { - list sub_result = st; - (*i)->add_lines(sub_result); - result.splice(result.end(), sub_result); - } - swap(result, st); + list sub_result = st; + (*i)->add_lines(sub_result); + result.splice(result.end(), sub_result); } + swap(result, st); } @@ -69,7 +219,7 @@ LinkedColorsCondition::LinkedColorsCondition(const Colors &c): colors(c) { } -Condition *LinkedColorsCondition::clone() const +LinkedColorsCondition *LinkedColorsCondition::clone() const { return new LinkedColorsCondition(colors); }