Search code examples
c++templatesc++11constexprstatic-assert

How do I check if a template parameter is a power of two?


I want to create a structure that allocates statically an array of 2^N bytes, but I don't want the users of this structure to specify this size as the exponent. Example:

my_stupid_array<char, 32> a1; // I want this!
my_stupid_array<char, 5> a2; // And not this...

How do I check if this template parameter is a power of two and warn the user with a nice message about this?

I've been able to check for this with a simple template:

template<int N>
struct is_power_of_two {
    enum {val = (N >= 1) & !(N & (N - 1))};
};

However, I'm unable to warn the user about this with a sane message. Any ideas?

EDIT

Fixed the ambiguous example.

EDIT

1 is a power of two indeed. Fixed that! :)

EDIT

Using BOOST_STATIC_ASSERT, I'm getting this compile error for this code with GCC:

template<int N>
struct is_power_of_two {
    enum {val = (N >= 1) & !(N & (N - 1))};
    BOOST_STATIC_ASSERT(val);
};

Error

..\main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' 

http://ideone.com/cMfEf

EDIT

Oh, I get it. That was the message that I'm supposed to get when the assert fails. But that fails to give the user some sane message. :(


Solution

  • These days, with constexpr and the bit twiddling hacks you can just

    constexpr bool is_powerof2(int v) {
        return v && ((v & (v - 1)) == 0);
    }