@@ -154,42 +154,84 @@ inline bool is_power_of_2(const T x) {
154154}
155155
156156// Function to find the next power of 2 to an integer.
157- static _FORCE_INLINE_ unsigned int next_power_of_2 (unsigned int x ) {
158- if (x == 0 ) {
157+ constexpr uint64_t next_power_of_2 (uint64_t p_number ) {
158+ if (p_number == 0 ) {
159159 return 0 ;
160160 }
161161
162- --x;
163- x |= x >> 1 ;
164- x |= x >> 2 ;
165- x |= x >> 4 ;
166- x |= x >> 8 ;
167- x |= x >> 16 ;
162+ --p_number;
163+ p_number |= p_number >> 1 ;
164+ p_number |= p_number >> 2 ;
165+ p_number |= p_number >> 4 ;
166+ p_number |= p_number >> 8 ;
167+ p_number |= p_number >> 16 ;
168+ p_number |= p_number >> 32 ;
168169
169- return ++x;
170+ return ++p_number;
171+ }
172+
173+ constexpr uint32_t next_power_of_2 (uint32_t p_number) {
174+ if (p_number == 0 ) {
175+ return 0 ;
176+ }
177+
178+ --p_number;
179+ p_number |= p_number >> 1 ;
180+ p_number |= p_number >> 2 ;
181+ p_number |= p_number >> 4 ;
182+ p_number |= p_number >> 8 ;
183+ p_number |= p_number >> 16 ;
184+
185+ return ++p_number;
170186}
171187
172188// Function to find the previous power of 2 to an integer.
173- static _FORCE_INLINE_ unsigned int previous_power_of_2 (unsigned int x) {
174- x |= x >> 1 ;
175- x |= x >> 2 ;
176- x |= x >> 4 ;
177- x |= x >> 8 ;
178- x |= x >> 16 ;
179- return x - (x >> 1 );
189+ constexpr uint64_t previous_power_of_2 (uint64_t p_number) {
190+ p_number |= p_number >> 1 ;
191+ p_number |= p_number >> 2 ;
192+ p_number |= p_number >> 4 ;
193+ p_number |= p_number >> 8 ;
194+ p_number |= p_number >> 16 ;
195+ p_number |= p_number >> 32 ;
196+ return p_number - (p_number >> 1 );
197+ }
198+
199+ constexpr uint32_t previous_power_of_2 (uint32_t p_number) {
200+ p_number |= p_number >> 1 ;
201+ p_number |= p_number >> 2 ;
202+ p_number |= p_number >> 4 ;
203+ p_number |= p_number >> 8 ;
204+ p_number |= p_number >> 16 ;
205+ return p_number - (p_number >> 1 );
180206}
181207
182208// Function to find the closest power of 2 to an integer.
183- static _FORCE_INLINE_ unsigned int closest_power_of_2 (unsigned int x) {
184- unsigned int nx = next_power_of_2 (x);
185- unsigned int px = previous_power_of_2 (x);
186- return (nx - x) > (x - px) ? px : nx;
209+ constexpr uint64_t closest_power_of_2 (uint64_t p_number) {
210+ uint64_t nx = next_power_of_2 (p_number);
211+ uint64_t px = previous_power_of_2 (p_number);
212+ return (nx - p_number) > (p_number - px) ? px : nx;
213+ }
214+
215+ constexpr uint32_t closest_power_of_2 (uint32_t p_number) {
216+ uint32_t nx = next_power_of_2 (p_number);
217+ uint32_t px = previous_power_of_2 (p_number);
218+ return (nx - p_number) > (p_number - px) ? px : nx;
187219}
188220
189221// Get a shift value from a power of 2.
190- static inline int get_shift_from_power_of_2 (unsigned int p_bits) {
191- for (unsigned int i = 0 ; i < 32 ; i++) {
192- if (p_bits == (unsigned int )(1 << i)) {
222+ constexpr int32_t get_shift_from_power_of_2 (uint64_t p_bits) {
223+ for (uint64_t i = 0 ; i < (uint64_t )64 ; i++) {
224+ if (p_bits == (uint64_t )((uint64_t )1 << i)) {
225+ return i;
226+ }
227+ }
228+
229+ return -1 ;
230+ }
231+
232+ constexpr int32_t get_shift_from_power_of_2 (uint32_t p_bits) {
233+ for (uint32_t i = 0 ; i < (uint32_t )32 ; i++) {
234+ if (p_bits == (uint32_t )((uint32_t )1 << i)) {
193235 return i;
194236 }
195237 }
@@ -198,30 +240,44 @@ static inline int get_shift_from_power_of_2(unsigned int p_bits) {
198240}
199241
200242template <typename T>
201- static _FORCE_INLINE_ T nearest_power_of_2_templated (T x ) {
202- --x ;
243+ static _FORCE_INLINE_ T nearest_power_of_2_templated (T p_number ) {
244+ --p_number ;
203245
204246 // The number of operations on x is the base two logarithm
205247 // of the number of bits in the type. Add three to account
206248 // for sizeof(T) being in bytes.
207- size_t num = get_shift_from_power_of_2 (sizeof (T)) + 3 ;
249+ constexpr size_t shift_steps = get_shift_from_power_of_2 (( uint64_t ) sizeof (T)) + 3 ;
208250
209251 // If the compiler is smart, it unrolls this loop.
210252 // If it's dumb, this is a bit slow.
211- for (size_t i = 0 ; i < num ; i++) {
212- x |= x >> (1 << i);
253+ for (size_t i = 0 ; i < shift_steps ; i++) {
254+ p_number |= p_number >> (1 << i);
213255 }
214256
215- return ++x ;
257+ return ++p_number ;
216258}
217259
218260// Function to find the nearest (bigger) power of 2 to an integer.
219- static inline unsigned int nearest_shift (unsigned int p_number) {
220- for (int i = 30 ; i >= 0 ; i--) {
221- if (p_number & (1 << i)) {
222- return i + 1 ;
261+ constexpr uint64_t nearest_shift (uint64_t p_number) {
262+ uint64_t i = 63 ;
263+ do {
264+ i--;
265+ if (p_number & ((uint64_t )1 << i)) {
266+ return i + (uint64_t )1 ;
223267 }
224- }
268+ } while (i != 0 );
269+
270+ return 0 ;
271+ }
272+
273+ constexpr uint32_t nearest_shift (uint32_t p_number) {
274+ uint32_t i = 31 ;
275+ do {
276+ i--;
277+ if (p_number & ((uint32_t )1 << i)) {
278+ return i + (uint32_t )1 ;
279+ }
280+ } while (i != 0 );
225281
226282 return 0 ;
227283}
0 commit comments