Regina 7.3 Calculation Engine
Public Member Functions | Static Public Attributes | Friends | List of all members
regina::Bitmask Class Reference

A bitmask that can store arbitrarily many true-or-false bits. More...

#include <utilities/bitmask.h>

Public Member Functions

 Bitmask ()
 Creates a new invalid bitmask. More...
 
 Bitmask (size_t length)
 Creates a new bitmask of the given length with all bits set to false. More...
 
 Bitmask (const Bitmask &src)
 Creates a clone of the given bitmask. More...
 
 Bitmask (Bitmask &&src) noexcept
 Moves the contents of the given bitmask into this new bitmask. More...
 
 ~Bitmask ()
 Destroys this bitmask. More...
 
bool get (size_t index) const
 Returns the value of the given bit of this bitmask. More...
 
void set (size_t index, bool value)
 Sets the given bit of this bitmask to the given value. More...
 
template<typename ForwardIterator >
void set (ForwardIterator indexBegin, ForwardIterator indexEnd, bool value)
 Sets all bits in the given sorted list to the given value. More...
 
void reset ()
 Sets all bits of this bitmask to false. More...
 
void reset (size_t length)
 Resizes this bitmask to the given length and sets all bits to false. More...
 
Bitmaskoperator= (const Bitmask &other)
 Sets this bitmask to a copy of the given bitmask. More...
 
Bitmaskoperator= (Bitmask &&src) noexcept
 Moves the contents of the given bitmask into this bitmask. More...
 
void swap (Bitmask &other) noexcept
 Swaps the contents of this and the given bitmask. More...
 
void truncate (size_t numBits)
 Leaves the first numBits bits of this bitmask intact, but sets all subsequent bits to false. More...
 
Bitmaskoperator&= (const Bitmask &other)
 Sets this to the intersection of this and the given bitmask. More...
 
Bitmaskoperator|= (const Bitmask &other)
 Sets this to the union of this and the given bitmask. More...
 
Bitmaskoperator^= (const Bitmask &other)
 Sets this to the exclusive disjunction (XOR) of this and the given bitmask. More...
 
Bitmaskoperator-= (const Bitmask &other)
 Sets this to the set difference of this and the given bitmask. More...
 
void flip ()
 Negates every bit in this bitmask. More...
 
bool operator== (const Bitmask &other) const
 Determines whether this and the given bitmask are identical. More...
 
bool operator!= (const Bitmask &other) const
 Determines whether this and the given bitmask are different. More...
 
bool lessThan (const Bitmask &other) const
 Determines whether this bitmask appears strictly before the given bitmask when bitmasks are sorted in lexicographical order. More...
 
bool operator<= (const Bitmask &other) const
 Determines whether this bitmask is entirely contained within the given bitmask. More...
 
bool inUnion (const Bitmask &x, const Bitmask &y) const
 Determines whether this bitmask is entirely contained within the union of the two given bitmasks. More...
 
bool containsIntn (const Bitmask &x, const Bitmask &y) const
 Determines whether this bitmask contains the intersection of the two given bitmasks. More...
 
size_t bits () const
 Returns the number of bits currently set to true in this bitmask. More...
 
ssize_t firstBit () const
 Returns the index of the first true bit in this bitmask, or -1 if there are no true bits. More...
 
ssize_t lastBit () const
 Returns the index of the last true bit in this bitmask, or -1 if there are no true bits. More...
 
bool atMostOneBit () const
 Determines whether at most one bit is set to true in this bitmask. More...
 

Static Public Attributes

static constexpr bool fixedSize = false
 A class constant indicating whether this class stores bitmasks whose sizes are fixed at compile time. More...
 

Friends

std::ostream & operator<< (std::ostream &out, const Bitmask &mask)
 Writes the given bitmask to the given output stream as a sequence of zeroes and ones. More...
 

Detailed Description

A bitmask that can store arbitrarily many true-or-false bits.

This bitmask packs the bits together, so that (unlike an array of bools) many bits can be stored in a single byte. As a result, operations on this class are fast because the CPU can work on many bits simultaneously.

Nevertheless, this class still has overhead because the bits must be allocated on the heap, and because every operation requires looping through the individual bytes. For reasonably small bitmasks, see the highly optimised Bitmask1 and Bitmask2 classes instead.

Once a bitmask is created, the only way its length (the number of bits) can be changed is by calling reset(size_t).

The length of the bitmask is not actually stored in this structure. This means that, upon construction (or reset), the length will be automatically rounded up to the next "raw unit of storage".

