# libprimesieve C++ examples This is a short selection of C++ code snippets that use libprimesieve to generate prime numbers. These examples cover the most frequently used functionality of libprimesieve. Arguably the most useful feature provided by libprimesieve is the ```primesieve::iterator``` which lets you iterate over primes using the ```next_prime()``` or ```prev_prime()``` methods. Additional libprimesieve documentation links: * [Install libprimesieve](https://github.com/kimwalisch/primesieve#installation) * [C++ API Reference](https://kimwalisch.github.io/primesieve/api) * [libprimesieve performance tips](https://github.com/kimwalisch/primesieve#libprimesieve-performance-tips) ## ```primesieve::iterator::next_prime()``` By default ```primesieve::iterator::next_prime()``` generates primes > 0 i.e. 2, 3, 5, 7, ... ```C++ #include #include int main() { primesieve::iterator it; uint64_t prime = it.next_prime(); uint64_t sum = 0; // iterate over the primes below 10^9 for (; prime < 1000000000; prime = it.next_prime()) sum += prime; std::cout << "Sum of the primes below 10^9 = " << sum << std::endl; return 0; } ``` * [Build instructions](#how-to-compile) ## ```primesieve::iterator::skipto()``` This method changes the start number of the ```primesieve::iterator``` object. (By default the start number is initialized to 0). Note that you can also specify the start number in the constructor of the ```primesieve::iterator``` object. ```C++ #include #include int main() { primesieve::iterator it; // iterate over primes > 1000 it.skipto(1000); uint64_t prime = it.next_prime(); // iterate over primes from ]1000, 1100] for (; prime <= 1100; prime = it.next_prime()) std::cout << prime << std::endl; return 0; } ``` * [Build instructions](#how-to-compile) The ```primesieve::iterator::skipto()``` method (and the ```primesieve::iterator``` constructor) take an optional ```stop_hint``` parameter for performance optimization. If ```stop_hint``` is set ```primesieve::iterator``` will only buffer primes up to this limit. ```C++ #include #include int main() { uint64_t start = 1000; uint64_t stop_hint = 1100; // iterate over primes > start primesieve::iterator it(start, stop_hint); uint64_t prime = it.next_prime(); // iterate over primes from ]1000, 1100] for (; prime <= 1100; prime = it.next_prime()) std::cout << prime << std::endl; return 0; } ``` * [Build instructions](#how-to-compile) ## ```primesieve::iterator::prev_prime()``` Before using ```primesieve::iterator::prev_prime()``` you must change the start number (either in the constructor or using the ```skipto()``` method) as the start number is initialized to 0 be default. ```C++ #include #include int main() { // iterate over primes < 1000 primesieve::iterator it(1000); uint64_t prime = it.prev_prime(); // iterate over primes from ]1000, 0[ for (; prime > 0; prime = it.prev_prime()) std::cout << prime << std::endl; return 0; } ``` * [Build instructions](#how-to-compile) ## ```primesieve::generate_primes()``` Stores the primes inside [start, stop] in a ```std::vector```. If you are iterating over the same primes many times in a loop you will likely get better performance if you store the primes in a vector instead of using a ```primesieve::iterator``` (provided your system has enough memory). ```C++ #include #include int main() { std::vector primes; // Store primes <= 1000 primesieve::generate_primes(1000, &primes); primes.clear(); // Store primes inside [1000, 2000] primesieve::generate_primes(1000, 2000, &primes); return 0; } ``` * [Build instructions](#how-to-compile) ## ```primesieve::generate_n_primes()``` Stores n primes in a ```std::vector```. ```C++ #include #include int main() { std::vector primes; // Store first 1000 primes primesieve::generate_n_primes(1000, &primes); primes.clear(); // Store first 10 primes >= 1000 primesieve::generate_n_primes(10, 1000, &primes); return 0; } ``` * [Build instructions](#how-to-compile) ## ```primesieve::count_primes()``` Counts the primes inside [start, stop]. This method is multi-threaded and uses all available CPU cores by default. ```C++ #include #include int main() { uint64_t count = primesieve::count_primes(0, 1000); std::cout << "Primes below 1000 = " << count << std::endl; return 0; } ``` * [Build instructions](#how-to-compile) ## ```primesieve::nth_prime()``` This method finds the nth prime e.g. ```nth_prime(25) = 97```. This method is multi-threaded and uses all available CPU cores by default. ```C++ #include #include int main() { uint64_t n = 25; uint64_t nth_prime = primesieve::nth_prime(n); std::cout << n << "th prime = " << nth_prime << std::endl; return 0; } ``` * [Build instructions](#how-to-compile) # Error handling If an error occurs libprimesieve throws a ```primesieve::primesieve_error``` exception that is derived from ```std::runtime_error```. Note that libprimesieve very rarely throws an exception, the two main cases which will trigger an exception are: memory allocation failure (throws ```std::bad_alloc```) and trying to generate primes > 2^64 (throws ```primesieve::primesieve_error```). ```C++ #include #include int main() { try { // Try generating primes > 2^64 uint64_t start = ~0ull - 1; uint64_t n = 1000; std::vector primes; primesieve::generate_n_primes(n, start, &primes); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } ``` # How to compile ### Unix-like OSes If [libprimesieve is installed](https://github.com/kimwalisch/primesieve#installation) on your system, then you can compile any of the C++ example programs above using: ```sh c++ -O3 primes.cpp -o primes -lprimesieve ``` If you have [built libprimesieve yourself](BUILD.md#primesieve-build-instructions), then the default installation path is usually ```/usr/local/lib```. Running the ```ldconfig``` program after ```make install``` ensures that Linux's dynamic linker/loader will find the shared primesieve library when you execute your program. However, some OSes are missing the ```ldconfig``` program or ```ldconfig``` does not include ```/usr/local/lib``` by default. In these cases you need to export some environment variables: ```sh export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH export CPLUS_INCLUDE_PATH=/usr/local/include:$CPLUS_INCLUDE_PATH ``` ### Microsoft Visual C++ ```sh cl /O2 /EHsc /MD primes.cpp /I "path\to\primesieve\include" /link "path\to\primesieve.lib" ``` # CMake support If you are using the CMake build system to compile your program and [libprimesieve is installed](https://github.com/kimwalisch/primesieve#installation) on your system, then you can add the following two lines to your ```CMakeLists.txt``` to link your program against libprimesieve. ```CMake find_package(primesieve REQUIRED) target_link_libraries(your_program primesieve::primesieve) ``` To link against the static libprimesieve use: ```CMake find_package(primesieve REQUIRED static) target_link_libraries(your_program primesieve::primesieve) ``` # Minimal CMake project file If you want to build your C++ program (named ```primes.cpp```) using CMake, then you can use the minimal ```CMakeLists.txt``` below. Note that this requires that [libprimesieve is installed](https://github.com/kimwalisch/primesieve#installation) on your system. Using CMake has the advantage that you don't need to specify the libprimesieve include path and the ```-lprimesieve``` linker option when building your project. ```CMake # File: CMakeLists.txt cmake_minimum_required(VERSION 3.4...3.19) project(primes CXX) find_package(primesieve REQUIRED) add_executable(primes primes.cpp) target_link_libraries(primes primesieve::primesieve) ``` Put the ```CMakeLists.txt``` file from above into the same directory as your ```primes.cpp``` file.
Then open a terminal, cd into that directory and build your project using: ```sh cmake . -DCMAKE_BUILD_TYPE=Release cmake --build . ``` Using the MSVC compiler (Windows) the build instructions are slightly different. First you should link against the static libprimesieve in your ```CMakeLists.txt``` using: ```find_package(primesieve REQUIRED static)```. Next open a Visual Studio Command Prompt, cd into your project's directory and build your project using: ```sh cmake -G "Visual Studio 16 2019" . cmake --build . --config Release ```