void pushBack_N_Primes(uint64_t n, uint64_t start) { n_ = n; PrimeSieve ps; std::size_t newSize = primes_.size() + static_cast<std::size_t>(n_); primes_.reserve(newSize); try { while (n_ > 0) { // choose stop > nth prime uint64_t logx = 50; uint64_t dist = n_ * logx + 10000; uint64_t stop = start + dist; // fix integer overflow if (stop < start) stop = get_max_stop(); ps.callbackPrimes(start, stop, this); start = stop + 1; if (stop >= get_max_stop()) throw primesieve_error("cannot generate primes > 2^64"); } } catch (cancel_callback&) { } }
void iterator::skipto(uint64_t start, uint64_t stop_hint) { if (start > get_max_stop()) throw primesieve_error("start must be <= " + PrimeFinder::getMaxStopString()); start_ = start; stop_ = start; stop_hint_ = stop_hint; i_ = 0; last_idx_ = 0; tiny_cache_size_ = 1 << 11; primes_.clear(); }
void iterator::generate_next_primes() { primes_.clear(); while (primes_.empty()) { start_ = add_overflow_safe(stop_, 1); stop_ = add_overflow_safe(start_, get_interval_size(start_)); if (start_ <= stop_hint_ && stop_ >= stop_hint_) stop_ = add_overflow_safe(stop_hint_, max_prime_gap(stop_hint_)); primesieve::generate_primes(start_, stop_, &primes_); if (primes_.empty() && stop_ >= get_max_stop()) throw primesieve_error("next_prime() > " + PrimeFinder::getMaxStopString()); } last_idx_ = primes_.size() - 1; i_ = 0; }
uint64_t add_overflow_safe(uint64_t a, uint64_t b) { uint64_t max_stop = get_max_stop(); return (a < max_stop - b) ? a + b : max_stop; }