]> git.tdb.fi Git - poefilter.git/commitdiff
Merge overlapping or adjacent ranges in or conditions
authorMikko Rasa <tdb@tdb.fi>
Fri, 17 Aug 2018 15:16:26 +0000 (18:16 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 17 Aug 2018 15:16:26 +0000 (18:16 +0300)
source/rangecondition.h

index d4d11fa852605bb4f93b13be0e97c14ea5dc8c5c..ad54e0a0582f6e89cdd3b1834cc06a88aa334e70 100644 (file)
@@ -136,25 +136,45 @@ RangeCondition<T> *RangeCondition<T>::clone() const
 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>