This class implements C++ move semantics and adheres to the C++ Swappable requirement. It is designed to avoid deep copies wherever possible, even when passing or returning objects by value.

Todo:
Optimise: Insist that sizeof(Piece) is a power of two, and replace expensive division/mod operations with cheap bit operations.
Warning
Because this class may increase the length of the bitmask (rounding up to the next unit of storage), bitwise computations may not give the results that you expect. In particular, flip() may set additional true bits in the "dead space" between the intended length and the actual length, and this may have a flow-on effect for other operations (such as subset testing, bit counting and so on). Be careful!

Constructor & Destructor Documentation

◆ Bitmask() [1/4]

regina::Bitmask::Bitmask ( )
inline

Creates a new invalid bitmask.

You must call the one-argument reset(size_t) or use the assignment operator to give the bitmask a length before it can be used.

Use of this default constructor is discouraged. The only reason it exists is to support arrays and containers of bitmasks, where the bitmasks must be created in bulk and then individually assigned lengths.

Warning
No other routines can be used with this bitmask until it has been assigned a length via reset(size_t) or the assignment operator. As the single exception, the class destructor is safe to use even if a bitmask has never been initialised.

◆ Bitmask() [2/4]

regina::Bitmask::Bitmask ( size_t  length)
inline

Creates a new bitmask of the given length with all bits set to false.

Parameters
lengththe number of bits stored in this bitmask; this must be at least one.

◆ Bitmask() [3/4]

regina::Bitmask::Bitmask ( const Bitmask src)
inline

Creates a clone of the given bitmask.

It is fine if the given bitmask is invalid (but in this case, the new bitmask will be invalid also). Invalid bitmasks must be assigned a length using reset(size_t) or the assignment operator.

Parameters
srcthe bitmask to clone.

◆ Bitmask() [4/4]

regina::Bitmask::Bitmask ( Bitmask &&  src)
inlinenoexcept

Moves the contents of the given bitmask into this new bitmask.

It is fine if the given bitmask is invalid (but in this case, the new bitmask will be invalid also). Invalid bitmasks must be assigned a length using reset(size_t) or the assignment operator.

The bitmask that was passed (src) will no longer be usable.

Parameters
srcthe bitmask whose contents should be moved.

◆ ~Bitmask()

regina::Bitmask::~Bitmask ( )
inline

Destroys this bitmask.

Member Function Documentation

◆ atMostOneBit()

bool regina::Bitmask::atMostOneBit ( ) const
inline

Determines whether at most one bit is set to true in this bitmask.

If this bitmask is entirely false or if only one bit is set to true, then this routine will return true. Otherwise this routine will return false.

Returns
true if and only if at most one bit is set to true.

◆ bits()

size_t regina::Bitmask::bits ( ) const
inline

Returns the number of bits currently set to true in this bitmask.

Returns
the number of true bits.

◆ containsIntn()

bool regina::Bitmask::containsIntn ( const Bitmask x,
const Bitmask y 
) const
inline

Determines whether this bitmask contains the intersection of the two given bitmasks.

For this routine to return true, every bit that is set in both x and y must be set in this bitmask also.

Precondition
Both x and y are the same length as this bitmask.
Parameters
xthe first bitmask used to form the intersection.
ythe first bitmask used to form the intersection.
Returns
true if and only if this bitmask entirely contains the intersection of x and y.

◆ firstBit()

ssize_t regina::Bitmask::firstBit ( ) const
inline

Returns the index of the first true bit in this bitmask, or -1 if there are no true bits.

Returns
the index of the first true bit.

◆ flip()

void regina::Bitmask::flip ( )
inline

Negates every bit in this bitmask.

All true bits will be set to false and vice versa.

Warning
Because this class may increase the bitmask length (rounding up to the next unit of storage), flip() may set additional true bits in the "dead space" between the intended length and the actual length. This may cause unexpected results for routines such as subset testing, bit counting and so on. Be careful!

◆ get()

bool regina::Bitmask::get ( size_t  index) const
inline

Returns the value of the given bit of this bitmask.

Parameters
indexindicates which bit to query; this must be at least zero and strictly less than the length of this bitmask.
Returns
the value of the (index)th bit.

◆ inUnion()

bool regina::Bitmask::inUnion ( const Bitmask x,
const Bitmask y 
) const
inline

Determines whether this bitmask is entirely contained within the union of the two given bitmasks.

For this routine to return true, every bit that is set in this bitmask must also be set in either x or y.

