LSST Applications g063fba187b+fee0456c91,g0f08755f38+ea96e5a5a3,g1653933729+a8ce1bb630,g168dd56ebc+a8ce1bb630,g1a2382251a+90257ff92a,g20f6ffc8e0+ea96e5a5a3,g217e2c1bcf+937a289c59,g28da252d5a+daa7da44eb,g2bbee38e9b+253935c60e,g2bc492864f+253935c60e,g3156d2b45e+6e55a43351,g32e5bea42b+31359a2a7a,g347aa1857d+253935c60e,g35bb328faa+a8ce1bb630,g3a166c0a6a+253935c60e,g3b1af351f3+a8ce1bb630,g3e281a1b8c+c5dd892a6c,g414038480c+416496e02f,g41af890bb2+afe91b1188,g599934f4f4+0db33f7991,g7af13505b9+e36de7bce6,g80478fca09+da231ba887,g82479be7b0+a4516e59e3,g858d7b2824+ea96e5a5a3,g89c8672015+f4add4ffd5,g9125e01d80+a8ce1bb630,ga5288a1d22+bc6ab8dfbd,gb58c049af0+d64f4d3760,gc28159a63d+253935c60e,gcab2d0539d+3f2b72788c,gcf0d15dbbd+4ea9c45075,gda6a2b7d83+4ea9c45075,gdaeeff99f8+1711a396fd,ge79ae78c31+253935c60e,gef2f8181fd+3031e3cf99,gf0baf85859+c1f95f4921,gfa517265be+ea96e5a5a3,gfa999e8aa5+17cd334064,w.2024.50
LSST Data Management Base Package
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | List of all members
lsst::sphgeom::RangeSet Class Reference

A RangeSet is a set of unsigned 64 bit integers. More...

#include <RangeSet.h>

Classes

struct  Iterator
 A constant iterator over the ranges (represented as 2-tuples) in a RangeSet. More...
 

Public Types

using difference_type = ptrdiff_t
 
using size_type = size_t
 
using value_type = std::tuple<std::uint64_t, std::uint64_t>
 
using const_iterator = Iterator
 

Public Member Functions

 RangeSet (RangeSet const &)=default
 
 RangeSet (RangeSet &&)=default
 
RangeSetoperator= (RangeSet const &)=default
 
RangeSetoperator= (RangeSet &&)=default
 
 RangeSet ()=default
 The default constructor creates an empty set.
 
template<typename InputIterator , typename = typename std::enable_if< std::is_base_of< std::input_iterator_tag, typename std::iterator_traits<InputIterator>::iterator_category >::value >::type>
 RangeSet (InputIterator a, InputIterator b)
 This generic constructor creates a set containing the integers or ranges obtained by dereferencing the iterators in [a, b).
 
template<typename Container , typename = typename std::enable_if< std::is_base_of< std::input_iterator_tag, typename std::iterator_traits<decltype( std::begin(std::declval<typename std::add_const<Container>::type>()) )>::iterator_category, ::value &&std::is_base_of< std::input_iterator_tag, typename std::iterator_traits< decltype(std::end(std::declval< typename std::add_const< Container >::type >()))>::iterator_category , ::value , ::type >
 RangeSet (Container const &c)
 This generic constructor creates a set containing the integers or integer ranges in the given container.
 
RangeSetsimplify (std::uint32_t n)
 simplify simplifies this range set by "coarsening" its ranges.
 
RangeSet simplified (std::uint32_t n) const
 simplified returns a simplified copy of this set.
 
RangeSetscale (std::uint64_t i)
 scale multiplies the endpoints of each range in this set by the given integer.
 
RangeSet scaled (std::uint64_t i) const
 scaled returns a scaled copy of this set.
 
void clear ()
 clear removes all integers from this set.
 
void fill ()
 fill adds all the unsigned 64 bit integers to this set.
 
bool empty () const
 empty checks whether there are any integers in this set.
 
bool full () const
 full checks whether all integers in the universe of range sets, [0, 2^64), are in this set.
 
Iterator beginc () const
 beginc returns a constant iterator to the first range in the complement of this set.
 
Iterator endc () const
 endc returns a constant iterator to to the range after the last one in the complement of this set.
 
size_t max_size () const
 max_size returns the maximum number of ranges a set can hold.
 
size_t size () const
 size returns the number of ranges in this set.
 
std::uint64_t cardinality () const
 cardinality returns the number of integers in this set.
 
void swap (RangeSet &s)
 
bool isValid () const
 isValid checks that this RangeSet is in a valid state.
 
 RangeSet (std::uint64_t u)
 
 RangeSet (std::uint64_t first, std::uint64_t last)
 
template<typename U , typename = typename std::enable_if< std::is_convertible<U, std::uint64_t>::value >::type>
 RangeSet (std::tuple< U, U > const &range)
 
 RangeSet (std::initializer_list< std::uint64_t >)
 
 RangeSet (std::initializer_list< std::pair< std::uint64_t, std::uint64_t > >)
 
bool operator== (RangeSet const &rs) const
 
bool operator!= (RangeSet const &rs) const
 
void insert (std::uint64_t u)
 
template<typename U , typename = typename std::enable_if< std::is_convertible<U, std::uint64_t>::value >::type>
void insert (std::tuple< U, U > const &range)
 
