ROSE 0.11.145.357
IntervalMap.h
1// WARNING: Changes to this file must be contributed back to Sawyer or else they will
2// be clobbered by the next update from Sawyer. The Sawyer repository is at
3// https://gitlab.com/charger7534/sawyer.git.
4
5
6
7
8#ifndef Sawyer_IntervalMap_H
9#define Sawyer_IntervalMap_H
10
11#include <boost/cstdint.hpp>
12#include <Sawyer/Assert.h>
13#include <Sawyer/Map.h>
14#include <Sawyer/Optional.h>
15#include <Sawyer/Sawyer.h>
16
17namespace Sawyer {
18namespace Container {
19
21template<class IntervalMap>
27
28template<class IntervalMap>
34
39template<typename I, typename T>
41public:
42 typedef I Interval;
43 typedef T Value;
44
45#ifdef SAWYER_HAVE_BOOST_SERIALIZATION
46private:
47 friend class boost::serialization::access;
48
49 template<class S>
50 void serialize(S&, const unsigned /*version*/) {
51 // nothing to serialize in this class
52 }
53#endif
54
55#ifdef SAWYER_HAVE_CEREAL
56private:
57 friend class cereal::access;
58
59 template<class Archive>
60 void CEREAL_SERIALIZE_FUNCTION_NAME(Archive&) {
61 // nothing to serialize in this class
62 }
63#endif
64
65public:
70 bool merge(const Interval &leftInterval, Value &leftValue, const Interval &rightInterval, Value &rightValue) {
71 SAWYER_ARGUSED(leftInterval);
72 SAWYER_ARGUSED(rightInterval);
73 return leftValue == rightValue;
74 }
75
82 Value split(const Interval &interval, Value &value, const typename Interval::Value &splitPoint) {
83 SAWYER_ARGUSED(interval);
84 SAWYER_ARGUSED(splitPoint);
85 return value;
86 }
87
92 void truncate(const Interval &interval, Value &value, const typename Interval::Value &splitPoint) {
93 SAWYER_ARGUSED(interval);
94 SAWYER_ARGUSED(value);
95 SAWYER_ARGUSED(splitPoint);
96 }
97};
98
179template<typename I, typename T, class Policy = MergePolicy<I, T> >
181public:
182 typedef I Interval;
183 typedef T Value;
185private:
186 // Nodes of the underlying map are sorted by their last value so that we can use that map's lowerBound method to find the
187 // range to which a scalar key might belong. Since the intervals in the map are non-overlapping, sorting by greatest values
188 // has the same effect as sorting by least values.
189 struct IntervalCompare {
190 bool operator()(const Interval &a, const Interval &b) const {
191 return a.greatest() < b.greatest();
192 }
193 };
194
195 typedef std::pair<Interval, Interval> IntervalPair;
196
197public:
200
205 typedef typename Map::Node Node;
206
212
233private:
234 Map map_;
235 Policy policy_;
236 typename Interval::Value size_; // number of values (map_.size is number of intervals)
237
238#ifdef SAWYER_HAVE_BOOST_SERIALIZATION
239private:
240 friend class boost::serialization::access;
241
242 template<class S>
243 void serialize(S &s, const unsigned /*version*/) {
244 s & BOOST_SERIALIZATION_NVP(map_);
245 s & BOOST_SERIALIZATION_NVP(policy_);
246 s & BOOST_SERIALIZATION_NVP(size_);
247 }
248#endif
249
250#ifdef SAWYER_HAVE_CEREAL
251private:
252 friend class cereal::access;
253
254 template<class Archive>
255 void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
256 archive(CEREAL_NVP(map_));
257 archive(CEREAL_NVP(policy_));
258 archive(CEREAL_NVP(size_));
259 }
260#endif
261
263 // Constructors
265public:
269 IntervalMap(): size_(0) {}
270
275 template<class Interval2, class T2, class Policy2>
277 typedef typename IntervalMap<Interval2, T2, Policy2>::ConstNodeIterator OtherIterator;
278 for (OtherIterator otherIter=other.nodes().begin(); other!=other.nodes().end(); ++other)
279 insert(Interval(otherIter->key()), Value(otherIter->value()));
280 }
281
286 template<class Interval2, class T2, class Policy2>
288 clear();
289 typedef typename IntervalMap<Interval2, T2, Policy2>::ConstNodeIterator OtherIterator;
290 for (OtherIterator otherIter=other.nodes().begin(); other!=other.nodes().end(); ++other)
291 insert(Interval(otherIter->key()), Value(otherIter->value()));
292 return *this;
293 }
294
296 // Searching
298public:
299
306 boost::iterator_range<NodeIterator> nodes() { return map_.nodes(); }
307 boost::iterator_range<ConstNodeIterator> nodes() const { return map_.nodes(); }
314 boost::iterator_range<ConstIntervalIterator> intervals() const { return map_.keys(); }
315
322 boost::iterator_range<ValueIterator> values() { return map_.values(); }
323 boost::iterator_range<ConstValueIterator> values() const { return map_.values(); }
331 NodeIterator lowerBound(const typename Interval::Value &scalar) {
332 return map_.lowerBound(Interval(scalar));
333 }
334 ConstNodeIterator lowerBound(const typename Interval::Value &scalar) const {
335 return map_.lowerBound(Interval(scalar));
336 }
344 NodeIterator upperBound(const typename Interval::Value &scalar) {
345 NodeIterator ub = map_.upperBound(Interval(scalar)); // first node that ENDS after scalar
346 while (ub!=map_.nodes().end() && ub->key().least() <= scalar)
347 ++ub;
348 return ub;
349 }
350 ConstNodeIterator upperBound(const typename Interval::Value &scalar) const {
351 ConstNodeIterator ub = map_.upperBound(Interval(scalar)); // first node that ENDS after scalar
352 while (ub!=map_.nodes().end() && ub->key().least() <= scalar)
353 ++ub;
354 return ub;
355 }
363 NodeIterator findPrior(const typename Interval::Value &scalar) {
364 return findPriorImpl(*this, scalar);
365 }
366 ConstNodeIterator findPrior(const typename Interval::Value &scalar) const {
367 return findPriorImpl(*this, scalar);
368 }
369
370 template<class IMap>
372 findPriorImpl(IMap &imap, const typename Interval::Value &scalar) {
373 typedef typename IntervalMapTraits<IMap>::NodeIterator Iter;
374 if (imap.isEmpty())
375 return imap.nodes().end();
376 Iter lb = imap.lowerBound(scalar);
377 if (lb!=imap.nodes().end() && lb->key().least() <= scalar)
378 return lb;
379 if (lb==imap.nodes().begin())
380 return imap.nodes().end();
381 return --lb;
382 }
390 NodeIterator find(const typename Interval::Value &scalar) {
391 return findImpl(*this, scalar);
392 }
393 ConstNodeIterator find(const typename Interval::Value &scalar) const {
394 return findImpl(*this, scalar);
395 }
396
397 template<class IMap>
399 findImpl(IMap &imap, const typename Interval::Value &scalar) {
400 typedef typename IntervalMapTraits<IMap>::NodeIterator Iter;
401 Iter found = imap.lowerBound(scalar);
402 if (found==imap.nodes().end() || scalar < found->key().least())
403 return imap.nodes().end();
404 return found;
405 }
413 boost::iterator_range<NodeIterator> findAll(const Interval &interval) {
414 return findAllImpl(*this, interval);
415 }
416 boost::iterator_range<ConstNodeIterator> findAll(const Interval &interval) const {
417 return findAllImpl(*this, interval);
418 }
419
420 template<class IMap>
421 static boost::iterator_range<typename IntervalMapTraits<IMap>::NodeIterator>
422 findAllImpl(IMap &imap, const Interval &interval) {
423 typedef typename IntervalMapTraits<IMap>::NodeIterator Iter;
424 if (interval.isEmpty())
425 return boost::iterator_range<Iter>(imap.nodes().end(), imap.nodes().end());
426 Iter begin = imap.lowerBound(interval.least());
427 if (begin==imap.nodes().end() || begin->key().least() > interval.greatest())
428 return boost::iterator_range<Iter>(imap.nodes().end(), imap.nodes().end());
429 return boost::iterator_range<Iter>(begin, imap.upperBound(interval.greatest()));
430 }
439 return findFirstOverlapImpl(*this, interval);
440 }
442 return findFirstOverlapImpl(*this, interval);
443 }
444
445 template<class IMap>
447 findFirstOverlapImpl(IMap &imap, const Interval &interval) {
448 typedef typename IntervalMapTraits<IMap>::NodeIterator Iter;
449 if (interval.isEmpty())
450 return imap.nodes().end();
451 Iter lb = imap.lowerBound(interval.least());
452 return lb!=imap.nodes().end() && interval.overlaps(lb->key()) ? lb : imap.nodes().end();
453 }
465 template<typename T2, class Policy2>
466 std::pair<NodeIterator, typename IntervalMap<Interval, T2, Policy2>::ConstNodeIterator>
469 return findFirstOverlapImpl(*this, thisIter, other, otherIter);
470 }
471 template<typename T2, class Policy2>
472 std::pair<ConstNodeIterator, typename IntervalMap<Interval, T2, Policy2>::ConstNodeIterator>
475 return findFirstOverlapImpl(*this, thisIter, other, otherIter);
476 }
477
478 template<class IMap, typename T2, class Policy2>
479 static std::pair<typename IntervalMapTraits<IMap>::NodeIterator,
485 while (thisIter!=imap.nodes().end() && otherIter!=other.nodes().end()) {
486 if (thisIter->key().overlaps(otherIter->key()))
487 return std::make_pair(thisIter, otherIter);
488 if (thisIter->key().greatest() < otherIter->key().greatest()) {
489 ++thisIter;
490 } else {
491 ++otherIter;
492 }
493 }
494 return std::make_pair(imap.nodes().end(), other.nodes().end());
495 }
510 return firstFitImpl(*this, size, start);
511 }
513 return firstFitImpl(*this, size, start);
514 }
515
516 template<class IMap>
518 firstFitImpl(IMap &imap, const typename Interval::Value &size, typename IntervalMapTraits<IMap>::NodeIterator start) {
519 typedef typename IntervalMapTraits<IMap>::NodeIterator Iter;
520 for (Iter iter=start; iter!=imap.nodes().end(); ++iter) {
521 if (isLarge(iter->key(), size))
522 return iter;
523 }
524 return imap.nodes().end();
525 }
526
542 return bestFitImpl(*this, size, start);
543 }
545 return bestFitImpl(*this, size, start);
546 }
547
548 template<class IMap>
550 bestFitImpl(IMap &imap, const typename Interval::Value &size, typename IntervalMapTraits<IMap>::NodeIterator start) {
551 typedef typename IntervalMapTraits<IMap>::NodeIterator Iter;
552 Iter best = imap.nodes().end();
553 for (Iter iter=start; iter!=imap.nodes().end(); ++iter) {
554 if (iter->key().size()==size && size!=0)
555 return iter;
556 if (iter->key().size() > size && (best==imap.nodes().end() || iter->key().size() < best->key().size()))
557 best = iter;
558 }
559 return best;
560 }
569 Interval firstUnmapped(typename Interval::Value minAddr) const {
571 for (ConstNodeIterator iter=lowerBound(minAddr); iter!=nodes().end(); ++iter) {
572 if (minAddr < iter->key().least()) // minAddr is not mapped
573 return Interval::hull(minAddr, iter->key().least()-1);
574 if (iter->key().greatest() == all.greatest())
575 return Interval(); // no unmapped addresses, prevent potential overflow in next statement
576 minAddr = iter->key().greatest() + 1;
577 }
578 return Interval::hull(minAddr, all.greatest());
579 }
580
587 Interval lastUnmapped(typename Interval::Value maxAddr) const {
589
590 if (isEmpty())
591 return Interval::hull(all.least(), maxAddr);
592
593 ConstNodeIterator iter = findPrior(maxAddr);
594
595 // Check for no nodes less than maxAddr
596 if (iter == nodes().end()) {
597 if (maxAddr > all.least()) {
598 return Interval::hull(all.least(), maxAddr);
599 } else {
600 return Interval();
601 }
602 }
603
604 // Check nodes less than maxAddr, incrementally making maxAddr smaller and smaller.
605 for (/*void*/; iter != nodes().begin(); --iter) {
606 // Unmapped space exists between the current node and the maxAddr
607 if (maxAddr > iter->key().greatest())
608 return Interval::hull(iter->key().greatest() + 1, maxAddr);
609
610 // Back up to the prior node.
611 if (iter->key().least() == all.least())
612 return Interval(); // no unmapped address; prevent potential overflow in next statement
613 maxAddr = iter->key().least() - 1;
614 }
615
616 // We backed up as far as we can get. Either there's some space before the first node or not.
617 if (iter == nodes().begin()) {
618 if (maxAddr > iter->key().greatest())
619 return Interval::hull(iter->key().greatest() + 1, maxAddr);
620 if (iter->key().least() > all.least())
621 return Interval::hull(all.least(), iter->key().least() - 1);
622 }
623
624 // No free space
625 return Interval();
626 }
627
631 bool exists(const typename Interval::Value &size) const {
632 return find(size)!=nodes().end();
633 }
634
636 // Accessors
638public:
649 const Value& operator[](const typename Interval::Value &scalar) const {
650 ConstNodeIterator found = find(scalar);
651 if (found==nodes().end())
652 throw std::domain_error("key lookup failure; key is not in map domain");
653 return found->value();
654 }
655
656 const Value& get(const typename Interval::Value &scalar) const {
657 ConstNodeIterator found = find(scalar);
658 if (found==nodes().end())
659 throw std::domain_error("key lookup failure; key is not in map domain");
660 return found->value();
661 }
677 Optional<Value> getOptional(const typename Interval::Value &scalar) const {
678 ConstNodeIterator found = find(scalar);
679 return found == nodes().end() ? Optional<Value>() : Optional<Value>(found->value());
680 }
681
689 Value& getOrElse(const typename Interval::Value &scalar, Value &dflt) {
690 NodeIterator found = find(scalar);
691 return found == nodes().end() ? dflt : found->value();
692 }
693 const Value& getOrElse(const typename Interval::Value &scalar, const Value &dflt) const {
694 ConstNodeIterator found = find(scalar);
695 return found == nodes().end() ? dflt : found->value();
696 }
703 const Value& getOrDefault(const typename Interval::Value &scalar) const {
704 static const Value dflt;
705 ConstNodeIterator found = find(scalar);
706 return found==nodes().end() ? dflt : found->value();
707 }
708
710 // Capacity
712public:
713
717 bool isEmpty() const {
718 return map_.isEmpty();
719 }
720
725 size_t nIntervals() const {
726 return map_.size();
727 }
728
733 typename Interval::Value size() const {
734 return size_;
735 }
736
738 typename Interval::Value least() const {
739 ASSERT_forbid(isEmpty());
740 return map_.keys().begin()->least();
741 }
742
744 typename Interval::Value greatest() const {
745 ASSERT_forbid(isEmpty());
746 ConstIntervalIterator last = map_.keys().end(); --last;
747 return last->greatest();
748 }
749
755 ConstNodeIterator found = lowerBound(lowerLimit); // first node ending at or after lowerLimit
756 if (found==nodes().end())
757 return Nothing();
758 return std::max(lowerLimit, found->key().least());
759 }
760
766 ConstNodeIterator found = findPrior(upperLimit); // last node beginning at or before upperLimit
767 if (found==nodes().end())
768 return Nothing();
769 return std::min(upperLimit, found->key().greatest());
770 }
771
777 for (ConstNodeIterator iter = lowerBound(lowerLimit); iter!=nodes().end(); ++iter) {
778 if (lowerLimit < iter->key().least())
779 return lowerLimit;
780 lowerLimit = iter->key().greatest() + 1;
781 if (lowerLimit <= iter->key().least()) // sensitive to GCC optimization
782 return Nothing(); // overflow
783 }
784 return lowerLimit;
785 }
786
792 for (ConstNodeIterator iter = findPrior(upperLimit); iter!=nodes().end(); --iter) {
793 if (upperLimit > iter->key().greatest())
794 return upperLimit;
795 upperLimit = iter->key().least() - 1;
796 if (upperLimit >= iter->key().greatest()) // sensitive to GCC optimization
797 return Nothing(); // overflow
798 if (iter==nodes().begin())
799 break;
800 }
801 return upperLimit;
802 }
803
805 Interval hull() const {
806 return isEmpty() ? Interval() : Interval::hull(least(), greatest());
807 }
808
809
811 // Mutators
813public:
814
816 void clear() {
817 map_.clear();
818 size_ = 0;
819 }
820
822 void erase(const Interval &erasure) {
823 if (erasure.isEmpty())
824 return;
825
826 // Find what needs to be removed, and create a list of things to insert, but delay actual removing until after
827 // the loop since Map::erase doesn't return a next iterator.
828 Map insertions; // what needs to be inserted back in
829 NodeIterator eraseBegin = nodes().end();
830 NodeIterator iter;
831 for (iter=lowerBound(erasure.least()); iter!=nodes().end() && !erasure.isLeftOf(iter->key()); ++iter) {
832 Interval foundInterval = iter->key();
833 Value &v = iter->value();
834 if (erasure.contains(foundInterval)) {
835 // erase entire found interval
836 if (eraseBegin==nodes().end())
837 eraseBegin = iter;
838 size_ -= foundInterval.size();
839 } else if (erasure.least()>foundInterval.least() && erasure.greatest()<foundInterval.greatest()) {
840 // erase the middle of the node, leaving a left and a right portion
841 ASSERT_require(eraseBegin==nodes().end());
842 eraseBegin = iter;
843 IntervalPair rt = splitInterval(foundInterval, erasure.greatest()+1);
844 Value rightValue = policy_.split(foundInterval, v /*in,out*/, rt.second.least());
845 insertions.insert(rt.second, rightValue);
846 IntervalPair lt = splitInterval(rt.first, erasure.least());
847 policy_.truncate(rt.first, v /*in,out*/, erasure.least());
848 insertions.insert(lt.first, v);
849 size_ -= erasure.size();
850 } else if (erasure.least() > foundInterval.least()) {
851 // erase the right part of the node
852 ASSERT_require(eraseBegin==nodes().end());
853 eraseBegin = iter;
854 IntervalPair halves = splitInterval(foundInterval, erasure.least());
855 policy_.truncate(foundInterval, v /*in,out*/, erasure.least());
856 insertions.insert(halves.first, v);
857 size_ -= halves.second.size();
858 } else if (erasure.greatest() < foundInterval.greatest()) {
859 // erase the left part of the node
860 if (eraseBegin==nodes().end())
861 eraseBegin = iter;
862 IntervalPair halves = splitInterval(foundInterval, erasure.greatest()+1);
863 Value rightValue = policy_.split(foundInterval, v /*in,out*/, halves.second.least());
864 insertions.insert(halves.second, rightValue);
865 size_ -= halves.first.size();
866 }
867 }
868
869 // Do the actual erasing and insert the new stuff, which is easy now because we know it doesn't overlap with anything.
870 if (eraseBegin!=nodes().end())
871 map_.eraseAtMultiple(eraseBegin, iter);
872 map_.insertMultiple(insertions.nodes());
873 }
874
878 template<typename T2, class Policy2>
880 ASSERT_forbid2((const void*)&other == (const void*)this, "use clear() instead");
882 for (OtherIter oi=other.nodes().begin(); oi!=other.nodes().end(); ++oi)
883 erase(oi->key());
884 }
885
890 void insert(Interval key, Value value, bool makeHole=true) {
891 if (key.isEmpty())
892 return;
893 if (makeHole) {
894 erase(key);
895 } else {
896 NodeIterator found = lowerBound(key.least());
897 if (found!=nodes().end() && key.overlaps(found->key()))
898 return;
899 }
900
901 // Attempt to merge with a left-adjoining node
902 if (key.least() - 1 < key.least()) {
903 NodeIterator left = find(key.least() - 1);
904 if (left!=nodes().end() &&
905 left->key().greatest()+1==key.least() &&
906 policy_.merge(left->key(), left->value(), key, value)) {
907 key = Interval::hull(left->key().least(), key.greatest());
908 std::swap(value, left->value());
909 size_ -= left->key().size();
910 map_.eraseAt(left);
911 }
912 }
913
914 // Attempt to merge with a right-adjoining node
915 if (key.greatest() + 1 > key.greatest()) {
916 NodeIterator right = find(key.greatest() + 1);
917 if (right!=nodes().end() &&
918 key.greatest()+1==right->key().least() &&
919 policy_.merge(key, value, right->key(), right->value())) {
920 key = Interval::hull(key.least(), right->key().greatest());
921 size_ -= right->key().size();
922 map_.eraseAt(right);
923 }
924 }
925
926 map_.insert(key, value);
927 size_ += key.size();
928 }
929
934 template<typename T2, class Policy2>
935 void insertMultiple(const IntervalMap<Interval, T2, Policy2> &other, bool makeHole=true) {
936 ASSERT_forbid2((const void*)&other == (const void*)this, "cannot insert a container into itself");
938 for (OtherIter oi=other.nodes().begin(); oi!=other.nodes().end(); ++oi)
939 insert(oi->key(), Value(oi->value()), makeHole);
940 }
941
942// FIXME[Robb Matzke 2014-04-13]
943// // Intersection
944// void intersect(const Interval&);
945
946
947
949 // Predicates
951public:
952 bool overlaps(const Interval &interval) const {
953 return findFirstOverlap(interval) != nodes().end();
954 }
955 bool isOverlapping(const Interval &interval) const {
956 return overlaps(interval);
957 }
958
959 template<typename T2, class Policy2>
960 bool overlaps(const IntervalMap<Interval, T2, Policy2> &other) const {
961 return findFirstOverlap(nodes().begin(), other, other.nodes().begin()).first != nodes().end();
962 }
963 template<typename T2, class Policy2>
964 bool isOverlapping(const IntervalMap<Interval, T2, Policy2> &other) const {
965 return overlaps(other);
966 }
967
968 bool isDistinct(const Interval &interval) const {
969 return !overlaps(interval);
970 }
971
972 template<typename T2, class Policy2>
973 bool isDistinct(const IntervalMap<Interval, T2, Policy2> &other) const {
974 return !overlaps(other);
975 }
976
977 bool contains(Interval key) const {
978 if (key.isEmpty())
979 return true;
980 ConstNodeIterator found = find(key.least());
981 while (1) {
982 if (found==nodes().end())
983 return false;
984 if (key.least() < found->key().least())
985 return false;
986 ASSERT_require(key.overlaps(found->key()));
987 if (key.greatest() <= found->key().greatest())
988 return true;
989 key = splitInterval(key, found->key().greatest()+1).second;
990 ++found;
991 }
992 }
993
994 template<typename T2, class Policy2>
995 bool contains(const IntervalMap<Interval, T2, Policy2> &other) const {
996 for (ConstNodeIterator iter=other.nodes().begin(); iter!=other.nodes().end(); ++iter) {
997 if (!contains(iter->key()))
998 return false;
999 }
1000 return true;
1001 }
1002
1003
1005 // Private support methods
1007private:
1008 static IntervalPair splitInterval(const Interval &interval, const typename Interval::Value &splitPoint) {
1009 ASSERT_forbid(interval.isEmpty());
1010 ASSERT_require(splitPoint > interval.least() && splitPoint <= interval.greatest());
1011
1012 Interval left = Interval::hull(interval.least(), splitPoint-1);
1013 Interval right = Interval::hull(splitPoint, interval.greatest());
1014 return IntervalPair(left, right);
1015 }
1016
1017 // a more convenient way to check whether interval contains at least size items and still handle overflow
1018 static bool isLarge(const Interval &interval, boost::uint64_t size) {
1019 return !interval.isEmpty() && (interval.size()==0 || interval.size() >= size);
1020 }
1021};
1022
1023} // namespace
1024} // namespace
1025
1026#endif
An associative container whose keys are non-overlapping intervals.
size_t nIntervals() const
Number of nodes in the container.
Map::ConstValueIterator ConstValueIterator
Value iterator.
const Value & getOrElse(const typename Interval::Value &scalar, const Value &dflt) const
Lookup and return a value or something else.
IntervalMap()
Default constructor.
const Value & get(const typename Interval::Value &scalar) const
Returns a reference to an existing value.
void insert(Interval key, Value value, bool makeHole=true)
Insert a key/value pair.
ConstNodeIterator upperBound(const typename Interval::Value &scalar) const
Find the first node whose interval begins above the specified scalar key.
Interval firstUnmapped(typename Interval::Value minAddr) const
Find the first unmapped region.
static IntervalMapTraits< IMap >::NodeIterator findPriorImpl(IMap &imap, const typename Interval::Value &scalar)
Find the last node whose interval starts at or below the specified scalar key.
void clear()
Empties the container.
static IntervalMapTraits< IMap >::NodeIterator bestFitImpl(IMap &imap, const typename Interval::Value &size, typename IntervalMapTraits< IMap >::NodeIterator start)
Find the best fit node at or after a starting point.
ConstNodeIterator firstFit(const typename Interval::Value &size, ConstNodeIterator start) const
Find the first fit node at or after a starting point.
Interval::Value greatest() const
Returns the maximum scalar key.
void eraseMultiple(const IntervalMap< Interval, T2, Policy2 > &other)
Erase intervals specified in another IntervalMap.
boost::iterator_range< ConstNodeIterator > nodes() const
Iterators for traversing nodes.
Optional< typename Interval::Value > least(typename Interval::Value lowerLimit) const
Returns the limited-minimum scalar key.
Interval hull() const
Returns the range of values in this map.
ConstNodeIterator findFirstOverlap(const Interval &interval) const
Find first interval that overlaps with the specified interval.
ConstNodeIterator lowerBound(const typename Interval::Value &scalar) const
Find the first node whose interval ends at or above the specified scalar key.
Interval lastUnmapped(typename Interval::Value maxAddr) const
Find the last unmapped region.
static IntervalMapTraits< IMap >::NodeIterator findFirstOverlapImpl(IMap &imap, const Interval &interval)
Find first interval that overlaps with the specified interval.
NodeIterator upperBound(const typename Interval::Value &scalar)
Find the first node whose interval begins above the specified scalar key.
IntervalMap(const IntervalMap< Interval2, T2, Policy2 > &other)
Copy constructor.
Optional< typename Interval::Value > greatest(typename Interval::Value upperLimit) const
Returns the limited-maximum scalar key.
Map::NodeIterator NodeIterator
Node iterator.
ConstNodeIterator find(const typename Interval::Value &scalar) const
Find the node containing the specified scalar key.
boost::iterator_range< NodeIterator > nodes()
Iterators for traversing nodes.
Interval::Value least() const
Returns the minimum scalar key.
NodeIterator firstFit(const typename Interval::Value &size, NodeIterator start)
Find the first fit node at or after a starting point.
boost::iterator_range< ValueIterator > values()
Iterators for traversing values.
std::pair< NodeIterator, typename IntervalMap< Interval, T2, Policy2 >::ConstNodeIterator > findFirstOverlap(typename IntervalMap::NodeIterator thisIter, const IntervalMap< Interval, T2, Policy2 > &other, typename IntervalMap< Interval, T2, Policy2 >::ConstNodeIterator otherIter)
Find first interval that overlaps with any in another container.
ConstNodeIterator bestFit(const typename Interval::Value &size, ConstNodeIterator start) const
Find the best fit node at or after a starting point.
void erase(const Interval &erasure)
Erase the specified interval.
static std::pair< typename IntervalMapTraits< IMap >::NodeIterator, typename IntervalMap< Interval, T2, Policy2 >::ConstNodeIterator > findFirstOverlapImpl(IMap &imap, typename IntervalMapTraits< IMap >::NodeIterator thisIter, const IntervalMap< Interval, T2, Policy2 > &other, typename IntervalMap< Interval, T2, Policy2 >::ConstNodeIterator otherIter)
Find first interval that overlaps with any in another container.
NodeIterator lowerBound(const typename Interval::Value &scalar)
Find the first node whose interval ends at or above the specified scalar key.
bool exists(const typename Interval::Value &size) const
Returns true if element exists.
static boost::iterator_range< typename IntervalMapTraits< IMap >::NodeIterator > findAllImpl(IMap &imap, const Interval &interval)
Finds all nodes overlapping the specified interval.
NodeIterator find(const typename Interval::Value &scalar)
Find the node containing the specified scalar key.
boost::iterator_range< ConstIntervalIterator > intervals() const
Iterators for traversing keys.
boost::iterator_range< NodeIterator > findAll(const Interval &interval)
Finds all nodes overlapping the specified interval.
NodeIterator findPrior(const typename Interval::Value &scalar)
Find the last node whose interval starts at or below the specified scalar key.
ConstNodeIterator findPrior(const typename Interval::Value &scalar) const
Find the last node whose interval starts at or below the specified scalar key.
NodeIterator findFirstOverlap(const Interval &interval)
Find first interval that overlaps with the specified interval.
Optional< typename Interval::Value > greatestUnmapped(typename Interval::Value upperLimit) const
Returns the limited-maximum unmapped scalar key.
std::pair< ConstNodeIterator, typename IntervalMap< Interval, T2, Policy2 >::ConstNodeIterator > findFirstOverlap(typename IntervalMap::ConstNodeIterator thisIter, const IntervalMap< Interval, T2, Policy2 > &other, typename IntervalMap< Interval, T2, Policy2 >::ConstNodeIterator otherIter) const
Find first interval that overlaps with any in another container.
bool isEmpty() const
Determine if the container is empty.
static IntervalMapTraits< IMap >::NodeIterator findImpl(IMap &imap, const typename Interval::Value &scalar)
Find the node containing the specified scalar key.
boost::iterator_range< ConstValueIterator > values() const
Iterators for traversing values.
Optional< Value > getOptional(const typename Interval::Value &scalar) const
Lookup and return a value or nothing.
Map::ConstNodeIterator ConstNodeIterator
Node iterator.
Map::Node Node
Storage node.
const Value & operator[](const typename Interval::Value &scalar) const
Returns a reference to an existing value.
const Value & getOrDefault(const typename Interval::Value &scalar) const
Lookup and return a value or a default.
Interval::Value size() const
Returns the number of values represented by this container.
boost::iterator_range< ConstNodeIterator > findAll(const Interval &interval) const
Finds all nodes overlapping the specified interval.
Container::Map< Interval, Value, IntervalCompare > Map
Type of the underlying map.
Map::ValueIterator ValueIterator
Value iterator.
Map::ConstKeyIterator ConstIntervalIterator
Interval iterator.
static IntervalMapTraits< IMap >::NodeIterator firstFitImpl(IMap &imap, const typename Interval::Value &size, typename IntervalMapTraits< IMap >::NodeIterator start)
Find the first fit node at or after a starting point.
void insertMultiple(const IntervalMap< Interval, T2, Policy2 > &other, bool makeHole=true)
Insert values from another container.
IntervalMap & operator=(const IntervalMap< Interval2, T2, Policy2 > &other)
Assignment operator.
Optional< typename Interval::Value > leastUnmapped(typename Interval::Value lowerLimit) const
Returns the limited-minimum unmapped scalar key.
NodeIterator bestFit(const typename Interval::Value &size, NodeIterator start)
Find the best fit node at or after a starting point.
Value & getOrElse(const typename Interval::Value &scalar, Value &dflt)
Lookup and return a value or something else.
Range of values delimited by endpoints.
Definition Interval.h:31
T greatest() const
Returns upper limit.
Definition Interval.h:224
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
Definition Interval.h:162
T Value
Types of values in the interval.
Definition Interval.h:34
static Interval whole()
Construct an interval that covers the entire domain.
Definition Interval.h:191
Bidirectional iterator over keys.
Definition Sawyer/Map.h:243
Bidirectional iterator over key/value nodes.
Definition Sawyer/Map.h:213
Bidirectional iterator over values.
Definition Sawyer/Map.h:296
Bidirectional iterator over key/value nodes.
Definition Sawyer/Map.h:187
Type for stored nodes.
Definition Sawyer/Map.h:107
const Key & key() const
Key part of key/value node.
Definition Sawyer/Map.h:116
Value & value()
Value part of key/value node.
Definition Sawyer/Map.h:123
Bidirectional iterator over values.
Definition Sawyer/Map.h:271
Container associating values with keys.
Definition Sawyer/Map.h:72
NodeIterator upperBound(const Key &key)
Find a node close to a key.
Definition Sawyer/Map.h:523
Map & eraseAt(const NodeIterator &iter)
Remove a node by iterator.
Definition Sawyer/Map.h:771
boost::iterator_range< ValueIterator > values()
Iterators for container values.
Definition Sawyer/Map.h:414
size_t size() const
Number of nodes, keys, or values in this container.
Definition Sawyer/Map.h:438
bool isEmpty() const
Determines whether this container is empty.
Definition Sawyer/Map.h:431
NodeIterator lowerBound(const Key &key)
Find a node close to a key.
Definition Sawyer/Map.h:506
boost::iterator_range< NodeIterator > nodes()
Iterators for container nodes.
Definition Sawyer/Map.h:387
Map & eraseAtMultiple(const Iter &begin, const Iter &end)
Remove multiple nodes by iterator range.
Definition Sawyer/Map.h:797
boost::iterator_range< ConstKeyIterator > keys()
Iterators for container keys.
Definition Sawyer/Map.h:400
Map & insert(const Key &key, const Value &value)
Insert or update a key/value pair.
Definition Sawyer/Map.h:646
Map & clear()
Remove all nodes.
Definition Sawyer/Map.h:732
Map & insertMultiple(const OtherNodeIterator &begin, const OtherNodeIterator &end)
Insert multiple values.
Definition Sawyer/Map.h:682
Policy indicating how values are merged and split.
Definition IntervalMap.h:40
Value split(const Interval &interval, Value &value, const typename Interval::Value &splitPoint)
Split one value into two values.
Definition IntervalMap.h:82
bool merge(const Interval &leftInterval, Value &leftValue, const Interval &rightInterval, Value &rightValue)
Merge two values if possible.
Definition IntervalMap.h:70
void truncate(const Interval &interval, Value &value, const typename Interval::Value &splitPoint)
Discard the right part of a value.
Definition IntervalMap.h:92
Represents no value.
Definition Optional.h:34
Holds a value or nothing.
Definition Optional.h:54
Sawyer support library.
IntervalMap::ValueIterator ValueIterator
Value iterator.
Definition IntervalMap.h:24
IntervalMap::NodeIterator NodeIterator
Node iterator.
Definition IntervalMap.h:23
IntervalMap::Value & ValueReference
Reference to value.
Definition IntervalMap.h:25