编译时间缓冲区解码

时间:2017-09-14 08:01:31

标签: c++ templates visual-studio-2017 c++17 compile-time

我有以下类,我想在编译时将二进制输入解码为某个值。它使用静态函数实现很好,但我希望非静态函数在编译时工作,这可能以某种方式?任何帮助将不胜感激。

class BinaryDecoder
{
public:
    BinaryDecoder(const BinaryDecoder&) = delete;
    BinaryDecoder& operator=(const BinaryDecoder&) = delete;

public:
    BinaryDecoder(const std::uint8_t* buffer, size_t size)
      : m_buffer(buffer),
        m_size(size)
    {}

    template<typename T>
    constexpr bool decode(size_t offset, T& decodedValue) noexcept
    {
        if constexpr (std::is_same< std::remove_reference_t<T>, std::uint32_t>::value)
            return decodeBuffer(offset, decodedValue);

        return false;
    }

    template<typename T>
    static constexpr T decode(const std::uint8_t* buffer, const size_t size, const size_t offset) noexcept
    {
        if constexpr (std::is_same< std::remove_reference_t<T>, std::uint32_t>::value)
            return decodeBuffer(buffer, size, offset);

        return 0;
    }

private:
    static constexpr std::uint32_t decodeBuffer(
        const std::uint8_t* buffer,
        const size_t size,
        const size_t offset) noexcept
    {
        if (offset + sizeof(std::uint32_t) > size)
            return 0;

        const uint8_t b0 = buffer[offset], b1 = buffer[offset + 1], b2 = buffer[offset + 2], b3 = buffer[offset + 3];
        return (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
    }

    constexpr bool decodeBuffer(
        const size_t offset,
        std::uint32_t& decodedValue) noexcept
    {
        if (offset + sizeof(std::uint32_t) > m_size)
            return false;

        const uint8_t b0 = m_buffer[offset], b1 = m_buffer[offset + 1], b2 = m_buffer[offset + 2], b3 = m_buffer[offset + 3];
        decodedValue = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
        return true;
    }

private:
    const std::uint8_t* m_buffer;
    const size_t m_size;
};

int main()
{
    constexpr std::uint8_t input[] = { 0x84, 0x03, 0x00, 0x00, 'H', 'e', 'l', 'l', 'o', 0x00, 0x90 };       
    static_assert(900 == BinaryDecoder::decode<std::uint32_t>(input, sizeof(input), 0), "Decoded value not equal to 900");

    constexpr std::uint8_t input2[] = { 0x84, 0x33, 0x00, 0x00, 'H', 'e', 'l', 'l', 'o', 0x00, 0x90 };
    BinaryDecoder binaryDecoder(input2, sizeof(input2));
    constexpr std::uint32_t value = 900;
    binaryDecoder.decode(0, value);
    // Should not compile since it is not 900.
    static_assert(900 == value, "Decoded value not equal to 900");
    return 0;
}

编辑:正如维托里奥罗密欧在评论中所指出的,这不是错误。当我在main函数中进行了以下调用时,我的IDE(Visual Studio 2017)标记了我的static_assert并出现错误。

    constexpr std::uint32_t value = 0;
    binaryDecoder.decode(0, value);
    static_assert(900 == value, "Decoded value not equal to 900");

我只是假设我的代码有问题但是Visual Studio对我来说很聪明。它以某种方式在后台编译它并将其标记为错误。如果我将值更改为900,那么所有编译都很好。

Edit2:但它在编译时没有解码它,这就是我想要的。

0 个答案:

没有答案