void insert (std::uint64_t first, std::uint64_t last)
 
void erase (std::uint64_t u)
 
template<typename U , typename = typename std::enable_if< std::is_convertible<U, std::uint64_t>::value >::type>
void erase (std::tuple< U, U > const &range)
 
void erase (std::uint64_t first, std::uint64_t last)
 
Set operations
RangeSetcomplement ()
 complement replaces this set S with U ∖ S, where U is the universe of range sets, [0, 2^64).
 
RangeSet complemented () const
 complemented returns a complemented copy of this set.
 
RangeSet intersection (RangeSet const &s) const
 intersection returns the intersection of this set and s.
 
RangeSet join (RangeSet const &s) const
 join returns the union of this set and s.
 
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.
 
RangeSet operator~ () const
 The ~ operator returns the complement of this set.
 
RangeSet operator& (RangeSet const &s) const
 The & operator returns the intersection of this set and s.
 
RangeSet operator| (RangeSet const &s) const
 The | operator returns the union of this set and s.
 
RangeSet operator- (RangeSet const &s) const
 The - operator returns the difference between this set and s.
 
RangeSet operator^ (RangeSet const &s) const
 The ^ operator returns the symmetric difference between this set and s.
 
RangeSetoperator&= (RangeSet const &s)
 The &= operator assigns the intersection of this set and s to this set.
 
RangeSetoperator|= (RangeSet const &s)
 The |= operator assigns the union of this set and s to this set.
 
RangeSetoperator-= (RangeSet const &s)
 The -= operator assigns the difference between this set and s to this set.
 
RangeSetoperator^= (RangeSet const &s)
 The ^= operator assigns the symmetric difference between this set and s to this set.
 
bool intersects (std::uint64_t u) const
 
bool intersects (std::uint64_t first, std::uint64_t last) const
 
bool intersects (RangeSet const &s) const
 
bool contains (std::uint64_t u) const
 
bool contains (std::uint64_t first, std::uint64_t last) const
 
bool contains (RangeSet const &s) const
 
bool isWithin (std::uint64_t u) const
 
bool isWithin (std::uint64_t first, std::uint64_t last) const
 
bool isWithin (RangeSet const &s) const
 
bool isDisjointFrom (std::uint64_t u) const
 
bool isDisjointFrom (std::uint64_t first, std::uint64_t last) const
 
bool isDisjointFrom (RangeSet const &s) const
 
Iterator begin () const
 
Iterator cbegin () const
 
Iterator end () const
 
Iterator cend () const
 

Detailed Description

A RangeSet is a set of unsigned 64 bit integers.

Internally, elements in the set are tracked using a sorted vector of disjoint, non-empty, half-open ranges, which is memory efficient for sets containing many consecutive integers.

Given a hierarchical pixelization of the sphere and a simple spherical region, a RangeSet is a good way to store the indexes of pixels intersecting the region. For an in-depth discussion of this use case, see:

‍Efficient data structures for masks on 2D grids M. Reinecke and E. Hivon Astronomy & Astrophysics, Volume 580, id.A132, 9 pp.

http://www.aanda.org/articles/aa/abs/2015/08/aa26549-15/aa26549-15.html

The beginning and end points of the disjoint, non-empty, half-open integer ranges in the set are stored in a std::vector<std::uint64_t>, with monotonically increasing values, except for the last one. Each pair of consecutive elements [begin, end) in the vector is a non-empty half-open range, where the value of end is defined as the integer obtained by adding one to the largest element in the range.

Mathematically, a half-open range with largest element equal to 2^64 - 1 would have an end point of 2^64. But arithmetic for unsigned 64 bit integers is modular, and adding 1 to 2^64 - 1 "wraps around" to 0. So in practice, ranges containing the largest std::uint64_t value have an end point of 0. Note that overflow is undefined for signed integers, which motivates the use of unsigned 64 bit integers for this class.

The first and last values of the internal vector are are always 0, even if no range in the set has a beginning or end point of 0. To illustrate why, consider the contents of the vector for a set containing a single integer, 3:

[0, 3, 4, 0]

The range obtained by extracting pairs of elements from the vector starting at index 1 is [3, 4), which corresponds to the contents of the set. The ranges obtained by starting at index 0 are [0, 3) and [4, 0). They correspond to the unsigned 64 bit integers not in the set.

The use of bookended half open ranges means that simply toggling the index of the first range between 0 and 1 corresponds to complementing the set. This allows many simplifications in the implementation - for example, set union and difference can be implemented in terms of set intersection and complement, since A ∪ B = ¬(¬A ∩ ¬B) and A ∖ B = A ∩ ¬B.

Many of the RangeSet methods accept ranges of integers [first, last) as input, either directly or in the form of a tuple. The values in a range are generated by starting with a value equal to first, and incrementing it until last is reached. If first == last, the range is full (it contains all possible std::uint64_t values), and if first > last, it wraps around - that is, it contains all std::uint64_t values except for [last, first).

The ranges in a set can be iterated over. Set modification may invalidate all iterators.

Definition at line 106 of file RangeSet.h.

Member Typedef Documentation

◆ const_iterator

