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 );