// // BitReverse.hpp // Clock Signal // // Created by Thomas Harte on 05/01/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // #ifndef BitReverse_hpp #define BitReverse_hpp #include namespace Numeric { /// @returns @c source with the order of its bits reversed. E.g. if @c IntT is @c uint8_t then /// the reverse of bit pattern abcd efgh is hgfd dcba. template constexpr IntT bit_reverse(IntT source); // The single-byte specialisation uses a lookup table. template<> constexpr uint8_t bit_reverse(uint8_t source) { struct ReverseTable { static constexpr std::array reverse_table() { std::array map{}; for(std::size_t c = 0; c < 256; ++c) { map[c] = uint8_t( ((c & 0x80) >> 7) | ((c & 0x40) >> 5) | ((c & 0x20) >> 3) | ((c & 0x10) >> 1) | ((c & 0x08) << 1) | ((c & 0x04) << 3) | ((c & 0x02) << 5) | ((c & 0x01) << 7) ); } return map; } }; const std::array map = ReverseTable::reverse_table(); return map[source]; } // All other versions just call the byte-level reverse the appropriate number of times. template constexpr IntT bit_reverse(IntT source) { IntT result; uint8_t *src = reinterpret_cast(&source); uint8_t *dest = reinterpret_cast(&result) + sizeof(result) - 1; for(size_t c = 0; c < sizeof(source); c++) { *dest = bit_reverse(*src); ++src; --dest; } return result; } } #endif /* BitReverse_hpp */