Definition at line 185 of file RangeSet.h.

◆ difference_type

Definition at line 182 of file RangeSet.h.

◆ size_type

Definition at line 183 of file RangeSet.h.

◆ value_type

Definition at line 184 of file RangeSet.h.

Constructor & Destructor Documentation

◆ RangeSet() [1/10]

lsst::sphgeom::RangeSet::RangeSet ( RangeSet const & )
default

◆ RangeSet() [2/10]

lsst::sphgeom::RangeSet::RangeSet ( RangeSet && )
default

◆ RangeSet() [3/10]

lsst::sphgeom::RangeSet::RangeSet ( )
default

The default constructor creates an empty set.

◆ RangeSet() [4/10]

lsst::sphgeom::RangeSet::RangeSet ( std::uint64_t u)
inlineexplicit

This constructor creates a set containing the given integer(s) or integer range(s).

Definition at line 198 of file RangeSet.h.

198 {
199 insert(u);
200 }
void insert(std::uint64_t u)
Definition RangeSet.h:292

◆ RangeSet() [5/10]

lsst::sphgeom::RangeSet::RangeSet ( std::uint64_t first,
std::uint64_t last )
inline

This constructor creates a set containing the given integer(s) or integer range(s).

Definition at line 202 of file RangeSet.h.

202 {
203 insert(first, last);
204 }

◆ RangeSet() [6/10]

template<typename U , typename = typename std::enable_if< std::is_convertible<U, std::uint64_t>::value >::type>
lsst::sphgeom::RangeSet::RangeSet ( std::tuple< U, U > const & range)
inlineexplicit

This constructor creates a set containing the given integer(s) or integer range(s).

Definition at line 212 of file RangeSet.h.

212 {
213 insert(static_cast<std::uint64_t>(std::get<0>(range)),
214 static_cast<std::uint64_t>(std::get<1>(range)));
215 }

◆ RangeSet() [7/10]

lsst::sphgeom::RangeSet::RangeSet ( std::initializer_list< std::uint64_t > list)

This constructor creates a set containing the given integer(s) or integer range(s).

Definition at line 101 of file RangeSet.cc.

101 :
102 RangeSet(list.begin(), list.end())
103{}
RangeSet()=default
The default constructor creates an empty set.

◆ RangeSet() [8/10]

lsst::sphgeom::RangeSet::RangeSet ( std::initializer_list< std::pair< std::uint64_t, std::uint64_t > > list)

This constructor creates a set containing the given integer(s) or integer range(s).

Definition at line 105 of file RangeSet.cc.

105 {
106 for (auto t: list) {
107 insert(std::get<0>(t), std::get<1>(t));
108 }
109}

◆ RangeSet() [9/10]

template<typename InputIterator , typename = typename std::enable_if< std::is_base_of< std::input_iterator_tag, typename std::iterator_traits<InputIterator>::iterator_category >::value >::type>
lsst::sphgeom::RangeSet::RangeSet ( InputIterator a,
InputIterator b )
inline

This generic constructor creates a set containing the integers or ranges obtained by dereferencing the iterators in [a, b).

It is hidden via SFINAE if InputIterator is not a standard input iterator.

Definition at line 242 of file RangeSet.h.

242 {
243 for (; a != b; ++a) {
244 insert(*a);
245 }
246 }
table::Key< int > b
table::Key< int > a

◆ RangeSet() [10/10]

template<typename Container , typename = typename std::enable_if< std::is_base_of< std::input_iterator_tag, typename std::iterator_traits<decltype( std::begin(std::declval<typename std::add_const<Container>::type>()) )>::iterator_category, ::value &&std::is_base_of< std::input_iterator_tag, typename std::iterator_traits< decltype(std::end(std::declval< typename std::add_const< Container >::type >()))>::iterator_category , ::value , ::type >
lsst::sphgeom::RangeSet::RangeSet ( Container const & c)
inlineexplicit

This generic constructor creates a set containing the integers or integer ranges in the given container.

It is hidden via SFINAE if Container does not provide constant input iterators over its elements.

Definition at line 271 of file RangeSet.h.

271 :
272 RangeSet(std::begin(c), std::end(c)) {}
T begin(T... args)
T end(T... args)

Member Function Documentation

◆ begin()

Iterator lsst::sphgeom::RangeSet::begin ( ) const
inline

This function returns a constant iterator to the first range in this set.

Definition at line 523 of file RangeSet.h.

523{ return Iterator(_begin()); }

◆ beginc()

Iterator lsst::sphgeom::RangeSet::beginc ( ) const
inline

beginc returns a constant iterator to the first range in the complement of this set.

Definition at line 536 of file RangeSet.h.

536{ return Iterator(_beginc()); }

◆ cardinality()

std::uint64_t lsst::sphgeom::RangeSet::cardinality ( ) const

cardinality returns the number of integers in this set.

Note that 0 is returned both for full and empty sets (a full set contains 2^64 integers, which is 0 modulo 2^64).

Definition at line 307 of file RangeSet.cc.

307 {
308 std::uint64_t sz = 0;
309 for (auto r = _begin(), e = _end(); r != e; r += 2) {
310 sz += r[1] - r[0];
311 }
312 return sz;
313}

◆ cbegin()

