static void test_ctz_clz(void) { header(); for (size_t i = 0; i < sizeof(vals) / sizeof(vals[0]); i++) { if (vals[i] == 0) continue; uint64_t val64 = vals[i]; uint32_t val32 = (uint32_t) vals[i]; printf("bit_ctz_u64(%" PRIu64 ") => %d\n", val64, bit_ctz_u64(val64)); printf("bit_clz_u64(%" PRIu64 ") => %d\n", val64, bit_clz_u64(val64)); if (vals[i] > UINT32_MAX) continue; printf("bit_ctz_u32(%" PRIu32 ") => %d\n", val32, bit_ctz_u32(val32)); printf("bit_clz_u32(%" PRIu32 ") => %d\n", val32, bit_clz_u32(val32)); } footer(); }
int * bit_index_u32(uint32_t x, int *indexes, int offset) { #if defined(HAVE_BUILTIN_CTZ) int prev_pos = 0; int i = 0; #if defined(HAVE_BUILTIN_POPCOUNT) /* fast implementation using built-in popcount function */ const int count = bit_count_u32(x); while (i < count) { #else /* sligtly slower implementation without using built-in popcount */ while(x) { #endif /* use ctz */ const int a = bit_ctz_u32(x); prev_pos += a + 1; x >>= a; x >>= 1; indexes[i++] = offset + prev_pos; } indexes[i] = 0; return indexes + i; #else /* !defined(HAVE_BUILTIN_CTZ) */ BITINDEX_NAIVE(uint32_t, x, sizeof(uint32_t) * CHAR_BIT); #endif } int * bit_index_u64(uint64_t x, int *indexes, int offset) { #if defined(HAVE_CTZLL) int prev_pos = 0; int i = 0; #if defined(HAVE_POPCOUNTLL) /* fast implementation using built-in popcount function */ const int count = bit_count_u64(x); while (i < count) { #else /* sligtly slower implementation without using built-in popcount */ while(x) { #endif /* use ctz */ const int a = bit_ctz_u64(x); prev_pos += a + 1; x >>= a; x >>= 1; indexes[i++] = offset + prev_pos; } indexes[i] = 0; return indexes + i; #else /* !defined(HAVE_CTZ) */ BITINDEX_NAIVE(uint64_t, x, sizeof(uint64_t) * CHAR_BIT); #endif } #undef BITINDEX_NAIVE extern inline void bit_iterator_init(struct bit_iterator *it, const void *data, size_t size, bool set); extern inline size_t bit_iterator_next(struct bit_iterator *it);