Home > Software engineering >  How to static_assert if a constexpr number is in a constexpr array at compile time?
How to static_assert if a constexpr number is in a constexpr array at compile time?

Time:09-30

I want to check if a constexpr number is in a constexpr array at compile time. If not, stop compiling. My ideographic example:

constexpr void PinValid(uint8_t Pin)
{
    constexpr uint8_t ValidPins[] = {2, 3, 18, 19, 20, 21};
    for (uint8_t P : ValidPins)
        if (Pin == P)
            return;
    static_assert(false);
}

This code fails for any given Pin even if it is in the ValidPins.

CodePudding user response:

You can write like this:

constexpr bool PinValid(uint8_t Pin)
{
    constexpr uint8_t ValidPins[] = {2, 3, 18, 19, 20, 21};
    for (uint8_t P : ValidPins)
        if (Pin == P)
            return true;
    return false;
}

static_assert(PinValid(3));

CodePudding user response:

I'd like to add the following solution, even if the quality of the error message isn't as good as in the example in the other answer, on some compilers.

In c 20 you can throw an exception in a constexpr function which will result in a compilation error if it gets thrown at compile-time:

#include <cstdint>
#include <array>
#include <stdexcept>


consteval void PinValid(uint8_t Pin)
{
    constexpr uint8_t ValidPins[] = {2, 3, 18, 19, 20, 21};
    for (uint8_t P : ValidPins)
        if (Pin == P)
            return;
    throw std::invalid_argument("not a valid pin");
}

int main() {
    PinValid(20);
    PinValid(5); // Does not compile
}

See the example on Compiler Explorer. Notice that it currently doesn't work on clang, though

  • Related