30#ifndef LSST_SPHGEOM_RANGESET_H_
31#define LSST_SPHGEOM_RANGESET_H_
38#include <initializer_list>
131 using difference_type = ptrdiff_t;
132 using value_type = std::tuple<uint64_t, uint64_t>;
133 using pointer = void;
134 using reference = std::tuple<uint64_t, uint64_t>;
135 using iterator_category = std::input_iterator_tag;
138 explicit Iterator(uint64_t
const * ptr) : p{ptr} {}
145 Iterator & operator++() { p += 2;
return *
this; }
146 Iterator & operator--() { p -= 2;
return *
this; }
154 Iterator & operator+=(ptrdiff_t n) { p += 2 * n;
return *
this; }
155 Iterator & operator-=(ptrdiff_t n) { p -= 2 * n;
return *
this; }
161 ptrdiff_t operator-(
Iterator const & i)
const {
return (p - i.p) / 2; }
164 bool operator==(
Iterator const & i)
const {
return p == i.p; }
165 bool operator!=(
Iterator const & i)
const {
return p != i.p; }
166 bool operator<(
Iterator const & i)
const {
return p < i.p; }
167 bool operator>(
Iterator const & i)
const {
return p > i.p; }
168 bool operator<=(
Iterator const & i)
const {
return p <= i.p; }
169 bool operator>=(
Iterator const & i)
const {
return p >= i.p; }
171 std::tuple<uint64_t, uint64_t> operator*() {
172 return std::make_tuple(p[0], p[1]);
175 std::tuple<uint64_t, uint64_t> operator[](ptrdiff_t n)
const {
176 return std::make_tuple(p[2 * n], p[2 * n + 1]);
179 uint64_t
const * p =
nullptr;
182 using difference_type = ptrdiff_t;
183 using size_type = size_t;
184 using value_type = std::tuple<uint64_t, uint64_t>;
202 RangeSet(uint64_t first, uint64_t last) {
208 typename =
typename std::enable_if<
209 std::is_convertible<U, uint64_t>::value
212 explicit RangeSet(std::tuple<U, U>
const & range) {
213 insert(
static_cast<uint64_t
>(std::get<0>(range)),
214 static_cast<uint64_t
>(std::get<1>(range)));
217 RangeSet(std::initializer_list<uint64_t>);
225 RangeSet(std::initializer_list<std::pair<uint64_t, uint64_t>>);
234 typename InputIterator,
235 typename =
typename std::enable_if<
237 std::input_iterator_tag,
238 typename std::iterator_traits<InputIterator>::iterator_category
243 for (; a != b; ++a) {
255 typename =
typename std::enable_if<
257 std::input_iterator_tag,
258 typename std::iterator_traits<
decltype(
259 std::begin(std::declval<
typename std::add_const<Container>::type>())
260 )>::iterator_category
264 std::input_iterator_tag,
265 typename std::iterator_traits<
decltype(
266 std::end(std::declval<
typename std::add_const<Container>::type>())
267 )>::iterator_category
272 RangeSet(std::begin(c), std::end(c)) {}
277 return _offset == rs._offset && _ranges == rs._ranges;
280 bool operator!=(
RangeSet const & rs)
const {
281 return _offset != rs._offset || _ranges != rs._ranges;
298 typename =
typename std::enable_if<
299 std::is_convertible<U, uint64_t>::value
302 void insert(std::tuple<U, U>
const & range) {
303 insert(std::get<0>(range), std::get<1>(range));
306 void insert(uint64_t first, uint64_t last);
319 typename =
typename std::enable_if<
320 std::is_convertible<U, uint64_t>::value
323 void erase(std::tuple<U, U>
const & range) {
324 erase(std::get<0>(range), std::get<1>(range));
327 void erase(uint64_t first, uint64_t last);
434 bool intersects(uint64_t first, uint64_t last)
const;
444 bool contains(uint64_t first, uint64_t last)
const;
454 bool isWithin(uint64_t first, uint64_t last)
const;
508 void clear() { _ranges = {0, 0}; _offset =
true; }
511 void fill() { _ranges = {0, 0}; _offset =
false; }
514 bool empty()
const {
return _begin() == _end(); }
518 bool full()
const {
return _beginc() == _endc(); }
524 Iterator cbegin()
const {
return begin(); }
531 Iterator cend()
const {
return end(); }
543 size_t max_size()
const {
return _ranges.max_size() / 2; }
546 size_t size()
const {
return (_ranges.size() - _offset) / 2; }
556 swap(_ranges, s._ranges);
557 swap(_offset, s._offset);
568 std::vector<uint64_t> _ranges = {0, 0};
575 uint64_t
const * _begin()
const {
return _ranges.data() + _offset; }
578 uint64_t
const * _end()
const {
579 size_t s = _ranges.
size();
580 return _ranges.data() + (s - ((s & 1) ^ _offset));
585 uint64_t
const * _beginc()
const {
return _ranges.data() + !_offset; }
589 uint64_t
const * _endc()
const {
590 size_t s = _ranges.size();
591 return _ranges.data() + (s - ((s & 1) ^ !_offset));
594 void _insert(uint64_t first, uint64_t last);
596 static void _intersectOne(std::vector<uint64_t> &,
598 uint64_t
const *, uint64_t
const *);
600 static void _intersect(std::vector<uint64_t> &,
601 uint64_t
const *, uint64_t
const *,
602 uint64_t
const *, uint64_t
const *);
604 void _intersect(uint64_t
const *, uint64_t
const *,
605 uint64_t
const *, uint64_t
const *);
607 static bool _intersectsOne(uint64_t
const *,
608 uint64_t
const *, uint64_t
const *);
610 static bool _intersects(uint64_t
const *, uint64_t
const *,
611 uint64_t
const *, uint64_t
const *);
615inline void swap(RangeSet & a, RangeSet & b) {
619std::ostream & operator<<(std::ostream &, RangeSet
const &);
Definition RangeSet.h:106
RangeSet intersection(RangeSet const &s) const
intersection returns the intersection of this set and s.
Definition RangeSet.cc:142
bool intersects(uint64_t u) const
Definition RangeSet.h:432
RangeSet operator-(RangeSet const &s) const
The - operator returns the difference between this set and s.
Definition RangeSet.h:375
RangeSet operator~() const
The ~ operator returns the complement of this set.
Definition RangeSet.h:358
void clear()
clear removes all integers from this set.
Definition RangeSet.h:508
Iterator beginc() const
Definition RangeSet.h:536
bool isValid() const
Definition RangeSet.cc:384
size_t max_size() const
max_size returns the maximum number of ranges a set can hold.
Definition RangeSet.h:543
Iterator end() const
Definition RangeSet.h:530
RangeSet & operator|=(RangeSet const &s)
Definition RangeSet.h:396
bool isWithin(uint64_t u) const
Definition RangeSet.h:452
void insert(uint64_t u)
Definition RangeSet.h:292
bool full() const
Definition RangeSet.h:518
RangeSet(InputIterator a, InputIterator b)
Definition RangeSet.h:242
RangeSet & operator-=(RangeSet const &s)
Definition RangeSet.h:406
bool contains(uint64_t u) const
Definition RangeSet.h:442
RangeSet join(RangeSet const &s) const
join returns the union of this set and s.
Definition RangeSet.cc:152
RangeSet & scale(uint64_t i)
Definition RangeSet.cc:361
bool isDisjointFrom(uint64_t u) const
Definition RangeSet.h:462
RangeSet simplified(uint32_t n) const
simplified returns a simplified copy of this set.
Definition RangeSet.h:486
bool empty() const
empty checks whether there are any integers in this set.
Definition RangeSet.h:514
RangeSet scaled(uint64_t i) const
scaled returns a scaled copy of this set.
Definition RangeSet.h:501
RangeSet & operator^=(RangeSet const &s)
Definition RangeSet.h:418
RangeSet & complement()
Definition RangeSet.h:335
Iterator endc() const
Definition RangeSet.h:540
RangeSet operator|(RangeSet const &s) const
The | operator returns the union of this set and s.
Definition RangeSet.h:370
Iterator begin() const
Definition RangeSet.h:523
RangeSet operator&(RangeSet const &s) const
The & operator returns the intersection of this set and s.
Definition RangeSet.h:365
size_t size() const
size returns the number of ranges in this set.
Definition RangeSet.h:546
RangeSet & operator&=(RangeSet const &s)
Definition RangeSet.h:386
RangeSet(Container const &c)
Definition RangeSet.h:271
RangeSet()=default
The default constructor creates an empty set.
void fill()
fill adds all the unsigned 64 bit integers to this set.
Definition RangeSet.h:511
RangeSet(uint64_t u)
Definition RangeSet.h:198
void erase(uint64_t u)
Definition RangeSet.h:313
RangeSet operator^(RangeSet const &s) const
The ^ operator returns the symmetric difference between this set and s.
Definition RangeSet.h:380
RangeSet complemented() const
complemented returns a complemented copy of this set.
Definition RangeSet.h:338
bool operator==(RangeSet const &rs) const
Definition RangeSet.h:276
RangeSet difference(RangeSet const &s) const
difference returns the difference between this set and s.
Definition RangeSet.cc:164
RangeSet & simplify(uint32_t n)
Definition RangeSet.cc:315
uint64_t cardinality() const
Definition RangeSet.cc:307
RangeSet symmetricDifference(RangeSet const &s) const
Definition RangeSet.cc:173
Definition RangeSet.h:129