#include <iostream>
#include <type_traits>
size_t bitcount(unsigned int v) {
size_t ret = 0;
while (v != 0) {
v &= v - 1;
ret++;
}
return ret;
}
size_t bitcount(unsigned char v) {
size_t ret = 0;
while (v != 0) {
v &= v - 1;
ret++;
}
return ret;
}
template<int N>
typename std::enable_if<(N == 1), size_t>::type bitcount_p(unsigned char *c) {
return bitcount(*c);
}
template<int N>
typename std::enable_if<(N > 1), size_t>::type bitcount_p(unsigned char *c) {
return bitcount(*c) + bitcount_p<N-1>(c+1);
}
template<int N>
typename std::enable_if<(N < sizeof(unsigned int)), size_t>::type bitcount_p(unsigned int *v) {
return bitcount_p<N>(reinterpret_cast<unsigned char *>(v));
}
template<int N>
typename std::enable_if<(N == sizeof(unsigned int)), size_t>::type bitcount_p(unsigned int *v) {
return bitcount(*v);
}
template<int N>
typename std::enable_if<(N > sizeof(unsigned int)), size_t>::type bitcount_p(unsigned int *v) {
return bitcount(*v) + bitcount_p<N - sizeof(unsigned int)>(v+1);
}
template<typename T>
size_t bitcount(T v) {
return bitcount_p<sizeof(T)>( reinterpret_cast<unsigned int *>(&v) );
}
int main() {
std::cout << bitcount(0x01234567) << std::endl;
std::cout << bitcount(0x0123456789abcdefULL) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzaXplX3QgYml0Y291bnQodW5zaWduZWQgaW50IHYpIHsKICBzaXplX3QgcmV0ID0gMDsKICB3aGlsZSAodiAhPSAwKSB7CiAgICB2ICY9IHYgLSAxOwogICAgcmV0Kys7CiAgfQogIHJldHVybiByZXQ7Cn0KCnNpemVfdCBiaXRjb3VudCh1bnNpZ25lZCBjaGFyIHYpIHsKICBzaXplX3QgcmV0ID0gMDsKICB3aGlsZSAodiAhPSAwKSB7CiAgICB2ICY9IHYgLSAxOwogICAgcmV0Kys7CiAgfQogIHJldHVybiByZXQ7Cn0KCnRlbXBsYXRlPGludCBOPgp0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwoTiA9PSAxKSwgc2l6ZV90Pjo6dHlwZSBiaXRjb3VudF9wKHVuc2lnbmVkIGNoYXIgKmMpIHsKICByZXR1cm4gYml0Y291bnQoKmMpOwp9Cgp0ZW1wbGF0ZTxpbnQgTj4KdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8KE4gPiAxKSwgc2l6ZV90Pjo6dHlwZSBiaXRjb3VudF9wKHVuc2lnbmVkIGNoYXIgKmMpIHsKICByZXR1cm4gYml0Y291bnQoKmMpICsgYml0Y291bnRfcDxOLTE+KGMrMSk7Cn0KCnRlbXBsYXRlPGludCBOPgp0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwoTiA8IHNpemVvZih1bnNpZ25lZCBpbnQpKSwgc2l6ZV90Pjo6dHlwZSBiaXRjb3VudF9wKHVuc2lnbmVkIGludCAqdikgewogIHJldHVybiBiaXRjb3VudF9wPE4+KHJlaW50ZXJwcmV0X2Nhc3Q8dW5zaWduZWQgY2hhciAqPih2KSk7Cn0KCnRlbXBsYXRlPGludCBOPgp0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwoTiA9PSBzaXplb2YodW5zaWduZWQgaW50KSksIHNpemVfdD46OnR5cGUgYml0Y291bnRfcCh1bnNpZ25lZCBpbnQgKnYpIHsKICByZXR1cm4gYml0Y291bnQoKnYpOwp9Cgp0ZW1wbGF0ZTxpbnQgTj4KdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8KE4gPiBzaXplb2YodW5zaWduZWQgaW50KSksIHNpemVfdD46OnR5cGUgYml0Y291bnRfcCh1bnNpZ25lZCBpbnQgKnYpIHsKICByZXR1cm4gYml0Y291bnQoKnYpICsgYml0Y291bnRfcDxOIC0gc2l6ZW9mKHVuc2lnbmVkIGludCk+KHYrMSk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnNpemVfdCBiaXRjb3VudChUIHYpIHsKICByZXR1cm4gYml0Y291bnRfcDxzaXplb2YoVCk+KCByZWludGVycHJldF9jYXN0PHVuc2lnbmVkIGludCAqPigmdikgKTsKfQoKaW50IG1haW4oKSB7CglzdGQ6OmNvdXQgPDwgYml0Y291bnQoMHgwMTIzNDU2NykgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IGJpdGNvdW50KDB4MDEyMzQ1Njc4OWFiY2RlZlVMTCkgPDwgc3RkOjplbmRsOwoJcmV0dXJuIDA7Cn0K