2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
5 //____________________________________________________________________
6 inline uint32_t LWHistBitUtils::posMSB( uint32_t x)
9 //Code snippet posted on http://www.southwindsgames.com by Juan Pablo:
11 if(x >= 1<<16) { x>>=16; l|=16; }
12 if(x >= 1<<8) { x>>=8; l|=8; }
13 if(x >= 1<<4) { x>>=4; l|=4; }
14 if(x >= 1<<2) { x>>=2; l|=2; }
19 //____________________________________________________________________
20 inline uint8_t LWHistBitUtils::posMSB( uint8_t x)
23 //Code snippet posted on http://www.southwindsgames.com by Juan Pablo:
25 if(x >= 1<<4) { x>>=4; l|=4; }
26 if(x >= 1<<2) { x>>=2; l|=2; }
31 //____________________________________________________________________
32 inline uint32_t LWHistBitUtils::posLSB(uint32_t x)
38 //____________________________________________________________________
39 inline uint8_t LWHistBitUtils::posLSB(uint8_t x)
46 //____________________________________________________________________
48 inline T LWHistBitUtils::countSetBits(T data)
53 for(T i=0;i<T(sizeof(T)*8);++i)
57 // "Brian Kernighan's" method (needs number of steps equal to number of set bits):
58 T c(0); // c accumulates the total bits set in v
60 data &= data - 1; // clear the least significant bit set
65 //____________________________________________________________________
67 inline T LWHistBitUtils::countSetBitsBefore(T data, T ibit)
69 const T result(countSetBits(T(data<<(sizeof(T)*8-ibit))));
75 assert(nDirect==result);
81 //____________________________________________________________________
82 template<uint8_t sizeofT>
83 uint8_t LWHistBitUtils::stageOffset8Bits(uint32_t stagepattern)
85 #define C1 sizeof(uint8_t)
86 #define C2 sizeof(uint16_t)
89 //Assume only the 8 rightmost bits are set:
90 assert(!(0xFFFFFF00&stagepattern));
92 if (!(stagepattern&0xAAAAAAAA)) {
93 //All stagepatterns are either 0x0 or 0x1, thus:
94 return stagepattern ? LWHistBitUtils::countSetBits<uint32_t>(stagepattern) * C1 : 0;
98 static const uint8_t lookup[16]
119 return lookup[ uint8_t(stagepattern & 0xF) ] + lookup[ uint8_t((stagepattern>>4)&0xF) ];
122 //____________________________________________________________________
123 template<uint8_t sizeofT>
124 inline uint8_t LWHistBitUtils::totalSummedOffsetInStages(uint32_t stagepattern )
127 uint32_t tmpstagepattern(stagepattern);
128 unsigned char expectedresult(0);
129 for (uint8_t ibin = 0; ibin<sizeof(uint32_t)*4;++ibin) {
130 switch((tmpstagepattern & 0x3)) {
131 case 0x1: expectedresult += sizeof(unsigned char); break;
132 case 0x2: expectedresult += sizeof(unsigned short); break;
133 case 0x3: expectedresult += sizeofT; break;
138 tmpstagepattern = (tmpstagepattern >> 2);
142 if (!(stagepattern&0xAAAAAAAA)) {
143 //All stagepatterns are either 0x0 or 0x1, thus:
144 assert(expectedresult==LWHistBitUtils::countSetBits<uint32_t>(stagepattern) * sizeof(uint8_t));
145 return LWHistBitUtils::countSetBits<uint32_t>(stagepattern) * sizeof(uint8_t);
147 //FIXME: Use LSB/MSB trick???
148 const uint8_t result = stageOffset8Bits<sizeofT>(stagepattern & 0xFF)
149 + stageOffset8Bits<sizeofT>((stagepattern>>8) & 0xFF)
150 + stageOffset8Bits<sizeofT>((stagepattern>>16) & 0xFF)
151 + stageOffset8Bits<sizeofT>((stagepattern>>24) & 0xFF);
152 assert(expectedresult==result);