brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 436cd05 Raw
87 lines · plain
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the definition of the RandomGenerator class, a concrete11/// range-based generator that randomly creates inputs from a given sequence of12/// ranges.13///14//===----------------------------------------------------------------------===//15 16#ifndef MATHTEST_RANDOMGENERATOR_HPP17#define MATHTEST_RANDOMGENERATOR_HPP18 19#include "mathtest/IndexedRange.hpp"20#include "mathtest/RandomState.hpp"21#include "mathtest/RangeBasedGenerator.hpp"22 23#include <cstddef>24#include <cstdint>25#include <tuple>26 27namespace mathtest {28 29template <typename... InTypes>30class [[nodiscard]] RandomGenerator final31    : public RangeBasedGenerator<RandomGenerator<InTypes...>, InTypes...> {32 33  friend class RangeBasedGenerator<RandomGenerator<InTypes...>, InTypes...>;34 35  using Base = RangeBasedGenerator<RandomGenerator<InTypes...>, InTypes...>;36 37  using Base::RangesTuple;38  using Base::Size;39 40public:41  explicit constexpr RandomGenerator(42      SeedTy BaseSeed, uint64_t Size,43      const IndexedRange<InTypes> &...Ranges) noexcept44      : Base(Size, Ranges...), BaseSeed(BaseSeed) {}45 46private:47  [[nodiscard]] static uint64_t getRandomIndex(RandomState &RNG,48                                               uint64_t RangeSize) noexcept {49    if (RangeSize == 0)50      return 0;51 52    const uint64_t Threshold = (-RangeSize) % RangeSize;53 54    uint64_t RandomNumber;55    do {56      RandomNumber = RNG.next();57    } while (RandomNumber < Threshold);58 59    return RandomNumber % RangeSize;60  }61 62  template <typename BufferPtrsTupleType>63  void writeInputs(uint64_t CurrentFlatIndex, uint64_t Offset,64                   BufferPtrsTupleType BufferPtrsTuple) const noexcept {65 66    RandomState RNG(SeedTy{BaseSeed.Value ^ (CurrentFlatIndex + Offset)});67    writeInputsImpl<0>(RNG, Offset, BufferPtrsTuple);68  }69 70  template <std::size_t Index, typename BufferPtrsTupleType>71  void writeInputsImpl(RandomState &RNG, uint64_t Offset,72                       BufferPtrsTupleType BufferPtrsTuple) const noexcept {73    if constexpr (Index < Base::NumInputs) {74      const auto &Range = std::get<Index>(RangesTuple);75      const auto RandomIndex = getRandomIndex(RNG, Range.getSize());76      std::get<Index>(BufferPtrsTuple)[Offset] = Range[RandomIndex];77 78      writeInputsImpl<Index + 1>(RNG, Offset, BufferPtrsTuple);79    }80  }81 82  SeedTy BaseSeed;83};84} // namespace mathtest85 86#endif // MATHTEST_RANDOMGENERATOR_HPP87