template<typename T>
bool RangeCondition<T>::can_merge(const Condition &other, const CompoundCondition &parent) const
{
- return dynamic_cast<const RangeCondition<T> *>(&other) && dynamic_cast<const AndCondition *>(&parent);
+ const RangeCondition<T> *other_range = dynamic_cast<const RangeCondition<T> *>(&other);
+ if(!other_range)
+ return false;
+
+ if(dynamic_cast<const AndCondition *>(&parent))
+ return true;
+ else if(dynamic_cast<const OrCondition *>(&parent))
+ return min<=other_range->max+1 && max+1>=other_range->min;
+ else
+ return false;
}
template<typename T>
RangeCondition<T> *RangeCondition<T>::merge(const std::vector<Condition *> &conditions, const CompoundCondition &parent) const
{
- if(dynamic_cast<const AndCondition *>(&parent) && !conditions.empty())
+ if(conditions.empty())
+ return 0;
+
+ bool intersect = dynamic_cast<const AndCondition *>(&parent);
+ RangeCondition<T> *result;
+ if(intersect)
+ result = new RangeCondition<T>(Traits::get_min(), Traits::get_max());
+ else
+ result = new RangeCondition<T>(Traits::get_max(), Traits::get_min());
+ for(std::vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
{
- RangeCondition<T> *result = new RangeCondition<T>(Traits::get_min(), Traits::get_max());
- for(std::vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
+ const RangeCondition<T> *c = static_cast<RangeCondition<T> *>(*i);
+ if(intersect)
{
- const RangeCondition<T> *c = static_cast<RangeCondition<T> *>(*i);
result->min = std::max(result->min, c->min);
result->max = std::min(result->max, c->max);
}
- return result;
+ else
+ {
+ result->min = std::min(result->min, c->min);
+ result->max = std::max(result->max, c->max);
+ }
}
- else
- return 0;
+ return result;
}
template<typename T>