library of assembled shared sources

http://lass.cocamware.com

bit_manip.inl

Go to the documentation of this file.
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 doxygen 1.5.7.1
SourceForge.net Logo