blob: cca241543cd3ede1fb16a8a5a2bf2aa001ac8bfd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _DECAF_UTIL_BITSET_H_
#define _DECAF_UTIL_BITSET_H_
#include <decaf/util/Config.h>
#include <string>
namespace decaf {
namespace util {
/**
* This class implements a vector of bits that grows as needed. Each component of
* the bit set has a boolean value. The bits of a BitSet are indexed by nonnegative
* integers. Individual indexed bits can be examined, set, or cleared. One BitSet
* may be used to modify the contents of another BitSet through logical AND, logical
* inclusive OR, and logical exclusive OR operations.
*
* By default, all bits in the set initially have the value false.
*
* Every bit set has a current size, which is the number of bits of space currently
* in use by the bit set. Note that the size is related to the implementation of a
* bit set, so it may change with implementation. The length of a bit set relates to
* logical length of a bit set and is defined independently of implementation.
*
* A BitSet is not safe for multi-threaded use without external synchronization.
*
* @since 1.0
*/
class DECAF_API BitSet {
private:
// The actual array of 64 bit bits elements
unsigned long long* bits;
int bitsSize;
// Optimization, when the array is all zero there's no need to traverse
bool needClear;
// Lazily maintained actual array length and state.
mutable int actualArrayLength;
mutable bool isLengthActual;
private:
BitSet(unsigned long long* bits, int bitsSize, bool needClear, int actualArrayLength, bool isLengthActual);
public:
/**
* Creates a new BitSet whose bits are all false.
*/
BitSet();
/**
* Creates a bit set whose initial size is large enough to explicitly represent bits
* with indices in the range 0 through bitCount-1. All bits are initially false. If the
* bitCount is not a multiple of 64 then the count is rounded to the next closest
* multiple of 64.
*
* @param bitCount
* The number of bits this BitSet should hold.
*
* @throws NegativeArraySizeException if bitCount is negative.
*/
BitSet(int bitCount);
/**
* Copy Constructor
*/
BitSet(const BitSet& set);
/**
* Assignment
*/
BitSet& operator= (const BitSet& set);
virtual ~BitSet();
/**
* Boolean comparison operator ==
*
* @param other
* The other BitSet to compare to this one.
*/
bool operator==(const BitSet& other) const {
return this->equals(other);
}
/**
* Boolean comparison operator !=
*
* @param other
* The other BitSet to compare to this one.
*/
bool operator!=(const BitSet& other) const {
return !this->equals(other);
}
public:
/**
* Performs a logical AND of this target bit set with the argument bit set. This bit
* set is modified so that each bit in it has the value true if and only if it both
* initially had the value true and the corresponding bit in the bit set argument
* also had the value true.
*
* @param set
* The BitSet to perform this action against.
*/
void AND(const BitSet& set);
/**
* Performs a logical OR of this bit set with the bit set argument. This bit set is
* modified so that a bit in it has the value true if and only if it either already had
* the value true or the corresponding bit in the bit set argument has the value true.
*
* @param set
* The BitSet to perform this action against.
*/
void OR(const BitSet& set);
/**
* Clears all of the bits in this BitSet whose corresponding bit is set in the specified BitSet.
*
* @param set
* The BitSet to perform this action against.
*/
void andNot(const BitSet& set);
/**
* Returns the number of bits set to true in this BitSet.
*
* @return the number of bits set to true in this BitSet.
*/
int cardinality();
/**
* Sets all of the bits in this BitSet to false.
*/
void clear();
/**
* Sets the bit specified by the index to false.
*
* @param index
* The index of the bit whose value is to be set to false
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
void clear(int index);
/**
* Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
* (exclusive) to false.
*
* @param fromIndex
* The index (inclusive) to start setting bits to false.
* @param toIndex
* The index (exclusive) to stop setting bits to false.
*
* @throws IndexOutOfBoundsException if fromIndex is negative, or toIndex is negative, or
* fromIndex is larger than toIndex.
*/
void clear(int fromIndex, int toIndex);
/**
* Compares this object against the specified object. The result is true if and only if
* is a Bitset object that has exactly the same set of bits set to true as this bit set.
* That is, for every nonnegative int index k,
*
* set.get(k) == this->get(k)
*
* must be true. The current sizes of the two bit sets are not compared.
*
* @return true if the sets are the same, false otherwise.
*/
bool equals(const BitSet& set) const;
/**
* Sets the bit at the specified index to the complement of its current value.
*
* @param index
* The index of the bit whose value is to be set to its compliment.
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
void flip(int index);
/**
* Sets each bit from the specified fromIndex (inclusive) to the specified toIndex
* (exclusive) to the complement of its current value.
*
* @param fromIndex
* The index (inclusive) to start setting bits to its compliment.
* @param toIndex
* The index (exclusive) to stop setting bits to its compliment.
*
* @throws IndexOutOfBoundsException if fromIndex is negative, or toIndex is negative, or
* fromIndex is larger than toIndex.
*/
void flip(int fromIndex, int toIndex);
/**
* Returns the value of the bit with the specified index. The value is true if the bit
* with the given index is currently set in this BitSet; otherwise, the result is false.
*
* @param index
* The index of the bit in question.
*
* @return the value of the bit with the specified index.
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
bool get(int index) const;
/**
* Returns a new BitSet composed of bits from this BitSet from fromIndex (inclusive) to
* toIndex (exclusive).
*
* @param fromIndex
* The index (inclusive) to start at.
* @param toIndex
* The index (exclusive) to stop at.
*
* @return a new BitSet containing the specified values.
*
* @throws IndexOutOfBoundsException if fromIndex is negative, or toIndex is negative, or
* fromIndex is larger than toIndex.
*/
BitSet get(int fromIndex, int toIndex) const;
/**
* Returns true if the specified BitSet has any bits set to true that are also set to
* true in this BitSet.
*
* @param set
* BitSet to intersect with.
*
* @return boolean indicating whether this BitSet intersects the specified BitSet.
*/
bool intersects(const BitSet& set) const;
/**
* Returns true if this BitSet contains no bits that are set to true.
*
* @return true if the set is empty, false otherwise.
*/
bool isEmpty() const;
/**
* Returns the "logical size" of this BitSet: the index of the highest set bit in the
* BitSet plus one. Returns zero if the BitSet contains no set bits.
*
* @return the logical size of the BitSet.
*/
int length() const;
/**
* Returns the index of the first bit that is set to false that occurs on or after the
* specified starting index.
*
* @param index
* The index to start the search from (inclusive).
*
* @return the index of the next clear bit.
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
int nextClearBit(int index) const;
/**
* Returns the index of the first bit that is set to true that occurs on or after the
* specified starting index.
*
* @param index
* The index to start the search from (inclusive).
*
* @return the index of the next set bit.
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
int nextSetBit(int index) const;
/**
* Sets the bit at the specified index to true.
*
* @param index
* The index to set to true.
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
void set(int index);
/**
* Sets the bit at the specified index to the specified value.
*
* @param index
* The index to set.
* @param value
* The value to assign to the given bit.
*
* @throws IndexOutOfBoundsException if the index value is negative.
*/
void set(int index, bool value);
/**
* Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
* (exclusive) to true.
*
* @param fromIndex
* The index (inclusive) to start at.
* @param toIndex
* The index (exclusive) to stop at.
*
* @throws IndexOutOfBoundsException if fromIndex is negative, or toIndex is negative, or
* fromIndex is larger than toIndex.
*/
void set(int fromIndex, int toIndex);
/**
* Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
* (exclusive) to the value given.
*
* @param fromIndex
* The index (inclusive) to start at.
* @param toIndex
* The index (exclusive) to stop at.
* @param value
* The boolean value to assign to the target bits.
*
* @throws IndexOutOfBoundsException if fromIndex is negative, or toIndex is negative, or
* fromIndex is larger than toIndex.
*/
void set(int fromIndex, int toIndex, bool value);
/**
* Returns the number of bits of space actually in use by this BitSet to represent bit
* values. The maximum element in the set is the size - 1st element.
*
* @return the number of bits currently in this bit set.
*/
int size() const;
/**
* Returns a string representation of this bit set. For every index for which this BitSet
* contains a bit in the set state, the decimal representation of that index is included
* in the result. Such indices are listed in order from lowest to highest, separated by
* ", " (a comma and a space) and surrounded by braces, resulting in the usual mathematical
* notation for a set of integers.
*
* @return string representation of the BitSet.
*/
std::string toString() const;
/**
* Performs a logical XOR of this bit set with the bit set argument. This bit set is modified
* so that a bit in it has the value true if and only if one of the following statements holds:
*
* * The bit initially has the value true, and the corresponding bit in the argument has
* the value false.
* * The bit initially has the value false, and the corresponding bit in the argument has
* the value true.
*
* @param set
* The BitSet to use.
*/
void XOR(const BitSet& set);
private:
/**
* Increase the size of the internal array to accommodate length bits.
* The new array max index will be a multiple of 64.
*
* @param length
* the index the new array needs to be able to access.
*/
void ensureCapacity(int length);
/**
* Gets the actual length of the BitSet bit array which is maintained in a
* sometimes lazy fashion to avoid excessive array traversals. The actual
* length is the number of non-zero array elements in the physical array
* used to back this BitSet.
*
* @return the actual array length.
*/
int getActualArrayLength() const;
};
}}
#endif /* _DECAF_UTIL_BITSET_H_ */