user986139
user986139

Reputation:

Conditional numerical constraint on template argument

I have a template for a data structure / container optimized for sizes in the power of 2 and will not work properly unless the size parameter is a power 2.

template <typename T, unsigned int __pow2int>
class CustomContainer {
}

What is the best way / is it even possible... to enforce a compile-time check to ensure that __pow2int is a power of 2?

I'm new to C++ and I've been looking at pages like this: http://www.stroustrup.com/bs_faq2.html#constraints but I find syntax such as...

static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
    Can_copy() { void(*p)(T1,T2) = constraints; }

totally confusing, I'm not even sure if that is the way to go about what I'm trying to achieve, I got totally lost trying to follow that FAQ.

The way I see it, perhaps I should declare a user-defined type that only creates power of 2 integers and use that as a template type?

I tried to implement it, but I ended up getting a "non-type template parameter cannot...." error.

class intb2 {
    const std::uint32_t _output;
public:
    intb2(std::uint8_t bit) : _output([&]() {
        uint8_t rbit=(bit == 0) ? 1 : bit;
        std::uint32_t i=1;
        return (i << (rbit-1));
    }()) {}

    const std::uint32_t& operator()() {
        return _output;
    }
};

template <typename T, intb2 __pow2int>
class CustomContainer {....

Upvotes: 2

Views: 192

Answers (2)

jrok
jrok

Reputation: 55415

The usual trick to check whether a number x is a power of two is to bitwise-and it with x-1 and see if the result is zero:

x != 0 && (x & (x−1)) == 0

Now use that in a static assert declaration:

template <typename T, unsigned int N>
class CustomContainer {
    static_assert( N != 0 && (N & (N−1)) == 0 , "Not a power of two!");
};

Upvotes: 5

sp2danny
sp2danny

Reputation: 7687

The easiest way to solve this is to use the exponent as the argument.

template <typename T, unsigned int exp>
class CustomContainer
{
    unsigned int __pow2int = 1<<exp;

};

Upvotes: 1

Related Questions