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