it currently returns
return std::popcount(~to_unsigned(x));
when x is smaller than int, e.g., short. to_unsigned(x) returns a value of type unsigned short. using it as an operand of an arithmetic operation ~x, it first gets promoted to int, then the operation gets applied, returning another int, which causes the call to std::popcount to fail since it's a signed integer type.
to fix this we could write it as
auto u = to_unsigned(x);
using unsigned = decltype(u);
return std::popcount(static_cast<unsigned>(~u));