rangemap.h

Go to the documentation of this file.
00001 #ifndef ROSE_RANGEMAP_H
00002 #define ROSE_RANGEMAP_H
00003 
00004 /* This file defines four main template classes:
00005  *    - RangeMap:      Time and space efficient storage of non-overlapping Range objects each associated with an arbitrary value.
00006  *    - Range:         Contiguous set of integers defined by the starting value and size.
00007  *    - RangeMapVoid:  Void value for RangeMap classes that don't store any useful value (just the ranges themselves).
00008  *    - RangeMapValue: Class for storing simple values in a RangeMap.
00009  */
00010 
00011 
00012 /* There is no need to include "sage3basic.h"; this file defines all it needs. */
00013 
00014 #ifndef __STDC_FORMAT_MACROS
00015 #define __STDC_FORMAT_MACROS
00016 #endif
00017 #include <inttypes.h>
00018 
00019 #include <cassert>
00020 #include <cmath>
00021 #include <cstdlib>
00022 #include <iostream>
00023 #include <map>
00024 #include <sstream>
00025 #include <string>
00026 
00027 /* Define this if you want the class to do fairly extensive testing of the consistency of the map after every operation.  Note
00028  * that this substantially increases execution time.  The NDEBUG preprocessor symbol must not be defined, or else the check()
00029  * method won't really do anything. */
00030 //#define RANGEMAP_CHECK
00031 
00032 /******************************************************************************************************************************
00033  *                                      Range<>
00034  ******************************************************************************************************************************/
00035 
00044 template<class T>
00045 class Range {
00046 public:
00047     typedef T Value;
00048     typedef std::pair<Range, Range> Pair;               
00050 protected:
00051     Value r_first;                                      
00052     Value r_last;                                       
00054 public:
00057     Range()
00058         : r_first(1), r_last(0) {} // see clear()
00059 
00061     explicit Range(const Value &first)
00062         : r_first(first), r_last(first) {}
00063 
00068     Range(const Value &first, const Value &size)
00069         : r_first(first), r_last(first+size-1) {
00070         if (0==size) {
00071             r_last = first; // or else clear() is a no-op leaving invalid values
00072             clear();
00073         } else {
00074             assert(!empty()); // checks for overflow
00075         }
00076     }
00077 
00079     template<class Other>
00080     explicit Range(const Other &other)
00081         : r_first(other.relaxed_first()), r_last(other.relaxed_last()) {}
00082 
00087     static Range inin(const Value &v1, const Value &v2) {
00088         assert(v1<=v2);
00089         Range retval;
00090         retval.first(v1);
00091         retval.last(v2);
00092         return retval;
00093     }
00094 
00098     void first(const Value &first) {
00099         r_first = first;
00100     }
00101     const Value first() const {
00102         assert(!empty());
00103         return r_first;
00104     }
00105     const Value relaxed_first() const {
00106         if (!empty())
00107             return first();
00108         if (1==r_first-r_last)
00109             return r_first-1;
00110         return r_first;
00111     }
00117     void last(const Value &last) {
00118         r_last = last;
00119     }
00120     const Value last() const {
00121         assert(!empty());
00122         return r_last;
00123     }
00124     const Value relaxed_last() const {
00125         return empty() ? relaxed_first() : last();
00126     }
00137     Value size() const {
00138         if (empty())
00139             return 0;
00140         return r_last + 1 - r_first;
00141     }
00142 
00152     void resize(const Value &new_size) {
00153         assert(!empty());
00154         if (0==new_size) {
00155             clear();
00156         } else {
00157             r_last = r_first + new_size - 1;
00158             assert(!empty()); // this one is to check for overflow of r_last
00159         }
00160     }
00161     void relaxed_resize(const Value &new_size) {
00162         if (0==new_size) {
00163             clear();
00164         } else {
00165             r_first = relaxed_first();
00166             r_last = r_first + new_size - 1;
00167             assert(!empty()); // this one is to check for overflow of r_last
00168         }
00169     }
00174     Pair split_range_at(const Value &at) const {
00175         assert(!empty());
00176         assert(at>first() && at<=last()); // neither half can be empty
00177         Range left(first(), at-first());
00178         Range right(at, last()+1-at);
00179         return std::make_pair(left, right);
00180     }
00181 
00185     Range join(const Range &right) const {
00186         if (empty())
00187             return right;
00188         if (right.empty())
00189             return *this;
00190         assert(abuts_lt(right));
00191         return Range::inin(first(), right.last());
00192     }
00193 
00197     bool empty() const {
00198         return r_last<r_first; // can't use first() or last() here because they're not valid for empty ranges.
00199     }
00200 
00203     void clear() {
00204         if (!empty()) {
00205             if (r_first<maximum()) {
00206                 r_first = r_first + 1;
00207                 r_last = r_first - 1;
00208             } else {
00209                 r_last = r_first - 2;
00210             }
00211             assert(empty());
00212         }
00213     }
00214 
00218     bool begins_with(const Range &x) const {
00219         if (empty() || x.empty())
00220             return false;
00221         return first() == x.first();
00222     }
00223 
00227     bool ends_with(const Range &x) const {
00228         if (empty() || x.empty())
00229             return false;
00230         return last() == x.last();
00231     }
00232 
00236     bool begins_after(const Range &x, bool strict=true) const {
00237         if (empty() || x.empty())
00238             return false;
00239         return strict ? first() > x.first() : first() >= x.first();
00240     }
00241 
00245     bool begins_before(const Range &x, bool strict=true) const {
00246         if (empty() || x.empty())
00247             return false;
00248         return strict ? first() < x.first() : first() <= x.first();
00249     }
00250 
00254     bool ends_after(const Range &x, bool strict=true) const {
00255         if (empty() || x.empty())
00256             return false;
00257         return strict ? last() > x.last() : last() >= x.last();
00258     }
00259 
00263     bool ends_before(const Range &x, bool strict=true) const {
00264         if (empty() || x.empty())
00265             return false;
00266         return strict ? last() < x.last() : last() <= x.last();
00267     }
00268 
00274     bool contains(const Range &x, bool strict=false) const {
00275         if (empty() || x.empty())
00276             return false;
00277         return strict ? x.first()>first() && x.last()<last() : x.first()>=first() && x.last()<=last();
00278     }
00279 
00285     bool contained_in(const Range &x, bool strict=false) const {
00286         if (empty() || x.empty())
00287             return false;
00288         return strict ? first()>x.first() && last()<x.last() : first()>=x.first() && last()<=x.last();
00289     }
00290 
00294     bool congruent(const Range &x) const {
00295         if (empty() && x.empty())
00296             return true;
00297         return first()==x.first() && last()==x.last();
00298     }
00299 
00304     bool left_of(const Range &x) const {
00305         if (empty() || x.empty())
00306             return false;
00307         return last() < x.first();
00308     }
00309 
00314     bool right_of(const Range &x) const {
00315         if (empty() || x.empty())
00316             return false;
00317         return first() > x.last();
00318     }
00319 
00323     bool overlaps(const Range &x) const {
00324         if (empty() || x.empty())
00325             return false;
00326         return !left_of(x) && !right_of(x);
00327     }
00328 
00333     bool distinct(const Range &x) const {
00334         if (empty() || x.empty())
00335             return true;
00336         return !overlaps(x);
00337     }
00338 
00343     bool abuts_lt(const Range &x) const {
00344         if (empty() || x.empty())
00345             return false;
00346         return last()+1 == x.first();
00347     }
00348 
00353     bool abuts_gt(const Range &x) const {
00354         if (empty() || x.empty())
00355             return false;
00356         return first() == x.last()+1;
00357     }
00358 
00360     static Value minimum() {
00361         return 0; // FIXME
00362     }
00363 
00365     static Value maximum() {
00366         return (Value)(-1); // FIXME
00367     }
00368 
00370     static Range all() {
00371         return Range::inin(minimum(), maximum());
00372     }
00373 
00374     void print(std::ostream &o) const {
00375         if (empty()) {
00376             o <<"<empty>";
00377         } else if (first()==last()) {
00378             o <<first();
00379         } else {
00380             o <<first() <<".." <<last();
00381         }
00382     }
00383 
00384     friend std::ostream& operator<<(std::ostream &o, const Range &x) {
00385         x.print(o);
00386         return o;
00387     }
00388 };
00389 
00390 /******************************************************************************************************************************
00391  *                                      Specializations for Range<double>
00392  ******************************************************************************************************************************/
00393 
00394 template<>
00395 Range<double>::Range();
00396 
00397 template<>
00398 bool
00399 Range<double>::empty() const;
00400 
00401 template<>
00402 void
00403 Range<double>::clear();
00404 
00405 template<>
00406 const double
00407 Range<double>::relaxed_first() const;
00408 
00409 template<>
00410 double
00411 Range<double>::size() const;
00412 
00413 template<>
00414 void
00415 Range<double>::resize(const double &new_size);
00416 
00417 template<>
00418 void
00419 Range<double>::relaxed_resize(const double &new_size);
00420 
00421 template<>
00422 Range<double>::Pair
00423 Range<double>::split_range_at(const double &at) const;
00424 
00425 template<>
00426 double
00427 Range<double>::minimum();
00428 
00429 template<>
00430 double
00431 Range<double>::maximum();
00432 
00433 /******************************************************************************************************************************
00434  *                                      Specializations for Range<float>
00435  ******************************************************************************************************************************/
00436 
00437 template<>
00438 Range<float>::Range();
00439 
00440 template<>
00441 bool
00442 Range<float>::empty() const;
00443 
00444 template<>
00445 void
00446 Range<float>::clear();
00447 
00448 template<>
00449 const float
00450 Range<float>::relaxed_first() const;
00451 
00452 template<>
00453 float
00454 Range<float>::size() const;
00455 
00456 template<>
00457 void
00458 Range<float>::resize(const float &new_size);
00459 
00460 template<>
00461 void
00462 Range<float>::relaxed_resize(const float &new_size);
00463 
00464 template<>
00465 Range<float>::Pair
00466 Range<float>::split_range_at(const float &at) const;
00467 
00468 template<>
00469 float
00470 Range<float>::minimum();
00471 
00472 template<>
00473 float
00474 Range<float>::maximum();
00475 
00476 /******************************************************************************************************************************
00477  *                                      RangeMap void values
00478  ******************************************************************************************************************************/
00479 
00482 template<class R>
00483 class RangeMapVoid {
00484 public:
00485     typedef R Range;
00486 
00487     RangeMapVoid() {}
00488 
00489     template<class Other>
00490     RangeMapVoid(const Other&) {}
00491 
00494     void removing(const Range &my_range) {
00495         assert(!my_range.empty());
00496     }
00497 
00501     void truncate(const Range &my_range, const typename Range::Value &new_end) {
00502         assert(new_end>my_range.first() && new_end<=my_range.last());
00503     }
00504 
00519     bool merge(const Range &my_range, const Range &other_range, const RangeMapVoid &other_value) {
00520         assert(!my_range.empty() && !other_range.empty());
00521         return true;
00522     }
00523 
00528     RangeMapVoid split(const Range &my_range, const typename Range::Value &new_end) {
00529         assert(my_range.contains(Range(new_end)));
00530         return RangeMapVoid();
00531     }
00532 
00533     void print(std::ostream &o) const {}
00534     friend std::ostream& operator<<(std::ostream &o, const RangeMapVoid &x) {
00535         x.print(o);
00536         return o;
00537     }
00538 };
00539 
00540 /******************************************************************************************************************************
00541  *                                      RangeMap simple values
00542  ******************************************************************************************************************************/
00543 
00547 template<class R, class T>
00548 class RangeMapValue {
00549 public:
00550     typedef R Range;
00551     typedef T Value;
00552 
00554     RangeMapValue() {}
00555 
00557     RangeMapValue(const Value &v) { // implicit
00558         value = v;
00559     }
00560 
00561     /* This class often serves as a base class, so we have some virtual methods. */
00562     virtual ~RangeMapValue() {}
00563     
00564 
00567     virtual void set(const Value &v) {
00568         value = v;
00569     }
00570     virtual Value get() const {
00571         return value;
00572     }
00577     virtual void removing(const Range &my_range) {
00578         assert(!my_range.empty());
00579     }
00580 
00582     virtual void truncate(const Range &my_range, const typename Range::Value &new_end) {
00583         assert(new_end>my_range.first() && new_end<=my_range.last());
00584     }
00585 
00587     bool merge(const Range &my_range, const Range &other_range, const RangeMapValue &other_value) {
00588         assert(!my_range.empty() && !other_range.empty());
00589         return get()==other_value.get();
00590     }
00591 
00592 #if 0 /* Must be implemented in the subclass due to return type. */
00593 
00594     RangeMapValue split(const Range &my_range, const typename Range::Value &new_end) {
00595         assert(my_range.contains(Range(new_end)));
00596         return *this;
00597     }
00598 #endif
00599 
00602     virtual void print(std::ostream &o) const {
00603         o <<value;
00604     }
00605     friend std::ostream& operator<<(std::ostream &o, const RangeMapValue &x) {
00606         x.print(o);
00607         return o;
00608     }
00611 protected:
00612     Value value;
00613 };
00614 
00615 /******************************************************************************************************************************
00616  *                                      RangeMap<>
00617  ******************************************************************************************************************************/
00618 
00721 template<class R, class T=RangeMapVoid<R> >
00722 class RangeMap {
00723 public:
00724     typedef R Range;                    
00725     typedef T Value;                    
00727 protected:
00728     /* The keys of the underlying map are sorted by their last value rather than beginning value.  This allows us to use the
00729      * map's lower_bound() method to find the range to which an address might belong.  Since the ranges in the map are
00730      * non-overlapping, sorting by ending address has the same effect as sorting by starting address. */
00731     struct RangeCompare {
00732         bool operator()(const Range &a, const Range &b) const {
00733             return a.last() < b.last();
00734         }
00735     };
00736 
00737     typedef std::pair<Range, Range> RangePair;
00738     typedef std::pair<Range, Value> MapPair;
00739     typedef std::map<Range, Value, RangeCompare> Map;
00740     Map ranges;
00741 
00742 public:
00743     typedef typename Map::iterator iterator;
00744     typedef typename Map::const_iterator const_iterator;
00745     typedef typename Map::reverse_iterator reverse_iterator;
00746     typedef typename Map::const_reverse_iterator const_reverse_iterator;
00747 
00748     /**************************************************************************************************************************
00749      *                                  Constructors
00750      **************************************************************************************************************************/
00751 public:
00752 
00754     RangeMap() {}
00755 
00757     template<class Other>
00758     RangeMap(const Other &other) {
00759         for (typename Other::const_iterator ri=other.begin(); ri!=other.end(); ++ri) {
00760             Range new_range(ri->first);
00761             Value new_value(ri->second);
00762             insert(new_range, new_value);
00763         }
00764     }
00765 
00766     /**************************************************************************************************************************
00767      *                                  Iterators and searching
00768      **************************************************************************************************************************/
00769 public:
00770 
00775     iterator begin() {
00776         return ranges.begin();
00777     }
00778     const_iterator begin() const {
00779         return ranges.begin();
00780     }
00787     iterator end() {
00788         return ranges.end();
00789     }
00790     const_iterator end() const {
00791         return ranges.end();
00792     }
00799     reverse_iterator rbegin() {
00800         return ranges.rbegin();
00801     }
00802     const_reverse_iterator rbegin() const {
00803         return ranges.rbegin();
00804     }
00812     reverse_iterator rend() {
00813         return ranges.rend();
00814     }
00815     const_reverse_iterator rend() const {
00816         return ranges.rend();
00817     }
00824     iterator find(const typename Range::Value &addr) {
00825         iterator ei = lower_bound(addr);
00826         if (ei==end() || Range(addr).left_of(ei->first))
00827             return end();
00828         return ei;
00829     }
00830     const_iterator find(const typename Range::Value &addr) const {
00831         const_iterator ei = lower_bound(addr);
00832         if (ei==end() || Range(addr).left_of(ei->first))
00833             return end();
00834         return ei;
00835     }
00842     iterator lower_bound(const typename Range::Value &addr) {
00843         return ranges.lower_bound(Range(addr));
00844     }
00845     const_iterator lower_bound(const typename Range::Value &addr) const {
00846         return ranges.lower_bound(Range(addr));
00847     }
00853     iterator find_prior(const typename Range::Value &addr) {
00854         if (empty())
00855             return end();
00856         iterator lb = lower_bound(addr);
00857         if (lb!=end() && lb->first.begins_before(Range(addr), false/*non-strict*/))
00858             return lb;
00859         if (lb==begin())
00860             return end();
00861         return --lb;
00862     }
00863     const_iterator find_prior(const typename Range::Value &addr) const {
00864         if (empty())
00865             return end();
00866         const_iterator lb = lower_bound(addr);
00867         if (lb!=end() && lb->first.begins_before(Range(addr), false/*non-strict*/))
00868             return lb;
00869         if (lb==begin())
00870             return end();
00871         return --lb;
00872     }
00880     iterator best_fit(const typename Range::Value &size, iterator start) {
00881         iterator best = end();
00882         for (iterator ri=start; ri!=end(); ++ri) {
00883             if (ri->first.size()==size)
00884                 return ri;
00885             if (ri->first.size()>size && (best==end() || ri->first.size()<best->first.size()))
00886                 best = ri;
00887         }
00888         return best;
00889     }
00890     const_iterator best_fit(const typename Range::Value &size, const_iterator start) const {
00891         const_iterator best = end();
00892         for (const_iterator ri=start; ri!=end(); ++ri) {
00893             if (ri->first.size()==size)
00894                 return ri;
00895             if (ri->first.size()>size && (best==end() || ri->first.size()<best->first.size()))
00896                 best = ri;
00897         }
00898         return best;
00899     }
00906     iterator first_fit(const typename Range::Value &size, iterator start) {
00907         for (iterator ri=start; ri!=end(); ++ri) {
00908             if (ri->first.size()>=size)
00909                 return ri;
00910         }
00911         return end();
00912     }
00913     const_iterator first_fit(const typename Range::Value &size, const_iterator start) {
00914         for (const_iterator ri=start; ri!=end(); ++ri) {
00915             if (ri->first.size()>=size)
00916                 return ri;
00917         }
00918         return end();
00919     }
00922     /**************************************************************************************************************************
00923      *                                  Capacity
00924      **************************************************************************************************************************/
00925 public:
00926 
00928     bool empty() const {
00929         return ranges.empty();
00930     }
00931 
00934     size_t nranges() const {
00935         return ranges.size();
00936     }
00937 
00942     typename Range::Value size() const {
00943         typename Range::Value retval = 0;
00944         for (const_iterator ei=begin(); ei!=end(); ++ei)
00945             retval += ei->first.size();
00946         return retval;
00947     }
00948 
00950     typename Range::Value min() const {
00951         assert(!empty());
00952         return ranges.begin()->first.first();
00953     }
00954 
00956     typename Range::Value max() const {
00957         assert(!empty());
00958         return ranges.rbegin()->first.last();
00959     }
00960 
00962     Range minmax() const {
00963         typename Range::Value lt=min(), rt=max();
00964         return Range::inin(lt, rt);
00965     }
00966 
00967     /**************************************************************************************************************************
00968      *                                  Low-level support functions
00969      **************************************************************************************************************************/
00970 protected:
00971 
00972     /**************************************************************************************************************************
00973      *                                  Modifiers
00974      **************************************************************************************************************************/
00975 public:
00976 
00979     void clear(bool notify=true) {
00980         if (notify) {
00981             for (iterator ei=begin(); ei!=end(); ++ei)
00982                 ei->second.removing(ei->first);
00983         }
00984         ranges.clear();
00985     }
00986 
00991     void erase(const Range &erase_range) {
00992         /* This loop figures out what needs to be removed and calls the elements' removing(), truncate(), etc. methods but does
00993          * not actually erase them from the underlying map yet.  We must not erase them yet because the std::map::erase()
00994          * method doesn't return any iterator.  Instead, we create a list (via an iterator range) of elements that will need to
00995          * be erased from the underlying map.
00996          *
00997          * This loop also creates a list of items that need to be inserted into the underlying map.  Even though the
00998          * std::map::insert() can return an iterator, we can't call it inside the loop because then our erasure iterators will
00999          * become invalid. */
01000         if (erase_range.empty())
01001             return;
01002         Map insertions;
01003         iterator erase_begin=end();
01004         iterator ei;
01005         for (ei=lower_bound(erase_range.first()); ei!=end() && !erase_range.left_of(ei->first); ++ei) {
01006             Range found_range = ei->first;
01007             Value &v = ei->second;
01008             if (erase_range.contains(found_range)) {
01009                 /* Erase entire found range. */
01010                 if (erase_begin==end())
01011                     erase_begin = ei;
01012                 v.removing(found_range);
01013             } else if (erase_range.contained_in(found_range, true/*strict*/)) {
01014                 /* Erase middle of found range. */
01015                 assert(erase_begin==end());
01016                 erase_begin = ei;
01017                 RangePair rt = found_range.split_range_at(erase_range.last()+1);
01018                 insertions[rt.second] = v.split(found_range, rt.second.first());
01019                 RangePair lt = rt.first.split_range_at(erase_range.first());
01020                 v.truncate(rt.first, erase_range.first());
01021                 insertions[lt.first] = v;
01022             } else if (erase_range.begins_after(found_range, true/*strict*/)) {
01023                 /* Erase right part of found range. */
01024                 assert(erase_begin==end());
01025                 erase_begin = ei;
01026                 RangePair halves = found_range.split_range_at(erase_range.first());
01027                 v.truncate(found_range, erase_range.first());
01028                 insertions[halves.first] = v;
01029             } else if (erase_range.ends_before(found_range, true/*strict*/)) {
01030                 /* Erase left part of found range. */
01031                 if (erase_begin==end())
01032                     erase_begin = ei;
01033                 RangePair halves = found_range.split_range_at(erase_range.last()+1);
01034                 insertions[halves.second] = v.split(found_range, halves.second.first());
01035                 v.removing(halves.first);
01036             }
01037         }
01038 
01039         /* Inserting is easy here because we already know that no merging is necessary. */
01040         if (erase_begin!=end())
01041             ranges.erase(erase_begin, ei);
01042         ranges.insert(insertions.begin(), insertions.end());
01043 #ifdef RANGEMAP_CHECK
01044         check();
01045 #endif
01046     }
01047 
01050     template<class OtherMap>
01051     void erase_ranges(const OtherMap &other) {
01052         assert((const void*)&other!=(const void*)this);
01053         for (typename OtherMap::const_iterator ri=other.begin(); ri!=other.end(); ++ri)
01054             erase(Range::inin(ri->first.first(), ri->first.last()));
01055     }
01056 
01062     iterator insert(Range new_range, Value new_value=Value(), bool make_hole=true) {
01063         if (new_range.empty())
01064             return end();
01065 
01066         if (make_hole) {
01067             erase(new_range);
01068         } else {
01069             iterator found = lower_bound(new_range.first());
01070             if (found!=end() && new_range.overlaps(found->first))
01071                 return end();
01072         }
01073 
01074         /* Attempt to merge with a left and/or right value. */
01075         iterator left = new_range.first()>Range::minimum() ? find(new_range.first()-1) : end();
01076         if (left!=end() && new_range.abuts_gt(left->first) && new_value.merge(new_range, left->first, left->second)) {
01077             new_range = left->first.join(new_range);
01078             ranges.erase(left);
01079         }
01080         iterator right = new_range.last()<new_range.maximum() ? find(new_range.last()+1) : end();
01081         if (right!=end() && new_range.abuts_lt(right->first) && new_value.merge(new_range, right->first, right->second)) {
01082             new_range = new_range.join(right->first);
01083             ranges.erase(right);
01084         }
01085 
01086         iterator retval = ranges.insert(end(), std::make_pair(new_range, new_value));
01087 #ifdef RANGEMAP_CHECK
01088         check();
01089 #endif
01090         return retval;
01091     }
01092 
01094     void insert_ranges(const RangeMap &x, bool make_hole=true) {
01095         assert(&x!=this);
01096         insert_ranges(x.begin(), x.end(), make_hole);
01097     }
01098 
01101     void insert_ranges(const_iterator start, const_iterator stop, bool make_hole=true) {
01102         for (const_iterator ri=start; ri!=stop; ri++)
01103             insert(ri->first, ri->second, make_hole);
01104     }
01105 
01106     /**************************************************************************************************************************
01107      *                                  Predicates
01108      **************************************************************************************************************************/
01109 public:
01110 
01112     bool overlaps(const RangeMap &x) const {
01113         return first_overlap(x)!=end();
01114     }
01115 
01118     bool overlaps(const Range &r) const {
01119         if (r.empty())
01120             return false;
01121         const_iterator found = lower_bound(r.first());
01122         return found!=end() && r.overlaps(found->first);
01123     }
01124 
01127     bool distinct(const RangeMap &x) const {
01128         return first_overlap(x)==end();
01129     }
01130 
01133     bool contains(Range need) const {
01134         if (need.empty())
01135             return true;
01136         const_iterator found=find(need.first());
01137         while (1) {
01138             if (found==end())
01139                 return false;
01140             if (need.begins_before(found->first))
01141                 return false;
01142             assert(need.overlaps(found->first));
01143             if (need.ends_before(found->first, false/*non-strict*/))
01144                 return true;
01145             need = need.split_range_at(found->first.last()+1).second;
01146             ++found;
01147         }
01148         assert(!"should not be reached");
01149         return true;
01150     }
01151 
01154     bool contains(const RangeMap &x) const {
01155         if (x.empty())
01156             return true;
01157         for (const_iterator xi=x.begin(); xi!=x.end(); ++xi) {
01158             if (!contains(xi->first))
01159                 return false;
01160         }
01161         return true;
01162     }
01163 
01164     /**************************************************************************************************************************
01165      *                                  Comparisons
01166      **************************************************************************************************************************/
01167 public:
01168 
01173     iterator find_overlap(const RangeMap &x) {
01174         return find_overlap(begin(), end(), x);
01175     }
01176     const_iterator first_overlap(const RangeMap &x) const {
01177         return find_overlap(begin(), end(), x);
01178     }
01187     iterator find_overlap(iterator start, iterator stop, const RangeMap &x) {
01188         if (start==stop)
01189             return end();
01190 
01191         iterator ia = start;
01192         const_iterator ib = x.lower_bound(start->first.first());
01193         while (ia!=stop && ib!=x.end() && ia->first.distinct(ib->first)) {
01194             while (ia!=stop && ia->first.left_of(ib->first))
01195                 ++ia;
01196             while (ib!=x.end() && ib->first.left_of(ia->first))
01197                 ++ib;
01198         }
01199 
01200         return ia!=stop && ib!=x.end() && ia->first.overlaps(ib->first);
01201     }
01202     const_iterator find_overlap(const_iterator start, const_iterator stop, const RangeMap &x) const {
01203         if (start==stop)
01204             return end();
01205 
01206         const_iterator ia = start;
01207         const_iterator ib = x.lower_bound(start->first.first());
01208         while (ia!=stop && ib!=x.end() && ia->first.distinct(ib->first)) {
01209             while (ia!=stop && ia->first.left_of(ib->first))
01210                 ++ia;
01211             while (ib!=x.end() && ib->first.left_of(ia->first))
01212                 ++ib;
01213         }
01214 
01215         return ia!=stop && ib!=x.end() && ia->first.overlaps(ib->first) ? ia : end();
01216     }
01219     /**************************************************************************************************************************
01220      *                                  Operators
01221      **************************************************************************************************************************/
01222 public:
01223 
01225     template<class ResultMap>
01226     ResultMap invert() const {
01227         return invert_within<ResultMap>(Range::all());
01228     }
01229 
01232     template<class ResultMap>
01233     ResultMap invert_within(const Range &limits) const {
01234         ResultMap retval;
01235         if (limits.empty())
01236             return retval;
01237         typename Range::Value pending = limits.first();
01238         for (const_iterator ri=lower_bound(limits.first()); ri!=end() && !limits.left_of(ri->first); ++ri) {
01239             if (pending < ri->first.first())
01240                 retval.insert(Range::inin(pending, ri->first.first()-1));
01241             pending = ri->first.last()+1;
01242         }
01243         if (pending <= limits.last())
01244             retval.insert(Range::inin(pending, limits.last()));
01245         if (!retval.empty())
01246             assert(retval.minmax().contained_in(limits, false));
01247         return retval;
01248     }
01249 
01252     RangeMap select_overlapping_ranges(const Range &selector) const {
01253         RangeMap retval;
01254         if (!selector.empty()) {
01255             for (const_iterator ri=lower_bound(selector.start()); ri!=end() && !selector.left_of(ri->first); ++ri) {
01256                 if (selector.overlaps(ri->first))
01257                     retval.insert(ri->first, ri->second);
01258             }
01259         }
01260         return retval;
01261     }
01262 
01263     /**************************************************************************************************************************
01264      *                                  Debugging
01265      **************************************************************************************************************************/
01266 public:
01267 
01268     void check() const {
01269 // DQ (11/8/2011): Commented out as part of ROSE compiling this ROSE source code (EDG frontend complains about errors).
01270 #ifndef USE_ROSE
01271 #ifndef NDEBUG
01272 #define RANGEMAP_CHECK(EXPR) if (!(EXPR)) {                                                                                    \
01273             std::cerr <<"RangeMap::check() failed at r1=" <<r1 <<" r2=" <<r2 <<": " #EXPR "\n";                                \
01274             std::cerr <<"Entire range map at point of failure:\n";                                                             \
01275             print(std::cerr, "    ");                                                                                          \
01276             assert(EXPR);                                                                                                      \
01277         }
01278             
01279         for (const_iterator i1=begin(); i1!=end(); ++i1) {
01280             const Range &r1 = i1->first;
01281             const_iterator i2 = i1; ++i2;
01282             if (i2!=end()) {
01283                 const Range &r2 = i2->first;
01284 
01285                 RANGEMAP_CHECK(!r2.empty());
01286 
01287                 RANGEMAP_CHECK(!r1.begins_with(r2));
01288                 RANGEMAP_CHECK(!r2.begins_with(r1));
01289 
01290                 RANGEMAP_CHECK(!r1.ends_with(r2));
01291                 RANGEMAP_CHECK(!r2.ends_with(r1));
01292 
01293                 RANGEMAP_CHECK(!r1.begins_after(r2, false));
01294                 RANGEMAP_CHECK(!r1.begins_after(r2, true));
01295                 RANGEMAP_CHECK(r2.begins_after(r1, false));
01296                 RANGEMAP_CHECK(r2.begins_after(r1, true));
01297 
01298                 RANGEMAP_CHECK(r1.begins_before(r2, false));
01299                 RANGEMAP_CHECK(r1.begins_before(r2, true));
01300                 RANGEMAP_CHECK(!r2.begins_before(r1, false));
01301                 RANGEMAP_CHECK(!r2.begins_before(r1, true));
01302 
01303                 RANGEMAP_CHECK(!r1.ends_after(r2, false));
01304                 RANGEMAP_CHECK(!r1.ends_after(r2, true));
01305                 RANGEMAP_CHECK(r2.ends_after(r1, false));
01306                 RANGEMAP_CHECK(r2.ends_after(r1, true));
01307 
01308                 RANGEMAP_CHECK(r1.ends_before(r2, false));
01309                 RANGEMAP_CHECK(r1.ends_before(r2, true));
01310                 RANGEMAP_CHECK(!r2.ends_before(r1, false));
01311                 RANGEMAP_CHECK(!r2.ends_before(r1, true));
01312 
01313                 RANGEMAP_CHECK(!r1.contains(r2, false));
01314                 RANGEMAP_CHECK(!r1.contains(r2, true));
01315                 RANGEMAP_CHECK(!r2.contains(r1, false));
01316                 RANGEMAP_CHECK(!r2.contains(r1, true));
01317 
01318                 RANGEMAP_CHECK(!r1.contained_in(r2, false));
01319                 RANGEMAP_CHECK(!r1.contained_in(r2, true));
01320                 RANGEMAP_CHECK(!r2.contained_in(r1, false));
01321                 RANGEMAP_CHECK(!r2.contained_in(r1, true));
01322 
01323                 RANGEMAP_CHECK(!r1.congruent(r2));
01324                 RANGEMAP_CHECK(!r2.congruent(r1));
01325 
01326                 RANGEMAP_CHECK(r1.left_of(r2));
01327                 RANGEMAP_CHECK(!r2.left_of(r1));
01328 
01329                 RANGEMAP_CHECK(!r1.right_of(r2));
01330                 RANGEMAP_CHECK(r2.right_of(r1));
01331 
01332                 RANGEMAP_CHECK(!r1.overlaps(r2));
01333                 RANGEMAP_CHECK(!r2.overlaps(r1));
01334 
01335                 RANGEMAP_CHECK(r1.distinct(r2));
01336                 RANGEMAP_CHECK(r2.distinct(r1));
01337 
01338                 RANGEMAP_CHECK(!r1.abuts_gt(r2)); // r1.abuts_lt(r2) is possible
01339                 RANGEMAP_CHECK(!r2.abuts_lt(r1)); // r2.abuts_gt(r1) is possible
01340             }
01341         }
01342 #undef RANGEMAP_CHECK
01343 #endif
01344 #endif
01345     }
01346 
01348     void print(std::ostream &o) const {
01349         for (const_iterator ri=begin(); ri!=end(); ++ri) {
01350             std::ostringstream s;
01351             s <<ri->second;
01352             o <<(ri==begin()?"":", ") <<ri->first;
01353             if (!s.str().empty())
01354                 o <<" {" <<s.str() <<"}";
01355         }
01356     }
01357 
01358     friend std::ostream& operator<<(std::ostream &o, const RangeMap &rmap) {
01359         rmap.print(o);
01360         return o;
01361     }
01362 
01363 };
01364 
01365 #endif

Generated on Sat May 19 00:53:06 2012 for ROSE by  doxygen 1.4.7