Precondition
Both x and y are the same length as this bitmask.
Parameters
xthe first bitmask used to form the union.
ythe first bitmask used to form the union.
Returns
true if and only if this bitmask is entirely contained within the union of x and y.

◆ lastBit()

ssize_t regina::Bitmask::lastBit ( ) const
inline

Returns the index of the last true bit in this bitmask, or -1 if there are no true bits.

Returns
the index of the last true bit.

◆ lessThan()

bool regina::Bitmask::lessThan ( const Bitmask other) const
inline

Determines whether this bitmask appears strictly before the given bitmask when bitmasks are sorted in lexicographical order.

Here the bit at index 0 is least significant, and the bit at index length-1 is most significant.

Precondition
This and the given bitmask have the same length.
Warning
We do not use < for this operation, since ≤ represents the subset operation.
Parameters
otherthe bitmask to compare against this.
Returns
true if and only if this is lexicographically strictly smaller than the given bitmask.

◆ operator!=()

bool regina::Bitmask::operator!= ( const Bitmask other) const
inline

Determines whether this and the given bitmask are different.

Warning
As explain in the class notes, bitmasks do not store their exact length; instead the length is rounded up to the next "raw unit of storage". This means that two bitmasks that were initialised with different lengths may still be considered equal if the two lengths round up to the same value and the extra bits in the longer bitmask are all false.
Parameters
otherthe bitmask to compare against this.
Returns
true if and only if this and the given bitmask are different.

◆ operator&=()

Bitmask & regina::Bitmask::operator&= ( const Bitmask other)
inline

Sets this to the intersection of this and the given bitmask.

Every bit that is unset in other will be unset in this bitmask.

Precondition
This and the given bitmask have the same length.
Parameters
otherthe bitmask to intersect with this.
Returns
a reference to this bitmask.

◆ operator-=()

Bitmask & regina::Bitmask::operator-= ( const Bitmask other)
inline

Sets this to the set difference of this and the given bitmask.

Every bit that is set in other will be cleared in this bitmask.

Precondition
This and the given bitmask have the same length.
Parameters
otherthe bitmask to XOR with this.
Returns
a reference to this bitmask.

◆ operator<=()

bool regina::Bitmask::operator<= ( const Bitmask other) const
inline

Determines whether this bitmask is entirely contained within the given bitmask.

For this routine to return true, every bit that is set in this bitmask must also be set in the given bitmask.

Precondition
This and the given bitmask have the same length.
Warning
This operation does not compare bitmasks lexicographically; moreover, it only describes a partial order, not a total order. To compare bitmasks lexicographically, use lessThan() instead.
Parameters
otherthe bitmask to compare against this.
Returns
true if and only if this bitmask is entirely contained within the given bitmask.

◆ operator=() [1/2]

Bitmask & regina::Bitmask::operator= ( Bitmask &&  src)
inlinenoexcept

Moves the contents of the given bitmask into this bitmask.

It is fine if the given bitmask is invalid (but in this case, the new bitmask will be invalid also). Invalid bitmasks must be assigned a length using reset(size_t) or the assignment operator.

The bitmask that was passed (src) will no longer be usable.

Parameters
srcthe bitmask whose contents should be moved.
Returns
a reference to this bitmask.

◆ operator=() [2/2]

Bitmask & regina::Bitmask::operator= ( const Bitmask other)
inline

Sets this bitmask to a copy of the given bitmask.

If this bitmask is invalid, this assignment operator can be used to initialise it with a length.

If this bitmask has already been initialised to a different length from that of the given bitmask, the length of this bitmask will be changed accordingly.

If the given bitmask is invalid, this bitmask will become invalid also. Invalid bitmasks must be assigned a length using reset(size_t) or this assignment operator.

Parameters
otherthe bitmask to clone.
Returns
a reference to this bitmask.

◆ operator==()

bool regina::Bitmask::operator== ( const Bitmask other) const
inline

Determines whether this and the given bitmask are identical.

Warning
As explain in the class notes, bitmasks do not store their exact length; instead the length is rounded up to the next "raw unit of storage". This means that two bitmasks that were initialised with different lengths may still be considered equal if the two lengths round up to the same value and the extra bits in the longer bitmask are all false.
Parameters
otherthe bitmask to compare against this.
Returns
true if and only if this and the given bitmask are identical.

◆ operator^=()

Bitmask & regina::Bitmask::operator^= ( const Bitmask other)
inline

Sets this to the exclusive disjunction (XOR) of this and the given bitmask.

