carl  24.04
Computer ARithmetic Library
PrimeFactory.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "numbers.h"
4 
5 #include <mutex>
6 
7 namespace carl {
8 
9 /**
10  * This class provides a convenient way to enumerate primes.
11  */
12 template<typename T>
14 {
15  static std::vector<T> mPrimes;
16 #ifdef THREAD_SAFE
17  static std::mutex mPrimeMutex;
18 #endif
19  std::size_t mNext = 0;
20 public:
21  /// Returns the number of already computed primes.
22  std::size_t size() const {
23  return mPrimes.size();
24  }
25  /// Provides const access to the computed primes. Asserts that id is smaller than size().
26  const T& operator[](std::size_t id) const {
27  assert(id < mPrimes.size());
28  return mPrimes[id];
29  }
30  /// Provides access to the computed primes. If id is at least size(), the missing primes are computed on-the-fly.
31  const T& operator[](std::size_t id) {
32  while (id >= mPrimes.size()) next_prime();
33  return mPrimes[id];
34  }
35  /// Computed the next prime and returns it.
36  const T& next_prime();
37 };
38 
39 template<typename T>
40 std::vector<T> PrimeFactory<T>::mPrimes = {
41  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
42  43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
43 };
44 #ifdef THREAD_SAFE
45 template<typename T>
46 std::mutex PrimeFactory<T>::mPrimeMutex;
47 #endif
48 
49 namespace detail {
50  inline uint next_prime(const uint& n, const PrimeFactory<uint>& pf) {
51  for (uint res = n + 2; ; res += 2) {
52  bool found = false;
53  for (std::size_t i = 1; !found && (i < pf.size()); i++) {
54  if (res % pf[i] == 0) found = true;
55  }
56  if (!found) return res;
57  }
58  }
59 
60  inline mpz_class next_prime(const mpz_class& n, const PrimeFactory<mpz_class>&) {
61  mpz_class res;
62  mpz_nextprime(res.get_mpz_t(), n.get_mpz_t());
63  return res;
64  }
65 
66 #ifdef USE_CLN_NUMBERS
67  inline cln::cl_I next_prime(const cln::cl_I& n, const PrimeFactory<cln::cl_I>&) {
68  return cln::nextprobprime(n + 1);
69  }
70 #endif
71 }
72 
73 template<typename T>
75  if (mNext == mPrimes.size()) {
76 #ifdef THREAD_SAFE
77  std::lock_guard<std::mutex> guard(mPrimeMutex);
78 #endif
79  mPrimes.emplace_back(detail::next_prime(mPrimes.back(), *this));
80  }
81  return mPrimes[mNext++];
82 }
83 
84 }
carl is the main namespace for the library.
std::uint64_t uint
Definition: numbers.h:16
uint next_prime(const uint &n, const PrimeFactory< uint > &pf)
Definition: PrimeFactory.h:50
This class provides a convenient way to enumerate primes.
Definition: PrimeFactory.h:14
const T & operator[](std::size_t id) const
Provides const access to the computed primes. Asserts that id is smaller than size().
Definition: PrimeFactory.h:26
const T & operator[](std::size_t id)
Provides access to the computed primes. If id is at least size(), the missing primes are computed on-...
Definition: PrimeFactory.h:31
std::size_t mNext
Definition: PrimeFactory.h:19
std::size_t size() const
Returns the number of already computed primes.
Definition: PrimeFactory.h:22
const T & next_prime()
Computed the next prime and returns it.
Definition: PrimeFactory.h:74
static std::vector< T > mPrimes
Definition: PrimeFactory.h:15