DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Bits.h
1 
17 #pragma once
18 
28 #ifndef BITS_HPP
29 #define BITS_HPP
30 
31 #include <string>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/base/BasicFunctors.h"
34 #include "DGtal/base/ExpressionTemplates.h"
35 
36 namespace DGtal
37 {
38 
39 
40 
41  struct Bits
42  {
58  template <typename T>
59  static std::string bitString(T value, unsigned nbBits = 0)
60  {
61  std::string bitStr;
62  /*MinFunctor<unsigned int> min;*/
63 
64  // if the requested number of bit is 0, use the size of the data type instead
65  if(nbBits == 0) nbBits = sizeof(T)*8;
66  int i = (int)(std::min((DGtal::int64_t)sizeof(T)*8-1, (DGtal::int64_t)nbBits-1));
67 
68  for(; i>=0; i--)
69  {
70  T mask = ((T)1) << i; // if you take these parenthesis out,
71  // a mountain of incredible runtime
72  // errors will jump on you.(I warned
73  // ya !)
74  if(value & mask)
75  bitStr += "1" ;
76  else
77  bitStr += "0" ;
78  }
79  return bitStr;
80  }
81 
82 
83  // ---------------------------------------------------------------------
84  // Other functions
85  // ---------------------------------------------------------------------
86 
90  template<typename T>
91  static inline T mask(unsigned nthBit)
92  {
93  return static_cast<T>(static_cast<T>(1) << nthBit);
94  }
95 
99  template <typename T>
100  static inline bool getBit(T key, unsigned nthBit)
101  {
102  return ( key & mask<T>(nthBit) );
103  }
104 
105 
110  template <typename T>
111  static inline T firstSetBit(T val)
112  {
113  return ( (val & -val) | (val & (~val + 1)) );
114  }
115 
116 
121  template <typename T>
122  static inline T firstUnsetBit(T val)
123  {
124  return ~val & (val + 1);
125  }
126 
127 
131  template <typename T>
132  static inline unsigned int nbSetBits(T val)
133  {
134 #ifdef TRACE_BITS
135  std::cerr << "unsigned int nbSetBits(T val)" << std::endl;
136 #endif
137  unsigned int i = 0;
138  for ( ; val; ++i) {val ^= val & -val; }
139  return i;
140  }
141 
146  static inline
147  unsigned int nbSetBits( DGtal::uint8_t val )
148  {
149 #ifdef TRACE_BITS
150  std::cerr << "unsigned int nbSetBits( DGtal::uint8_t val )" << std::endl;
151 #endif
152  return myBitCount[ val ];
153  }
154 
159  static inline
160  unsigned int nbSetBits( DGtal::uint16_t val )
161  {
162 #ifdef TRACE_BITS
163  std::cerr << "unsigned int nbSetBits( DGtal::uint16_t val )" << std::endl;
164 #endif
165  return nbSetBits( static_cast<DGtal::uint8_t>( val & 0xff ) )
166  + nbSetBits( static_cast<DGtal::uint8_t>( val >> 8 ) );
167  }
168 
173  static inline
174  unsigned int nbSetBits( DGtal::uint32_t val )
175  {
176 #ifdef TRACE_BITS
177  std::cerr << "unsigned int nbSetBits( DGtal::uint32_t val )" << std::endl;
178 #endif
179  return nbSetBits( static_cast<DGtal::uint16_t>( val & 0xffff ) )
180  + nbSetBits( static_cast<DGtal::uint16_t>( val >> 16 ) );
181  }
182 
187  static inline
188  unsigned int nbSetBits( DGtal::uint64_t val )
189  {
190 #ifdef TRACE_BITS
191  std::cerr << "unsigned int nbSetBits( DGtal::uint64_t val )" << std::endl;
192 #endif
193  return nbSetBits( static_cast<DGtal::uint32_t>( val & 0xffffffffLL ) )
194  + nbSetBits( static_cast<DGtal::uint32_t>( val >> 32 ) );
195  }
196 
208  static inline
209  unsigned int indexInSetBits( DGtal::uint8_t n, unsigned int b )
210  {
211  ASSERT( b < 8 );
212  return myIndexInSetBits[ b ][ n ];
213  }
214 
226  static inline
227  unsigned int indexInSetBits( DGtal::uint16_t n, unsigned int b )
228  {
229  ASSERT( b < 16 );
230  if ( b < 8 )
231  return indexInSetBits( static_cast<DGtal::uint8_t>( n & 0xff ), b );
232  else
233  {
234  unsigned int idx = indexInSetBits( static_cast<DGtal::uint8_t>( n >> 8 ), b - 8 );
235  return ( idx == 0 )
236  ? 0 // bit b is not set
237  : idx + nbSetBits( static_cast<DGtal::uint8_t>( n & 0xff ) );
238  }
239  }
240 
252  static inline
253  unsigned int indexInSetBits( DGtal::uint32_t n, unsigned int b )
254  {
255  ASSERT( b < 32 );
256  if ( b < 16 )
257  return indexInSetBits( static_cast<DGtal::uint16_t>( n & 0xffff ), b );
258  else
259  {
260  unsigned int idx = indexInSetBits( static_cast<DGtal::uint16_t>( n >> 16 ), b - 16 );
261  return ( idx == 0 )
262  ? 0 // bit b is not set
263  : idx + nbSetBits( static_cast<DGtal::uint16_t>( n & 0xffff ) );
264  }
265  }
266 
278  static inline
279  unsigned int indexInSetBits( DGtal::uint64_t n, unsigned int b )
280  {
281  ASSERT( b < 64 );
282  if ( b < 32 )
283  return indexInSetBits( static_cast<DGtal::uint32_t>( n & 0xffffffffLL ), b );
284  else
285  {
286  unsigned int idx = indexInSetBits( static_cast<DGtal::uint32_t>( n >> 32 ), b - 32 );
287  return ( idx == 0 )
288  ? 0 // bit b is not set
289  : idx + nbSetBits( static_cast<DGtal::uint32_t>( n & 0xffffffffLL ) );
290  }
291  }
292 
297  static inline
299  {
300  return myLSB[ n ];
301  }
302 
307  static inline
309  {
310  return ( n & 0xff )
312  : 8 + leastSignificantBit( (DGtal::uint8_t) (n>>8) );
313  }
314 
319  static inline
321  {
322  return ( n & 0xffff )
324  : 16 + leastSignificantBit( (DGtal::uint16_t) (n>>16) );
325  }
326 
331  static inline
333  {
334  return ( n & 0xffffffffLL )
336  : 32 + leastSignificantBit( (DGtal::uint32_t) (n>>32) );
337  }
338 
339 
344  static const DGtal::uint8_t myBitCount[ 256 ];
345 
349  static const DGtal::uint8_t myLSB[ 256 ];
350 
360  static const DGtal::uint8_t myIndexInSetBits[ 8 ][ 256 ];
361 
362 
363  };//struct
364 }
365 #endif