The nth prime
The nth prime for n below 100 in modern C++, built at compile time and checked at run time.
#include <array>
#include <cstddef>
#include <optional>
#include <print>
// The 99th prime is 523, so a sieve up to 523 covers every n below 100.
inline constexpr std::size_t max_n = 99;
inline constexpr std::size_t sieve_limit = 523;
consteval auto first_primes() {
std::array<int, max_n> primes{};
std::array<bool, sieve_limit + 1> composite{};
std::size_t found = 0;
for (std::size_t i = 2; i <= sieve_limit && found < primes.size(); ++i) {
if (composite[i]) continue;
primes[found++] = static_cast<int>(i);
for (std::size_t j = i * i; j <= sieve_limit; j += i) composite[j] = true;
}
return primes;
}
inline constexpr auto table = first_primes();
/// The nth prime, counting from 1, or nothing when n is outside 1..99.
[[nodiscard]] constexpr std::optional<int> nth_prime(std::size_t n) noexcept {
if (n == 0 || n > table.size()) return std::nullopt;
return table[n - 1];
}
static_assert(nth_prime(1) == 2);
static_assert(nth_prime(25) == 97);
static_assert(nth_prime(99) == 523);
static_assert(!nth_prime(100));
int main() {
for (std::size_t n : {1uz, 10uz, 25uz, 99uz, 100uz}) {
if (auto p = nth_prime(n)) std::println("prime #{} is {}", n, *p);
else std::println("prime #{} is out of range (1 to 99 only)", n);
}
}
The primes are found once, while the compiler builds the program, by a sieve in a consteval function, so looking one up is just an array read. nth_prime returns std::optional instead of a magic value when n is out of range, and the static_asserts check the table before the program ever runs. Try changing n in main, or edit the sieve, then press run.