Skip to content

Commit

Permalink
hashtest: support initializer_list arguments to ChooseRandomElement
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 651513074
  • Loading branch information
ncbray authored and copybara-github committed Jul 11, 2024
1 parent f688074 commit bd4260c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
7 changes: 6 additions & 1 deletion fuzzer/hashtest/hashtest_generator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ TEST(RandUtil, MultipleRandomBits) {
EXPECT_THAT(popped_bits, UnorderedElementsAre(11, 13, 53, 97));
}

TEST(RandUtil, RandomElement) {
TEST(RandUtil, RandomElementVec) {
std::mt19937_64 rng(0);
std::vector<int> v = {7};
EXPECT_EQ(7, ChooseRandomElement(rng, v));
}

TEST(RandUtil, RandomElementInitList) {
std::mt19937_64 rng(0);
EXPECT_EQ(11, ChooseRandomElement(rng, {11}));
}

TEST(WeightedChooseOne, Single) {
std::mt19937_64 rng(0);
size_t a = 0;
Expand Down
25 changes: 21 additions & 4 deletions fuzzer/hashtest/rand_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include <bitset>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <random>
#include <vector>

Expand All @@ -39,11 +41,26 @@ void SometimesSwap(Rng& rng, T& a, T& b) {
}
}

// Return a random element from `vec`.
// Return a random element in an iterable range.
template <typename Rng, typename Iter>
auto& ChooseRandomElement(Rng& rng, Iter begin, Iter end) {
std::uniform_int_distribution<size_t> dist(0, std::distance(begin, end) - 1);
std::advance(begin, dist(rng));
return *begin;
}

// Return a random element of an iterable type `collection`.
template <typename Rng, typename C>
auto& ChooseRandomElement(Rng& rng,
C& collection ABSL_ATTRIBUTE_LIFETIME_BOUND) {
return ChooseRandomElement(rng, std::begin(collection), std::end(collection));
}

// Template type resolution cannot handle literal lists like "{1, 2, 3}" being
// passed as a parameter unless there is an initializer_list overload.
template <typename Rng, typename T>
const T& ChooseRandomElement(
Rng& rng, const std::vector<T>& vec ABSL_ATTRIBUTE_LIFETIME_BOUND) {
return vec[std::uniform_int_distribution<size_t>(0, vec.size() - 1)(rng)];
T ChooseRandomElement(Rng& rng, std::initializer_list<T> collection) {
return ChooseRandomElement(rng, std::begin(collection), std::end(collection));
}

// Return the index of a random set bit in `bits`.
Expand Down

0 comments on commit bd4260c

Please sign in to comment.