Iterator lsst::sphgeom::RangeSet::cbegin ( ) const
inline

This function returns a constant iterator to the first range in this set.

Definition at line 524 of file RangeSet.h.

524{ return begin(); }
Iterator begin() const
Definition RangeSet.h:523

◆ cend()

Iterator lsst::sphgeom::RangeSet::cend ( ) const
inline

This function returns a constant iterator to the range after the last one in this set.

Definition at line 531 of file RangeSet.h.

531{ return end(); }
Iterator end() const
Definition RangeSet.h:530

◆ clear()

void lsst::sphgeom::RangeSet::clear ( )
inline

clear removes all integers from this set.

Definition at line 508 of file RangeSet.h.

508{ _ranges = {0, 0}; _offset = true; }

◆ complement()

RangeSet & lsst::sphgeom::RangeSet::complement ( )
inline

complement replaces this set S with U ∖ S, where U is the universe of range sets, [0, 2^64).

It runs in constant time.

Definition at line 335 of file RangeSet.h.

335{ _offset = !_offset; return *this; }

◆ complemented()

RangeSet lsst::sphgeom::RangeSet::complemented ( ) const
inline

complemented returns a complemented copy of this set.

Definition at line 338 of file RangeSet.h.

338 {
339 RangeSet s(*this);
340 s.complement();
341 return s;
342 }

◆ contains() [1/3]

bool lsst::sphgeom::RangeSet::contains ( RangeSet const & s) const

contains returns true iff every one of the given integers is in this set.

Definition at line 287 of file RangeSet.cc.

287 {
288 if (s.empty() || full()) {
289 return true;
290 }
291 return !_intersects(_beginc(), _endc(), s._begin(), s._end());
292}
bool full() const
full checks whether all integers in the universe of range sets, [0, 2^64), are in this set.
Definition RangeSet.h:518

◆ contains() [2/3]

bool lsst::sphgeom::RangeSet::contains ( std::uint64_t first,
std::uint64_t last ) const

contains returns true iff every one of the given integers is in this set.

Definition at line 271 of file RangeSet.cc.

271 {
272 if (full()) {
273 return true;
274 }
275 if (first == last) {
276 return false;
277 }
278 if (first <= last - 1) {
279 std::uint64_t r[2] = {first, last};
280 return !_intersectsOne(r, _beginc(), _endc());
281 }
282 std::uint64_t r[4] = {0, last, first, 0};
283 return !_intersectsOne(r, _beginc(), _endc()) &&
284 !_intersectsOne(r + 2, _beginc(), _endc());
285}

◆ contains() [3/3]

bool lsst::sphgeom::RangeSet::contains ( std::uint64_t u) const
inline

contains returns true iff every one of the given integers is in this set.

Definition at line 442 of file RangeSet.h.

442{ return contains(u, u + 1); }
bool contains(std::uint64_t u) const
Definition RangeSet.h:442

◆ difference()

RangeSet lsst::sphgeom::RangeSet::difference ( RangeSet const & s) const

difference returns the difference between this set and s.

Definition at line 164 of file RangeSet.cc.

164 {
165 RangeSet result;
166 if (this != &s) {
167 // A ∖ B = A ∩ ¬B
168 result._intersect(_begin(), _end(), s._beginc(), s._endc());
169 }
170 return result;
171}
py::object result
Definition _schema.cc:429

◆ empty()

bool lsst::sphgeom::RangeSet::empty ( ) const
inline

empty checks whether there are any integers in this set.

Definition at line 514 of file RangeSet.h.

514{ return _begin() == _end(); }

◆ end()

Iterator lsst::sphgeom::RangeSet::end ( ) const
inline

This function returns a constant iterator to the range after the last one in this set.

Definition at line 530 of file RangeSet.h.

530{ return Iterator(_end()); }

◆ endc()

Iterator lsst::sphgeom::RangeSet::endc ( ) const
inline

endc returns a constant iterator to to the range after the last one in the complement of this set.

Definition at line 540 of file RangeSet.h.

540{ return Iterator(_endc()); }

◆ erase() [1/3]

template<typename U , typename = typename std::enable_if< std::is_convertible<U, std::uint64_t>::value >::type>
void lsst::sphgeom::RangeSet::erase ( std::tuple< U, U > const & range)
inline

erase removes the given integers from this set.

The strong exception safety guarantee is provided.

Definition at line 323 of file RangeSet.h.

323 {
324 erase(std::get<0>(range), std::get<1>(range));
325 }
void erase(std::uint64_t u)
Definition RangeSet.h:313

◆ erase() [2/3]

void lsst::sphgeom::RangeSet::erase ( std::uint64_t first,
std::uint64_t last )

erase removes the given integers from this set.

The strong exception safety guarantee is provided.

Definition at line 128 of file RangeSet.cc.

128 {
129 // To erase [first, last), insert it into the complement of this set,
130 // then complement the result. The complements are performed in the
131 // constructor and destructor of a local object, so that the second
132 // complement is executed even if insert throws.
133 struct Complementor {
134 RangeSet & set;
135 Complementor(RangeSet & s) : set(s) { set.complement(); }
136 ~Complementor() { set.complement(); }
137 };
138 Complementor c(*this);
139 insert(first, last);
140}
daf::base::PropertySet * set
Definition fits.cc:931

