Skip to content

Instantly share code, notes, and snippets.

@pr8x
Last active June 12, 2020 14:08
Show Gist options
  • Save pr8x/4e10b79a8647b79fde19505003df8565 to your computer and use it in GitHub Desktop.
Save pr8x/4e10b79a8647b79fde19505003df8565 to your computer and use it in GitHub Desktop.
constexpr int portable_ffs(uint32_t mask) {
if (std::is_constant_evaluated()) {
if (mask == 0) return 0;
auto count = 1;
while ((mask & 1U) == 0) {
mask >>= 1;
++count;
}
return count;
}
unsigned long r;
if (_BitScanForward(&r, mask)) {
return static_cast<int>(r + 1);
}
return 0;
}
template <class Iterator, class K, class C>
constexpr Iterator lower_bound_eytzinger(Iterator beg, Iterator end, const K& key, const C& comp) {
auto k = 1;
auto n = std::distance(beg, end);
while (k <= n) {
//__builtin_prefetch(b + k * block_size);
auto c = comp(*(beg + k - 1), key);
k = 2 * k + static_cast<int>(c);
}
k >>= util::portable_ffs(~k);
return beg + k - 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment