<p>Stumbled across this looking for the same thing. I ended up writing the following:</p>
<pre><code>#include &lt;bitset&gt;
#include &lt;limits&gt;
#include &lt;type_traits&gt;

#include &lt;boost/multiprecision/cpp_int.hpp&gt;

// N.B.: Prior to Boost 1.79 MinBits and MaxBits were unsigned,
//       not size_t - using auto to paper over this difference.
template &lt;
    auto MinBits,
    auto MaxBits,
    boost::multiprecision::cpp_integer_type SignType,
    boost::multiprecision::cpp_int_check_type Checked,
    class Allocator&gt;
size_t popcount(
        const boost::multiprecision::number&lt;
            boost::multiprecision::cpp_int_backend&lt;
                MinBits,
                MaxBits,
                SignType,
                Checked,
                Allocator&gt;&gt;&amp; bits) {
    const auto&amp; backend = bits.backend();

    // Using std::bitset::count to access a native popcnt.
    // In principle the limb type could be larger than what a
    // bitset can natively handle, in practice it likely isn't.
    using BitsetNativeType = unsigned long long;
    constexpr size_t kNativeBits = std::numeric_limits&lt;BitsetNativeType&gt;::digits;
    using LimbType = std::decay_t&lt;decltype(*backend.limbs())&gt;;
    constexpr size_t kLimbBits = std::numeric_limits&lt;LimbType&gt;::digits;

    constexpr size_t kNativesToCount = (kLimbBits + kNativeBits - 1) / kNativeBits;
    constexpr size_t kShiftPerNative = kNativesToCount &gt; 1 ? kNativeBits : 0;
    static_assert(kNativesToCount &gt; 0, &quot;bad bit counts&quot;);

    size_t result = 0;
    for (size_t i = 0; i != backend.size(); ++i) {
        auto limb_value = backend.limbs()[i];
        for (size_t j = 0; j != kNativesToCount; ++j) {
            const std::bitset&lt;kNativeBits&gt; limb_bitset{BitsetNativeType(limb_value)};
            result += limb_bitset.count();
            limb_value &gt;&gt;= kShiftPerNative;            
        }
    }
    return result;
}
</code></pre>
<p>For native word sizes (i.e., &lt;= 64 bits) this compiles to a single <code>popcnt</code>. Above that it compiles to two <code>popcnt</code> up to 128 bits. Beyond that it auto-vectorizes in clang - presumably to something inspired by <a href="https://arxiv.org/pdf/1611.07612.pdf" rel="nofollow noreferrer">Faster Population Counts Using AVX2 Instructions</a> but frankly I didn't investigate further. In gcc it just doesn't unroll the loop and still uses <code>popcnt</code>.</p>
<hr />
<p>clang demo: <a href="https://godbolt.org/z/fve195TeM" rel="nofollow noreferrer">https://godbolt.org/z/fve195TeM</a><br />
gcc demo: <a href="https://godbolt.org/z/P4ndY8ccq" rel="nofollow noreferrer">https://godbolt.org/z/P4ndY8ccq</a></p>
How do I get the population count of an unsigned unchecked number with boost::multiprecision?
<p>I'm using boost::multiprecision to have fixed but arbitrary precision integers. 
I was planning to use <code>number&lt;cpp_int&lt;W, W, unsigned_magnitude, unchecked, void&gt;&gt;</code>. The first obvious question is:</p>

<p>Does this datatype have the standard bit pattern of any unsigned integer of a given precision? I heard that signed extended precision numbers don't use 2's complement, but I think that unsigned ones should use the standard representation, or am I missing something?</p>

<p>If this is the case, then ho can i get the population count of the integer? I doesn't seem to be any public interface to do that. I could be happy also of a way to get the internal
memory so I can count the population of the single words used as storage.</p>

<p>Thank you</p>