◆ erase() [3/3]

void lsst::sphgeom::RangeSet::erase ( std::uint64_t u)
inline

erase removes the given integers from this set.

The strong exception safety guarantee is provided.

Definition at line 313 of file RangeSet.h.

313 {
314 erase(u, u + 1);
315 }

◆ fill()

void lsst::sphgeom::RangeSet::fill ( )
inline

fill adds all the unsigned 64 bit integers to this set.

Definition at line 511 of file RangeSet.h.

511{ _ranges = {0, 0}; _offset = false; }

◆ full()

bool lsst::sphgeom::RangeSet::full ( ) const
inline

full checks whether all integers in the universe of range sets, [0, 2^64), are in this set.

Definition at line 518 of file RangeSet.h.

518{ return _beginc() == _endc(); }

◆ insert() [1/3]

template<typename U , typename = typename std::enable_if< std::is_convertible<U, std::uint64_t>::value >::type>
void lsst::sphgeom::RangeSet::insert ( std::tuple< U, U > const & range)
inline

insert adds the given integer(s) to this set.

It is strongly exception safe, and runs in amortized constant time if the given integers extend or follow the last (largest) range in this set. Otherwise, the worst case run time is O(N), where N is the number of ranges in the set.

Definition at line 302 of file RangeSet.h.

302 {
303 insert(std::get<0>(range), std::get<1>(range));
304 }

◆ insert() [2/3]

void lsst::sphgeom::RangeSet::insert ( std::uint64_t first,
std::uint64_t last )

insert adds the given integer(s) to this set.

It is strongly exception safe, and runs in amortized constant time if the given integers extend or follow the last (largest) range in this set. Otherwise, the worst case run time is O(N), where N is the number of ranges in the set.

Definition at line 111 of file RangeSet.cc.

111 {
112 if (first == last) {
113 fill();
114 } else {
115 // Ensure that there is enough space for 2 new values in _ranges.
116 // Afterwards, none of the possible modifications of _ranges will throw,
117 // so the strong exception safety guarantee is provided.
118 _ranges.reserve(_ranges.size() + 2);
119 if (first <= last - 1) {
120 _insert(first, last);
121 } else {
122 _insert(0, last);
123 _insert(first, 0);
124 }
125 }
126}
void fill()
fill adds all the unsigned 64 bit integers to this set.
Definition RangeSet.h:511
T reserve(T... args)
T size(T... args)

◆ insert() [3/3]

void lsst::sphgeom::RangeSet::insert ( std::uint64_t u)
inline

insert adds the given integer(s) to this set.

It is strongly exception safe, and runs in amortized constant time if the given integers extend or follow the last (largest) range in this set. Otherwise, the worst case run time is O(N), where N is the number of ranges in the set.

Definition at line 292 of file RangeSet.h.

292 {
293 insert(u, u + 1);
294 }

◆ intersection()

RangeSet lsst::sphgeom::RangeSet::intersection ( RangeSet const & s) const

intersection returns the intersection of this set and s.

Definition at line 142 of file RangeSet.cc.

142 {
143 RangeSet result;
144 if (this == &s) {
145 result = s;
146 } else {
147 result._intersect(_begin(), _end(), s._begin(), s._end());
148 }
149 return result;
150}

◆ intersects() [1/3]

bool lsst::sphgeom::RangeSet::intersects ( RangeSet const & s) const

intersects returns true iff the intersection of this set and the given integers is non-empty.

Definition at line 264 of file RangeSet.cc.

264 {
265 if (empty() || s.empty()) {
266 return false;
267 }
268 return _intersects(_begin(), _end(), s._begin(), s._end());
269}
bool empty() const
empty checks whether there are any integers in this set.
Definition RangeSet.h:514

◆ intersects() [2/3]

bool lsst::sphgeom::RangeSet::intersects ( std::uint64_t first,
std::uint64_t last ) const

intersects returns true iff the intersection of this set and the given integers is non-empty.

Definition at line 248 of file RangeSet.cc.

248 {
249 if (empty()) {
250 return false;
251 }
252 if (first == last) {
253 return true;
254 }
255 if (first <= last - 1) {
256 std::uint64_t r[2] = {first, last};
257 return _intersectsOne(r, _begin(), _end());
258 }
259 std::uint64_t r[4] = {0, last, first, 0};
260 return _intersectsOne(r, _begin(), _end()) ||
261 _intersectsOne(r + 2, _begin(), _end());
262}

◆ intersects() [3/3]

bool lsst::sphgeom::RangeSet::intersects ( std::uint64_t u) const
inline

intersects returns true iff the intersection of this set and the given integers is non-empty.

Definition at line 432 of file RangeSet.h.

432{ return intersects(u, u + 1); }
bool intersects(std::uint64_t u) const
Definition RangeSet.h:432

◆ isDisjointFrom() [1/3]

bool lsst::sphgeom::RangeSet::isDisjointFrom ( RangeSet const & s) const
inline

isDisjointFrom returns true iff the intersection of this set and the given integers is empty.

Definition at line 468 of file RangeSet.h.

468{ return !intersects(s); }

◆ isDisjointFrom() [2/3]

