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<std::uint64_t, std::uint64_t>;
133 using pointer = void;
134 using reference = std::tuple<std::uint64_t, std::uint64_t>;
135 using iterator_category = std::input_iterator_tag;
137 Iterator() =
default;
138 explicit Iterator(std::uint64_t
const * ptr) : p{ptr} {}
140 friend void swap(Iterator & a, Iterator & b) {
145 Iterator & operator++() { p += 2;
return *
this; }
146 Iterator & operator--() { p -= 2;
return *
this; }
148 Iterator operator++(
int) { Iterator i(*
this); p += 2;
return i; }
149 Iterator operator--(
int) { Iterator i(*
this); p -= 2;
return i; }
151 Iterator operator+(ptrdiff_t n)
const {
return Iterator(p + 2 * n); }
152 Iterator operator-(ptrdiff_t n)
const {
return Iterator(p + 2 * n); }
154 Iterator & operator+=(ptrdiff_t n) { p += 2 * n;
return *
this; }
155 Iterator & operator-=(ptrdiff_t n) { p -= 2 * n;
return *
this; }
157 friend Iterator operator+(ptrdiff_t n, Iterator
const & i) {
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<std::uint64_t, std::uint64_t> operator*() {
172 return std::make_tuple(p[0], p[1]);
175 std::tuple<std::uint64_t, std::uint64_t> operator[](ptrdiff_t n)
const {
176 return std::make_tuple(p[2 * n], p[2 * n + 1]);
179 std::uint64_t
const * p =
nullptr;
182 using difference_type = ptrdiff_t;
183 using size_type = size_t;
184 using value_type = std::tuple<std::uint64_t, std::uint64_t>;
187 RangeSet(RangeSet
const &) =
default;
189 RangeSet & operator=(RangeSet
const &) =
default;
190 RangeSet & operator=(RangeSet &&) =
default;
202 RangeSet(std::uint64_t first, std::uint64_t last) {
208 typename =
typename std::enable_if<
209 std::is_convertible<U, std::uint64_t>::value
212 explicit RangeSet(std::tuple<U, U>
const & range) {
213 insert(
static_cast<std::uint64_t
>(std::get<0>(range)),
214 static_cast<std::uint64_t
>(std::get<1>(range)));
217 RangeSet(std::initializer_list<std::uint64_t>);
225 RangeSet(std::initializer_list<std::pair<std::uint64_t, std::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, std::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(std::uint64_t first, std::uint64_t last);
319 typename =
typename std::enable_if<
320 std::is_convertible<U, std::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(std::uint64_t first, std::uint64_t last);
335 RangeSet &
complement() { _offset = !_offset;
return *
this; }
398 RangeSet r =
join(s);
434 bool intersects(std::uint64_t first, std::uint64_t last)
const;
444 bool contains(std::uint64_t first, std::uint64_t last)
const;
454 bool isWithin(std::uint64_t first, std::uint64_t last)
const;
464 bool isDisjointFrom(std::uint64_t first, std::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<std::uint64_t> _ranges = {0, 0};
575 std::uint64_t
const * _begin()
const {
return _ranges.data() + _offset; }
578 std::uint64_t
const * _end()
const {
579 size_t s = _ranges.
size();
580 return _ranges.data() + (s - ((s & 1) ^ _offset));
585 std::uint64_t
const * _beginc()
const {
return _ranges.data() + !_offset; }
589 std::uint64_t
const * _endc()
const {
590 size_t s = _ranges.size();
591 return _ranges.data() + (s - ((s & 1) ^ !_offset));
594 void _insert(std::uint64_t first, std::uint64_t last);
596 static void _intersectOne(std::vector<std::uint64_t> &,
597 std::uint64_t
const *,
598 std::uint64_t
const *, std::uint64_t
const *);
600 static void _intersect(std::vector<std::uint64_t> &,
601 std::uint64_t
const *, std::uint64_t
const *,
602 std::uint64_t
const *, std::uint64_t
const *);
604 void _intersect(std::uint64_t
const *, std::uint64_t
const *,
605 std::uint64_t
const *, std::uint64_t
const *);
607 static bool _intersectsOne(std::uint64_t
const *,
608 std::uint64_t
const *, std::uint64_t
const *);
610 static bool _intersects(std::uint64_t
const *, std::uint64_t
const *,
611 std::uint64_t
const *, std::uint64_t
const *);
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
std::uint64_t cardinality() const
Definition RangeSet.cc:307
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
RangeSet(std::uint64_t u)
Definition RangeSet.h:198
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 full() const
Definition RangeSet.h:518
RangeSet & scale(std::uint64_t i)
Definition RangeSet.cc:361
bool intersects(std::uint64_t u) const
Definition RangeSet.h:432
RangeSet(InputIterator a, InputIterator b)
Definition RangeSet.h:242
RangeSet & operator-=(RangeSet const &s)
Definition RangeSet.h:406
RangeSet join(RangeSet const &s) const
join returns the union of this set and s.
Definition RangeSet.cc:152
bool empty() const
empty checks whether there are any integers in this set.
Definition RangeSet.h:514
RangeSet & operator^=(RangeSet const &s)
Definition RangeSet.h:418
void erase(std::uint64_t u)
Definition RangeSet.h:313
bool contains(std::uint64_t u) const
Definition RangeSet.h:442
RangeSet & complement()
Definition RangeSet.h:335
Iterator endc() const
Definition RangeSet.h:540
bool isWithin(std::uint64_t u) const
Definition RangeSet.h:452
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 simplified(std::uint32_t n) const
simplified returns a simplified copy of this set.
Definition RangeSet.h:486
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
bool isDisjointFrom(std::uint64_t u) const
Definition RangeSet.h:462
RangeSet()=default
The default constructor creates an empty set.
RangeSet & simplify(std::uint32_t n)
Definition RangeSet.cc:315
void fill()
fill adds all the unsigned 64 bit integers to this set.
Definition RangeSet.h:511
RangeSet operator^(RangeSet const &s) const
The ^ operator returns the symmetric difference between this set and s.
Definition RangeSet.h:380
RangeSet scaled(std::uint64_t i) const
scaled returns a scaled copy of this set.
Definition RangeSet.h:501
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 symmetricDifference(RangeSet const &s) const
Definition RangeSet.cc:173
void insert(std::uint64_t u)
Definition RangeSet.h:292
Definition RangeSet.h:129