136. Compile-Time Power-of-Two Validator

#include <iostream>

template <int Size>
class PowerOfTwoBuffer {
public:
    // Compile-time check: Size must be > 0 and Power of Two
    // (Size & (Size - 1)) removes the lowest set bit. 
    // If result is 0, it had only one bit set (Power of 2).
    static_assert(Size > 0 && (Size & (Size - 1)) == 0, "Buffer Size must be a Power of Two");

    int getWrappedIndex(int raw_index) {
        // Optimization: Bitwise AND is faster than Modulo (%)
        // Only works if Size is Power of Two.
        return raw_index & (Size - 1);
    }
};

int main() {
    PowerOfTwoBuffer<16> buffer;

    // Uncommenting the line below should cause a COMPILER ERROR
    // PowerOfTwoBuffer<10> invalid_buffer; 

    int N;
    if (!(std::cin >> N)) return 0;

    for (int i = 0; i < N; ++i) {
        int raw;
        std::cin >> raw;
        std::cout << "Wrapped: " << buffer.getWrappedIndex(raw) << std::endl;
    }
    return 0;
}

Explanation & Logic Summary:

  • The Check: x & (x - 1) is a classic bitwise trick. If x = 8 (binary 1000), then x-1 = 7 (0111). 1000 & 0111 = 0000. This proves x is a power of 2.
  • static_assert: This keyword evaluates the boolean expression during compilation. If false, the build stops with the custom error message. This prevents broken code from ever reaching the target hardware.
  • The Optimization: In embedded systems, the modulo operator (%) usually involves a division instruction, which can take 10-20 CPU cycles. The bitwise AND (&) takes 1 cycle. Enforcing the power-of-two constraint allows us to safely use the fast optimization.

Firmware Relevance:

  • DMA Buffers: Hardware circular buffers (like in Audio codecs) often require strict alignment and size constraints (Powers of 2) to function correctly with DMA controllers.
  • FFT Algorithms: Fast Fourier Transform implementations typically require the input sample array size to be a power of two.
  • Safety: static_assert is a key tool in "Modern Embedded C++" to catch configuration errors early, rather than debugging obscure crashes on the device.

 

 

 

 

Loading...

Input

3 5 16 20

Expected Output

Wrapped: 5 Wrapped: 0 Wrapped: 4