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.