Line data Source code
1 : #pragma once 2 : 3 : #include <cstdlib> 4 : #include <cstdint> 5 : #include <cinttypes> 6 : #include <limits> 7 : 8 : namespace elsa::mr::detail 9 : { 10 : // NOLINTBEGIN 11 : template <typename T> 12 : static constexpr T bit_width(T t) 13 1023247 : { 14 : // TODO: use std::bit_width when C++20 becomes available, or find a useful bit hack for this 15 1023247 : T c = 0; 16 14092918 : while (t) { 17 13069671 : t >>= 1; 18 13069671 : ++c; 19 13069671 : } 20 1023247 : return c; 21 1023247 : } 22 : 23 : template <typename T> 24 : static constexpr T log2Floor(T t) 25 717231 : { 26 717231 : return bit_width(t) - 1; 27 717231 : } 28 : 29 : // does not work for t == 0 30 : template <typename T> 31 : static constexpr T log2Ceil(T t) 32 121068 : { 33 121068 : return bit_width(t - 1); 34 121068 : } 35 : 36 : // not zero indexed! lowestSetBit(0) == 0! 37 : template <typename T> 38 : static constexpr T lowestSetBit(T t) 39 184948 : { 40 184948 : return bit_width(t & ~(t - 1)); 41 184948 : } 42 : 43 : template <typename T> 44 : static constexpr bool isPowerOfTwo(T t) 45 478802 : { 46 478802 : return (t != 0) && !(t & (t - 1)); 47 478802 : } 48 : 49 : // alignment must be a power of 2 50 : template <typename T> 51 : static constexpr T alignDown(T value, T alignment) 52 800075 : { 53 800075 : return value & ~(alignment - 1); 54 800075 : } 55 : 56 : // alignment must be a power of 2 57 : template <typename T> 58 : static constexpr T alignUp(T value, T alignment) 59 290186 : { 60 290186 : return alignDown(value + alignment - 1, alignment); 61 290186 : } 62 : 63 : // alignment must be a power of 2 64 : static inline void* alignDown(void* ptr, size_t alignment) 65 509889 : { 66 509889 : return reinterpret_cast<void*>(alignDown(reinterpret_cast<uintptr_t>(ptr), alignment)); 67 509889 : } 68 : 69 : // alignment must be a power of 2 70 : static inline void* alignUp(void* ptr, size_t alignment) 71 191716 : { 72 191716 : return reinterpret_cast<void*>(alignUp(reinterpret_cast<uintptr_t>(ptr), alignment)); 73 191716 : } 74 : 75 : // alignment must be a power of 2 76 : static inline bool checkAlignment(void* ptr, size_t alignment) 77 509889 : { 78 509889 : return ptr == alignDown(ptr, alignment); 79 509889 : } 80 : 81 : static inline void* voidPtrOffset(void* ptr, size_t offset) 82 706317 : { 83 706317 : return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + offset); 84 706317 : } 85 : // NOLINTEND 86 : } // namespace elsa::mr::detail