46inline ptrdiff_t roundUpToEven(ptrdiff_t i) {
return i + (i & 1); }
54 using difference_type = ptrdiff_t;
60 RangeIter() =
default;
63 friend void swap(RangeIter & a, RangeIter &
b) {
std::swap(a.ptr,
b.ptr); }
66 RangeIter & operator++() {
ptr += 2;
return *
this; }
67 RangeIter & operator--() {
ptr -= 2;
return *
this; }
69 RangeIter operator++(
int) { RangeIter i(*
this);
ptr += 2;
return i; }
70 RangeIter operator--(
int) { RangeIter i(*
this);
ptr -= 2;
return i; }
72 RangeIter
operator+(ptrdiff_t n)
const {
return RangeIter(ptr + 2 * n); }
73 RangeIter
operator-(ptrdiff_t n)
const {
return RangeIter(ptr + 2 * n); }
75 RangeIter &
operator+=(ptrdiff_t n) {
ptr += 2 * n;
return *
this; }
76 RangeIter &
operator-=(ptrdiff_t n) {
ptr -= 2 * n;
return *
this; }
78 friend RangeIter
operator+(ptrdiff_t n, RangeIter
const & i) {
return i + n; }
80 ptrdiff_t
operator-(RangeIter
const & i)
const {
return (ptr - i.ptr) / 2; }
83 bool operator==(RangeIter
const & i)
const {
return ptr == i.ptr; }
84 bool operator!=(RangeIter
const & i)
const {
return ptr != i.ptr; }
85 bool operator<(RangeIter
const & i)
const {
return ptr < i.ptr; }
86 bool operator>(RangeIter
const & i)
const {
return ptr > i.ptr; }
87 bool operator<=(RangeIter
const & i)
const {
return ptr <= i.ptr; }
88 bool operator>=(RangeIter
const & i)
const {
return ptr >= i.ptr; }
107 insert(std::get<0>(t), std::get<1>(t));
119 if (first <= last - 1) {
120 _insert(first, last);
133 struct Complementor {
135 Complementor(
RangeSet & s) :
set(s) { set.complement(); }
136 ~Complementor() { set.complement(); }
138 Complementor c(*
this);
147 result._intersect(_begin(), _end(), s._begin(), s._end());
158 result._intersect(_beginc(), _endc(), s._beginc(), s._endc());
168 result._intersect(_begin(), _end(), s._beginc(), s._endc());
178 }
else if (s.empty()) {
203 int astate = (*a == 0);
204 int bstate = (*
b == 0);
209 int state = astate ^ bstate;
214 result._offset = (state == 0);
216 while (a != aend &&
b != bend) {
221 bool ainc = (av <= bv);
222 bool binc = (bv <= av);
227 if (state != (astate ^ bstate)) {
228 result._ranges.push_back(minval + 1);
240 if ((aend[-1] == 0) == (bend[-1] == 0)) {
241 result._ranges.push_back(0);
255 if (first <= last - 1) {
257 return _intersectsOne(r, _begin(), _end());
260 return _intersectsOne(r, _begin(), _end()) ||
261 _intersectsOne(r + 2, _begin(), _end());
265 if (
empty() || s.empty()) {
268 return _intersects(_begin(), _end(), s._begin(), s._end());
278 if (first <= last - 1) {
280 return !_intersectsOne(r, _beginc(), _endc());
283 return !_intersectsOne(r, _beginc(), _endc()) &&
284 !_intersectsOne(r + 2, _beginc(), _endc());
288 if (s.empty() ||
full()) {
291 return !_intersects(_beginc(), _endc(), s._begin(), s._end());
295 if (
empty() || first == last) {
298 if (last <= first - 1) {
300 return !_intersectsOne(r, _begin(), _end());
303 return !_intersectsOne(r, _begin(), _end()) &&
304 !_intersectsOne(r + 2, _begin(), _end());
309 for (
auto r = _begin(), e = _end(); r != e; r += 2) {
316 if (
empty() || n == 0) {
318 }
else if (n >= 64) {
332 if (r[0] != 0 && first == 0) {
340 for (r += 2; last != 0 && r != rend; r += 2) {
362 if (
empty() || i == 1) {
369 auto r = _ranges.
begin();
370 auto rend = _ranges.
end();
371 for (; r < rend; ++r) {
373 if (value > overflowThreshold) {
380 _ranges.
erase(r, rend);
386 if (_ranges.
size() < 2) {
389 if (_ranges.
front() != 0 || _ranges.
back() != 0) {
393 for (
auto i = _ranges.
begin() + 1, e = _ranges.
end() - 1; i != e; ++i) {
412 _ranges.
assign(array + (first == 0), array + (4 - (last == 0)));
413 _offset = (first != 0);
414 }
else if (first >= rend[-2]) {
416 if (first <= rend[-1]) {
418 rend[-1] =
std::max(last - 1, rend[-1] - 1) + 1;
443 return u - 1 < v - 1;
463 }
else if (last == 0) {
498 if (a[0] > bend[-1] - 1 || a[1] - 1 <
b[0]) {
508 }
else if (a[0] <=
b[0] && a[1] - 1 >= bend[-1] - 1) {
516 _intersectOne(v, a,
b, bmid);
517 _intersectOne(v, a, bmid, bend);
539 _intersectOne(v, a,
b, bend);
540 }
else if (
b + 2 == bend) {
541 _intersectOne(v,
b, a, aend);
542 }
else if (a[0] <= bend[-1] - 1 && aend[-1] - 1 >=
b[0]) {
551 std::uint64_t const * amid = a + roundUpToEven((aend - a) >> 1);
553 _intersect(v, a, amid,
b, bmid);
554 _intersect(v, a, amid, bmid, bend);
555 _intersect(v, amid, aend,
b, bmid);
556 _intersect(v, amid, aend, bmid, bend);
565 if (a == aend ||
b == bend) {
572 _offset = ((*a != 0) || (*
b != 0));
574 _intersect(_ranges, a, aend,
b, bend);
575 if ((aend[-1] != 0) || (bend[-1] != 0)) {
588 if (a[0] > bend[-1] - 1 || a[1] - 1 <
b[0]) {
591 if (
b + 2 == bend || a[0] <=
b[0] || a[1] - 1 >= bend[-1] - 1) {
595 return _intersectsOne(a,
b, bmid) || _intersectsOne(a, bmid, bend);
607 return _intersectsOne(a,
b, bend);
610 return _intersectsOne(
b, a, aend);
612 if (a[0] > bend[-1] - 1 || aend[-1] - 1 <
b[0]) {
615 std::uint64_t const * amid = a + roundUpToEven((aend - a) >> 1);
617 return _intersects(a, amid,
b, bmid) ||
618 _intersects(a, amid, bmid, bend) ||
619 _intersects(amid, aend,
b, bmid) ||
620 _intersects(amid, aend, bmid, bend);
624 os <<
"{\"RangeSet\": [";
626 for (
auto const & t: s) {
631 os << '[' << std::get<0>(t) <<
", " << std::get<1>(t) <<
']';
This file provides a type for representing integer sets.
A RangeSet is a set of unsigned 64 bit integers.
RangeSet intersection(RangeSet const &s) const
intersection returns the intersection of this set and s.
std::uint64_t cardinality() const
cardinality returns the number of integers in this set.
void clear()
clear removes all integers from this set.
bool isValid() const
isValid checks that this RangeSet is in a valid state.
bool full() const
full checks whether all integers in the universe of range sets, [0, 2^64), are in this set.
RangeSet & scale(std::uint64_t i)
scale multiplies the endpoints of each range in this set by the given integer.
bool intersects(std::uint64_t u) const
RangeSet join(RangeSet const &s) const
join returns the union of this set and s.
bool empty() const
empty checks whether there are any integers in this set.
void erase(std::uint64_t u)
bool contains(std::uint64_t u) const
bool isWithin(std::uint64_t u) const
RangeSet()=default
The default constructor creates an empty set.
RangeSet & simplify(std::uint32_t n)
simplify simplifies this range set by "coarsening" its ranges.
void fill()
fill adds all the unsigned 64 bit integers to this set.
RangeSet difference(RangeSet const &s) const
difference returns the difference between this set and s.
RangeSet symmetricDifference(RangeSet const &s) const
symmetricDifference returns the symmetric difference of this set and s.
void insert(std::uint64_t u)
daf::base::PropertyList * list
daf::base::PropertySet * set
bool operator==(const String &lhs, const String &rhs)
std::shared_ptr< Image< PixelT > > operator+(Image< PixelT > const &img, ImageSlice< PixelT > const &slc)
Overload operator+()
Image< LhsPixelT > & operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e. pixel-by-pixel addition) where types are different.
Image< LhsPixelT > & operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Subtract lhs from Image rhs (i.e. pixel-by-pixel subtraction) where types are different.
std::shared_ptr< Image< PixelT > > operator-(Image< PixelT > const &img, ImageSlice< PixelT > const &slc)
Overload operator-()
void swap(RangeSet &a, RangeSet &b)
std::ostream & operator<<(std::ostream &, Angle const &)
Angle operator*(double a, Angle const &b)