次のコードは、GCC の clz/ctz の組み込み関数を呼び出します。他のシステムでは、C バージョンがあります。明らかに、システムに組み込みの clz/ctz 命令 (x86 や ARM など) がある場合、C バージョンは少し最適ではありません。
#ifdef __GNUC__
#define clz(x) __builtin_clz(x)
#define ctz(x) __builtin_ctz(x)
#else
static uint32_t ALWAYS_INLINE popcnt( uint32_t x )
{
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static uint32_t ALWAYS_INLINE clz( uint32_t x )
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - popcnt(x);
}
static uint32_t ALWAYS_INLINE ctz( uint32_t x )
{
return popcnt((x & -x) - 1);
}
#endif
ここで MSVC の適切な ifdef を追加するには、どの関数を呼び出す必要がありますか、どのヘッダーを含める必要がありますか? 私はすでにこのページを見てきましたが、#pragma の目的 (必須ですか?) と、コンパイルの MSVC バージョン要件にどのような制限を課すのか、完全にはわかりません。MSVC を実際に使用していない人として、これらの組み込み関数が他のアーキテクチャで同等の C を持っているかどうか、またはそれらを #define するときに x86/x86_64 を #ifdef する必要があるかどうかもわかりません。