19 #include <lunchbox/debug.h> 21 #include <boost/iterator/iterator_facade.hpp> 27 class IntervalSet<T>::const_iterator
28 :
public boost::iterator_facade<typename IntervalSet<T>::const_iterator, T,
29 std::forward_iterator_tag, T>
35 friend class boost::iterator_core_access;
38 typedef typename IntervalSet<T>::EdgeSet::const_iterator edge_iterator;
40 const_iterator(
const IntervalSet&
set,
const edge_iterator& interval)
41 : _intervalIteratorEnd(set._intervals.
end())
42 , _startEdge(interval)
44 if (_startEdge != _intervalIteratorEnd)
45 _value = _startEdge->first;
48 const_iterator(
const IntervalSet&
set,
const edge_iterator& interval,
51 , _intervalIteratorEnd(set._intervals.
end())
52 , _startEdge(interval)
58 if (_startEdge == _intervalIteratorEnd)
61 edge_iterator endEdge = _startEdge;
64 if (_value >= _startEdge->first && _value < endEdge->first)
70 if (_startEdge != _intervalIteratorEnd)
71 _value = _startEdge->first;
75 bool equal(
const const_iterator& rhs)
const 77 return (_startEdge == _intervalIteratorEnd &&
78 rhs._startEdge == _intervalIteratorEnd) ||
79 (_startEdge == rhs._startEdge && _value == rhs._value);
82 T dereference()
const {
return _value; }
84 edge_iterator _intervalIteratorEnd;
85 edge_iterator _startEdge;
100 template <
typename T>
103 erase(element, element);
106 template <
typename T>
109 LBASSERT(startElement <= endElement);
111 Edge startValue(startElement,
true);
112 Edge endValue(endElement,
false);
114 if (_intervals.empty())
116 _intervals.insert(startValue);
117 _intervals.insert(endValue);
118 _size = endElement - startElement + 1;
123 typename EdgeSet::iterator previous_to_start =
124 _intervals.lower_bound(startValue);
125 if (previous_to_start != _intervals.end())
127 if (previous_to_start == _intervals.begin())
129 if (startValue.first < previous_to_start->first)
130 previous_to_start = _intervals.end();
136 previous_to_start = (++_intervals.rbegin()).base();
139 typename EdgeSet::iterator position;
141 size_t overlappingPortion = 0;
142 T overlappingStart = T();
144 if (previous_to_start == _intervals.end())
149 position = _intervals.insert(startValue);
152 else if (!previous_to_start->second)
155 if (previous_to_start->first + 1 == startElement)
159 position = previous_to_start;
161 _intervals.erase(previous_to_start);
165 position = _intervals.insert(previous_to_start, startValue);
171 position = previous_to_start;
173 overlappingStart = startElement;
178 while (position != _intervals.end() && position->first <= endElement)
185 LBASSERT(!position->second);
186 overlappingPortion += position->first - overlappingStart + 1;
189 overlappingStart = position->first;
191 fallsInside = position->second;
196 _intervals.erase(position++);
199 if (position != _intervals.end() && position->second &&
200 position->first == endElement + 1)
205 _intervals.erase(position);
207 else if (!fallsInside)
211 _intervals.insert(position, endValue);
214 overlappingPortion += endElement - overlappingStart + 1;
216 _size += size_t(endElement - startElement + 1) - overlappingPortion;
217 LBASSERT(_intervals.size() % 2 == 0);
220 template <
typename T>
223 LBASSERT(startElement <= endElement);
225 if (_intervals.empty())
229 typename EdgeSet::iterator nextToStart =
230 _intervals.lower_bound(std::make_pair(startElement,
true));
231 typename EdgeSet::iterator previousToStart = nextToStart;
232 if (nextToStart == _intervals.begin())
233 previousToStart = _intervals.end();
234 else if (nextToStart == _intervals.end())
240 typename EdgeSet::iterator position;
242 T overlappingStart = 0;
243 size_t overlapping_portion = 0;
245 if (previousToStart != _intervals.end())
248 if (previousToStart->second)
253 _intervals.insert(std::make_pair(startElement - 1,
false));
255 overlappingStart = startElement;
259 position = previousToStart;
268 position = _intervals.begin();
269 overlappingStart = position->first;
274 while (position != _intervals.end() && position->first <= endElement)
277 overlapping_portion += position->first - overlappingStart + 1;
279 overlappingStart = position->first;
281 inside = position->second;
286 _intervals.erase(position++);
291 LBASSERT(position != _intervals.end());
294 _intervals.insert(std::make_pair(endElement + 1,
true));
295 overlapping_portion += endElement - overlappingStart + 1;
298 _size -= overlapping_portion;
299 LBASSERT(_intervals.size() % 2 == 0);
302 template <
typename T>
305 for (
typename EdgeSet::const_iterator i = rhs._intervals.begin();
306 i != rhs._intervals.end(); ++i)
308 insert(i->first, i->second);
312 template <
typename T>
319 template <
typename T>
325 template <
typename T>
327 const T& element)
const 329 if (_intervals.empty())
332 typename EdgeSet::const_iterator next =
333 _intervals.lower_bound(std::make_pair(element,
false));
337 if (next == _intervals.end() || next == _intervals.begin())
341 typename EdgeSet::const_iterator previous = next;
343 if (previous->second)
344 return const_iterator(*
this, previous, element);
348 template <
typename T>
351 if (_intervals.empty())
353 return const_iterator(*
this, _intervals.begin());
356 template <
typename T>
359 return const_iterator(*
this, _intervals.end());
362 template <
typename T>
368 template <
typename T>
374 template <
typename T>
377 _intervals.swap(rhs._intervals);
const_iterator find(const T &element) const
bool exists(const T &element) const
IntervalSet()
Construct a new interval set.
void erase(const T &element)
Remove the given element.
void swap(IntervalSet &rhs)
Swap this container with another one.
void insert(const T &element)
Insert a new element.
const_iterator begin() const
Abstraction layer and common utilities for multi-threaded programming.
const_iterator end() const
void clear()
Remove all stored elements.