library of assembled shared sources |
http://lass.cocamware.com |
00001 /** @file 00002 * @author Bram de Greve (bramz@users.sourceforge.net) 00003 * @author Tom De Muer (tomdemuer@users.sourceforge.net) 00004 * 00005 * *** BEGIN LICENSE INFORMATION *** 00006 * 00007 * The contents of this file are subject to the Common Public Attribution License 00008 * Version 1.0 (the "License"); you may not use this file except in compliance with 00009 * the License. You may obtain a copy of the License at 00010 * http://lass.sourceforge.net/cpal-license. The License is based on the 00011 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 00012 * use of software over a computer network and provide for limited attribution for 00013 * the Original Developer. In addition, Exhibit A has been modified to be consistent 00014 * with Exhibit B. 00015 * 00016 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 00017 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific 00018 * language governing rights and limitations under the License. 00019 * 00020 * The Original Code is LASS - Library of Assembled Shared Sources. 00021 * 00022 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer. 00023 * The Original Developer is the Initial Developer. 00024 * 00025 * All portions of the code written by the Initial Developer are: 00026 * Copyright (C) 2004-2007 the Initial Developer. 00027 * All Rights Reserved. 00028 * 00029 * Contributor(s): 00030 * 00031 * Alternatively, the contents of this file may be used under the terms of the 00032 * GNU General Public License Version 2 or later (the GPL), in which case the 00033 * provisions of GPL are applicable instead of those above. If you wish to allow use 00034 * of your version of this file only under the terms of the GPL and not to allow 00035 * others to use your version of this file under the CPAL, indicate your decision by 00036 * deleting the provisions above and replace them with the notice and other 00037 * provisions required by the GPL License. If you do not delete the provisions above, 00038 * a recipient may use your version of this file under either the CPAL or the GPL. 00039 * 00040 * *** END LICENSE INFORMATION *** 00041 */ 00042 00043 00044 00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_BIT_MANIP_INL 00046 #define LASS_GUARDIAN_OF_INCLUSION_UTIL_BIT_MANIP_INL 00047 00048 00049 #include "bit_manip.h" 00050 00051 00052 00053 namespace lass 00054 { 00055 00056 namespace util 00057 { 00058 00059 /** Set a bit high. 00060 * @ingroup BitManip 00061 * @author Bram de Greve [Bramz] 00062 * @param a_bits the bitfield of which a bit must be set high. 00063 * @param a_bit the index of the bit to be set high (0 => 0x1, 1 => 0x2, ...) 00064 */ 00065 template<typename T> 00066 void setBit(T& a_bits, unsigned a_bit) 00067 { 00068 a_bits |= (1 << a_bit); 00069 } 00070 00071 00072 00073 /** set a bit low. 00074 * @ingroup BitManip 00075 * @author Bram de Greve [Bramz] 00076 * @param a_bits the bitfield of which a bit must be set low. 00077 * @param a_bit the index of the bit to be set low (0 => 0x1, 1 => 0x2, ...) 00078 */ 00079 template<typename T> 00080 void clearBit(T& a_bits, unsigned a_bit) 00081 { 00082 a_bits &= ~(1 << a_bit); 00083 } 00084 00085 00086 00087 /** flip state of a bit (low->high, high->low). 00088 * @ingroup BitManip 00089 * @author Bram de Greve [Bramz] 00090 * @param a_bits the bitfield of which a bit must be flipped. 00091 * @param a_bit the index of the bit to be flipped (0 => 0x1, 1 => 0x2, ...) 00092 */ 00093 template<typename T> 00094 void flipBit(T& a_bits, unsigned a_bit) 00095 { 00096 a_bits ^= (1 << a_bit); 00097 } 00098 00099 00100 00101 /** set a bit high if (and only if) a condition is fullfilled. 00102 * @ingroup BitManip 00103 * @author Bram de Greve [Bramz] 00104 * @param a_bits the bitfield of which a bit must be set high. 00105 * @param a_bit the index of the bit to be set high (0 => 0x1, 1 => 0x2, ...) 00106 * @param a_condition true if the bit must be set high, false if not. 00107 */ 00108 template<typename T> 00109 void setBitIf(T& a_bits, unsigned a_bit, bool a_condition) 00110 { 00111 setMasked(a_bits, a_condition ? (1 << a_bit) : 0); 00112 } 00113 00114 00115 00116 /** set a bit low if (and only if) a condition is fullfilled is true. 00117 * @ingroup BitManip 00118 * @author Bram de Greve [Bramz] 00119 * @param a_bits the bitfield of which a bit must be set low. 00120 * @param a_bit the index of the bit to be set low (0 => 0x1, 1 => 0x2, ...) 00121 * @param a_condition true if the bit must be set low, false if not. 00122 */ 00123 template<typename T> 00124 void clearBitIf(T& a_bits, unsigned a_bit, bool a_condition) 00125 { 00126 clearMasked(a_bits, a_condition ? (1 << a_bit) : 0); 00127 } 00128 00129 00130 00131 /** flip a bit if (and only if) a condition is fullfilled (low->high, high->low). 00132 * @ingroup BitManip 00133 * @author Bram de Greve [Bramz] 00134 * @param a_bits the bitfield of which a bit must be flipped. 00135 * @param a_bit the index of the bit to be flipped (0 => 0x1, 1 => 0x2, ...) 00136 * @param a_condition true if the bit must be flipped, false if not. 00137 */ 00138 template<typename T> 00139 void flipBitIf(T& a_bits, unsigned a_bit, bool a_condition) 00140 { 00141 flipMasked(a_bits, a_condition ? (1 << a_bit) : 0); 00142 } 00143 00144 00145 00146 /** set a bit to a given state. 00147 * @ingroup BitManip 00148 * @author Bram de Greve [Bramz] 00149 * @param a_bits the bitfield of which a bit must be set. 00150 * @param a_bit the index of the bit to be set (0 => 0x1, 1 => 0x2, ...) 00151 * @param a_state the state to which the bit must be set: true for high, false for low. 00152 */ 00153 template<typename T> 00154 void setBitTo(T& a_bits, unsigned a_bit, bool a_state) 00155 { 00156 clearBit(a_bits, a_bit); 00157 setBitIf(a_bits, a_bit, a_state); 00158 } 00159 00160 00161 00162 /** return true if a bit is set high. 00163 * @ingroup BitManip 00164 * @author Bram de Greve [Bramz] 00165 * @param a_bits the bitfield of which a bit must be checked. 00166 * @param a_bit the index of the bit to be checked (0 => 0x1, 1 => 0x2, ...) 00167 */ 00168 template<typename T> 00169 bool checkBit(T a_bits, unsigned a_bit) 00170 { 00171 return a_bits & (1 << a_bit); 00172 } 00173 00174 00175 00176 00177 /** Set masked bits high. 00178 * @ingroup BitManip 00179 * @author Bram de Greve [Bramz] 00180 * @param a_bits the bitfield of which some bits must be set high. 00181 * @param a_mask mask indicating the bits that must be set high. 00182 * The high bits in the mask indicate the bits in the bitfield to be set, 00183 * the low bits in the mask indicate the bits in the bitfield to be left 00184 * untouched. 00185 */ 00186 template<typename T> 00187 void setMasked(T& a_bits, const T& a_mask) 00188 { 00189 a_bits |= a_mask; 00190 } 00191 00192 00193 00194 /** Set masked bits low. 00195 * @ingroup BitManip 00196 * @author Bram de Greve [Bramz] 00197 * @param a_bits the bitfield of which some bits must be set low. 00198 * @param a_mask mask indicating the bits that must be set low. 00199 * The high bits in the mask indicate the bits in the bitfield to be set, 00200 * the low bits in the mask indicate the bits in the bitfield to be left 00201 * untouched. 00202 */ 00203 template<typename T> 00204 void clearMasked(T& a_bits, const T& a_mask) 00205 { 00206 a_bits &= ~a_mask; 00207 } 00208 00209 00210 00211 /** flip masked bits. 00212 * @ingroup BitManip 00213 * @author Bram de Greve [Bramz] 00214 * @param a_bits the bitfield of which some bits must be flipped. 00215 * @param a_mask mask indicating the bits that must be flipped. 00216 * The high bits in the mask indicate the bits in the bitfield to be flipped, 00217 * the low bits in the mask indicate the bits in the bitfield to be left 00218 * untouched. 00219 */ 00220 template<typename T> 00221 void flipMasked(T& a_bits, const T& a_mask) 00222 { 00223 a_bits ^= a_mask; 00224 } 00225 00226 00227 00228 /** Set masked bits high if (and only if) a condition is fullfilled. 00229 * @ingroup BitManip 00230 * @author Bram de Greve [Bramz] 00231 * @param a_bits the bitfield of which some bits must be set high. 00232 * @param a_mask mask indicating the bits that must be set high. 00233 * The high bits in the mask indicate the bits in the bitfield to be set, 00234 * the low bits in the mask indicate the bits in the bitfield to be left 00235 * untouched. 00236 * @param a_condition true if the bits must be set, false if not. 00237 */ 00238 template<typename T> 00239 void setMaskedIf(T& a_bits, const T& a_mask, bool a_condition) 00240 { 00241 setMasked(a_bits, a_condition ? a_mask : T(0)); 00242 } 00243 00244 00245 00246 /** Set masked bits low if (and only if) a condition is fullfilled. 00247 * @ingroup BitManip 00248 * @author Bram de Greve [Bramz] 00249 * @param a_bits the bitfield of which some bits must be set low. 00250 * @param a_mask mask indicating the bits that must be set low. 00251 * The high bits in the mask indicate the bits in the bitfield to be set, 00252 * the low bits in the mask indicate the bits in the bitfield to be left 00253 * untouched. 00254 * @param a_condition true if the bits must be set, false if not. 00255 */ 00256 template<typename T> 00257 void clearMaskedIf(T& a_bits, const T& a_mask, bool a_condition) 00258 { 00259 clearMasked(a_bits, a_condition ? a_mask : T(0)); 00260 } 00261 00262 00263 00264 /** Flip the masked bits if (and only if) a condition is fullfilled. 00265 * @ingroup BitManip 00266 * @author Bram de Greve [Bramz] 00267 * @param a_bits the bitfield of which some bits must be flipped. 00268 * @param a_mask mask indicating the bits that must be flipped. 00269 * The high bits in the mask indicate the bits in the bitfield to be flipped, 00270 * the low bits in the mask indicate the bits in the bitfield to be left 00271 * untouched. 00272 * @param a_condition true if the bits must be flipped, false if not. 00273 */ 00274 template<typename T> 00275 void flipMaskedIf(T& a_bits, const T& a_mask, bool a_condition) 00276 { 00277 flipMasked(a_bits, a_condition ? a_mask : T(0)); 00278 } 00279 00280 00281 00282 /** Set the masked bits to a given state if (and only if) a condition is fullfilled. 00283 * @ingroup BitManip 00284 * @author Bram de Greve [Bramz] 00285 * @param a_bits the bitfield of which some bits must be set. 00286 * @param a_mask mask indicating the bits that must be set. 00287 * The high bits in the mask indicate the bits in the bitfield to be set, 00288 * the low bits in the mask indicate the bits in the bitfield to be left 00289 * untouched. 00290 * @param a_state the state to which the bits must be set: true for high, false for low. 00291 */ 00292 template<typename T> 00293 void setMaskedTo(T& a_bits, const T& a_mask, bool a_state) 00294 { 00295 clearMasked(a_bits, a_mask); 00296 setMaskedIf(a_bits, a_mask, a_state); 00297 } 00298 00299 00300 00301 /** Check the masked bits and return true if they are ALL set. 00302 * @ingroup BitManip 00303 * @author Bram de Greve [Bramz] 00304 * @param a_bits the bitfield of which some bits must be checked. 00305 * @param a_mask mask indicating the bits that must be checked. 00306 * The high bits in the mask indicate the bits in the bitfield to be checked, 00307 * the low bits in the mask indicate the bits in the bitfield to be left 00308 * untouched. 00309 * @return true if ALL masked bits are set, false if not. So it also returns if only 00310 * a few of the masked bits are set, but not all of them. 00311 */ 00312 template<typename T> 00313 bool checkMaskedAll(T a_bits, const T& a_mask) 00314 { 00315 return (a_bits & a_mask) == a_mask; 00316 } 00317 00318 00319 00320 /** Check the masked bits and return true if at least one is set. 00321 * @ingroup BitManip 00322 * @author Bram de Greve [Bramz] 00323 * @param a_bits the bitfield of which some bits must be checked. 00324 * @param a_mask mask indicating the bits that must be checked. 00325 * The high bits in the mask indicate the bits in the bitfield to be checked, 00326 * the low bits in the mask indicate the bits in the bitfield to be left 00327 * untouched. 00328 * @return true if at least one masked bits is set, false if not. 00329 */ 00330 template<typename T> 00331 bool checkMaskedSome(T a_bits, const T& a_mask) 00332 { 00333 return (a_bits & a_mask) != 0; 00334 } 00335 00336 00337 00338 namespace impl 00339 { 00340 /** lookup table of number of bits in a byte 00341 * @ingroup BitManip 00342 * @internal 00343 */ 00344 const size_t bitsInByte[256] = 00345 { 00346 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 00347 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 00348 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 00349 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 00350 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 00351 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 00352 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 00353 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 00354 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 00355 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 00356 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 00357 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 00358 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 00359 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 00360 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 00361 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 00362 }; 00363 00364 /** countBits helper 00365 * @ingroup BitManip 00366 * @internal 00367 */ 00368 template <size_t numBytes> struct BitCounter; 00369 00370 template <> 00371 struct BitCounter<1> 00372 { 00373 template <typename T> static const size_t count(T bits) 00374 { 00375 return bitsInByte[(num::Tuint8) bits]; 00376 } 00377 }; 00378 00379 template <> 00380 struct BitCounter<2> 00381 { 00382 template <typename T> static const size_t count(T bits) 00383 { 00384 const num::Tuint16 x = (num::Tuint16) bits; 00385 return impl::bitsInByte[x >> 8] + impl::bitsInByte[x & 0xff]; 00386 } 00387 }; 00388 00389 template <> 00390 struct BitCounter<4> 00391 { 00392 template <typename T> static const size_t count(T bits) 00393 { 00394 const num::Tuint32 x = (num::Tuint32) bits; 00395 return impl::bitsInByte[x >> 24] + impl::bitsInByte[(x >> 16) & 0xff] + 00396 impl::bitsInByte[(x >> 8) & 0xff] + impl::bitsInByte[x & 0xff]; 00397 } 00398 }; 00399 00400 template <> 00401 struct BitCounter<8> 00402 { 00403 template <typename T> static const size_t count(T bits) 00404 { 00405 const num::Tuint64 x = (num::Tuint64) bits; 00406 return impl::bitsInByte[x >> 56] + impl::bitsInByte[(x >> 48) & 0xff] + 00407 impl::bitsInByte[(x >> 40) & 0xff] + impl::bitsInByte[(x >> 32) & 0xff] + 00408 impl::bitsInByte[(x >> 24) & 0xff] + impl::bitsInByte[(x >> 16) & 0xff] + 00409 impl::bitsInByte[(x >> 8) & 0xff] + impl::bitsInByte[x & 0xff]; 00410 } 00411 }; 00412 } 00413 00414 /** returns number of set bits in @a bits 00415 * @ingroup BitManip 00416 */ 00417 template <typename T> inline const size_t countBits(T bits) 00418 { 00419 return impl::BitCounter<sizeof(T)>::count(bits); 00420 } 00421 00422 } 00423 00424 } 00425 00426 #endif 00427 00428 // --- END OF FILE ------------------------------------------------------------------------------
Generated on Mon Nov 10 14:20:00 2008 for Library of Assembled Shared Sources by 1.5.7.1 |