#ifndef LABS_CPP_PERSON_H
#define LABS_CPP_PERSON_H
#include <vector>
#include <cstdint>
#include <algorithm>
class PrimeNumberGenerator {
 public:
  explicit PrimeNumberGenerator(int start) : _tableInternalIndex(start) {
	while (_size < start)
	  _size *= 2;
	_primeTable = std::vector<int64_t>(_size);
	CalcPrimes(start);
  }

  int GetNextPrime() {
	std::vector<int64_t>::iterator it{};
	int64_t answ{};
	if (!_primeNumbers.empty()) {
	  it = std::find(std::begin(_primeNumbers),
					 std::end(_primeNumbers), _primeNumbers.front());
	}

	if (it == std::end(_primeNumbers)) { // empty
	  _size *= 2;
	  CalcPrimes(_size / 2);
	}
	answ = *it;
	_primeNumbers.erase(it);
	return answ;
  }
 private:

  void CalcPrimes(int start) {
	for (size_t i = 0; i < _size; ++i) {
	  _primeTable[i] = i;
	}

	_primeTable[1] = 0;
	for (size_t i = 2; i < _size; ++i) {
	  if (_primeTable[i] != 0) {
		for (size_t j = i * i; j < _size; j += i)
		  _primeTable[j] = 0;
	  }
	}
	int i = 0;
	while (_primeTable[i] < start) {
	  _primeTable[i] = 0;
	  i++;
	}
	FetchFromTable();
  }

  void FetchFromTable() {
	for (auto x : _primeTable)
	  if (x != 0)
		_primeNumbers.push_back(x);
  }
  size_t _size = 1500000;
  int _tableInternalIndex = 0;
  std::vector<int64_t> _primeTable;
  std::vector<int64_t> _primeNumbers;
};
#endif