Changeset 2357 for trunk/yat/utility/SegmentSet.h
- Timestamp:
- Dec 1, 2010, 10:08:29 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/yat/utility/SegmentSet.h
r2356 r2357 51 51 /// value_type same as key_type 52 52 typedef key_type value_type; 53 53 54 /// key_compare 54 struct key_compare55 class key_compare : public std::binary_function<key_type, key_type, bool> 55 56 { 57 public: 56 58 /// return true if lhs.begin() < rhs.begin() 57 59 bool operator()(const key_type& lhs, const key_type& rhs) const 58 { return Compare()(lhs.begin(),rhs.begin()); }60 { return compare(lhs,rhs); } 59 61 }; 62 60 63 /// value_compare is same as key_compare 61 64 typedef key_compare value_compare; … … 81 84 82 85 /** 83 \brief default constructor86 \brief creates a set with no segments 84 87 */ 85 88 SegmentSet(void) {} 86 89 87 90 /** 91 \return const iterator to first Segment 92 */ 93 const_iterator begin(void) const { return set_.begin(); } 94 95 /** 88 96 \return iterator to first Segment 89 97 */ 90 const_iterator begin(void) const { return set_.begin(); }91 92 /**93 \return iterator to first Segment94 */95 98 iterator begin(void) { return set_.begin(); } 96 99 97 100 /** 98 \brief erases all thesegments101 \brief erases all segments 99 102 */ 100 103 void clear(void) { set_.clear(); } 101 104 102 105 /** 103 \return 1 if there is a set that overlaps with \a vt104 */ 105 size_t count(const typename value_type::value_type& vt) const;106 107 /** 108 \return \c true if SegmentSet is empty106 \return 1 if there is a set that overlaps with \a element 107 */ 108 size_type count(const T& element) const; 109 110 /** 111 \return \c true 109 112 */ 110 113 bool empty(void) const { return set_.empty(); } … … 124 127 vt. If no Segment contains \a vt, end() is returned. 125 128 */ 126 const_iterator find(const typename value_type::value_type& vt) const;129 const_iterator find(const T& vt) const; 127 130 128 131 /** … … 141 144 /** 142 145 insert \a segment into set. If there is no gap between \a 143 segment and neighboring segments the segments are merged. Note 144 that this might also happen for non-overlapping segments, e.g., 145 [0,1) and [1,2) would be merged into [0,2). 146 segment and neighboring segments the segments are merged. 146 147 */ 147 148 const_iterator insert_merge(const value_type& segment); 149 150 /** 151 \return Comparison functor to compare to segments 152 */ 153 key_compare key_comp(void) const { return key_compare(Compare()); } 148 154 149 155 /** … … 151 157 \a segment or is greater than \a segment. 152 158 */ 153 const_iterator lower_bound(const value_type& segment) const;159 const_iterator lower_bound(const key_type& segment) const; 154 160 155 161 /** 156 162 \return number of segments in set 157 163 */ 158 size_t size(void) const { return set_.size(); }164 size_type size(void) const { return set_.size(); } 159 165 160 166 /** … … 162 168 \a segment. 163 169 */ 164 const_iterator upper_bound(const value_type& segment) const; 170 const_iterator upper_bound(const key_type& segment) const; 171 172 /** 173 \return Comparison functor to compare to segments 174 */ 175 value_compare value_comp(void) const { return key_comp(); } 165 176 166 177 private: … … 172 183 overlap with \a segment. 173 184 */ 174 std::pair<iterator, iterator> overlap_range(const value_type& segment) 185 // FIXME: can this be removed? 186 std::pair<iterator, iterator> overlap_range(const key_type& segment) 175 187 { 176 188 iterator first = set_.lower_bound(segment); … … 187 199 } 188 200 189 190 /**191 pair.first first (smallest) segment that overlaps with \a192 segment and pair.second first (smallest) segment that does not193 overlap with \a segment.194 */195 std::pair<const_iterator, const_iterator>196 overlap_range(const value_type& segment) const197 {198 const_iterator first = set_.lower_bound(segment);199 if (first!=begin()) {200 --first;201 if (compare(*first, segment))202 ++first;203 }204 const_iterator last = first;205 while (last!=end() && !compare(segment, *last))206 ++last;207 return std::make_pair(first, last);208 }209 210 201 // using compiler generated copying 211 202 //SegmentSet(const SegmentSet&); … … 214 205 215 206 template<typename T, class Compare> 216 size_t217 SegmentSet<T, Compare>::count(const typename value_type::value_type& vt) const207 typename SegmentSet<T, Compare>::size_type 208 SegmentSet<T, Compare>::count(const T& vt) const 218 209 { 219 210 if (find(vt)==end()) … … 225 216 template<typename T, class Compare> 226 217 typename SegmentSet<T, Compare>::const_iterator 227 SegmentSet<T, Compare>::find(const typename value_type::value_type& vt) const218 SegmentSet<T, Compare>::find(const T& vt) const 228 219 { 229 220 Segment<T, Compare> segment(vt, vt); 230 std::pair<const_iterator, const_iterator> p = overlap_range(segment); 231 if (p.first == end()) 221 const_iterator iter = lower_bound(segment); 222 Compare comp; 223 if (iter==end() || comp(vt, iter->begin())) 232 224 return end(); 233 Compare comp; 234 if (comp(vt, p.first->begin())) 235 return end(); 236 return p.first; 225 return iter; 237 226 } 238 227 … … 242 231 SegmentSet<T, Compare>::insert(const value_type& segment) 243 232 { 244 std::pair<iterator, iterator> p = overlap_range(segment); 245 std::pair<typename SegmentSet<T, Compare>::iterator, bool> result; 246 if (p.first==p.second) { 247 result.first = set_.insert(p.first, segment); 248 result.second = true; 249 return result; 250 } 251 result.first = p.first; 252 result.second = false; 253 return result; 233 return set_.insert(segment); 254 234 } 255 235 … … 260 240 { 261 241 std::pair<iterator, iterator> p = overlap_range(segment); 262 if (p.first==p.second) { 242 if (p.first==p.second) { // no overlap between set and segment 263 243 return set_.insert(p.first, segment); 264 244 } 245 /* 246 p.first last p.second 247 ---> ---> ---> ---> 248 249 -----------------------> 250 segment 251 */ 265 252 Compare comp; 266 i f (comp(segment.begin(), p.first->begin()))267 const_cast<value_type&>(*p.first).begin() = segment.begin();268 269 -- p.second;270 const_cast<value_type&>(*p.first).end() =271 std::max(p.second->end(), segment.end(), comp); 272 ++p.second;273 iterator begin(p.first);274 ++begin;275 set_.erase(begin, p.second);276 return p.first;253 iterator last=p.second; 254 YAT_ASSERT(last==end() || compare(segment, *last)); 255 YAT_ASSERT(last!=begin()); // last!=p.first 256 --last; 257 YAT_ASSERT(compare_3way(segment, *last)==0); 258 259 Segment<T, Compare> segment2(std::min(p.first->begin(),segment.begin(),comp), 260 std::max(last->end(),segment.end(),comp)); 261 set_.erase(p.first, p.second); 262 // FIXME: use a better hint than end() 263 return set_.insert(end(), segment2); 277 264 } 278 265 … … 280 267 template<typename T, class Compare> 281 268 typename SegmentSet<T, Compare>::const_iterator 282 SegmentSet<T, Compare>::lower_bound(const value_type& segment) const269 SegmentSet<T, Compare>::lower_bound(const key_type& segment) const 283 270 { 284 271 const_iterator result = set_.lower_bound(segment); 285 if (result!=begin()) { 286 --result; 287 if (compare(*result, segment)) 288 ++result; 289 } 272 // result is larger or overlapping with segment (i.e.! result<segment) 273 YAT_ASSERT(result==end() || !compare(*result,segment)); 290 274 return result; 291 275 } … … 294 278 template<typename T, class Compare> 295 279 typename SegmentSet<T, Compare>::const_iterator 296 SegmentSet<T, Compare>::upper_bound(const value_type& segment) const297 { 298 const_iterator result = set_. lower_bound(segment);299 while (result!=end() && !compare(segment, *result))300 ++result;280 SegmentSet<T, Compare>::upper_bound(const key_type& segment) const 281 { 282 const_iterator result = set_.upper_bound(segment); 283 // result is larger than segment 284 YAT_ASSERT(result==end() || compare(segment, *result)); 301 285 return result; 302 286 }
Note: See TracChangeset
for help on using the changeset viewer.