Very nice!
One small note: In an Eratosthenes sieve, you can start crossing out numbers from p^2, since i*p for i<p will have already been crossed out in step i at the latest. You can simply replace
for (size_t i=2; i <= 0xFFFFFFFF / p; i++) {
by for (size_t i=p; i <= 0xFFFFFFFF / p; i++) {