rangeset.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00038 #ifndef COL_RANGESET_H
00039 #define COL_RANGESET_H
00040
00041 #include "fastlib/col/arraylist.h"
00042
00043
00053 template<typename TBoundary>
00054 class RangeSet {
00055 public:
00056 typedef TBoundary Boundary;
00057
00058 public:
00059 struct Range {
00060 Boundary begin;
00061 Boundary end;
00062
00063 OT_DEF_BASIC(Range) {
00064 OT_MY_OBJECT(begin);
00065 OT_MY_OBJECT(end);
00066 }
00067 };
00068
00069 private:
00070 ArrayList<Range> ranges_;
00071
00072 OT_DEF(RangeSet) {
00073 OT_MY_OBJECT(ranges_);
00074 }
00075
00076 public:
00080 void Init() {
00081 ranges_.Init();
00082 }
00083
00087 void Reset() {
00088 ranges_.Clear();
00089 }
00090
00096 void Union(const Boundary& begin, const Boundary& end);
00097
00098 const ArrayList<Range>& ranges() const {
00099 return ranges_;
00100 }
00101
00105 const Range& operator[] (index_t i) const {
00106 return ranges_[i];
00107 }
00108
00112 index_t size() const {
00113 return ranges_.size();
00114 }
00115
00116 };
00117
00118 template<typename TBoundary>
00119 void RangeSet<TBoundary>::Union(
00120 const Boundary& begin, const Boundary& end) {
00121 if (unlikely(!(begin < end))) {
00122
00123 return;
00124 }
00125
00126
00127 ArrayList<Range> new_list;
00128 index_t i;
00129
00130 new_list.Init();
00131
00132 i = 0;
00133
00134
00135 while (i < ranges_.size() && !(begin <= ranges_[i].end)) {
00136 new_list.PushBackCopy(ranges_[i]);
00137 i++;
00138 }
00139
00140
00141 const Boundary *selected_end = &end;
00142 const Boundary *selected_begin = &begin;
00143
00144 while (i < ranges_.size() && end >= ranges_[i].begin) {
00145 if (ranges_[i].begin < *selected_begin) {
00146 selected_begin = &ranges_[i].begin;
00147 }
00148 if (ranges_[i].end > *selected_end) {
00149 selected_end = &ranges_[i].end;
00150 }
00151 i++;
00152 }
00153
00154 Range *new_range = new_list.PushBackRaw();
00155 new(&new_range->begin)Boundary(*selected_begin);
00156 new(&new_range->end)Boundary(*selected_end);
00157
00158
00159 for (; i < ranges_.size(); i++) {
00160 new_list.PushBackCopy(ranges_[i]);
00161 }
00162
00163
00164 ranges_.Swap(&new_list);
00165 }
00166
00167 #endif