blob: 5ddd97f247fedfa551f01bf78cbb4b27e9635244 [file] [log] [blame]
//===- subzero/src/IceRNG.h - Random number generator -----------*- C++ -*-===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares a random number generator.
///
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICERNG_H
#define SUBZERO_SRC_ICERNG_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <cstdint>
namespace Ice {
class RandomNumberGenerator {
RandomNumberGenerator() = delete;
RandomNumberGenerator(const RandomNumberGenerator &) = delete;
RandomNumberGenerator &operator=(const RandomNumberGenerator &) = delete;
public:
explicit RandomNumberGenerator(uint64_t Seed, llvm::StringRef Salt = "");
uint64_t next(uint64_t Max);
private:
uint64_t State;
};
/// This class adds additional random number generator utilities. The
/// reason for the wrapper class is that we want to keep the
/// RandomNumberGenerator interface identical to LLVM's.
class RandomNumberGeneratorWrapper {
RandomNumberGeneratorWrapper() = delete;
RandomNumberGeneratorWrapper(const RandomNumberGeneratorWrapper &) = delete;
RandomNumberGeneratorWrapper &
operator=(const RandomNumberGeneratorWrapper &) = delete;
public:
uint64_t operator()(uint64_t Max) { return RNG.next(Max); }
bool getTrueWithProbability(float Probability);
explicit RandomNumberGeneratorWrapper(RandomNumberGenerator &RNG)
: RNG(RNG) {}
private:
RandomNumberGenerator &RNG;
};
/// RandomShuffle is an implementation of std::random_shuffle() that
/// doesn't change across stdlib implementations. Adapted from a
/// sample implementation at cppreference.com.
template <class RandomIt, class RandomFunc>
void RandomShuffle(RandomIt First, RandomIt Last, RandomFunc &&RNG) {
for (auto i = Last - First - 1; i > 0; --i)
std::swap(First[i], First[RNG(i + 1)]);
}
} // end of namespace Ice
#endif // SUBZERO_SRC_ICERNG_H