bool lsst::sphgeom::RangeSet::isDisjointFrom ( std::uint64_t first,
std::uint64_t last ) const
inline

isDisjointFrom returns true iff the intersection of this set and the given integers is empty.

Definition at line 464 of file RangeSet.h.

464 {
465 return !intersects(first, last);
466 }

◆ isDisjointFrom() [3/3]

bool lsst::sphgeom::RangeSet::isDisjointFrom ( std::uint64_t u) const
inline

isDisjointFrom returns true iff the intersection of this set and the given integers is empty.

Definition at line 462 of file RangeSet.h.

462{ return !intersects(u); }

◆ isValid()

bool lsst::sphgeom::RangeSet::isValid ( ) const

isValid checks that this RangeSet is in a valid state.

It is intended for use by unit tests, but calling it in other contexts is harmless. A return value of false means the RangeSet implementation isn't preserving its invariants, i.e. has a bug.

Definition at line 384 of file RangeSet.cc.

384 {
385 // Bookends are mandatory.
386 if (_ranges.size() < 2) {
387 return false;
388 }
389 if (_ranges.front() != 0 || _ranges.back() != 0) {
390 return false;
391 }
392 // Values except the last one must be monotonically increasing.
393 for (auto i = _ranges.begin() + 1, e = _ranges.end() - 1; i != e; ++i) {
394 if (i[0] <= i[-1]) {
395 return false;
396 }
397 }
398 return true;
399}
T back(T... args)
T front(T... args)

◆ isWithin() [1/3]

bool lsst::sphgeom::RangeSet::isWithin ( RangeSet const & s) const
inline

isWithin returns true iff every integer in this set is also one of the given integers.

Definition at line 456 of file RangeSet.h.

456{ return s.contains(*this); }

◆ isWithin() [2/3]

bool lsst::sphgeom::RangeSet::isWithin ( std::uint64_t first,
std::uint64_t last ) const

isWithin returns true iff every integer in this set is also one of the given integers.

Definition at line 294 of file RangeSet.cc.

294 {
295 if (empty() || first == last) {
296 return true;
297 }
298 if (last <= first - 1) {
299 std::uint64_t r[2] = {last, first};
300 return !_intersectsOne(r, _begin(), _end());
301 }
302 std::uint64_t r[4] = {0, first, last, 0};
303 return !_intersectsOne(r, _begin(), _end()) &&
304 !_intersectsOne(r + 2, _begin(), _end());
305}

◆ isWithin() [3/3]

bool lsst::sphgeom::RangeSet::isWithin ( std::uint64_t u) const
inline

isWithin returns true iff every integer in this set is also one of the given integers.

Definition at line 452 of file RangeSet.h.

452{ return isWithin(u, u + 1); }
bool isWithin(std::uint64_t u) const
Definition RangeSet.h:452

◆ join()

RangeSet lsst::sphgeom::RangeSet::join ( RangeSet const & s) const

join returns the union of this set and s.

Definition at line 152 of file RangeSet.cc.

152 {
153 RangeSet result;
154 if (this == &s) {
155 result = s;
156 } else {
157 // A ∪ B = ¬(¬A ∩ ¬B)
158 result._intersect(_beginc(), _endc(), s._beginc(), s._endc());
159 result.complement();
160 }
161 return result;
162}

◆ max_size()

size_t lsst::sphgeom::RangeSet::max_size ( ) const
inline

max_size returns the maximum number of ranges a set can hold.

Definition at line 543 of file RangeSet.h.

543{ return _ranges.max_size() / 2; }
T max_size(T... args)

◆ operator!=()

bool lsst::sphgeom::RangeSet::operator!= ( RangeSet const & rs) const
inline

Two RangeSet instances are equal iff they contain the same integers.

Definition at line 280 of file RangeSet.h.

280 {
281 return _offset != rs._offset || _ranges != rs._ranges;
282 }

◆ operator&()

RangeSet lsst::sphgeom::RangeSet::operator& ( RangeSet const & s) const
inline

The & operator returns the intersection of this set and s.

Definition at line 365 of file RangeSet.h.

365 {
366 return intersection(s);
367 }
RangeSet intersection(RangeSet const &s) const
intersection returns the intersection of this set and s.
Definition RangeSet.cc:142

◆ operator&=()

RangeSet & lsst::sphgeom::RangeSet::operator&= ( RangeSet const & s)
inline

The &= operator assigns the intersection of this set and s to this set.

It is strongly exception safe.

Definition at line 386 of file RangeSet.h.

386 {
387 if (this != &s) {
388 RangeSet r = intersection(s);
389 swap(r);
390 }
391 return *this;
392 }
void swap(RangeSet &s)
Definition RangeSet.h:554

◆ operator-()

RangeSet lsst::sphgeom::RangeSet::operator- ( RangeSet const & s) const
inline

The - operator returns the difference between this set and s.

Definition at line 375 of file RangeSet.h.

375 {
376 return difference(s);
377 }
RangeSet difference(RangeSet const &s) const
difference returns the difference between this set and s.
Definition RangeSet.cc:164

◆ operator-=()

RangeSet & lsst::sphgeom::RangeSet::operator-= ( RangeSet const & s)
inline