Every bit that is set in other will be flipped in this bitmask.

Precondition
This and the given bitmask have the same length.
Parameters
otherthe bitmask to XOR with this.
Returns
a reference to this bitmask.

◆ operator|=()

Bitmask & regina::Bitmask::operator|= ( const Bitmask other)
inline

Sets this to the union of this and the given bitmask.

Every bit that is set in other will be set in this bitmask.

Precondition
This and the given bitmask have the same length.
Parameters
otherthe bitmask to union with this.
Returns
a reference to this bitmask.

◆ reset() [1/2]

void regina::Bitmask::reset ( )
inline

Sets all bits of this bitmask to false.

Warning
The length of this bitmask must already have been initialised. In particular, if the default constructor was used, you must call the one-argument reset(size_t) before you can use this routine.

◆ reset() [2/2]

void regina::Bitmask::reset ( size_t  length)
inline

Resizes this bitmask to the given length and sets all bits to false.

This routine can be used to change the length (number of bits) of the bitmask if desired.

Parameters
lengththe number of bits to store in this bitmask; this must be at least one.

◆ set() [1/2]

template<typename ForwardIterator >
void regina::Bitmask::set ( ForwardIterator  indexBegin,
ForwardIterator  indexEnd,
bool  value 
)
inline

Sets all bits in the given sorted list to the given value.

This is a convenience routine for setting many bits at once. The indices of the bits to set should be sorted and stored in some container, such as a std::set or a C-style array. This routine takes iterators over this container, and sets the bits at the corresponding indices to the given value.

For example, the following code would set bits 3, 5 and 6 to true:

std::vector<unsigned> indices;
indices.push(3); indices.push(5); indices.push(6);
bitmask.set(indices.begin(), indices.end(), true);

Likewise, the following code would set bits 1, 4 and 7 to false:

unsigned indices[3] = { 1, 4, 7 };
bitmask.set(indices, indices + 3, false);

All other bits of this bitmask are unaffected by this routine.

Precondition
ForwardIterator is a forward iterator type that iterates over integer values.
The list of indices described by these iterators is in sorted order. This is to allow optimisations for larger bitmask types.
All indices in the given list are at least zero and strictly less than the length of this bitmask.
Python
Instead of a pair of iterators, you should pass a Python list (which, as described above, must be a sorted list of indices).
Parameters
indexBeginthe beginning of the iterator range containing the sorted indices of the bits to set.
indexEndthe end of the iterator range containing the sorted indices of the bits to set.
valuethe value that will be assigned to each of the corresponding bits.

◆ set() [2/2]

void regina::Bitmask::set ( size_t  index,
bool  value 
)
inline

Sets the given bit of this bitmask to the given value.

Parameters
indexindicates which bit to set; this must be at least zero and strictly less than the length of this bitmask.
valuethe value that will be assigned to the (index)th bit.

◆ swap()

void regina::Bitmask::swap ( Bitmask other)
inlinenoexcept

Swaps the contents of this and the given bitmask.

Parameters
otherthe bitmask whose contents should be swapped with this.

◆ truncate()

void regina::Bitmask::truncate ( size_t  numBits)
inline

Leaves the first numBits bits of this bitmask intact, but sets all subsequent bits to false.

In other words, this routine "truncates" this bitmask to the given number of bits.

This routine does not change the length of this bitmask (as passed to the contructor or to reset()).

Precondition
numBits is at most the length of this bitmask.
Parameters
numBitsthe number of bits that will not be cleared.

Friends And Related Function Documentation

◆ operator<<

std::ostream & operator<< ( std::ostream &  out,
const Bitmask mask 
)
friend

Writes the given bitmask to the given output stream as a sequence of zeroes and ones.

Since the length of the bitmask is not stored, the number of bits written might be greater than the length initially assigned to this bitmask (specifically, the length will be rounded up to the next "raw unit of storage").

Parameters
outthe output stream to which to write.
maskthe bitmask to write.
Returns
a reference to the given output stream.

Member Data Documentation

◆ fixedSize

constexpr bool regina::Bitmask::fixedSize = false
staticconstexpr

A class constant indicating whether this class stores bitmasks whose sizes are fixed at compile time.

For the general Bitmask class, this is false. For the highly optimised Bitmask1 and Bitmask2 template classes, this is true.


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

Copyright © 1999-2023, The Regina development team
This software is released under the GNU General Public License, with some additional permissions; see the source code for details.
For further information, or to submit a bug or other problem, please contact Ben Burton (bab@maths.uq.edu.au).