Xyris  0.5
Bitset.hpp
Go to the documentation of this file.
1 /**
2  * @file Bitset.hpp
3  * @author Micah Switzer ([email protected])
4  * @author Keeton Feasvel ([email protected])
5  * @brief A basic bitmap implementation
6  * @version 0.3
7  * @date 2020-07-08
8  *
9  * @copyright Copyright the Xyris Contributors (c) 2020
10  *
11  */
12 #pragma once
13 
14 #include <Arch/Arch.hpp>
15 #include <Library/string.hpp>
16 #include <limits.h>
17 #include <stddef.h>
18 #include <stdint.h>
19 
20 template<size_t S>
21 class Bitset {
22 public:
23  /**
24  * @brief Construct a new Bitset object and initalize
25  * the bitmap to zero.
26  *
27  */
29  {
30  memset(&map, 0, S);
31  }
32 
33  /**
34  * @brief Construct a new Bitset object and initialize
35  * the bitmap with the desired value
36  *
37  * @param val Initialization value
38  */
39  Bitset(size_t val)
40  {
41  for (size_t i = 0; i < S; i++)
42  map[i] = val;
43  }
44 
45  /**
46  * @brief Returns the size of the bitset in bytes
47  *
48  * @return size_t Size of the bitset in bytes
49  */
50  [[gnu::always_inline]] size_t Size()
51  {
52  return S;
53  }
54 
55  /**
56  * @brief Set the bit for a given position
57  *
58  * @param pos Target bit to be set
59  */
60  [[gnu::always_inline]] void Set(size_t pos)
61  {
62  map[Index(pos)] |= 1UL << Offset(pos);
63  }
64 
65  /**
66  * @brief Reset (clear) the bit at the given position
67  *
68  * @param pos Target bit to be reset
69  */
70  [[gnu::always_inline]] void Reset(size_t pos)
71  {
72  map[Index(pos)] &= ~(1UL << Offset(pos));
73  }
74 
75  /**
76  * @brief Flip the bit at the given position
77  *
78  * @param pos Target bit to be flipped
79  */
80  [[gnu::always_inline]] void Flip(size_t pos)
81  {
82  Test(pos) ? Reset(pos) : Set(pos);
83  }
84 
85  /**
86  * @brief Return the value of the bit at the given position
87  *
88  * @param pos Position to be tested
89  * @return bool Bit value
90  */
91  [[gnu::always_inline]] bool Test(size_t pos)
92  {
93  return map[Index(pos)] >> Offset(pos) & 1;
94  }
95 
96  /**
97  * @brief Return the value of the bit at the given position
98  * Same functionality as Test() as an operator
99  * This operator cannot be used to set a bit, only test
100  *
101  * @param pos Position to be tested
102  * @return bool Bit value
103  */
104  [[gnu::always_inline]] bool operator[](size_t pos)
105  {
106  return Test(pos);
107  }
108 
109  /**
110  * @brief Finds and returns the position of the first clear bit.
111  *
112  * @param isSet If true, find the first bit that is set.
113  * @return size_t Position of the first bit with desired polarity.
114  * If all bits are polarized, SIZE_MAX is returned.
115  */
116  [[gnu::always_inline]] size_t FindFirstBit(bool isSet)
117  {
118  for (size_t i = 0; i < S; i++) {
119  if (Test(i) == isSet)
120  return i;
121  }
122  return SIZE_MAX;
123  }
124 
125  /**
126  * @brief Finds a range of `count` clear bits and returns the starting position.
127  *
128  * @param count Number of clear bits desired
129  * @param isSet If true, find the first range of `count` bits that are set.
130  * @return size_t Position of the first bit with desired range and polarity.
131  * If all bits are polarized, SIZE_MAX is returned.
132  */
133  [[gnu::always_inline]] size_t FindFirstRange(size_t count, bool isSet)
134  {
135  size_t checkLow, checkHigh, check, idx, offset;
136  size_t mask = ((size_t)1 << count) - (size_t)1;
137  for (size_t i = 0UL; i < S - count; i++) {
138  idx = Index(i);
139  offset = Offset(i);
140  checkLow = map[idx] >> offset;
141  checkHigh = offset ? map[idx + 1] << (TypeSize() - offset) : 0;
142  check = checkLow | checkHigh;
143 
144  if ((check & mask) == isSet)
145  return i;
146  }
147  return SIZE_MAX;
148  }
149 
150 private:
151  size_t map[S];
152  [[gnu::always_inline]] size_t TypeSize()
153  {
154  return sizeof(size_t) * CHAR_BIT;
155  }
156 
157  [[gnu::always_inline]] size_t Index(size_t bit)
158  {
159  return bit / TypeSize();
160  }
161 
162  [[gnu::always_inline]] size_t Offset(size_t bit)
163  {
164  return bit % TypeSize();
165  }
166 };
Bitset::TypeSize
size_t TypeSize()
Definition: Bitset.hpp:152
Bitset::Test
bool Test(size_t pos)
Return the value of the bit at the given position.
Definition: Bitset.hpp:91
Bitset::Index
size_t Index(size_t bit)
Definition: Bitset.hpp:157
Bitset::Set
void Set(size_t pos)
Set the bit for a given position.
Definition: Bitset.hpp:60
Bitset::Offset
size_t Offset(size_t bit)
Definition: Bitset.hpp:162
Bitset::map
size_t map[S]
Definition: Bitset.hpp:151
string.hpp
Standard string and memory utility library.
Bitset::operator[]
bool operator[](size_t pos)
Return the value of the bit at the given position Same functionality as Test() as an operator This op...
Definition: Bitset.hpp:104
Bitset::FindFirstBit
size_t FindFirstBit(bool isSet)
Finds and returns the position of the first clear bit.
Definition: Bitset.hpp:116
Bitset::Bitset
Bitset()
Construct a new Bitset object and initalize the bitmap to zero.
Definition: Bitset.hpp:28
Arch.hpp
Architecture control and initialization.
Bitset::Flip
void Flip(size_t pos)
Flip the bit at the given position.
Definition: Bitset.hpp:80
Bitset::FindFirstRange
size_t FindFirstRange(size_t count, bool isSet)
Finds a range of count clear bits and returns the starting position.
Definition: Bitset.hpp:133
Bitset::Bitset
Bitset(size_t val)
Construct a new Bitset object and initialize the bitmap with the desired value.
Definition: Bitset.hpp:39
memset
void * memset(void *bufptr, int value, size_t size)
Sets the number of bytes in memory at ptr to the value.
Definition: string.cpp:106
Bitset
Definition: Bitset.hpp:21
Bitset::Size
size_t Size()
Returns the size of the bitset in bytes.
Definition: Bitset.hpp:50
Bitset::Reset
void Reset(size_t pos)
Reset (clear) the bit at the given position.
Definition: Bitset.hpp:70