The -= operator assigns the difference between this set and s to this set.

It is strongly exception safe.

Definition at line 406 of file RangeSet.h.

406 {
407 if (this != &s) {
408 RangeSet r = difference(s);
409 swap(r);
410 } else {
411 clear();
412 }
413 return *this;
414 }
void clear()
clear removes all integers from this set.
Definition RangeSet.h:508

◆ operator=() [1/2]

RangeSet & lsst::sphgeom::RangeSet::operator= ( RangeSet && )
default

◆ operator=() [2/2]

RangeSet & lsst::sphgeom::RangeSet::operator= ( RangeSet const & )
default

◆ operator==()

bool lsst::sphgeom::RangeSet::operator== ( RangeSet const & rs) const
inline

Two RangeSet instances are equal iff they contain the same integers.

Definition at line 276 of file RangeSet.h.

276 {
277 return _offset == rs._offset && _ranges == rs._ranges;
278 }

◆ operator^()

RangeSet lsst::sphgeom::RangeSet::operator^ ( RangeSet const & s) const
inline

The ^ operator returns the symmetric difference between this set and s.

Definition at line 380 of file RangeSet.h.

380 {
381 return symmetricDifference(s);
382 }
RangeSet symmetricDifference(RangeSet const &s) const
symmetricDifference returns the symmetric difference of this set and s.
Definition RangeSet.cc:173

◆ operator^=()

RangeSet & lsst::sphgeom::RangeSet::operator^= ( RangeSet const & s)
inline

The ^= operator assigns the symmetric difference between this set and s to this set.

It is strongly exception safe.

Definition at line 418 of file RangeSet.h.

418 {
419 if (this != &s) {
420 RangeSet r = symmetricDifference(s);
421 swap(r);
422 } else {
423 clear();
424 }
425 return *this;
426 }

◆ operator|()

RangeSet lsst::sphgeom::RangeSet::operator| ( RangeSet const & s) const
inline

The | operator returns the union of this set and s.

Definition at line 370 of file RangeSet.h.

370 {
371 return join(s);
372 }
RangeSet join(RangeSet const &s) const
join returns the union of this set and s.
Definition RangeSet.cc:152

◆ operator|=()

RangeSet & lsst::sphgeom::RangeSet::operator|= ( RangeSet const & s)
inline

The |= operator assigns the union of this set and s to this set.

It is strongly exception safe.

Definition at line 396 of file RangeSet.h.

396 {
397 if (this != &s) {
398 RangeSet r = join(s);
399 swap(r);
400 }
401 return *this;
402 }

◆ operator~()

RangeSet lsst::sphgeom::RangeSet::operator~ ( ) const
inline

The ~ operator returns the complement of this set.

Definition at line 358 of file RangeSet.h.

358 {
359 RangeSet s(*this);
360 s.complement();
361 return s;
362 }

◆ scale()

RangeSet & lsst::sphgeom::RangeSet::scale ( std::uint64_t i)

scale multiplies the endpoints of each range in this set by the given integer.

Given ranges that correspond to pixel indexes in a hierarchical pixelization of the sphere like HTM or Q3C, scaling by 4 corresponds to increasing the subdivision level of the pixelization by 1.

Definition at line 361 of file RangeSet.cc.

361 {
362 if (empty() || i == 1) {
363 return *this;
364 } else if (i == 0) {
365 clear();
366 return *this;
367 }
368 std::uint64_t overflowThreshold = static_cast<std::uint64_t>(-1) / i;
369 auto r = _ranges.begin();
370 auto rend = _ranges.end();
371 for (; r < rend; ++r) {
373 if (value > overflowThreshold) {
374 *r = 0;
375 ++r;
376 break;
377 }
378 *r = value * i;
379 }
380 _ranges.erase(r, rend);
381 return *this;
382}
T erase(T... args)

◆ scaled()

RangeSet lsst::sphgeom::RangeSet::scaled ( std::uint64_t i) const
inline

scaled returns a scaled copy of this set.

Definition at line 501 of file RangeSet.h.

501 {
502 RangeSet rs(*this);
503 rs.scale(i);
504 return rs;
505 }

◆ simplified()

RangeSet lsst::sphgeom::RangeSet::simplified ( std::uint32_t n) const
inline

simplified returns a simplified copy of this set.

Definition at line 486 of file RangeSet.h.

486 {
487 RangeSet rs(*this);
488 rs.simplify(n);
489 return rs;
490 }

◆ simplify()

RangeSet & lsst::sphgeom::RangeSet::simplify ( std::uint32_t n)

simplify simplifies this range set by "coarsening" its ranges.

The result is defined as the union of the ranges obtained by rounding existing range beginnings down to the nearest multiple of 2^n, and rounding the ends up. Therefore, simplifying a range set always results in a superset of the original set.

This function replaces many small ranges with fewer coarser ranges. If the ranges correspond to pixels in a hierarchical pixelization of the sphere that overlap a region R, then this operation can be thought of as computing a lower resolution representation of the coverage of R.

Definition at line 315 of file RangeSet.cc.

