Compile time log2

Been working on some wrappers over data containers allowing to move code to SPU easier recently and found myself in need of a compile-time log2 (for shifts, so integers only). Luckily, it’s pretty straightforward to achieve using some template voodoo and boils down to using fact that log2(x) == log2(x / 2) + 1:

 1	template<size_t V>
 2	struct Log2
 3	{
 4		enum
 5		{
 6			Value = Log2<V / 2>::Value + 1
 7		};
 8		typedef char V_MustBePowerOfTwo[((V & (V - 1)) == 0 ? 1 : -1)];
 9	};
10	template<> struct Log2<1> { enum { Value = 0 }; };
11
12	RDE_COMPILE_CHECK(Log2<8>::Value == 3);
13	RDE_COMPILE_CHECK(Log2<256>::Value == 8);
14    // Just to see it's really compile-time.
15    int tab[Log2<16>::Value];

Sidenote: tried this with VS2010 and it’s actually able to evaluate those compile time assertions in real-time (as you type, kinda like C# or Java). Little thing, but kinda neat (OTOH it’s slow as hell on my laptop, feels very sluggish when compared to VS2008). Template itself shouldn’t stress the compiler too much, unless you go really crazy with argument value. Doesn’t leave any trace in generated code (except for the constant).

Old comments

Tomasz Dabrowski 2011-01-30 00:15:15

Doesn’t VS2010 support constexpr? It’d be much prettier than template wizardry.

admin 2011-01-30 00:46:13

It might, I still need it to run on 2008 & ProDG.

Tom 2011-01-30 12:23:23

Here’s a real compile-time log2 ;)
http://pastebin.com/scDBhr2D

rride 2011-02-18 21:35:45

It could be so nice to have another article - log2 compile time=)

More Reading
Newer// Retro Pinball