X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcondition.cpp;h=1ff316c361f76f51d6f0c13db000cd21a4b621f1;hb=746329e61ac9f26962af740b0b11dee716803521;hp=a8a5a90d9c8b6ce1c87f542dad8422a0063d121d;hpb=694d2890065b1555a01a81994cb80f106ca577ee;p=poefilter.git diff --git a/source/condition.cpp b/source/condition.cpp index a8a5a90..1ff316c 100644 --- a/source/condition.cpp +++ b/source/condition.cpp @@ -18,14 +18,16 @@ void CompoundCondition::clone_to(CompoundCondition &other) const void CompoundCondition::add(Condition *cond) { + if(!cond) + throw invalid_argument("CompoundCondition::add"); conditions.push_back(cond); } -const Condition *CompoundCondition::get(unsigned i) const +const Condition &CompoundCondition::get(unsigned i) const { if(i>=conditions.size()) throw out_of_range("CompoundCondition::get"); - return conditions[i]; + return *conditions[i]; } Condition *CompoundCondition::flatten() const @@ -40,7 +42,10 @@ Condition *CompoundCondition::flatten() const merge = conditions.front()->can_merge(**i, *this); if(merge) - return conditions.front()->merge(conditions, *this); + { + vector merge_conds(conditions.begin(), conditions.end()); + return conditions.front()->merge(merge_conds, *this); + } else { Condition *result = 0; @@ -49,11 +54,15 @@ Condition *CompoundCondition::flatten() const Condition *sub = (*i)->flatten(); if(!result) result = sub; - else + else if(sub) result = dispatch_flatten(result, sub); } - return result; + if(result && result->is_viable()) + return result; + + delete result; + return 0; } } @@ -93,21 +102,29 @@ Condition *CompoundCondition::dispatch_flatten(Condition *cond1, Condition *cond Condition *CompoundCondition::merge_two(Condition *cond1, Condition *cond2, bool del) const { - vector parts; - parts.reserve(2); - parts.push_back(cond1); - parts.push_back(cond2); + vector parts(2); + parts[0] = cond1; + parts[1] = cond2; Condition *result = cond1->merge(parts, *this); + if(del) { delete cond1; delete cond2; + + if(!result->is_viable()) + { + delete result; + return 0; + } } + return result; } Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition *target, bool del) const { + bool merged = false; for(vector::iterator i=target->conditions.begin(); i!=target->conditions.end(); ++i) if((*i)->can_merge(*cond, *target)) { @@ -116,10 +133,19 @@ Condition *CompoundCondition::add_merged_to(Condition *cond, CompoundCondition * if(del) delete cond; *i = m; - return target; + merged = true; + break; } - target->add(del ? cond : cond->clone()); + if(!merged) + target->add(del ? cond : cond->clone()); + + if(del && !target->is_viable()) + { + delete target; + return 0; + } + return target; } @@ -129,7 +155,12 @@ Condition *CompoundCondition::merge_contents_to(CompoundCondition *cond, Compoun add_merged_to(*i, target, false); delete cond; - return target; + + if(target->is_viable()) + return target; + + delete target; + return 0; } @@ -166,9 +197,15 @@ 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))); + if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), (i+1clone() : cond2))) + result->add(sub); delete cond1; - return result; + + if(result->is_viable()) + return result; + + delete result; + return 0; } Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const @@ -183,10 +220,25 @@ Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const OrCondition *result = new OrCondition; for(unsigned i=0; iadd(dispatch_flatten(cond1->get(i)->clone(), cond2->get(j)->clone())); + if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), cond2->get(j).clone())) + result->add(sub); + delete cond1; delete cond2; - return result; + + if(result->is_viable()) + return result; + + delete result; + return 0; +} + +bool AndCondition::is_viable() const +{ + for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) + if(!(*i)->is_viable()) + return false; + return !conditions.empty(); } void AndCondition::add_lines(list &st) const @@ -239,6 +291,14 @@ Condition *OrCondition::flatten(OrCondition *cond1, OrCondition *cond2) const return merge_contents_to(cond2, cond1); } +bool OrCondition::is_viable() const +{ + for(vector::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) + if((*i)->is_viable()) + return true; + return false; +} + void OrCondition::add_lines(list &st) const { list result;