// // BitReverse.hpp // Clock Signal // // Created by Thomas Harte on 05/01/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // #pragma once #include "Sizes.hpp" #include #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) { source = uint8_t(((source & 0b1111'0000) >> 4) | ((source & 0b0000'1111) << 4)); source = uint8_t(((source & 0b1100'1100) >> 2) | ((source & 0b0011'0011) << 2)); source = uint8_t(((source & 0b1010'1010) >> 1) | ((source & 0b0101'0101) << 1)); return source; } // All other versions recursively subdivide. template constexpr IntT bit_reverse(const IntT source) { static_assert(std::is_same_v || std::is_same_v || std::is_same_v); constexpr auto HalfSize = sizeof(IntT) * 4; using HalfIntT = uint_t; return IntT( IntT(bit_reverse(HalfIntT(source >> HalfSize))) | IntT(bit_reverse(HalfIntT(source))) << HalfSize ); } }