ezEngine  Milestone 7
Bitfield_inl.h
1 #pragma once
2 
3 template<class Container>
4 EZ_FORCE_INLINE ezUInt32 ezBitfield<Container>::GetBitInt(ezUInt32 uiBitIndex) const
5 {
6  return (uiBitIndex >> 5); // div 32
7 }
8 
9 template<class Container>
10 EZ_FORCE_INLINE ezUInt32 ezBitfield<Container>::GetBitMask(ezUInt32 uiBitIndex) const
11 {
12  return 1 << (uiBitIndex & 0x1F); // modulo 32, shifted to bit position
13 }
14 
15 template<class Container>
16 ezBitfield<Container>::ezBitfield() : m_uiCount(0)
17 {
18 }
19 
20 template<class Container>
22 {
23  return m_uiCount;
24 }
25 
26 template<class Container>
27 void ezBitfield<Container>::SetCount(ezUInt32 uiBitCount)
28 {
29  const ezUInt32 uiInts = (uiBitCount + 31) >> 5;
30  m_Container.SetCount(uiInts);
31 
32  m_uiCount = uiBitCount;
33 }
34 
35 template<class Container>
36 void ezBitfield<Container>::SetCount(ezUInt32 uiBitCount, bool bSetNew)
37 {
38  if (m_uiCount == uiBitCount)
39  return;
40 
41  const ezUInt32 uiOldBits = m_uiCount;
42 
43  SetCount(uiBitCount);
44 
45  // if there are new bits, initialize them
46  if (uiBitCount > uiOldBits)
47  {
48  if (bSetNew)
49  SetRange(uiOldBits, uiBitCount - 1);
50  else
51  ClearRange(uiOldBits, uiBitCount - 1);
52  }
53 }
54 
55 template<class Container>
57 {
58  return m_uiCount == 0;
59 }
60 
61 template<class Container>
63 {
64  m_uiCount = 0;
65  m_Container.Clear();
66 }
67 
68 template<class Container>
69 void ezBitfield<Container>::SetBit(ezUInt32 uiBit)
70 {
71  EZ_ASSERT_DEV(uiBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiBit, m_uiCount);
72 
73  m_Container[GetBitInt(uiBit)] |= GetBitMask(uiBit);
74 }
75 
76 template<class Container>
77 void ezBitfield<Container>::ClearBit(ezUInt32 uiBit)
78 {
79  EZ_ASSERT_DEV(uiBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiBit, m_uiCount);
80 
81  m_Container[GetBitInt(uiBit)] &= ~GetBitMask(uiBit);
82 }
83 
84 template<class Container>
85 bool ezBitfield<Container>::IsSet(ezUInt32 uiBit) const
86 {
87  EZ_ASSERT_DEV(uiBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiBit, m_uiCount);
88 
89  return (m_Container[GetBitInt(uiBit)] & GetBitMask(uiBit)) != 0;
90 }
91 
92 template<class Container>
94 {
95  for (ezUInt32 i = 0; i < m_Container.GetCount(); ++i)
96  m_Container[i] = 0;
97 }
98 
99 template<class Container>
101 {
102  for (ezUInt32 i = 0; i < m_Container.GetCount(); ++i)
103  m_Container[i] = 0xFFFFFFFF;
104 }
105 
106 template<class Container>
107 void ezBitfield<Container>::SetRange(ezUInt32 uiFirstBit, ezUInt32 uiLastBit)
108 {
109  EZ_ASSERT_DEV(uiFirstBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiFirstBit, m_uiCount);
110  EZ_ASSERT_DEV(uiLastBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiLastBit, m_uiCount);
111 
112  const ezUInt32 uiFirstInt = GetBitInt(uiFirstBit);
113  const ezUInt32 uiLastInt = GetBitInt(uiLastBit);
114 
115  // all within the same int
116  if (uiFirstInt == uiLastInt)
117  {
118  for (ezUInt32 i = uiFirstBit; i <= uiLastBit; ++i)
119  SetBit(i);
120 
121  return;
122  }
123 
124  const ezUInt32 uiNextIntBit = (uiFirstInt + 1) * 32;
125  const ezUInt32 uiPrevIntBit = uiLastInt * 32;
126 
127  // set the bits in the first int individually
128  for (ezUInt32 i = uiFirstBit; i < uiNextIntBit; ++i)
129  SetBit(i);
130 
131  // set the bits in the ints in between with one operation
132  for (ezUInt32 i = uiFirstInt + 1; i < uiLastInt; ++i)
133  m_Container[i] = 0xFFFFFFFF;
134 
135  // set the bits in the last int individually
136  for (ezUInt32 i = uiPrevIntBit; i <= uiLastBit; ++i)
137  SetBit(i);
138 }
139 
140 template<class Container>
141 void ezBitfield<Container>::ClearRange(ezUInt32 uiFirstBit, ezUInt32 uiLastBit)
142 {
143  EZ_ASSERT_DEV(uiFirstBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiFirstBit, m_uiCount);
144  EZ_ASSERT_DEV(uiLastBit < m_uiCount, "Cannot access bit %i, the bitfield only has %i bits.", uiLastBit, m_uiCount);
145 
146  const ezUInt32 uiFirstInt = GetBitInt(uiFirstBit);
147  const ezUInt32 uiLastInt = GetBitInt(uiLastBit);
148 
149  // all within the same int
150  if (uiFirstInt == uiLastInt)
151  {
152  for (ezUInt32 i = uiFirstBit; i <= uiLastBit; ++i)
153  ClearBit(i);
154 
155  return;
156  }
157 
158  const ezUInt32 uiNextIntBit = (uiFirstInt + 1) * 32;
159  const ezUInt32 uiPrevIntBit = uiLastInt * 32;
160 
161  // set the bits in the first int individually
162  for (ezUInt32 i = uiFirstBit; i < uiNextIntBit; ++i)
163  ClearBit(i);
164 
165  // set the bits in the ints in between with one operation
166  for (ezUInt32 i = uiFirstInt + 1; i < uiLastInt; ++i)
167  m_Container[i] = 0;
168 
169  // set the bits in the last int individually
170  for (ezUInt32 i = uiPrevIntBit; i <= uiLastBit; ++i)
171  ClearBit(i);
172 }
173