315 {
316 if (empty() || n == 0) {
317 return *this;
318 } else if (n >= 64) {
319 fill();
320 return *this;
321 }
322 // Compute m, the integer with n LSBs set to 1. Then, (x & ~m) is x
323 // rounded down to the nearest multiple of 2^n, and (x + m) & ~m is
324 // x rounded up to the nearest multiple of 2^n.
325 std::uint64_t const m = (static_cast<std::uint64_t>(1) << n) - 1;
326 std::uint64_t * r = const_cast<std::uint64_t *>(_begin());
327 std::uint64_t * rend = const_cast<std::uint64_t *>(_end());
328 std::uint64_t * out = r;
329 // Expand the first range.
330 std::uint64_t first = r[0] & ~m;
331 std::uint64_t last = (r[1] + m) & ~m;
332 if (r[0] != 0 && first == 0) {
333 // The expanded first range now contains the leading bookend.
334 _offset = false;
335 --out;
336 }
337 out[0] = first;
338 out[1] = last;
339 // Expand the remaining ranges.
340 for (r += 2; last != 0 && r != rend; r += 2) {
341 std::uint64_t u = r[0] & ~m;
342 std::uint64_t v = (r[1] + m) & ~m;
343 if (u > last) {
344 out += 2;
345 out[0] = u;
346 }
347 out[1] = v;
348 last = v;
349 }
350 out += 2;
351 if (last != 0) {
352 // Append a trailing bookend if necessary.
353 *out = 0;
354 ++out;
355 }
356 // Erase everything after the location of the new trailing bookend.
357 _ranges.erase(_ranges.begin() + (out - _ranges.data()), _ranges.end());
358 return *this;
359}
int m
Definition SpanSet.cc:48
T data(T... args)

◆ size()

size_t lsst::sphgeom::RangeSet::size ( ) const
inline

size returns the number of ranges in this set.

Definition at line 546 of file RangeSet.h.

546{ return (_ranges.size() - _offset) / 2; }

◆ swap()

void lsst::sphgeom::RangeSet::swap ( RangeSet & s)
inline

Definition at line 554 of file RangeSet.h.

554 {
555 using std::swap;
556 swap(_ranges, s._ranges);
557 swap(_offset, s._offset);
558 }
T swap(T... args)

◆ symmetricDifference()

RangeSet lsst::sphgeom::RangeSet::symmetricDifference ( RangeSet const & s) const

symmetricDifference returns the symmetric difference of this set and s.

Definition at line 173 of file RangeSet.cc.

173 {
174 RangeSet result;
175 if (this != &s) {
176 if (empty()) {
177 result = s;
178 } else if (s.empty()) {
179 result = *this;
180 } else {
181 // Sweep through the beginning and end points of the ranges from
182 // sets A and B in ascending order.
183 //
184 // Passing through the beginning of a range toggles the
185 // corresponding state (astate or bstate) from 0 to 1, and passing
186 // through the end toggles it from 1 to 0. The XOR of astate and
187 // bstate determines whether or not the current position of the
188 // sweep is inside the symmetric set difference of A and B.
189 //
190 // Merging the sorted lists of ranges from each set is complicated
191 // by trailing zero bookends. These compare less than or equal to
192 // all other values, even though logically they are greater than
193 // them all.
194 //
195 // To handle this, leading zero bookends are dealt with outside of
196 // the main loop. Then, 1 is subtracted from all other values prior
197 // to comparison, yielding the proper ordering (since subtracting
198 // 1 from a trailing zero bookend results in 2^64 - 1).
199 std::uint64_t const * a = _begin();
200 std::uint64_t const * aend = _end();
201 std::uint64_t const * b = s._begin();
202 std::uint64_t const * bend = s._end();
203 int astate = (*a == 0);
204 int bstate = (*b == 0);
205 a += astate;
206 b += bstate;
207 // state is 0 if the next value to output is the beginning
208 // of a range, and 1 otherwise.
209 int state = astate ^ bstate;
210 // Start with a vector containing just the leading bookend.
211 result._ranges = {0};
212 // If 0 is contained in exactly one of the two sets, it is
213 // in their symmetric difference.
214 result._offset = (state == 0);
215 // Merge lists until one or both are exhausted.
216 while (a != aend && b != bend) {
217 std::uint64_t av = *a - 1;
218 std::uint64_t bv = *b - 1;
219 // The pointer(s) yielding the minimal value will be
220 // incremented.
221 bool ainc = (av <= bv);
222 bool binc = (bv <= av);
223 std::uint64_t minval = ainc ? av : bv;
224 astate ^= ainc;
225 bstate ^= binc;
226 // Output the minimum value if the output state changes.
227 if (state != (astate ^ bstate)) {
228 result._ranges.push_back(minval + 1);
229 state ^= 1;
230 }
231 a += ainc;
232 b += binc;
233 }
234 // The sweep has exhausted at least one list. Each remaining
235 // beginning and end point in the other list will toggle the
236 // output state, so they can simply be appended to the result.
237 result._ranges.insert(result._ranges.end(), a, aend);
238 result._ranges.insert(result._ranges.end(), b, bend);
239 // Append a trailing bookend if necessary.
240 if ((aend[-1] == 0) == (bend[-1] == 0)) {
241 result._ranges.push_back(0);
242 }
243 }
244 }
245 return result;
246}

The documentation for this class was generated from the following files: