There are many instances of prime number sieve implementation both here and other places on the web, but I wanted something a little different. In particular, I wanted to create a static array of the first 1024 prime numbers at compile time as a simple reusable structure. I also wanted to allow for relatively simple creation of larger or smaller arrays.
I combined the code from this question with a little bit of macro magic from this other question to come up with code that meets my goal.
Questions:
I'd like to be able to use something more elegant than the stack of macros (templates perhaps), and would prefer to have the result be something more like an STL container than a raw array. Comments on how to do those things, or comments generally to clean up the code would be welcome.
primeconsttest.cpp
#include "primeconst.h"
#include <vector>
#include <iterator>
#include <iostream>
int main() {
std::vector<int> prime{std::begin(primes), std::end(primes)};
for (unsigned i=0; i < prime.size(); ++i)
std::cout << i << '\t' << prime[i] << '\n';
}
primeconst.h
extern const int primes[1024];
primeconst.cpp
constexpr bool isPrimeLoop(int i, int k) {
return (k*k > i)?true:(i%k == 0)?false:isPrimeLoop(i, k + 1);
}
constexpr bool isPrime(int i) {
return isPrimeLoop(i, 2);
}
constexpr int nextPrime(int k) {
return isPrime(k)?k:nextPrime(k + 1);
}
constexpr int getPrimeLoop(int i, int k) {
return (i == 0)?k:
(i % 2)?getPrimeLoop(i-1, nextPrime(k + 1)):
getPrimeLoop(i/2, getPrimeLoop(i/2, k));
}
constexpr int getPrime(int i) {
return getPrimeLoop(i, 2);
}
static_assert(getPrime(511) == 3671, "computed incorrectly");
#define K(x) J(x) J(x + 512)
#define J(x) I(x) I(x + 256)
#define I(x) H(x) H(x + 128)
#define H(x) G(x) G(x + 64)
#define G(x) F(x) F(x + 32)
#define F(x) E(x) E(x + 16)
#define E(x) D(x) D(x + 8)
#define D(x) C(x) C(x + 4)
#define C(x) B(x) B(x + 2)
#define B(x) A(x) A(x + 1)
#define A(x) getPrime(x) ,
extern constexpr int primes[] = { K(0) };
Output
0 2
1 3
2 5
3 7
4 11
5 13
6 17
...
1017 8093
1018 8101
1019 8111
1020 8117
1021 8123
1022 8147
1023 8161