6#include "hegel/config.h"
46 HEGEL_REQUIRES(std::is_integral_v<T>)
47 class IntegerGenerator :
public IGenerator<T> {
48 static_assert(std::is_integral_v<T>,
49 "integers<T> requires an integral type T");
53 : min_(params.min_value.value_or(std::numeric_limits<T>::min())),
54 max_(params.max_value.value_or(std::numeric_limits<T>::max())) {
56 throw std::invalid_argument(
57 "Cannot have max_value < min_value");
61 T do_draw(
const TestCase& tc)
const override {
62 if constexpr (std::is_signed_v<T>) {
63 return static_cast<T
>(hegel::internal::draw_integer(
64 tc,
static_cast<int64_t
>(min_),
65 static_cast<int64_t
>(max_)));
67 return static_cast<T
>(hegel::internal::draw_integer_unsigned(
68 tc,
static_cast<uint64_t
>(min_),
69 static_cast<uint64_t
>(max_)));
81 HEGEL_REQUIRES(std::is_floating_point_v<T>)
83 static_assert(std::is_floating_point_v<T>,
84 "floats<T> requires a floating-point type T");
87 explicit FloatGenerator(
const FloatsParams<T>& params = {}) {
88 bool has_min = params.min_value.has_value();
89 bool has_max = params.max_value.has_value();
90 allow_nan_ = params.allow_nan.value_or(!has_min && !has_max);
92 params.allow_infinity.value_or(!has_min || !has_max);
93 if (allow_nan_ && (has_min || has_max)) {
94 throw std::invalid_argument(
95 "Cannot have allow_nan=true with min_value or max_value");
97 if (has_min && has_max && *params.min_value > *params.max_value) {
98 throw std::invalid_argument(
99 "Cannot have max_value < min_value");
101 if (allow_infinity_ && has_min && has_max) {
102 throw std::invalid_argument(
103 "Cannot have allow_infinity=true with both min_value and "
109 min_ = has_min ?
static_cast<double>(*params.min_value)
111 ? -std::numeric_limits<double>::infinity()
112 : static_cast<double>(std::numeric_limits<T>::lowest());
113 max_ = has_max ?
static_cast<double>(*params.max_value)
115 ? std::numeric_limits<double>::infinity()
116 : static_cast<double>(std::numeric_limits<T>::max());
117 exclude_min_ = params.exclude_min;
118 exclude_max_ = params.exclude_max;
121 T do_draw(
const TestCase& tc)
const override {
122 constexpr uint32_t width =
sizeof(T) * 8;
123 return static_cast<T
>(hegel::internal::draw_float(
124 tc, width, min_, max_, allow_nan_, allow_infinity_,
125 exclude_min_, exclude_max_,
126 static_cast<double>(std::numeric_limits<T>::denorm_min())));
133 bool allow_infinity_;
157 template <
typename T =
int64_t>
158 HEGEL_REQUIRES(std::is_integral_v<T>)
160 return Generator<T>(
new IntegerGenerator<T>(std::move(params)));
179 template <
typename T =
double>
180 HEGEL_REQUIRES(std::is_floating_point_v<T>)
182 return Generator<T>(
new FloatGenerator<T>(std::move(params)));
The base class of all generators.
Definition core.h:67
Hegel generators.
Definition core.h:17
Generator< T > integers(IntegersParams< T > params={})
Generate random integers. For a given integral type T, produces values in the range [std::numeric_lim...
Definition numeric.h:159
Generator< T > floats(FloatsParams< T > params={})
Generate random floating point numbers.
Definition numeric.h:181
Parameters for floats() generator.
Definition numeric.h:30
bool exclude_min
If true, exclude min_value (exclusive bound).
Definition numeric.h:33
std::optional< T > min_value
Minimum value. Default: no minimum.
Definition numeric.h:31
std::optional< T > max_value
Maximum value. Default: no maximum.
Definition numeric.h:32
std::optional< bool > allow_nan
Allow NaN. Default: true if unbounded.
Definition numeric.h:38
bool exclude_max
If true, exclude max_value (exclusive bound).
Definition numeric.h:35
std::optional< bool > allow_infinity
Allow infinity. Default: true if unbounded.
Definition numeric.h:40
Base interface for generators.
Definition core.h:29
Parameters for integers() generator.
Definition numeric.h:19
std::optional< T > max_value
Maximum value (inclusive). Default: type maximum.
Definition numeric.h:23
std::optional< T > min_value
Minimum value (inclusive). Default: type minimum.
Definition numeric.h:21