Skip to content

Commit

Permalink
Merge pull request #4 from LTLA/rng_scope
Browse files Browse the repository at this point in the history
Implement the RNGScope class for RAII-based RNG control.
  • Loading branch information
szhorvat authored Jul 18, 2024
2 parents d38f44c + 85324d6 commit 0a64adf
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ make_test(ex_list)
make_test(ex_decompose)
make_test(ex_error)
make_test(ex_views)
make_test(ex_rng_scope)
make_test(ex_igraph_tutorial)
31 changes: 31 additions & 0 deletions examples/ex_rng_scope.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <iostream>
#include <igraph.hpp>
#include "ex_vector_print.hpp"

int main() {
// Check that we can influence the RNG.
{
ig::RNGScope filled(1000);
std::cout << "New RNG scope:" << std::endl;
std::cout << " Draw from [0, 100]: " << igraph_rng_get_integer(igraph_rng_default(), 0, 100) << std::endl;
std::cout << " Draw from [0, 100]: " << igraph_rng_get_integer(igraph_rng_default(), 0, 100) << std::endl;
}

// Check that the destructor correctly unsets the RNG.
{
ig::RNGScope filled(1000);
std::cout << "New RNG scope:" << std::endl;
std::cout << " Draw from [0, 100]: " << igraph_rng_get_integer(igraph_rng_default(), 0, 100) << std::endl;

{
ig::RNGScope nested; // uses a default seed and type.
std::cout << " New RNG scope:" << std::endl;
std::cout << " Draw from [0, 100]: " << igraph_rng_get_integer(igraph_rng_default(), 0, 100) << std::endl;
std::cout << " Draw from [0, 100]: " << igraph_rng_get_integer(igraph_rng_default(), 0, 100) << std::endl;
}

std::cout << " Draw from [0, 100]: " << igraph_rng_get_integer(igraph_rng_default(), 0, 100) << std::endl;
}

return 0;
}
2 changes: 2 additions & 0 deletions include/igraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ using igIntVecList = igVecList<igraph_integer_t>;
using igBoolVec = igVec<igraph_bool_t>;
using igBoolMat = igMat<igraph_bool_t>;

#include "rng_scope.hpp"

class igGraphList;

class igGraph {
Expand Down
41 changes: 41 additions & 0 deletions include/rng_scope.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class RNGScope {
public:
RNGScope(igraph_uint_t seed) : RNGScope(seed, &igraph_rngtype_pcg32) {}

RNGScope(igraph_uint_t seed, const igraph_rng_type_t* type) {
igCheck(igraph_rng_init(&current, type));

auto errcode = igraph_rng_seed(&current, seed);
if (errcode != IGRAPH_SUCCESS) {
igraph_rng_destroy(&current);
throw igException(errcode);
}

previous = *(igraph_rng_default());
igraph_rng_set_default(&current);
}

RNGScope(const igraph_rng_type_t* type) {
igCheck(igraph_rng_init(&current, type));
previous = *(igraph_rng_default());
igraph_rng_set_default(&current);
}

RNGScope() : RNGScope(&igraph_rngtype_pcg32) {}

public:
// We shouldn't be copying or moving an RNGscope object, as this defeats the logic provided by scoping.
RNGScope(const RNGScope&) = delete;
RNGScope& operator=(const RNGScope&) = delete;
RNGScope(RNGScope&&) = delete;
RNGScope& operator=(RNGScope&&) = delete;

~RNGScope() {
igraph_rng_set_default(&previous);
igraph_rng_destroy(&current);
}

private:
igraph_rng_t previous;
igraph_rng_t current;
};

0 comments on commit 0a64adf

Please sign in to comment.