Library of Assembled Shared Sources
bit_manip.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_BIT_MANIP_INL
46#define LASS_GUARDIAN_OF_INCLUSION_UTIL_BIT_MANIP_INL
47
48
49#include "bit_manip.h"
50
51
52
53namespace lass
54{
55
56namespace util
57{
58
59/** Set a bit high.
60 * @ingroup BitManip
61 * @author Bram de Greve [Bramz]
62 * @param a_bits the bitfield of which a bit must be set high.
63 * @param a_bit the index of the bit to be set high (0 => 0x1, 1 => 0x2, ...)
64 */
65template<typename T>
66void setBit(T& a_bits, size_t a_bit)
67{
68 a_bits |= (T(1) << a_bit);
69}
70
71
72
73/** set a bit low.
74 * @ingroup BitManip
75 * @author Bram de Greve [Bramz]
76 * @param a_bits the bitfield of which a bit must be set low.
77 * @param a_bit the index of the bit to be set low (0 => 0x1, 1 => 0x2, ...)
78 */
79template<typename T>
80void clearBit(T& a_bits, size_t a_bit)
81{
82 a_bits &= ~(T(1) << a_bit);
83}
84
85
86
87/** flip state of a bit (low->high, high->low).
88 * @ingroup BitManip
89 * @author Bram de Greve [Bramz]
90 * @param a_bits the bitfield of which a bit must be flipped.
91 * @param a_bit the index of the bit to be flipped (0 => 0x1, 1 => 0x2, ...)
92 */
93template<typename T>
94void flipBit(T& a_bits, size_t a_bit)
95{
96 a_bits ^= (T(1) << a_bit);
97}
98
99
100
101/** set a bit high if (and only if) a condition is fullfilled.
102 * @ingroup BitManip
103 * @author Bram de Greve [Bramz]
104 * @param a_bits the bitfield of which a bit must be set high.
105 * @param a_bit the index of the bit to be set high (0 => 0x1, 1 => 0x2, ...)
106 * @param a_condition true if the bit must be set high, false if not.
107 */
108template<typename T>
109void setBitIf(T& a_bits, size_t a_bit, bool a_condition)
110{
111 setMasked(a_bits, a_condition ? (T(1) << a_bit) : T(0));
112}
113
114
115
116/** set a bit low if (and only if) a condition is fullfilled is true.
117 * @ingroup BitManip
118 * @author Bram de Greve [Bramz]
119 * @param a_bits the bitfield of which a bit must be set low.
120 * @param a_bit the index of the bit to be set low (0 => 0x1, 1 => 0x2, ...)
121 * @param a_condition true if the bit must be set low, false if not.
122 */
123template<typename T>
124void clearBitIf(T& a_bits, size_t a_bit, bool a_condition)
125{
126 clearMasked(a_bits, a_condition ? (T(1) << a_bit) : T(0));
127}
128
129
130
131/** flip a bit if (and only if) a condition is fullfilled (low->high, high->low).
132 * @ingroup BitManip
133 * @author Bram de Greve [Bramz]
134 * @param a_bits the bitfield of which a bit must be flipped.
135 * @param a_bit the index of the bit to be flipped (0 => 0x1, 1 => 0x2, ...)
136 * @param a_condition true if the bit must be flipped, false if not.
137 */
138template<typename T>
139void flipBitIf(T& a_bits, size_t a_bit, bool a_condition)
140{
141 flipMasked(a_bits, a_condition ? (T(1) << a_bit) : T(0));
142}
143
144
145
146/** set a bit to a given state.
147 * @ingroup BitManip
148 * @author Bram de Greve [Bramz]
149 * @param a_bits the bitfield of which a bit must be set.
150 * @param a_bit the index of the bit to be set (0 => 0x1, 1 => 0x2, ...)
151 * @param a_state the state to which the bit must be set: true for high, false for low.
152 */
153template<typename T>
154void setBitTo(T& a_bits, size_t a_bit, bool a_state)
155{
156 clearBit(a_bits, a_bit);
157 setBitIf(a_bits, a_bit, a_state);
158}
159
160
161
162/** return true if a bit is set high.
163 * @ingroup BitManip
164 * @author Bram de Greve [Bramz]
165 * @param a_bits the bitfield of which a bit must be checked.
166 * @param a_bit the index of the bit to be checked (0 => 0x1, 1 => 0x2, ...)
167 */
168template<typename T>
169bool checkBit(T a_bits, size_t a_bit)
170{
171 return (a_bits & (T(1) << a_bit)) != 0;
172}
173
174
175
176
177/** Set masked bits high.
178 * @ingroup BitManip
179 * @author Bram de Greve [Bramz]
180 * @param a_bits the bitfield of which some bits must be set high.
181 * @param a_mask mask indicating the bits that must be set high.
182 * The high bits in the mask indicate the bits in the bitfield to be set,
183 * the low bits in the mask indicate the bits in the bitfield to be left
184 * untouched.
185 */
186template<typename T>
187void setMasked(T& a_bits, const T& a_mask)
188{
189 a_bits |= a_mask;
190}
191
192
193
194/** Set masked bits low.
195 * @ingroup BitManip
196 * @author Bram de Greve [Bramz]
197 * @param a_bits the bitfield of which some bits must be set low.
198 * @param a_mask mask indicating the bits that must be set low.
199 * The high bits in the mask indicate the bits in the bitfield to be set,
200 * the low bits in the mask indicate the bits in the bitfield to be left
201 * untouched.
202 */
203template<typename T>
204void clearMasked(T& a_bits, const T& a_mask)
205{
206 a_bits &= ~a_mask;
207}
208
209
210
211/** flip masked bits.
212 * @ingroup BitManip
213 * @author Bram de Greve [Bramz]
214 * @param a_bits the bitfield of which some bits must be flipped.
215 * @param a_mask mask indicating the bits that must be flipped.
216 * The high bits in the mask indicate the bits in the bitfield to be flipped,
217 * the low bits in the mask indicate the bits in the bitfield to be left
218 * untouched.
219 */
220template<typename T>
221void flipMasked(T& a_bits, const T& a_mask)
222{
223 a_bits ^= a_mask;
224}
225
226
227
228/** Set masked bits high if (and only if) a condition is fullfilled.
229 * @ingroup BitManip
230 * @author Bram de Greve [Bramz]
231 * @param a_bits the bitfield of which some bits must be set high.
232 * @param a_mask mask indicating the bits that must be set high.
233 * The high bits in the mask indicate the bits in the bitfield to be set,
234 * the low bits in the mask indicate the bits in the bitfield to be left
235 * untouched.
236 * @param a_condition true if the bits must be set, false if not.
237 */
238template<typename T>
239void setMaskedIf(T& a_bits, const T& a_mask, bool a_condition)
240{
241 setMasked(a_bits, a_condition ? a_mask : T(0));
242}
243
244
245
246/** Set masked bits low if (and only if) a condition is fullfilled.
247 * @ingroup BitManip
248 * @author Bram de Greve [Bramz]
249 * @param a_bits the bitfield of which some bits must be set low.
250 * @param a_mask mask indicating the bits that must be set low.
251 * The high bits in the mask indicate the bits in the bitfield to be set,
252 * the low bits in the mask indicate the bits in the bitfield to be left
253 * untouched.
254 * @param a_condition true if the bits must be set, false if not.
255 */
256template<typename T>
257void clearMaskedIf(T& a_bits, const T& a_mask, bool a_condition)
258{
259 clearMasked(a_bits, a_condition ? a_mask : T(0));
260}
261
262
263
264/** Flip the masked bits if (and only if) a condition is fullfilled.
265 * @ingroup BitManip
266 * @author Bram de Greve [Bramz]
267 * @param a_bits the bitfield of which some bits must be flipped.
268 * @param a_mask mask indicating the bits that must be flipped.
269 * The high bits in the mask indicate the bits in the bitfield to be flipped,
270 * the low bits in the mask indicate the bits in the bitfield to be left
271 * untouched.
272 * @param a_condition true if the bits must be flipped, false if not.
273 */
274template<typename T>
275void flipMaskedIf(T& a_bits, const T& a_mask, bool a_condition)
276{
277 flipMasked(a_bits, a_condition ? a_mask : T(0));
278}
279
280
281
282/** Set the masked bits to a given state if (and only if) a condition is fullfilled.
283 * @ingroup BitManip
284 * @author Bram de Greve [Bramz]
285 * @param a_bits the bitfield of which some bits must be set.
286 * @param a_mask mask indicating the bits that must be set.
287 * The high bits in the mask indicate the bits in the bitfield to be set,
288 * the low bits in the mask indicate the bits in the bitfield to be left
289 * untouched.
290 * @param a_state the state to which the bits must be set: true for high, false for low.
291 */
292template<typename T>
293void setMaskedTo(T& a_bits, const T& a_mask, bool a_state)
294{
295 clearMasked(a_bits, a_mask);
296 setMaskedIf(a_bits, a_mask, a_state);
297}
298
299
300
301/** Check the masked bits and return true if they are ALL set.
302 * @ingroup BitManip
303 * @author Bram de Greve [Bramz]
304 * @param a_bits the bitfield of which some bits must be checked.
305 * @param a_mask mask indicating the bits that must be checked.
306 * The high bits in the mask indicate the bits in the bitfield to be checked,
307 * the low bits in the mask indicate the bits in the bitfield to be left
308 * untouched.
309 * @return true if ALL masked bits are set, false if not. So it also returns if only
310 * a few of the masked bits are set, but not all of them.
311 */
312template<typename T>
313bool checkMaskedAll(T a_bits, const T& a_mask)
314{
315 return (a_bits & a_mask) == a_mask;
316}
317
318
319
320/** Check the masked bits and return true if at least one is set.
321 * @ingroup BitManip
322 * @author Bram de Greve [Bramz]
323 * @param a_bits the bitfield of which some bits must be checked.
324 * @param a_mask mask indicating the bits that must be checked.
325 * The high bits in the mask indicate the bits in the bitfield to be checked,
326 * the low bits in the mask indicate the bits in the bitfield to be left
327 * untouched.
328 * @return true if at least one masked bits is set, false if not.
329 */
330template<typename T>
331bool checkMaskedSome(T a_bits, const T& a_mask)
332{
333 return (a_bits & a_mask) != 0;
334}
335
336
337
338namespace impl
339{
340 /** lookup table of number of bits in a byte
341 * @ingroup BitManip
342 * @internal
343 */
344 const size_t bitsInByte[256] =
345 {
346 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
347 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
348 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
349 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
350 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
351 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
352 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
353 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
354 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
355 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
356 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
357 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
358 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
359 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
360 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
361 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
362 };
363
364 /** countBits helper
365 * @ingroup BitManip
366 * @internal
367 */
368 template <size_t numBytes> struct BitCounter;
369
370 template <>
371 struct BitCounter<1>
372 {
373 template <typename T> static size_t count(T bits)
374 {
375 return bitsInByte[(num::Tuint8) bits];
376 }
377 };
378
379 template <>
380 struct BitCounter<2>
381 {
382 template <typename T> static size_t count(T bits)
383 {
384 const num::Tuint16 x = (num::Tuint16) bits;
385 return impl::bitsInByte[x >> 8] + impl::bitsInByte[x & 0xff];
386 }
387 };
388
389 template <>
390 struct BitCounter<4>
391 {
392 template <typename T> static size_t count(T bits)
393 {
394 const num::Tuint32 x = (num::Tuint32) bits;
395 return impl::bitsInByte[x >> 24] + impl::bitsInByte[(x >> 16) & 0xff] +
396 impl::bitsInByte[(x >> 8) & 0xff] + impl::bitsInByte[x & 0xff];
397 }
398 };
399
400 template <>
401 struct BitCounter<8>
402 {
403 template <typename T> static size_t count(T bits)
404 {
405 const num::Tuint64 x = (num::Tuint64) bits;
406 return impl::bitsInByte[x >> 56] + impl::bitsInByte[(x >> 48) & 0xff] +
407 impl::bitsInByte[(x >> 40) & 0xff] + impl::bitsInByte[(x >> 32) & 0xff] +
408 impl::bitsInByte[(x >> 24) & 0xff] + impl::bitsInByte[(x >> 16) & 0xff] +
409 impl::bitsInByte[(x >> 8) & 0xff] + impl::bitsInByte[x & 0xff];
410 }
411 };
412}
413
414/** returns number of set bits in @a bits
415 * @ingroup BitManip
416 */
417template <typename T> inline size_t countBits(T bits)
418{
419 return impl::BitCounter<sizeof(T)>::count(bits);
420}
421
422}
423
424}
425
426#endif
427
428// --- END OF FILE ------------------------------------------------------------------------------
bool checkBit(T a_bits, size_t a_bit)
return true if a bit is set high.
bool checkMaskedSome(T a_bits, const T &a_mask)
Check the masked bits and return true if at least one is set.
void setBit(T &a_bits, size_t a_bit)
Set a bit high.
Definition bit_manip.inl:66
void setMaskedIf(T &a_bits, const T &a_mask, bool a_condition)
Set masked bits high if (and only if) a condition is fullfilled.
const size_t bitsInByte[256]
lookup table of number of bits in a byte
void setBitTo(T &a_bits, size_t a_bit, bool a_state)
set a bit to a given state.
void flipMaskedIf(T &a_bits, const T &a_mask, bool a_condition)
Flip the masked bits if (and only if) a condition is fullfilled.
bool checkMaskedAll(T a_bits, const T &a_mask)
Check the masked bits and return true if they are ALL set.
void flipBitIf(T &a_bits, size_t a_bit, bool a_condition)
flip a bit if (and only if) a condition is fullfilled (low->high, high->low).
void clearMasked(T &a_bits, const T &a_mask)
Set masked bits low.
void setMasked(T &a_bits, const T &a_mask)
Set masked bits high.
size_t countBits(T bits)
returns number of set bits in bits
void clearMaskedIf(T &a_bits, const T &a_mask, bool a_condition)
Set masked bits low if (and only if) a condition is fullfilled.
void clearBitIf(T &a_bits, size_t a_bit, bool a_condition)
set a bit low if (and only if) a condition is fullfilled is true.
void setBitIf(T &a_bits, size_t a_bit, bool a_condition)
set a bit high if (and only if) a condition is fullfilled.
void flipMasked(T &a_bits, const T &a_mask)
flip masked bits.
void clearBit(T &a_bits, size_t a_bit)
set a bit low.
Definition bit_manip.inl:80
void flipBit(T &a_bits, size_t a_bit)
flip state of a bit (low->high, high->low).
Definition bit_manip.inl:94
void setMaskedTo(T &a_bits, const T &a_mask, bool a_state)
Set the masked bits to a given state if (and only if) a condition is fullfilled.
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Definition config.h:53