Put this in the repo so Arthur and I can discuss it.

This commit is contained in:
JoelKatz
2012-10-24 16:52:56 -07:00
parent c49fb35a88
commit 65f2275fb2
2 changed files with 179 additions and 0 deletions

112
src/RangeSet.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include "RangeSet.h"
inline int min(int x, int y) { return (x < y) ? x : y; }
inline int max(int x, int y) { return (x > y) ? x : y; }
bool RangeSet::hasValue(int v) const
{
for (const_iterator it = begin(); it != end(); ++it)
{
if ((v >= it->first) && (v <= it->second))
return true;
}
return false;
}
int RangeSet::getFirst() const
{
const_iterator it = begin();
if (it == end())
return RangeSetAbsent;
return it->first;
}
int RangeSet::getNext(int v) const
{
for (const_iterator it = begin(); it != end(); ++it)
{
if (it->second > v)
return min(v + 1, it->first);
}
return RangeSetAbsent;
}
int RangeSet::getLast() const
{
const_reverse_iterator it = rbegin();
if (it == rend())
return RangeSetAbsent;
return it->second;
}
int RangeSet::getPrev(int v) const
{
for (const_reverse_iterator it = rbegin(); it != rend(); ++it)
{
if (it->first < v)
return max(v - 1, it->second);
}
return RangeSetAbsent;
}
bool RangeSet::setValue(int v)
{
for (iterator it = begin(); it != end(); ++it)
{
if (it->first >= v)
{ // entry goes before or in this entry
if (it->second <= v)
return false;
if (it->first > (v - 1))
{
mRanges.insert(it, std::make_pair(v, v));
return true;
}
else if (it->first == (v - 1))
{
it->first = v;
// WRITEME: check for consolidation
}
// WRITEME
}
}
mRanges.push_back(std::make_pair(v, v));
return true;
}
void RangeSet::setRange(int minV, int maxV)
{
}
bool RangeSet::clearValue(int v)
{
for (iterator it = begin(); it != end(); ++it)
{
if (it->first >= v)
{ // we are at or past the value we need to clear
if (it->second > v)
return false;
if ((it->first == v) && (it->second == v))
mRanges.erase(it);
else if (it->first == v)
++it->first;
else if (it->second == v)
--it->second;
else
{ // this pokes a hole
int first = it->first;
it->first = v + 1;
mRanges.insert(it, std::make_pair(first, v - 1));
}
return true;
}
}
return false;
}
void RangeSet::clearRange(int minV, int maxV)
{
}

67
src/RangeSet.h Normal file
View File

@@ -0,0 +1,67 @@
#ifndef RANGESET__H
#define RANGESET__H
#include <list>
#include <boost/foreach.hpp>
class RangeSet
{
public:
typedef std::pair<int, int> Range;
typedef std::list<Range>::iterator iterator;
typedef std::list<Range>::const_iterator const_iterator;
typedef std::list<Range>::reverse_iterator reverse_iterator;
typedef std::list<Range>::const_reverse_iterator const_reverse_iterator;
static const int RangeSetAbsent = -1;
protected:
std::list<Range> mRanges;
public:
RangeSet() { ; }
bool hasValue(int) const;
int getFirst() const;
int getNext(int) const;
int getLast() const;
int getPrev(int) const;
bool setValue(int);
void setRange(int, int);
bool clearValue(int);
void clearRange(int, int);
// iterator stuff
iterator begin() { return mRanges.begin(); }
iterator end() { return mRanges.end(); }
const_iterator begin() const { return mRanges.begin(); }
const_iterator end() const { return mRanges.end(); }
reverse_iterator rbegin() { return mRanges.rbegin(); }
reverse_iterator rend() { return mRanges.rend(); }
const_reverse_iterator rbegin() const { return mRanges.rbegin(); }
const_reverse_iterator rend() const { return mRanges.rend(); }
};
inline RangeSet::const_iterator range_begin(const RangeSet& r) { return r.begin(); }
inline RangeSet::iterator range_begin(RangeSet& r) { return r.begin(); }
inline RangeSet::const_iterator range_end(const RangeSet& r) { return r.end(); }
inline RangeSet::iterator range_end(RangeSet& r) { return r.end(); }
namespace boost
{
template<> struct range_mutable_iterator<RangeSet>
{
typedef RangeSet::iterator type;
};
template<> struct range_const_iterator<RangeSet>
{
typedef RangeSet::const_iterator type;
};
}
#endif