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.