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 1023241 : { 14 : // TODO: use std::bit_width when C++20 becomes available, or find a useful bit hack for this 15 1023241 : T c = 0; 16 14092852 : while (t) { 17 13069611 : t >>= 1; 18 13069611 : ++c; 19 13069611 : } 20 1023241 : return c; 21 1023241 : } 22 : 23 : template <typename T> 24 : static constexpr T log2Floor(T t) 25 717225 : { 26 717225 : return bit_width(t) - 1; 27 717225 : } 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 478835 : { 46 478835 : return (t != 0) && !(t & (t - 1)); 47 478835 : } 48 : 49 : // alignment must be a power of 2 50 : template <typename T> 51 : static constexpr T alignDown(T value, T alignment) 52 800105 : { 53 800105 : return value & ~(alignment - 1); 54 800105 : } 55 : 56 : // alignment must be a power of 2 57 : template <typename T> 58 : static constexpr T alignUp(T value, T alignment) 59 290219 : { 60 290219 : return alignDown(value + alignment - 1, alignment); 61 290219 : } 62 : 63 : // alignment must be a power of 2 64 : static inline void* alignDown(void* ptr, size_t alignment) 65 509886 : { 66 509886 : return reinterpret_cast<void*>(alignDown(reinterpret_cast<uintptr_t>(ptr), alignment)); 67 509886 : } 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 509886 : { 78 509886 : return ptr == alignDown(ptr, alignment); 79 509886 : } 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