Geant4  10.01.p03
UBits.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UBits
12 //
13 // 19.10.12 Marek Gayer
14 // Created from original implementation in ROOT (TBits)
15 // --------------------------------------------------------------------
16 
17 #include "UBits.hh"
18 #include <stdio.h>
19 //______________________________________________________________________________
20 UBits::UBits(unsigned int nBits) :
21  fNBits(nBits>0 ? nBits : 0),
22  fNBytes(fNBits ? ((fNBits - 1) / 8) + 1 : 1),
23  fAllBits(new unsigned char[fNBytes])
24 {
25  // UBits constructor. All bits set to 0
26 
27  // this is redundant only with libNew
28  std::memset(fAllBits, 0, fNBytes);
29 }
30 
31 //______________________________________________________________________________
32 UBits::UBits(const UBits& original) :
33  fNBits(original.fNBits),
34  fNBytes(original.fNBytes),
35  fAllBits(new unsigned char[fNBytes])
36 {
37  // UBits copy constructor
38 
39  std::memcpy(fAllBits, original.fAllBits, fNBytes);
40 
41 }
42 
43 
44 //______________________________________________________________________________
46 {
47  // UBits assignment operator
48  // Check assignment to self
49  if (this == &rhs) { return *this; }
50 
51  // TObject::operator=(rhs);
52  fNBits = rhs.fNBits;
53  fNBytes = rhs.fNBytes;
54  delete [] fAllBits;
55  if (fNBytes != 0) {
56  fAllBits = new unsigned char[fNBytes];
57  std::memcpy(fAllBits,rhs.fAllBits,fNBytes);
58  } else {
59  fAllBits = 0;
60  }
61  return *this;
62 }
63 
64 //______________________________________________________________________________
66 {
67  // UBits destructor
68 
69  delete [] fAllBits;
70 }
71 
72 //______________________________________________________________________________
74 {
75  // Clear the value.
76 
77  delete [] fAllBits;
78  fAllBits = 0;
79  fNBits = 0;
80  fNBytes = 0;
81 }
82 
83 //______________________________________________________________________________
85 {
86  // Reduce the storage used by the object to a minimun
87 
88  if (!fNBits || !fAllBits) return;
89  unsigned int needed;
90  for (needed = fNBytes - 1;
91  needed > 0 && fAllBits[needed] == 0;)
92  {
93  needed--;
94  };
95  needed++;
96 
97  if (needed != fNBytes)
98  {
99  unsigned char* old_location = fAllBits;
100  fAllBits = new unsigned char[needed];
101 
102  std::memcpy(fAllBits, old_location, needed);
103  delete [] old_location;
104 
105  fNBytes = needed;
106  fNBits = 8 * fNBytes;
107  }
108 }
109 
110 /*
111 //______________________________________________________________________________
112 unsigned int UBits::CounUBits(unsigned int startBit) const
113 {
114  // Return number of bits set to 1 starting at bit startBit
115 
116  static const int nBitsCached[256] = {
117  0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
118  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
119  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
120  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
121  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
122  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
123  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
124  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
125  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
126  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
127  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
128  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
129  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
130  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
131  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
132  4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
133 
134  unsigned int i,count = 0;
135  if (startBit == 0) {
136  for(i=0; i<fNBytes; i++) {
137  count += nBitsCached[fAllBits[i]];
138  }
139  return count;
140  }
141  if (startBit >= fNBits) return count;
142  unsigned int startByte = startBit/8;
143  unsigned int ibit = startBit%8;
144  if (ibit) {
145  for (i=ibit;i<8;i++) {
146  if (fAllBits[startByte] & (1<<ibit)) count++;
147  }
148  startByte++;
149  }
150  for(i=startByte; i<fNBytes; i++) {
151  count += nBitsCached[fAllBits[i]];
152  }
153  return count;
154 }
155 */
156 
157 /*
158 //______________________________________________________________________________
159 void UBits::DoAndEqual(const UBits& rhs)
160 {
161  // Execute (*this) &= rhs;
162  // Extra bits in rhs are ignored
163  // Missing bits in rhs are assumed to be zero.
164 
165  unsigned int min = (fNBytes<rhs.fNBytes) ? fNBytes : rhs.fNBytes;
166  for(unsigned int i=0; i<min; ++i) {
167  fAllBits[i] &= rhs.fAllBits[i];
168  }
169  if (fNBytes>min) {
170  std::memset(&(fAllBits[min]),0,fNBytes-min);
171  }
172 }
173 */
174 
175 /*
176 //______________________________________________________________________________
177 void UBits::DoOrEqual(const UBits& rhs)
178 {
179  // Execute (*this) &= rhs;
180  // Extra bits in rhs are ignored
181  // Missing bits in rhs are assumed to be zero.
182 
183  unsigned int min = (fNBytes<rhs.fNBytes) ? fNBytes : rhs.fNBytes;
184  for(unsigned int i=0; i<min; ++i) {
185  fAllBits[i] |= rhs.fAllBits[i];
186  }
187 }
188 
189 //______________________________________________________________________________
190 void UBits::DoXorEqual(const UBits& rhs)
191 {
192  // Execute (*this) ^= rhs;
193  // Extra bits in rhs are ignored
194  // Missing bits in rhs are assumed to be zero.
195 
196  unsigned int min = (fNBytes<rhs.fNBytes) ? fNBytes : rhs.fNBytes;
197  for(unsigned int i=0; i<min; ++i) {
198  fAllBits[i] ^= rhs.fAllBits[i];
199  }
200 }
201 
202 //______________________________________________________________________________
203 void UBits::DoFlip()
204 {
205  // Execute ~(*this)
206 
207  for(unsigned int i=0; i<fNBytes; ++i) {
208  fAllBits[i] = ~fAllBits[i];
209  }
210  // NOTE: out-of-bounds bit were also flipped!
211 }
212 
213 //______________________________________________________________________________
214 void UBits::DoLeftShift(unsigned int shift)
215 {
216  // Execute the left shift operation.
217 
218  if (shift==0) return;
219  const unsigned int wordshift = shift / 8;
220  const unsigned int offset = shift % 8;
221  if (offset==0) {
222  for(unsigned int n = fNBytes - 1; n >= wordshift; --n) {
223  fAllBits[n] = fAllBits[ n - wordshift ];
224  }
225  } else {
226  const unsigned int sub_offset = 8 - offset;
227  for(unsigned int n = fNBytes - 1; n > wordshift; --n) {
228  fAllBits[n] = (fAllBits[n - wordshift] << offset) |
229  (fAllBits[n - wordshift - 1] >> sub_offset);
230  }
231  fAllBits[wordshift] = fAllBits[0] << offset;
232  }
233  std::memset(fAllBits,0,wordshift);
234 }
235 
236 //______________________________________________________________________________
237 void UBits::DoRightShift(unsigned int shift)
238 {
239  // Execute the left shift operation.
240 
241  if (shift==0) return;
242  const unsigned int wordshift = shift / 8;
243  const unsigned int offset = shift % 8;
244  const unsigned int limit = fNBytes - wordshift - 1;
245 
246  if (offset == 0)
247  for (unsigned int n = 0; n <= limit; ++n)
248  fAllBits[n] = fAllBits[n + wordshift];
249  else
250  {
251  const unsigned int sub_offset = 8 - offset;
252  for (unsigned int n = 0; n < limit; ++n)
253  fAllBits[n] = (fAllBits[n + wordshift] >> offset) |
254  (fAllBits[n + wordshift + 1] << sub_offset);
255  fAllBits[limit] = fAllBits[fNBytes-1] >> offset;
256  }
257 
258  std::memset(&(fAllBits[limit + 1]),0, fNBytes - limit - 1);
259 }
260 */
261 
262 /*
263 //______________________________________________________________________________
264 unsigned int UBits::FirstNullBit(unsigned int startBit) const
265 {
266  // Return position of first null bit (starting from position 0 and up)
267 
268  static const int fbits[256] = {
269  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
270  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
271  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
272  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
273  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
274  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
275  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
276  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
277  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
278  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
279  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
280  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
281  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
282  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
283  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
284  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8};
285 
286  unsigned int i;
287  if (startBit == 0) {
288  for(i=0; i<fNBytes; i++) {
289  if (fAllBits[i] != 255) return 8*i + fbits[fAllBits[i]];
290  }
291  return fNBits;
292  }
293  if (startBit >= fNBits) return fNBits;
294  unsigned int startByte = startBit/8;
295  unsigned int ibit = startBit%8;
296  if (ibit) {
297  for (i=ibit;i<8;i++) {
298  if ((fAllBits[startByte] & (1<<i)) == 0) return 8*startByte+i;
299  }
300  startByte++;
301  }
302  for(i=startByte; i<fNBytes; i++) {
303  if (fAllBits[i] != 255) return 8*i + fbits[fAllBits[i]];
304  }
305  return fNBits;
306 }
307 
308 //______________________________________________________________________________
309 unsigned int UBits::FirstSetBit(unsigned int startBit) const
310 {
311  // Return position of first non null bit (starting from position 0 and up)
312 
313  static const int fbits[256] = {
314  8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
315  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
316  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
317  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
318  6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
319  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
320  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
321  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
322  7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
323  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
324  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
325  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
326  6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
327  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
328  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
329  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
330 
331  unsigned int i;
332  if (startBit == 0) {
333  for(i=0; i<fNBytes; i++) {
334  if (fAllBits[i] != 0) return 8*i + fbits[fAllBits[i]];
335  }
336  return fNBits;
337  }
338  if (startBit >= fNBits) return fNBits;
339  unsigned int startByte = startBit/8;
340  unsigned int ibit = startBit%8;
341  if (ibit) {
342  for (i=ibit;i<8;i++) {
343  if ((fAllBits[startByte] & (1<<i)) != 0) return 8*startByte+i;
344  }
345  startByte++;
346  }
347  for(i=startByte; i<fNBytes; i++) {
348  if (fAllBits[i] != 0) return 8*i + fbits[fAllBits[i]];
349  }
350  return fNBits;
351 }
352 */
353 
354 //______________________________________________________________________________
355 void UBits::Output(std::ostream& os) const
356 {
357  // Print the value to the std::ostream
358  for (unsigned int i = 0; i < fNBytes; ++i)
359  {
360  unsigned char val = fAllBits[fNBytes - 1 - i];
361  for (unsigned int j = 0; j < 8; ++j)
362  {
363  os << (bool)(val & 0x80);
364  val <<= 1;
365  }
366  }
367 }
368 
369 //______________________________________________________________________________
370 void UBits::Print() const
371 {
372  // Print the list of active bits
373  int count = 0;
374  for (unsigned int i = 0; i < fNBytes; ++i)
375  {
376  unsigned char val = fAllBits[i];
377  for (unsigned int j = 0; j < 8; ++j)
378  {
379  if (val & 1) printf(" bit:%4d = 1\n", count);
380  count++;
381  val = val >> 1;
382  }
383  }
384 }
385 
386 //______________________________________________________________________________
387 void UBits::ResetAllBits(bool value)
388 {
389  if (fAllBits) std::memset(fAllBits, value ? 0xFF : 0, fNBytes);
390 }
391 
392 //______________________________________________________________________________
393 void UBits::ReserveBytes(unsigned int nbytes)
394 {
395  // Reverse each bytes.
396 
397  if (nbytes > fNBytes)
398  {
399  // do it in this order to remain exception-safe.
400  unsigned char* newBits = new unsigned char[nbytes];
401  delete[] fAllBits;
402  fNBytes = nbytes;
403  fAllBits = newBits;
404  }
405 }
406 
407 //______________________________________________________________________________
408 void UBits::Set(unsigned int nBits, const char* array)
409 {
410  // Set all the bytes
411  unsigned int nbytes = (nBits + 7) >> 3;
412 
413  ReserveBytes(nbytes);
414 
415  fNBits = nBits;
416  std::memcpy(fAllBits, array, nbytes);
417 }
418 
419 //______________________________________________________________________________
420 void UBits::Get(char* array) const
421 {
422  // Copy all the byes.
423  std::memcpy(array, fAllBits, (fNBits + 7) >> 3);
424 }
425 
426 // If we are on a little endian machine, a bitvector represented using
427 // any integer type is identical to a bitvector represented using bytes. -- FP.
428 
429 
430 void UBits::Set(unsigned int nBits, const int* array)
431 {
432  // Set all the bytes.
433 
434  Set(nBits, (const char*)array);
435 }
436 
437 void UBits::Get(int* array) const
438 {
439  // Get all the bytes.
440 
441  Get((char*)array);
442 }
443 
444 
445 
446 /*
447 bool UBits::operator==(const UBits &other) const
448 {
449  // Compare object.
450 
451  if (fNBits == other.fNBits) {
452  return !memcmp(fAllBits, other.fAllBits, (fNBits+7)>>3);
453  } else if (fNBits < other.fNBits) {
454  return !memcmp(fAllBits, other.fAllBits, (fNBits+7)>>3) && other.FirstSetBit(fNBits) == other.fNBits;
455  } else {
456  return !memcmp(fAllBits, other.fAllBits, (other.fNBits+7)>>3) && FirstSetBit(other.fNBits) == fNBits;
457  }
458 }
459 */
unsigned int fNBits
Definition: UBits.hh:135
void Output(std::ostream &) const
Definition: UBits.cc:355
UBits & operator=(const UBits &rhs)
Definition: UBits.cc:45
void ResetAllBits(bool value=false)
Definition: UBits.cc:387
unsigned char * fAllBits
Definition: UBits.hh:139
void Clear()
Definition: UBits.cc:73
void Set(unsigned int nbits, const char *array)
Definition: UBits.cc:408
virtual ~UBits()
Definition: UBits.cc:65
void Print() const
Definition: UBits.cc:370
unsigned int fNBytes
Definition: UBits.hh:136
UBits(unsigned int nbits=0)
Definition: UBits.cc:20
void ReserveBytes(unsigned int nbytes)
Definition: UBits.cc:393
void Get(char *array) const
Definition: UBits.cc:420
Definition: UBits.hh:38
void Compact()
Definition: UBits.cc:84