19 #include <lunchbox/debug.h>
21 #include <boost/iterator/iterator_facade.hpp>
27 template<
typename T >
28 class UnorderedIntervalSet< T >::const_iterator :
29 public boost::iterator_facade<
30 typename UnorderedIntervalSet< T >::const_iterator,
31 T, std::forward_iterator_tag, T >
39 friend class boost::iterator_core_access;
42 typedef typename UnorderedIntervalSet< T >::EdgeSet::const_iterator
46 const edge_iterator& interval)
47 : _intervalIteratorEnd( set._intervals.
end( ))
48 , _startEdge( interval )
50 if (_startEdge != _intervalIteratorEnd )
51 _value = _startEdge->first;
55 const edge_iterator & interval,
const T& current )
57 , _intervalIteratorEnd( set._intervals.
end( ))
58 , _startEdge( interval )
64 if( _startEdge == _intervalIteratorEnd )
67 edge_iterator endEdge = _startEdge;
70 if( _value >= _startEdge->first && _value < endEdge->first )
76 if( _startEdge != _intervalIteratorEnd )
77 _value = _startEdge->first;
81 bool equal(
const const_iterator& rhs )
const
83 return (_startEdge == _intervalIteratorEnd &&
84 rhs._startEdge == _intervalIteratorEnd) ||
85 (_startEdge == rhs._startEdge && _value == rhs._value );
94 edge_iterator _intervalIteratorEnd;
95 edge_iterator _startEdge;
98 template <
typename T >
103 template <
typename T >
106 insert( element, element );
109 template <
typename T >
112 erase( element, element );
115 template <
typename T >
117 const T& endElement )
119 LBASSERT( startElement <= endElement );
121 Edge startValue( startElement,
true );
122 Edge endValue( endElement,
false );
124 if( _intervals.empty( ))
126 _intervals.insert( startValue );
127 _intervals.insert( endValue );
128 _size = endElement - startElement + 1;
133 typename EdgeSet::iterator previous_to_start =
134 _intervals.lower_bound( startValue );
135 if( previous_to_start != _intervals.end( ))
137 if (previous_to_start == _intervals.begin( ))
138 previous_to_start = _intervals.end();
143 previous_to_start = (++_intervals.rbegin()).base();
146 typename EdgeSet::iterator position;
148 size_t overlappingPortion = 0;
149 T overlappingStart = T();
151 if( previous_to_start == _intervals.end( ))
156 position = _intervals.insert( startValue );
159 else if( !previous_to_start->second )
162 if( previous_to_start->first + 1 == startElement )
166 position = previous_to_start;
168 _intervals.erase( previous_to_start );
172 position = _intervals.insert( previous_to_start, startValue );
178 position = previous_to_start;
180 overlappingStart = startElement;
185 while( position != _intervals.end() && position->first <= endElement )
192 LBASSERT( !position->second );
193 overlappingPortion += position->first - overlappingStart + 1;
196 overlappingStart = position->first;
198 fallsInside = position->second;
203 _intervals.erase( position++ );
206 if( position != _intervals.end() &&
207 position->second && position->first == endElement + 1 )
212 _intervals.erase(position);
214 else if( !fallsInside )
218 _intervals.insert(position, endValue);
221 overlappingPortion += endElement - overlappingStart + 1;
223 _size += size_t(endElement - startElement + 1) - overlappingPortion;
224 LBASSERT( _intervals.size() % 2 == 0 );
227 template <
typename T >
229 const T& endElement )
231 LBASSERT( startElement <= endElement );
233 if( _intervals.empty( ))
237 typename EdgeSet::iterator nextToStart =
238 _intervals.lower_bound( std::make_pair( startElement,
true ));
239 typename EdgeSet::iterator previousToStart = nextToStart;
240 if( nextToStart == _intervals.begin( ))
241 previousToStart = _intervals.end();
242 else if( nextToStart == _intervals.end( ))
248 typename EdgeSet::iterator position;
250 T overlappingStart = 0;
251 size_t overlapping_portion = 0;
253 if( previousToStart != _intervals.end( ))
256 if( previousToStart->second )
261 _intervals.insert( std::make_pair( startElement - 1,
false ));
263 overlappingStart = startElement;
267 position = previousToStart;
276 position = _intervals.begin();
277 overlappingStart = position->first;
282 while( position != _intervals.end() && position->first <= endElement )
285 overlapping_portion += position->first - overlappingStart + 1;
287 overlappingStart = position->first;
289 inside = position->second;
294 _intervals.erase( position++ );
299 LBASSERT( position != _intervals.end( ));
302 _intervals.insert (std::make_pair( endElement + 1,
true ));
303 overlapping_portion += endElement - overlappingStart + 1;
306 _size -= overlapping_portion;
307 LBASSERT( _intervals.size() % 2 == 0 );
310 template <
typename T >
313 for(
typename EdgeSet::const_iterator i = rhs._intervals.begin();
314 i != rhs._intervals.end(); ++i )
316 insert( i->first, i->second );
320 template <
typename T >
327 template <
typename T >
330 return find( element ) != end();
333 template <
typename T >
334 typename UnorderedIntervalSet< T >::const_iterator
337 if( _intervals.empty( ))
340 typename EdgeSet::const_iterator next =
341 _intervals.lower_bound( std::make_pair( element,
false ));
345 if( next == _intervals.end() || next == _intervals.begin( ))
349 typename EdgeSet::const_iterator previous = next;
351 if( previous->second )
352 return const_iterator( *
this, previous, element );
356 template <
typename T >
357 typename UnorderedIntervalSet< T >::const_iterator
360 if( _intervals.empty( ))
362 return const_iterator( *
this, _intervals.begin( ));
365 template <
typename T >
366 typename UnorderedIntervalSet< T >::const_iterator
369 return const_iterator( *
this, _intervals.end());
372 template <
typename T >
378 template <
typename T >
384 template <
typename T >
387 _intervals.swap( rhs._intervals );