1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_fuzzing_FuzzingTraits_h
8 #define mozilla_fuzzing_FuzzingTraits_h
10 #include "mozilla/Assertions.h"
13 #include <type_traits>
20 static unsigned int Random(unsigned int aMax
);
21 static bool Sometimes(unsigned int aProbability
);
23 * Frequency() defines how many mutations of a kind shall be applied to a
24 * target buffer by using a user definable factor. The higher the factor,
25 * the less mutations are being made.
27 static size_t Frequency(const size_t aSize
, const uint64_t aFactor
);
29 static std::mt19937_64
& Rng();
33 * RandomNumericLimit returns either the min or max limit of an arithmetic
37 T
RandomNumericLimit() {
38 static_assert(std::is_arithmetic_v
<T
> == true,
39 "T must be an arithmetic type");
40 return FuzzingTraits::Sometimes(2) ? std::numeric_limits
<T
>::min()
41 : std::numeric_limits
<T
>::max();
45 * RandomInteger generates negative and positive integers in 2**n increments.
49 static_assert(std::is_integral_v
<T
> == true, "T must be an integral type");
51 static_cast<double>(FuzzingTraits::Random((sizeof(T
) * CHAR_BIT
) + 1));
52 T x
= static_cast<T
>(pow(2.0, r
)) - 1;
53 if (std::numeric_limits
<T
>::is_signed
&& FuzzingTraits::Sometimes(2)) {
60 * RandomIntegerRange returns a random integral within a [min, max] range.
63 T
RandomIntegerRange(T min
, T max
) {
64 static_assert(std::is_integral_v
<T
> == true, "T must be an integral type");
65 MOZ_ASSERT(min
< max
);
66 std::uniform_int_distribution
<T
> d(min
, max
);
67 return d(FuzzingTraits::Rng());
70 * uniform_int_distribution is undefined for char/uchar. Need to handle them
74 inline unsigned char RandomIntegerRange(unsigned char min
, unsigned char max
) {
75 MOZ_ASSERT(min
< max
);
76 std::uniform_int_distribution
<unsigned short> d(min
, max
);
77 return static_cast<unsigned char>(d(FuzzingTraits::Rng()));
80 inline char RandomIntegerRange(char min
, char max
) {
81 MOZ_ASSERT(min
< max
);
82 std::uniform_int_distribution
<short> d(min
, max
);
83 return static_cast<char>(d(FuzzingTraits::Rng()));
87 * RandomFloatingPointRange returns a random floating-point number within a
91 T
RandomFloatingPointRange(T min
, T max
) {
92 static_assert(std::is_floating_point_v
<T
> == true,
93 "T must be a floating point type");
94 MOZ_ASSERT(min
< max
);
95 std::uniform_real_distribution
<T
> d(
96 min
, std::nextafter(max
, std::numeric_limits
<T
>::max()));
97 return d(FuzzingTraits::Rng());
101 * RandomFloatingPoint returns a random floating-point number in 2**n
104 template <typename T
>
105 T
RandomFloatingPoint() {
106 static_assert(std::is_floating_point_v
<T
> == true,
107 "T must be a floating point type");
108 int radix
= RandomIntegerRange
<int>(std::numeric_limits
<T
>::min_exponent
,
109 std::numeric_limits
<T
>::max_exponent
);
110 T x
= static_cast<T
>(pow(2.0, static_cast<double>(radix
)));
111 return x
* RandomFloatingPointRange
<T
>(-1.0, 1.0);
114 } // namespace fuzzing
115 } // namespace mozilla