bitOp.h
Go to the documentation of this file.
00001 #ifndef OSL_MISC_BITOP_H
00002 #define OSL_MISC_BITOP_H
00003 
00004 #include "osl/config.h"
00005 #include <cassert>
00006 namespace osl
00007 {
00008   namespace misc
00009   {
00013   template <class Integer> struct Bsf;
00014 
00015   template <> 
00016   struct Bsf<unsigned int>
00017   {
00018     static int bsf(unsigned int mask)
00019     {
00020       assert(mask);
00021 #ifdef __x86_64__
00022       int ret;
00023       __asm__("bsfl %1,%0" : "=r"(ret) : "r"(mask));
00024       return ret;
00025 #else /* これ以下は 32bit 環境 */
00026 #  ifdef __i386__
00027       int ret;
00028       __asm__("bsfl %1,%0" : "=r"(ret) : "r"(mask));
00029       return ret;
00030 #  elif defined __GNUC__
00031       return __builtin_ctzl(mask);
00032 #  else
00033       for (int i=0;i<32;i++)
00034         if (mask & (1<<i))
00035           return i;
00036 #  endif
00037 #endif
00038       assert(0);
00039       return -1;
00040     }
00041   };
00042   template <> 
00043   struct Bsf<unsigned short>
00044   {
00045     static unsigned short bsf(unsigned short mask)
00046     {
00047       assert(mask);
00048 #ifdef __x86_64__
00049       unsigned short ret;
00050       __asm__("bsfw %1,%0" : "=r"(ret) : "r"(mask));
00051       return ret;
00052 #else /* これ以下は 32bit 環境 */
00053 #  ifdef __i386__
00054       unsigned short ret;
00055       __asm__("bsfw %1,%0" : "=r"(ret) : "r"(mask));
00056       return ret;
00057 #  else
00058       return __builtin_ctzl(mask);
00059 #  endif
00060 #endif
00061     }
00062   };
00063   
00064   template <> 
00065   struct Bsf<unsigned long long>
00066   {
00067     static int bsf(unsigned long long mask)
00068     {
00069       assert(mask);
00070 #ifdef __x86_64__
00071       long long ret;
00072       __asm__("bsfq %1,%0" : "=r"(ret) : "r"(mask));
00073       return static_cast<int>(ret);
00074 #else /* これ以下は 32bit 環境 */
00075       unsigned int mask32 = static_cast<unsigned int>(mask);
00076       if (mask32)
00077         return Bsf<unsigned int>::bsf(mask32);
00078       mask32 = static_cast<unsigned int>(mask >> 32);
00079       return 32+Bsf<unsigned int>::bsf(mask32);
00080 #endif
00081     }
00082   };
00083 
00084   template <class Integer> struct Bsr;
00085 
00086   template <> 
00087   struct Bsr<unsigned int>
00088   {
00089     static int bsr(unsigned int mask)
00090     {
00091       assert(mask);
00092 #ifdef __x86_64__
00093       int ret;
00094       __asm__("bsrl %1,%0" : "=r"(ret) : "r"(mask));
00095       return ret;
00096 #else /* これ以下は 32bit 環境 */
00097 #  ifdef __i386__
00098       int ret;
00099       __asm__("bsrl %1,%0" : "=r"(ret) : "r"(mask));
00100       return ret;
00101 #  elif __GNUC__
00102       return __builtin_clzl(mask);
00103 #  else
00104       for (int i=31; i>=0; --i)
00105         if (mask & (1<<i))
00106           return i;
00107 #  endif
00108 #endif
00109       assert(0);
00110       return -1;
00111     }
00112   };
00113   
00114   template <> 
00115   struct Bsr<unsigned long long>
00116   {
00117     static int bsr(unsigned long long mask)
00118     {
00119       assert(mask);
00120 #ifdef __x86_64__
00121       long long ret;
00122       __asm__("bsrq %1,%0" : "=r"(ret) : "r"(mask));
00123       return static_cast<int>(ret);
00124 #else /* これ以下は 32bit 環境 */
00125       unsigned int mask32 = static_cast<unsigned int>(mask >> 32);
00126       if (mask32)
00127         return 32+Bsr<unsigned int>::bsr(mask32);
00128       mask32 = static_cast<unsigned int>(mask);
00129       return Bsr<unsigned int>::bsr(mask32);
00130 #endif
00131     }
00132   };
00133   
00134   struct BitOp
00135   {
00136     template <class Integer>
00137     static int bsf(Integer mask)
00138     {
00139       return Bsf<Integer>::bsf(mask);
00140     }
00141     template <class Integer>
00142     static int bsr(Integer mask)
00143     {
00144       return Bsr<Integer>::bsr(mask);
00145     }
00146     template <class Integer>
00147     static int takeOneBit(Integer& mask){
00148       assert(mask);
00149       const int num=bsf(mask);
00150       mask &= mask-1;
00151       return num;
00152     }
00153 
00154     template <class Integer>
00155     static int
00156 #ifdef __GNUC__
00157         __attribute__ ((const))
00158 #endif
00159     countBit(Integer mask)
00160     {
00161       int count=0;
00162       while (mask) 
00163       {
00164         ++count;
00165         mask &= (mask-1);
00166       }
00167       return count;
00168     }
00169     template <class Integer>
00170     static bool hasMultipleBit(Integer mask){
00171       assert(mask);
00172       return (mask & (mask-1));
00173     }
00177     template <class Integer>
00178     static Integer lowestBit(Integer mask){
00179       assert(mask);
00180       return static_cast<Integer>(mask & (-mask));
00181     }
00182   };
00183   
00184 #if 0
00185 
00198   inline int countBitDense(unsigned int mask)
00199   {
00200     mask = ((mask>>1)&0x55555555)+(mask&0x55555555);
00201     mask = ((mask>>2)&0x33333333)+(mask&0x33333333);
00202     mask = ((mask>>4)+mask)&0xf0f0f0f;
00203     mask = (mask>>8)+mask;
00204     return ((mask>>16)+mask)&0x3f;
00205   }
00206 #endif
00207   } // namespace misc
00208 } // namespace osl
00209 #endif // _BITOP_H
00210 // ;;; Local Variables:
00211 // ;;; mode:c++
00212 // ;;; c-basic-offset:2
00213 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines