mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-08-03 17:26:08 -04:00
131 lines
3.2 KiB
C++
131 lines
3.2 KiB
C++
//=======================================================================
|
|
// Copyright Baptiste Wicht 2013-2018.
|
|
// Distributed under the terms of the MIT License.
|
|
// (See accompanying file LICENSE or copy at
|
|
// http://www.opensource.org/licenses/MIT)
|
|
//=======================================================================
|
|
|
|
#ifndef BITMAP_H
|
|
#define BITMAP_H
|
|
|
|
#include "assert.hpp"
|
|
|
|
/*!
|
|
* \brief A static bitmap.
|
|
*
|
|
* This bitmap cannot be extended. The data must be provided via one of its init functions.
|
|
*/
|
|
struct static_bitmap {
|
|
using data_type = uint64_t; ///< The word type
|
|
|
|
static constexpr const size_t bits_per_word = sizeof(data_type) * 8; ///< The number of bits stored in each word
|
|
static constexpr const size_t npos = 18446744073709551615ULL; ///< Special number indicating an error
|
|
|
|
template<typename Array>
|
|
void init(Array& array){
|
|
words = array.size();
|
|
data = array.data();
|
|
}
|
|
|
|
void init(size_t w, data_type* d){
|
|
words = w;
|
|
data = d;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the word in which the bit is
|
|
*/
|
|
static constexpr size_t word_offset(size_t bit){
|
|
return bit / bits_per_word;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the offset of the bit inside its word
|
|
*/
|
|
static constexpr size_t bit_offset(size_t bit){
|
|
return bit % bits_per_word;
|
|
}
|
|
|
|
/*
|
|
* \brief Constructs a bit mask for the given bit
|
|
*/
|
|
static constexpr data_type bit_mask(size_t bit){
|
|
return static_cast<data_type>(1) << bit_offset(bit);
|
|
}
|
|
|
|
/*!
|
|
* \brief Clear the complete bit map (set everything to zero)
|
|
*/
|
|
void clear_all(){
|
|
for(size_t i = 0; i < words; ++i){
|
|
data[i] = 0;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Set the complete bit map (set everything to one)
|
|
*/
|
|
void set_all(){
|
|
for(size_t i = 0; i < words; ++i){
|
|
data[i] = ~static_cast<data_type>(0);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the first set bit in the bit map
|
|
*/
|
|
size_t set_bit() const {
|
|
for(size_t w = 0; w < words; ++w){
|
|
if(data[w]){
|
|
for(size_t b = 0; b < bits_per_word; ++b){
|
|
if(data[w] & bit_mask(b)){
|
|
return w * bits_per_word + b;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return npos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the first set word in the bit map
|
|
*/
|
|
size_t set_word() const {
|
|
for(size_t w = 0; w < words; ++w){
|
|
if(data[w] == ~static_cast<data_type>(0)){
|
|
return w * bits_per_word;
|
|
}
|
|
}
|
|
|
|
return npos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Indicates if the given bit is set
|
|
*/
|
|
bool is_set(size_t bit) const {
|
|
return data[word_offset(bit)] & bit_mask(bit);
|
|
}
|
|
|
|
/*!
|
|
* \brief Sets the given bit to 1
|
|
*/
|
|
void set(size_t bit){
|
|
data[word_offset(bit)] |= bit_mask(bit);
|
|
}
|
|
|
|
/*!
|
|
* \brief clear the given bit to 1
|
|
*/
|
|
void unset(size_t bit){
|
|
data[word_offset(bit)] &= ~bit_mask(bit);
|
|
}
|
|
|
|
private:
|
|
size_t words; ///< Number of words used in the bitmap
|
|
data_type* data; ///< The data storage
|
|
};
|
|
|
|
#endif
|