|
C Container Collection (CCC)
|
The Bit Set Interface. More...


Go to the source code of this file.
The Bit Set Interface.
A bit set offers efficient set membership operations when the range of values can be tracked via an index. Both a fixed size and dynamic variant are possible depending on initialization options.
Conceptually, the bit set can be thought of as an arbitrary length integer with index 0 being the Least Significant Bit and index N - 1 being the Most Significant Bit of the integer. Internally, this is implemented by populating each block of the bit set from Least Significant Bit to Most Significant Bit. Therefore, "trailing" means starting from the Least Significant Bit and "leading" means starting from the Most Significant Bit; this is done to stay consistent with upcoming bit operations introduced to the C23 standard.
A bit set can be used for modeling integer operations on integers that exceed the widths available on one's platform. The provided bitwise operation functions are helpful for these types of manipulations.
A bit set can also be used for modeling data that can be abstracted to a position and binary value. For example, disk blocks in a file system, free blocks in a memory allocator, and many other resource abstractions can benefit from a bit set. For these use cases the bit set offers efficient functions to find the first bits set to zero or one from either the trailing or leading direction. A bit set can also efficiently report if contiguous ranges of zeros or ones are available.
All *_range functions interpret their range input argument parameters as [index, index + count), a starting index and a positive forward length. This convention is consistent for all operations. The implementation automatically chooses the optimal scan direction, Least Significant Bit to Most Significant Bit for trailing scans, Most Significant Bit to Least Significant Bit for leading scans. However, the user always specifies the range in the same way for consistency.
To shorten names in the interface, define the following preprocessor directive at the top of your file.
All types and functions can then be written without the CCC_ prefix.
Container Initialization | |
Initialize and create containers with memory and permissions. | |
| #define | CCC_bitset_block_count(bit_cap) CCC_private_bitset_block_count(bit_cap) |
| Get the number of bit blocks needed for the desired bit set capacity. | |
| #define | CCC_bitset_block_bytes(bit_cap) CCC_private_bitset_block_bytes(bit_cap) |
| Get the number of bytes needed for the desired bit set capacity. | |
| #define | CCC_bitset_blocks(bit_cap, optional_storage_duration...) CCC_private_bitset_blocks(bit_cap, optional_storage_duration) |
| Allocate the necessary number of blocks at compile or runtime on the stack or data segment. | |
| #define | CCC_bitset_initialize(bitblock_pointer, allocate, context, cap, optional_count...) |
| Initialize the bit set with memory and allocation permissions. | |
| #define | CCC_bitset_from(allocate, context, start_string_index, count, bit_on_char, input_string, optional_capacity...) |
| Initialize the bit set with a custom input string. | |
| #define | CCC_bitset_with_capacity(allocate, context, capacity, optional_count...) |
| Initialize the bit set with a starting capacity and size at runtime. | |
| #define | CCC_bitset_with_compound_literal(count, compound_literal_array) CCC_private_bitset_with_compound_literal(count, compound_literal_array) |
| Initialize the bit set with a starting capacity and size at runtime or compile time with no allocation permissions or context from a compound literal of bitset blocks. | |
| #define | CCC_bitset_with_context_compound_literal(count, compound_literal_array) |
| Initialize the bit set with a starting capacity and size at runtime or compile time with no allocation permissions from a compound literal of bitset blocks. | |
| enum | : size_t { CCC_BITSET_BLOCK_BITS = CCC_PRIVATE_BITSET_BLOCK_BITS } |
| CCC_Result | CCC_bitset_copy (CCC_Bitset *destination, CCC_Bitset const *source, CCC_Allocator *allocate) |
| Copy the bit set at source to destination. | |
| CCC_Result | CCC_bitset_reserve (CCC_Bitset *bitset, size_t to_add, CCC_Allocator *allocate) |
| Reserves space for at least to_add more bits. | |
Container Types | |
Types available in the container interface. | |
| typedef struct CCC_Bitset | CCC_Bitset |
| The bit set type that may be stored and initialized on the stack, heap, or data segment at compile or run time. | |
Bit Membership Interface | |
Test for the presence of bits. | |
| CCC_Tribool | CCC_bitset_test (CCC_Bitset const *bitset, size_t index) |
| Test the bit at index index for boolean status (CCC_TRUE or CCC_FALSE). | |
Bit Modification Interface | |
Set and flip bits in the set. | |
| CCC_Tribool | CCC_bitset_set (CCC_Bitset *bitset, size_t index, CCC_Tribool bit) |
| Set the bit at valid index index to value bit (true or false). | |
| CCC_Result | CCC_bitset_set_all (CCC_Bitset *bitset, CCC_Tribool bit) |
| Set all the bits to the provided value (CCC_TRUE or CCC_FALSE). | |
| CCC_Result | CCC_bitset_set_range (CCC_Bitset *bitset, size_t range_start_index, size_t range_bit_count, CCC_Tribool bit) |
| Set all the bits in the specified range starting at the Least Significant Bit of the range and ending at the Most Significant Bit of the range (CCC_TRUE or CCC_FALSE). | |
| CCC_Tribool | CCC_bitset_reset (CCC_Bitset *bitset, size_t index) |
| Set the bit at valid index index to boolean value b (true or false). | |
| CCC_Result | CCC_bitset_reset_all (CCC_Bitset *bitset) |
| Set all the bits to CCC_FALSE. | |
| CCC_Result | CCC_bitset_reset_range (CCC_Bitset *bitset, size_t range_start_index, size_t range_bit_count) |
| Set all the bits in the specified range starting at the Least Significant Bit of the range and ending at the Most Significant Bit of the range to CCC_FALSE. | |
| CCC_Tribool | CCC_bitset_flip (CCC_Bitset *bitset, size_t index) |
| Toggle the bit at index i. | |
| CCC_Result | CCC_bitset_flip_all (CCC_Bitset *bitset) |
| Toggle all of the bits to their opposing boolean value. | |
| CCC_Result | CCC_bitset_flip_range (CCC_Bitset *bitset, size_t range_start_index, size_t range_bit_count) |
| Flip all the bits in the range, starting at the Least Significant Bit in range and ending at the Most Significant Bit, to their opposite value. | |
Bit Scan Interface | |
Find bits with a specific status. | |
| CCC_Tribool | CCC_bitset_any (CCC_Bitset const *bitset) |
| Return true if any bits in set are 1. | |
| CCC_Tribool | CCC_bitset_any_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
Return true if any bits are 1 in the range [index, index + count). | |
| CCC_Tribool | CCC_bitset_none (CCC_Bitset const *bitset) |
| Return true if all bits are set to 0. | |
| CCC_Tribool | CCC_bitset_none_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
Return true if all bits are 0 in the range [index, index + count). | |
| CCC_Tribool | CCC_bitset_all (CCC_Bitset const *bitset) |
| Return true if all bits in set are 1. | |
| CCC_Tribool | CCC_bitset_all_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
Return true if all bits are set to 1 in the range [index, index + count). | |
| CCC_Count | CCC_bitset_first_trailing_one (CCC_Bitset const *bitset) |
| Return the index of the first trailing bit set to 1 in the set. | |
| CCC_Count | CCC_bitset_first_trailing_one_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
Return the index of the first trailing bit set to 1 in the range [i, index + count). | |
| CCC_Count | CCC_bitset_first_trailing_ones (CCC_Bitset const *bitset, size_t ones_count) |
| Returns the index of the start of the first trailing number of contiguous 1 bits. | |
| CCC_Count | CCC_bitset_first_trailing_ones_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count, size_t ones_count) |
Returns the index of the start of the first trailing number of contiguous 1 bits in the range [index, index + count). | |
| CCC_Count | CCC_bitset_first_trailing_zero (CCC_Bitset const *bitset) |
| Return the index of the first bit set to 0 in the set. | |
| CCC_Count | CCC_bitset_first_trailing_zero_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
Return the index of the first bit set to 0 in the range [i, index + count). | |
| CCC_Count | CCC_bitset_first_trailing_zeros (CCC_Bitset const *bitset, size_t zeros_count) |
| Returns the index of the start of the first trailing number of contiguous 0 bits in the set. | |
| CCC_Count | CCC_bitset_first_trailing_zeros_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count, size_t zeros_count) |
Returns the index of the start of the first trailing zeros_count contiguous 0 bits in the range [i, index + count). | |
| CCC_Count | CCC_bitset_first_leading_one (CCC_Bitset const *bitset) |
| Return the index of the first leading bit set to 1 in the set, starting from the Most Significant Bit at index size - 1. | |
| CCC_Count | CCC_bitset_first_leading_one_range (CCC_Bitset const *bitset, size_t index, size_t count) |
Return the index of the first leading bit set to 1 in the range [i, index + count). | |
| CCC_Count | CCC_bitset_first_leading_ones (CCC_Bitset const *bitset, size_t ones_count) |
| Returns the index of the start of the first leading bit_count contiguous 1 bits. | |
| CCC_Count | CCC_bitset_first_leading_ones_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count, size_t ones_count) |
Returns the index of the start of the first leading bit_count contiguous 1 bits in the range [i, index + count). | |
| CCC_Count | CCC_bitset_first_leading_zero (CCC_Bitset const *bitset) |
| Return the index of the first leading bit set to 0 in the set, starting from the Most Significant Bit at index size - 1. | |
| CCC_Count | CCC_bitset_first_leading_zero_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
Return the index of the first leading bit set to 0 in the range [i, index + count). | |
| CCC_Count | CCC_bitset_first_leading_zeros (CCC_Bitset const *bitset, size_t zeros_count) |
| Returns the index of the start of the first leading number of contiguous 0 bits. | |
| CCC_Count | CCC_bitset_first_leading_zeros_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count, size_t zeros_count) |
Returns the index of the start of the first leading number of contiguous 0 bits in the range [i, index + count). | |
Bit Operations Interface | |
Use standard integer width bit operations on the entire set. | |
| CCC_Result | CCC_bitset_or (CCC_Bitset *destination, CCC_Bitset const *source) |
| Bitwise OR destination set with source set. | |
| CCC_Result | CCC_bitset_and (CCC_Bitset *destination, CCC_Bitset const *source) |
| Bitwise AND destination set with source set. | |
| CCC_Result | CCC_bitset_xor (CCC_Bitset *destination, CCC_Bitset const *source) |
| Bitwise XOR destination set with source set. | |
| CCC_Result | CCC_bitset_shift_left (CCC_Bitset *bitset, size_t left_shifts) |
| Shift the bit set left by left_shifts amount. | |
| CCC_Result | CCC_bitset_shift_right (CCC_Bitset *bitset, size_t right_shifts) |
| Shift the bit set right by right_shifts amount. | |
| CCC_Tribool | CCC_bitset_is_equal (CCC_Bitset const *left, CCC_Bitset const *right) |
| Checks two bit sets of the same size (not capacity) for equality. | |
Set Operations Interface | |
Perform basic mathematical set operations on the bit set. | |
| CCC_Tribool | CCC_bitset_is_proper_subset (CCC_Bitset const *subset, CCC_Bitset const *set) |
| Return CCC_TRUE if subset is a proper subset of set (subset ⊂ set). | |
| CCC_Tribool | CCC_bitset_is_subset (CCC_Bitset const *subset, CCC_Bitset const *set) |
| Return CCC_TRUE if subset is a subset of set (subset ⊆ set). | |
State Interface | |
Obtain state from the container. | |
| void * | CCC_bitset_data (CCC_Bitset const *bitset) |
| Return a reference to the base of the underlying block array. | |
| CCC_Count | CCC_bitset_capacity (CCC_Bitset const *bitset) |
| Return total number of bits the capacity of the set can hold. | |
| CCC_Count | CCC_bitset_count (CCC_Bitset const *bitset) |
| Return total number of bits actively tracked by the user and set. | |
| CCC_Count | CCC_bitset_blocks_capacity (CCC_Bitset const *bitset) |
| Return number of CCC_bitblocks used by bit set for capacity bits. | |
| CCC_Count | CCC_bitset_blocks_count (CCC_Bitset const *bitset) |
| Return number of CCC_bitblocks used by the bit set for size bits. | |
| CCC_Tribool | CCC_bitset_is_empty (CCC_Bitset const *bitset) |
| Return true if no bits are actively tracked by the user and set. | |
| CCC_Count | CCC_bitset_popcount (CCC_Bitset const *bitset) |
| Return the number of bits set to CCC_TRUE. O(n). | |
| CCC_Count | CCC_bitset_popcount_range (CCC_Bitset const *bitset, size_t range_start_index, size_t range_bit_count) |
| Return the number of bits set to CCC_TRUE in the range. O(n). | |
Destructor Interface | |
Clear the set and manage its memory. | |
| CCC_Result | CCC_bitset_clear (CCC_Bitset *bitset) |
| Clears the bit set by setting the size to 0 and all bits to 0. The underlying memory capacity remains unchanged. | |
| CCC_Result | CCC_bitset_clear_and_free (CCC_Bitset *bitset) |
| Clears the bit set by setting the size to 0 and freeing the underlying memory. Capacity becomes 0 as well. | |
| CCC_Result | CCC_bitset_clear_and_free_reserve (CCC_Bitset *bitset, CCC_Allocator *allocate) |
| Frees the Buffer for the bit set that was previously dynamically reserved with the reserve function. | |
Dynamic Interface | |
Allows adding to and removing from the set. | |
| CCC_Result | CCC_bitset_push_back (CCC_Bitset *bitset, CCC_Tribool bit) |
| Append a bit value to the set as the new Most Significant Bit. | |
| CCC_Tribool | CCC_bitset_pop_back (CCC_Bitset *bitset) |
| Remove the Most Significant Bit from the set. | |
| #define CCC_bitset_block_bytes | ( | bit_cap | ) | CCC_private_bitset_block_bytes(bit_cap) |
Get the number of bytes needed for the desired bit set capacity.
| [in] | bit_cap | the number of bits representing this bit set. |
| #define CCC_bitset_block_count | ( | bit_cap | ) | CCC_private_bitset_block_count(bit_cap) |
Get the number of bit blocks needed for the desired bit set capacity.
| [in] | bit_cap | the number of bits representing this bit set. |
| #define CCC_bitset_blocks | ( | bit_cap, | |
| optional_storage_duration... | |||
| ) | CCC_private_bitset_blocks(bit_cap, optional_storage_duration) |
Allocate the necessary number of blocks at compile or runtime on the stack or data segment.
| [in] | bit_cap | the desired number of bits to store in the bit set. |
| [in] | optional_storage_duration | an optional storage duration specifier such as static or automatic. |
This method can be used for compile time initialization of bit set. For example:
The above example also illustrates the benefits of a static compound literal to encapsulate the bits within the bit set array to prevent dangling references. If the compiler does not support storage duration of compound literals the more traditional example follows:
This macro is required for any initialization where the bit block memory comes from the stack or data segment. For one time dynamic reservations of bit block memory see the CCC_bitset_reserve and CCC_bitset_clear_and_free_reserve interface.
| #define CCC_bitset_from | ( | allocate, | |
| context, | |||
| start_string_index, | |||
| count, | |||
| bit_on_char, | |||
| input_string, | |||
| optional_capacity... | |||
| ) |
Initialize the bit set with a custom input string.
| [in] | allocate | the allocation function for the dynamic bit set. |
| [in] | context | context data needed for allocation of the bit set. |
| [in] | start_string_index | the index of the input string to start reading is CCC_Tribool input. |
| [in] | count | number of characters to read from start_string_index. |
| [in] | bit_on_char | the character that when encountered equates to CCC_TRUE and results in the corresponding bit in the bit set being set CCC_TRUE. Any other character encountered results in the corresponding bit being set to CCC_FALSE. |
| [in] | input_string | the string literal or pointer to a string. |
| [in] | optional_capacity | the custom capacity other than the count passed to this initializer. If a greater capacity than the input string is desired because more bits will be pushed later, specify with this input. If this input is less than count, count becomes the capacity. |
A dynamic bit set with input string pushed.
A dynamic bit set that allocates greater capacity.
This initializer is only available to dynamic bit sets due to the inability to run such input code at compile time.
| #define CCC_bitset_initialize | ( | bitblock_pointer, | |
| allocate, | |||
| context, | |||
| cap, | |||
| optional_count... | |||
| ) |
Initialize the bit set with memory and allocation permissions.
| [in] | bitblock_pointer | the pointer to existing blocks or NULL. |
| [in] | allocate | the allocation function for a dynamic bit set or NULL. |
| [in] | context | context data needed for allocation of the bit set. |
| [in] | cap | the number of bits that will be stored in this bit set. |
| [in] | optional_count | an optional starting size <= capacity. This value defaults to the same value as capacity which is appropriate for most cases. For any case where this is not desirable, set the size manually (for example, a fixed size bit set that is pushed to dynamically would have a non-zero capacity and 0 size). |
A fixed size bit set with size equal to capacity.
A fixed size bit set with dynamic push and pop.
A dynamic bit set initialization.
See types.h for more on allocation functions.
| #define CCC_bitset_with_capacity | ( | allocate, | |
| context, | |||
| capacity, | |||
| optional_count... | |||
| ) |
Initialize the bit set with a starting capacity and size at runtime.
| [in] | allocate | the allocation function for a dynamic bit. |
| [in] | context | context data needed for allocation of the bit set. |
| [in] | capacity | the number of bits that will be stored in this bit set. |
| [in] | optional_count | an optional starting size <= capacity. This value defaults to the same value as capacity which is appropriate for most cases. For any case where this is not desirable, set the size manually (for example, a bit set that will push bits back would have a non-zero capacity and 0 size). |
A fixed size bit set with size equal to capacity.
A bit set with dynamic push and pop.
This initialization can only be used at runtime. See the normal initializer for static and stack based initialization options.
| #define CCC_bitset_with_compound_literal | ( | count, | |
| compound_literal_array | |||
| ) | CCC_private_bitset_with_compound_literal(count, compound_literal_array) |
Initialize the bit set with a starting capacity and size at runtime or compile time with no allocation permissions or context from a compound literal of bitset blocks.
| [in] | count | the count of bits <= capacity of this bit set. |
| [in] | compound_literal_array | the compound literal of bitset blocks. Use the CCC_bitset_blocks() macro to help construct this. |
A fixed size bit set.
This saves some initialization boilerplate.
| #define CCC_bitset_with_context_compound_literal | ( | count, | |
| compound_literal_array | |||
| ) |
Initialize the bit set with a starting capacity and size at runtime or compile time with no allocation permissions from a compound literal of bitset blocks.
| [in] | context | context for the bitset. |
| [in] | count | the count of bits <= capacity of this bit set. |
| [in] | compound_literal_array | the compound literal of bitset blocks. Use the CCC_bitset_blocks() macro to help construct this. |
A fixed size bit set.
This saves some initialization boilerplate.
| typedef struct CCC_Bitset CCC_Bitset |
The bit set type that may be stored and initialized on the stack, heap, or data segment at compile or run time.
A bit set offers fast membership testing and bit range manipulations when the data can be modeled as a 0-indexed key value data set. In the case of a bit set the key is the index in the bit set and the value is 1 or 0. Operations on single bits occur in O(1) time. All scanning operations operate in O(N) time.
| anonymous enum : size_t |
| CCC_Tribool CCC_bitset_all | ( | CCC_Bitset const * | bitset | ) |
Return true if all bits in set are 1.
| [in] | bitset | a pointer to the bit set. |
| CCC_Tribool CCC_bitset_all_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return true if all bits are set to 1 in the range [index, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting position. |
| [in] | range_bit_count | the size of the range to check. |
| CCC_Result CCC_bitset_and | ( | CCC_Bitset * | destination, |
| CCC_Bitset const * | source | ||
| ) |
Bitwise AND destination set with source set.
| [in] | destination | the set to modified with the AND operation. |
| [in] | source | the set to be read as the source bits for the AND operation. |
Note that sets are aligned from their Least Significant Bit and a smaller source set is conceptually padded with 0's in its higher order bits to align with the larger destination set (no modifications to the smaller set are performed to achieve this). This is done to stay consistent with integer promotion and widening rules in C.
| CCC_Tribool CCC_bitset_any | ( | CCC_Bitset const * | bitset | ) |
Return true if any bits in set are 1.
| [in] | bitset | a pointer to the bit set. |
| CCC_Tribool CCC_bitset_any_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return true if any bits are 1 in the range [index, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting position. |
| [in] | range_bit_count | the size of the range to check. |
| CCC_Count CCC_bitset_blocks_capacity | ( | CCC_Bitset const * | bitset | ) |
Return number of CCC_bitblocks used by bit set for capacity bits.
| [in] | bitset | a pointer to the bit set. |
Capacity may be greater than or equal to size.
| CCC_Count CCC_bitset_blocks_count | ( | CCC_Bitset const * | bitset | ) |
Return number of CCC_bitblocks used by the bit set for size bits.
| [in] | bitset | a pointer to the bit set. |
Size may be less than or equal to capacity.
| CCC_Count CCC_bitset_capacity | ( | CCC_Bitset const * | bitset | ) |
Return total number of bits the capacity of the set can hold.
| [in] | bitset | a pointer to the bit set. |
| CCC_Result CCC_bitset_clear | ( | CCC_Bitset * | bitset | ) |
Clears the bit set by setting the size to 0 and all bits to 0. The underlying memory capacity remains unchanged.
| [in] | bitset | a pointer to the bit set. |
| CCC_Result CCC_bitset_clear_and_free | ( | CCC_Bitset * | bitset | ) |
Clears the bit set by setting the size to 0 and freeing the underlying memory. Capacity becomes 0 as well.
| [in] | bitset | a pointer to the bit set. |
| CCC_Result CCC_bitset_clear_and_free_reserve | ( | CCC_Bitset * | bitset, |
| CCC_Allocator * | allocate | ||
| ) |
Frees the Buffer for the bit set that was previously dynamically reserved with the reserve function.
| [in] | bitset | the bitset to be cleared. |
| [in] | allocate | the required allocation function to provide to a dynamically reserved bs. Any context data provided upon initialization will be passed to the allocation function when called. |
This function covers the edge case of reserving a dynamic capacity for a bitset at runtime but denying the bitset allocation permission to resize. This can help prevent a bitset from growing untree. The user in this case knows the bitset does not have allocation permission and therefore no further memory will be dedicated to the bs.
However, to free the bitset in such a case this function must be used because the bitset has no ability to free itself. Just as the allocation function is required to reserve memory so to is it required to free memory.
This function will work normally if called on a bitset with allocation permission however the normal CCC_bitset_clear_and_free is sufficient for that use case.
| CCC_Result CCC_bitset_copy | ( | CCC_Bitset * | destination, |
| CCC_Bitset const * | source, | ||
| CCC_Allocator * | allocate | ||
| ) |
Copy the bit set at source to destination.
| [in] | destination | the initialized destination for the copy of the source set. |
| [in] | source | the initialized source of the set. |
| [in] | allocate | the optional allocation function if resizing is needed. |
Note that there are two ways to copy data from source to destination: provide sufficient memory and pass NULL as allocate, or allow the copy function to take care of allocation for the copy.
Manual memory management with no allocation function provided.
The above requires destination capacity be greater than or equal to source capacity. Here is memory management handed over to the copy function.
The above allows destination to have a capacity less than that of the source as long as copy has been provided an allocation function to resize destination. Note that this would still work if copying to a destination that the user wants as a fixed size map.
The above sets up destination with fixed size while source is a dynamic map. Because an allocation function is provided, the destination is resized once for the copy and retains its fixed size after the copy is complete. This would require the user to manually free the underlying Buffer at destination eventually if this method is used. Usually it is better to allocate the memory explicitly before the copy if copying between maps without allocation permission.
These options allow users to stay consistent across containers with their memory management strategies.
| CCC_Count CCC_bitset_count | ( | CCC_Bitset const * | bitset | ) |
Return total number of bits actively tracked by the user and set.
| [in] | bitset | a pointer to the bit set. |
| void * CCC_bitset_data | ( | CCC_Bitset const * | bitset | ) |
Return a reference to the base of the underlying block array.
| [in] | bitset | a pointer to the bit set. |
Every block populates bits from Least Significant Bit (LSB) to Most Significant Bit (MSB) so this reference is to the base or LSB of the entire set.
| CCC_Count CCC_bitset_first_leading_one | ( | CCC_Bitset const * | bitset | ) |
Return the index of the first leading bit set to 1 in the set, starting from the Most Significant Bit at index size - 1.
| [in] | bitset | a pointer to the bit set. |
| CCC_Count CCC_bitset_first_leading_one_range | ( | CCC_Bitset const * | bitset, |
| size_t | index, | ||
| size_t | count | ||
| ) |
Return the index of the first leading bit set to 1 in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | index | the starting index to search. |
| [in] | count | the size of the range to check from index towards index 0. |
| CCC_Count CCC_bitset_first_leading_ones | ( | CCC_Bitset const * | bitset, |
| size_t | ones_count | ||
| ) |
Returns the index of the start of the first leading bit_count contiguous 1 bits.
| [in] | bitset | a pointer to the bit set. |
| [in] | ones_count | the number of leading contiguous 1 bits to find. |
[returned_index, returned_index - ones_count). If such a sequence cannot be found CCC_RESULT_FAIL is set. If bitset is NULL or any argument is out of range an argument error is set. | CCC_Count CCC_bitset_first_leading_ones_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count, | ||
| size_t | ones_count | ||
| ) |
Returns the index of the start of the first leading bit_count contiguous 1 bits in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search. |
| [in] | range_bit_count | the size of the range to check. |
| [in] | ones_count | the number of leading contiguous 1 bits to find. |
[returned_index, returned_index - ones_count). If such a sequence cannot be found CCC_RESULT_FAIL is set. If bitset is NULL or any argument is out of range an argument error is set. | CCC_Count CCC_bitset_first_leading_zero | ( | CCC_Bitset const * | bitset | ) |
Return the index of the first leading bit set to 0 in the set, starting from the Most Significant Bit at index size - 1.
| [in] | bitset | a pointer to the bit set. |
| CCC_Count CCC_bitset_first_leading_zero_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return the index of the first leading bit set to 0 in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search for a 0 bit. |
| [in] | range_bit_count | size to search from Most Significant Bit to Least in range. |
| CCC_Count CCC_bitset_first_leading_zeros | ( | CCC_Bitset const * | bitset, |
| size_t | zeros_count | ||
| ) |
Returns the index of the start of the first leading number of contiguous 0 bits.
| [in] | bitset | a pointer to the bit set. |
| [in] | zeros_count | the number of leading contiguous 0 bits to find. |
[returned_index, returned_index - zeros_count). If such a sequence cannot be found CCC_RESULT_FAIL is set. If bitset is NULL or any argument is out of range an argument error is set. | CCC_Count CCC_bitset_first_leading_zeros_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count, | ||
| size_t | zeros_count | ||
| ) |
Returns the index of the start of the first leading number of contiguous 0 bits in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search. |
| [in] | range_bit_count | the size of the range to check. |
| [in] | zeros_count | the number of leading contiguous 0 bits to find. |
[returned_index, returned_index - zeros_count). If such a sequence cannot be found CCC_RESULT_FAIL is set. If bitset is NULL or any argument is out of range an argument error is set. | CCC_Count CCC_bitset_first_trailing_one | ( | CCC_Bitset const * | bitset | ) |
Return the index of the first trailing bit set to 1 in the set.
| [in] | bitset | a pointer to the bit set. |
| CCC_Count CCC_bitset_first_trailing_one_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return the index of the first trailing bit set to 1 in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search. |
| [in] | range_bit_count | the size of the range to check. |
| CCC_Count CCC_bitset_first_trailing_ones | ( | CCC_Bitset const * | bitset, |
| size_t | ones_count | ||
| ) |
Returns the index of the start of the first trailing number of contiguous 1 bits.
| [in] | bitset | a pointer to the bit set. |
| [in] | ones_count | the number of trailing contiguous 1 bits to find. |
| CCC_Count CCC_bitset_first_trailing_ones_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count, | ||
| size_t | ones_count | ||
| ) |
Returns the index of the start of the first trailing number of contiguous 1 bits in the range [index, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search. |
| [in] | range_bit_count | the size of the range to check. |
| [in] | ones_count | the number of trailing contiguous 1 bits to find. |
| CCC_Count CCC_bitset_first_trailing_zero | ( | CCC_Bitset const * | bitset | ) |
Return the index of the first bit set to 0 in the set.
| [in] | bitset | a pointer to the bit set. |
| CCC_Count CCC_bitset_first_trailing_zero_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return the index of the first bit set to 0 in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search. |
| [in] | range_bit_count | the size of the range to check. |
| CCC_Count CCC_bitset_first_trailing_zeros | ( | CCC_Bitset const * | bitset, |
| size_t | zeros_count | ||
| ) |
Returns the index of the start of the first trailing number of contiguous 0 bits in the set.
| [in] | bitset | a pointer to the bit set. |
| [in] | zeros_count | the number of trailing contiguous 0 bits to find. |
| CCC_Count CCC_bitset_first_trailing_zeros_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count, | ||
| size_t | zeros_count | ||
| ) |
Returns the index of the start of the first trailing zeros_count contiguous 0 bits in the range [i, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to search. |
| [in] | range_bit_count | the size of the range to check. |
| [in] | zeros_count | the number of trailing contiguous 0 bits to find. |
| CCC_Tribool CCC_bitset_flip | ( | CCC_Bitset * | bitset, |
| size_t | index | ||
| ) |
Toggle the bit at index i.
| [in] | bitset | a pointer to the bit set. |
| [in] | index | the index identifying the bit to toggle |
| CCC_Result CCC_bitset_flip_all | ( | CCC_Bitset * | bitset | ) |
Toggle all of the bits to their opposing boolean value.
| [in] | bitset | a pointer to the bit set. |
| CCC_Result CCC_bitset_flip_range | ( | CCC_Bitset * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Flip all the bits in the range, starting at the Least Significant Bit in range and ending at the Most Significant Bit, to their opposite value.
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to reset. |
| [in] | range_bit_count | the count of bits starting at index to reset. |
Note that a range is defined from index to index + count, where index + count is the exclusive end of the range. This is equivalent to moving from Least to Most Significant Bit in an integer.
| CCC_Tribool CCC_bitset_is_empty | ( | CCC_Bitset const * | bitset | ) |
Return true if no bits are actively tracked by the user and set.
| [in] | bitset | a pointer to the bit set. |
| CCC_Tribool CCC_bitset_is_equal | ( | CCC_Bitset const * | left, |
| CCC_Bitset const * | right | ||
| ) |
Checks two bit sets of the same size (not capacity) for equality.
| [in] | left | pointer to a bit set. |
| [in] | right | pointer to another bit set of equal size. |
| CCC_Tribool CCC_bitset_is_proper_subset | ( | CCC_Bitset const * | subset, |
| CCC_Bitset const * | set | ||
| ) |
Return CCC_TRUE if subset is a proper subset of set (subset ⊂ set).
| [in] | subset | the subset to confirm as a proper subset of set. |
| [in] | set | the set to check subset against. |
If set is of size 0 the function returns CCC_FALSE regardless of the size of subset. If set is not of size 0 and subset is of size 0 the function returns CCC_TRUE.
| CCC_Tribool CCC_bitset_is_subset | ( | CCC_Bitset const * | subset, |
| CCC_Bitset const * | set | ||
| ) |
Return CCC_TRUE if subset is a subset of set (subset ⊆ set).
| [in] | the | subset to confirm as a subset of set. |
| [in] | the | set to check subset against. |
If set is size zero subset must also be of size 0 to return CCC_TRUE. If subset is size 0 the function returns CCC_TRUE regardless of the size of set.
| CCC_Tribool CCC_bitset_none | ( | CCC_Bitset const * | bitset | ) |
Return true if all bits are set to 0.
| [in] | bitset | a pointer to the bit set. |
| CCC_Tribool CCC_bitset_none_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return true if all bits are 0 in the range [index, index + count).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting position. |
| [in] | range_bit_count | the size of the range to check. |
| CCC_Result CCC_bitset_or | ( | CCC_Bitset * | destination, |
| CCC_Bitset const * | source | ||
| ) |
Bitwise OR destination set with source set.
| [in] | destination | the set to modified with the OR operation. |
| [in] | source | the set to be read as the source bits for the OR operation. |
Note that sets are aligned from their Least Significant Bit and a smaller source set is conceptually padded with 0's in its higher order bits to align with the larger destination set (no modifications to the smaller set are performed to achieve this). This is done to stay consistent with how the operation would work on a smaller integer stored in a larger integer to align with the larger.
| CCC_Tribool CCC_bitset_pop_back | ( | CCC_Bitset * | bitset | ) |
Remove the Most Significant Bit from the set.
| [in] | bitset | a pointer to the bit set. |
| CCC_Count CCC_bitset_popcount | ( | CCC_Bitset const * | bitset | ) |
Return the number of bits set to CCC_TRUE. O(n).
| [in] | bitset | a pointer to the bit set. |
| CCC_Count CCC_bitset_popcount_range | ( | CCC_Bitset const * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Return the number of bits set to CCC_TRUE in the range. O(n).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting position. |
| [in] | range_bit_count | the size of the range to check. |
| CCC_Result CCC_bitset_push_back | ( | CCC_Bitset * | bitset, |
| CCC_Tribool | bit | ||
| ) |
Append a bit value to the set as the new Most Significant Bit.
| [in] | bitset | a pointer to the bit set. |
| [in] | bit | the value to push at the Most Significant Bit CCC_TRUE/CCC_FALSE. |
| CCC_Result CCC_bitset_reserve | ( | CCC_Bitset * | bitset, |
| size_t | to_add, | ||
| CCC_Allocator * | allocate | ||
| ) |
Reserves space for at least to_add more bits.
| [in] | bitset | a pointer to the bit set. |
| [in] | to_add | the number of elements to add to the current size. |
| [in] | allocate | the allocation function to use to reserve memory. |
This function can be used for a dynamic bit set with or without allocation permission. If the bit set has allocation permission, it will reserve the required space and later resize if more space is needed.
If the bit set has been initialized with no allocation permission and no memory this function can serve as a one-time reservation. This is helpful when a fixed size is needed but that size is only known dynamically at runtime. To free the bit set in such a case see the CCC_bitset_clear_and_free_reserve() function.
| CCC_Tribool CCC_bitset_reset | ( | CCC_Bitset * | bitset, |
| size_t | index | ||
| ) |
Set the bit at valid index index to boolean value b (true or false).
| [in] | bitset | a pointer to the bit set. |
| [in] | index | the valid index identifying the bit to set. |
| CCC_Result CCC_bitset_reset_all | ( | CCC_Bitset * | bitset | ) |
Set all the bits to CCC_FALSE.
| [in] | bitset | a pointer to the bit set. |
| CCC_Result CCC_bitset_reset_range | ( | CCC_Bitset * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count | ||
| ) |
Set all the bits in the specified range starting at the Least Significant Bit of the range and ending at the Most Significant Bit of the range to CCC_FALSE.
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to reset. |
| [in] | range_bit_count | the count of bits starting at index to reset. |
Note that a range is defined from [index, index + count). This is equivalent to moving from Least to Most Significant bit in an integer.
| CCC_Tribool CCC_bitset_set | ( | CCC_Bitset * | bitset, |
| size_t | index, | ||
| CCC_Tribool | bit | ||
| ) |
Set the bit at valid index index to value bit (true or false).
| [in] | bitset | a pointer to the bit set. |
| [in] | index | the valid index identifying the bit to set. |
| [in] | bit | the value to set at position index (CCC_TRUE or CCC_FALSE). |
| CCC_Result CCC_bitset_set_all | ( | CCC_Bitset * | bitset, |
| CCC_Tribool | bit | ||
| ) |
Set all the bits to the provided value (CCC_TRUE or CCC_FALSE).
| [in] | bitset | a pointer to the bit set. |
| [in] | bit | the value to set (CCC_TRUE or CCC_FALSE). |
| CCC_Result CCC_bitset_set_range | ( | CCC_Bitset * | bitset, |
| size_t | range_start_index, | ||
| size_t | range_bit_count, | ||
| CCC_Tribool | bit | ||
| ) |
Set all the bits in the specified range starting at the Least Significant Bit of the range and ending at the Most Significant Bit of the range (CCC_TRUE or CCC_FALSE).
| [in] | bitset | a pointer to the bit set. |
| [in] | range_start_index | the starting index to set. |
| [in] | range_bit_count | the count of bits starting at index to set. |
| [in] | bit | the value to set (CCC_TRUE or CCC_FALSE). |
Note that a range is defined from [index, index + count). This is equivalent to moving from Least to Most Significant bit in an integer.
| CCC_Result CCC_bitset_shift_left | ( | CCC_Bitset * | bitset, |
| size_t | left_shifts | ||
| ) |
Shift the bit set left by left_shifts amount.
| [in] | bitset | a pointer to the bit set. |
| [in] | left_shifts | the number of left shifts to perform. |
Note that if the number of shifts is greater than the bit set size the bit set is zeroed out rather than exhibiting undefined behavior as in the equivalent integer operation.
| CCC_Result CCC_bitset_shift_right | ( | CCC_Bitset * | bitset, |
| size_t | right_shifts | ||
| ) |
Shift the bit set right by right_shifts amount.
| [in] | bitset | a pointer to the bit set. |
| [in] | right_shifts | the number of right shifts to perform. |
Note that if the number of shifts is greater than the bit set size the bit set is zeroed out rather than exhibiting undefined behavior as in the equivalent integer operation.
| CCC_Tribool CCC_bitset_test | ( | CCC_Bitset const * | bitset, |
| size_t | index | ||
| ) |
Test the bit at index index for boolean status (CCC_TRUE or CCC_FALSE).
| [in] | bitset | a pointer to the bit set. |
| [in] | index | the index identifying the bit to set. |
| CCC_Result CCC_bitset_xor | ( | CCC_Bitset * | destination, |
| CCC_Bitset const * | source | ||
| ) |
Bitwise XOR destination set with source set.
| [in] | destination | the set to modified with the XOR operation. |
| [in] | source | the set to be read as the source bits for the XOR operation. |
Note that sets are aligned from their Least Significant Bit and a smaller source set is conceptually padded with 0's in its higher order bits to align with the larger destination set (no modifications to the smaller set are performed to achieve this). This is done to stay consistent with how the operation would work on a smaller integer stored in a larger integer to align with the larger.