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( ))
139 if( startValue.first < previous_to_start->first )
140 previous_to_start = _intervals.end();
146 previous_to_start = (++_intervals.rbegin()).base();
149 typename EdgeSet::iterator position;
151 size_t overlappingPortion = 0;
152 T overlappingStart = T();
154 if( previous_to_start == _intervals.end( ))
159 position = _intervals.insert( startValue );
162 else if( !previous_to_start->second )
165 if( previous_to_start->first + 1 == startElement )
169 position = previous_to_start;
171 _intervals.erase( previous_to_start );
175 position = _intervals.insert( previous_to_start, startValue );
181 position = previous_to_start;
183 overlappingStart = startElement;
188 while( position != _intervals.end() && position->first <= endElement )
195 LBASSERT( !position->second );
196 overlappingPortion += position->first - overlappingStart + 1;
199 overlappingStart = position->first;
201 fallsInside = position->second;
206 _intervals.erase( position++ );
209 if( position != _intervals.end() &&
210 position->second && position->first == endElement + 1 )
215 _intervals.erase(position);
217 else if( !fallsInside )
221 _intervals.insert(position, endValue);
224 overlappingPortion += endElement - overlappingStart + 1;
226 _size += size_t(endElement - startElement + 1) - overlappingPortion;
227 LBASSERT( _intervals.size() % 2 == 0 );
230 template <
typename T >
232 const T& endElement )
234 LBASSERT( startElement <= endElement );
236 if( _intervals.empty( ))
240 typename EdgeSet::iterator nextToStart =
241 _intervals.lower_bound( std::make_pair( startElement,
true ));
242 typename EdgeSet::iterator previousToStart = nextToStart;
243 if( nextToStart == _intervals.begin( ))
244 previousToStart = _intervals.end();
245 else if( nextToStart == _intervals.end( ))
251 typename EdgeSet::iterator position;
253 T overlappingStart = 0;
254 size_t overlapping_portion = 0;
256 if( previousToStart != _intervals.end( ))
259 if( previousToStart->second )
264 _intervals.insert( std::make_pair( startElement - 1,
false ));
266 overlappingStart = startElement;
270 position = previousToStart;
279 position = _intervals.begin();
280 overlappingStart = position->first;
285 while( position != _intervals.end() && position->first <= endElement )
288 overlapping_portion += position->first - overlappingStart + 1;
290 overlappingStart = position->first;
292 inside = position->second;
297 _intervals.erase( position++ );
302 LBASSERT( position != _intervals.end( ));
305 _intervals.insert (std::make_pair( endElement + 1,
true ));
306 overlapping_portion += endElement - overlappingStart + 1;
309 _size -= overlapping_portion;
310 LBASSERT( _intervals.size() % 2 == 0 );
313 template <
typename T >
316 for(
typename EdgeSet::const_iterator i = rhs._intervals.begin();
317 i != rhs._intervals.end(); ++i )
319 insert( i->first, i->second );
323 template <
typename T >
330 template <
typename T >
333 return find( element ) != end();
336 template <
typename T >
337 typename UnorderedIntervalSet< T >::const_iterator
340 if( _intervals.empty( ))
343 typename EdgeSet::const_iterator next =
344 _intervals.lower_bound( std::make_pair( element,
false ));
348 if( next == _intervals.end() || next == _intervals.begin( ))
352 typename EdgeSet::const_iterator previous = next;
354 if( previous->second )
355 return const_iterator( *
this, previous, element );
359 template <
typename T >
360 typename UnorderedIntervalSet< T >::const_iterator
363 if( _intervals.empty( ))
365 return const_iterator( *
this, _intervals.begin( ));
368 template <
typename T >
369 typename UnorderedIntervalSet< T >::const_iterator
372 return const_iterator( *
this, _intervals.end());
375 template <
typename T >
381 template <
typename T >
387 template <
typename T >
390 _intervals.swap( rhs._intervals );
void erase(const T &element)
Remove the given element.
const_iterator find(const T &element) const
const_iterator begin() const
void clear()
Remove all stored elements.
void insert(const T &element)
Insert a new element.
bool exists(const T &element) const
UnorderedIntervalSet()
Construct a new interval set.
const_iterator end() const
void swap(UnorderedIntervalSet &rhs)
Swap this container with another one.
std::vector< T >::iterator find(std::vector< T > &container, const T &element)
Find the element in the given vector.
Abstraction layer and common utilities for multi-threaded programming.