Hi, I have a struct POW which calculates the power of a number in compiletime, and it looked like this before:
Code:
template<uint64 b, uint n>
struct POW {
private:
STATIC_ASSERT(b <= 1 || n < (sizeof b) * CHAR_BIT); /* Quick check for power overflow */
enum {pre_pow = b > 1 && n ? POW<b, n/2>::value : 1,
factor = pre_pow * (n & 1 ? b : 1) };
STATIC_ASSERT(b <= 1 || n == 0 ||
pre_pow*factor/factor == pre_pow); /* Extensive check for power overflow */
public:
enum {value = (b == 1 || n == 0 ? 1 :
b <= 1 ? 0 :
pre_pow * factor)};
};
But I got the compile error
Code:
preprocessing.hpp: In instantiation of `POW<2ull, 0u>':
preprocessing.hpp:41: instantiated from `POW<2ull, 1u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 2u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 4u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 8u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 16u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 32u>'
integer.hpp:51: instantiated from here
preprocessing.hpp:41: error: incomplete type `POW<2ull, 0u>' used in nested name specifier
preprocessing.hpp:41: error: enumerator value for `pre_pow' not integer constant
Line 41 is the line where I calculate pre_pow. So I changed the line to
Code:
pre_pow = b > 1 && n ? POW<b, n/2 - !n>::value : 1
instead, and now I get this error:
Code:
preprocessing.hpp: In instantiation of `POW<2ull, -1u>':
preprocessing.hpp:41: instantiated from `POW<2ull, 0u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 1u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 2u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 4u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 8u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 16u>'
preprocessing.hpp:41: instantiated from `POW<2ull, 32u>'
integer.hpp:51: instantiated from here
preprocessing.hpp:40: error: invalid application of `sizeof' to incomplete type `COMPILE_TIME_ERROR<1u>'
Why do I get this error? Does it maybe have to do with my STATIC_ASSERT macro (which is tested and should work)?
Everything works fine though if I add an extra
Code:
template<uint64 b> struct POW<b, 0> { enum {value = 1}; };
afterwards. This however, I didn't need to do for my LOG_B struct which works perfectly; it looks like this by the way:
Code:
template<uint b, uint64 n>
struct LOG_B {
STATIC_ASSERT(b > 1);
STATIC_ASSERT(n > 0);
enum {value = n >= b ? LOG_B<b, n/b>::value + 1 : 0};
};