Ocean
RandomI.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_BASE_RANDOM_I_H
9 #define META_OCEAN_BASE_RANDOM_I_H
10 
11 #include "ocean/base/Base.h"
13 
14 #include <limits>
15 
16 namespace Ocean
17 {
18 
19 /**
20  * This class provides base random functions and several random functions for integer data types.
21  * Beware: All function must not be used without a initialize() call for each thread!<br>
22  * The performance of the random number generator may be very poor in multi-threaded environments.<br>
23  * Therefore, use an instance of the RandomGenerator class in functions which are invoked in parallel.<br>
24  * @see initialize().
25  * @see RandomGenerator.
26  * @ingroup base
27  */
28 class OCEAN_BASE_EXPORT RandomI
29 {
30  protected:
31 
32  // Forward declaration.
33  class ThreadDatabase;
34 
35  public:
36 
37  /**
38  * Initializes the standard random generator for this thread with a time-based seed value.
39  * Please ensure that you have called RandomI::initialize() just once (for each individual thread) before using any other function of this class.<br>
40  * You also my use a user-defined seed value e.g., to be able to reproduce the behavior of a system using random numbers, just use the second initialize function in this case.
41  */
42  static void initialize();
43 
44  /**
45  * Initializes the standard random generator for this thread with a user-defined seed value.
46  * In contrast to the time-based initialization function, this function here can be invoked as often as necessary for any thread at any time.
47  * @param value Initialization value to be used, with range [0, infinity)
48  */
49  static void initialize(const unsigned int value);
50 
51  /**
52  * Returns one random integer number with range [0x00000000, 0xFFFFFFFF].
53  * Use this function only if the standard random() functions with range parameters are not large enough.<br>
54  * @return Random integer number, with range [0, infinity)
55  */
56  static uint32_t random32();
57 
58  /**
59  * Returns one random integer number with range [0x00000000, 0xFFFFFFFF] using an explicit random generator.
60  * Use this function only if the standard random() functions with range parameters are not large enough.<br>
61  * @param randomGenerator The random generator to be used
62  * @return Random integer number, with range [0, infinity)
63  */
64  static uint32_t random32(RandomGenerator& randomGenerator);
65 
66  /**
67  * Returns one random integer number with range [0x00000000 00000000, 0xFFFFFFFF FFFFFFFF].
68  * Use this function only if the standard random() functions with range parameters are not large enough.<br>
69  * @return Random integer number, with range [0, infinity)
70  */
71  static uint64_t random64();
72 
73  /**
74  * Returns one random integer number with range [0x00000000 00000000, 0xFFFFFFFF FFFFFFFF] using an explicit random generator.
75  * Use this function only if the standard random() functions with range parameters are not large enough.<br>
76  * @return Random integer number, with range [0, infinity)
77  */
78  static uint64_t random64(RandomGenerator& randomGenerator);
79 
80  /**
81  * Returns one random integer value with specified maximum value.
82  * @param maxValue Maximum value, with range [0, infinity)
83  * @return Random integer number, with range [0, maxValue]
84  */
85  static unsigned int random(const unsigned int maxValue);
86 
87  /**
88  * Returns one random integer value with specified maximum value using an explicit random generator.
89  * @param randomGenerator The random generator to be used
90  * @param maxValue Maximum value, with range [0, infinity)
91  * @return Random integer number, with range [0, maxValue]
92  */
93  static inline unsigned int random(RandomGenerator& randomGenerator, const unsigned int maxValue);
94 
95  /**
96  * Returns one random integer value within a specific range.
97  * @param lower The lower border, with range (-infinity, infinity)
98  * @param upper The upper border, with range [lower, infinity)
99  * @return Random integer number, with range [lower, lower + 2147483647]
100  */
101  static int random(const int lower, const int upper);
102 
103  /**
104  * Returns one random integer value within a specific range.
105  * @param lower The lower border, with range [0, infinity)
106  * @param upper The upper border, with range [lower, infinity)
107  * @return Random integer number, with range [lower, upper]
108  */
109  static unsigned int random(const unsigned int lower, const unsigned int upper);
110 
111  /**
112  * Returns one random integer value within a specific range using an explicit random generator.
113  * @param randomGenerator The random generator to be used
114  * @param lower The lower border, with range (-infinity, infinity)
115  * @param upper The upper border, with range [lower, lower + 2147483647]
116  * @return Random integer number, with range [lower, upper]
117  */
118  static inline int random(RandomGenerator& randomGenerator, const int lower, const int upper);
119 
120  /**
121  * Returns one random integer value within a specific range using an explicit random generator.
122  * @param randomGenerator The random generator to be used
123  * @param lower The lower border, with range [0, infinity)
124  * @param upper The upper border, with range [lower, infinity)
125  * @return Random integer number, with range [lower, upper]
126  */
127  static inline unsigned int random(RandomGenerator& randomGenerator, const unsigned int lower, const unsigned int upper);
128 
129  /**
130  * Returns two different random integer values with specified maximum value.
131  * @param maxValue Maximum value, must be large enough to ensure two different random numbers, with range [1, infinity)
132  * @param first Resulting first unique random number, with range [0, maxValue]
133  * @param second Resulting second unique random number, with range [0, maxValue]
134  */
135  static void random(const unsigned int maxValue, unsigned int& first, unsigned int& second);
136 
137  /**
138  * Returns two different random integer values with specified maximum value using an explicit random generator.
139  * @param randomGenerator The random generator to be used
140  * @param maxValue Maximum value, must be large enough to ensure three different random numbers, with range [1, infinity)
141  * @param first Resulting first unique random number, with range [0, maxValue]
142  * @param second Resulting second unique random number, with range [0, maxValue]
143  */
144  static void random(RandomGenerator& randomGenerator, const unsigned int maxValue, unsigned int& first, unsigned int& second);
145 
146  /**
147  * Returns three different random integer values with specified maximum value.
148  * @param maxValue Maximum value, must be large enough to ensure three different random numbers, with range [2, infinity)
149  * @param first Resulting first unique random number, with range [0, maxValue]
150  * @param second Resulting second unique random number, with range [0, maxValue]
151  * @param third Resulting third unique random number, with range [0, maxValue]
152  */
153  static void random(const unsigned int maxValue, unsigned int& first, unsigned int& second, unsigned int& third);
154 
155  /**
156  * Returns three different random integer values with specified maximum value using an explicit random generator.
157  * @param randomGenerator The random generator to be used
158  * @param maxValue Maximum value, must be large enough to ensure three different random numbers, with range [2, infinity)
159  * @param first Resulting first unique random number, with range [0, maxValue]
160  * @param second Resulting second unique random number, with range [0, maxValue]
161  * @param third Resulting third unique random number, with range [0, maxValue]
162  */
163  static void random(RandomGenerator& randomGenerator, const unsigned int maxValue, unsigned int& first, unsigned int& second, unsigned int& third);
164 
165  /**
166  * Returns a random bool value.
167  * @return True or False
168  */
169  static inline bool boolean();
170 
171  /**
172  * Returns a random bool value.
173  * @param randomGenerator The random generator to be used
174  * @return True or False
175  */
176  static inline bool boolean(RandomGenerator& randomGenerator);
177 
178  /**
179  * Randomly returns one element from a given vector.
180  * @param elements The elements from which one elements will be chosen randomly, must contain at least one element
181  * @return The randomly selected element
182  * @tparam T The data type of the element
183  */
184  template <typename T>
185  static T random(const std::vector<T>& elements);
186 
187  /**
188  * Randomly returns one element from a given initializer list.
189  * @param elements The elements from which one elements will be chosen randomly, must contain at least one element
190  * @return The randomly selected element
191  * @tparam T The data type of the element
192  */
193  template <typename T>
194  static T random(const std::initializer_list<T>& elements);
195 
196  /**
197  * Randomly returns one element from a given vector.
198  * @param randomGenerator The random generator to be used
199  * @param elements The elements from which one elements will be chosen randomly, must contain at least one element
200  * @return The randomly selected element
201  * @tparam T The data type of the element
202  */
203  template <typename T>
204  static T random(RandomGenerator& randomGenerator, const std::vector<T>& elements);
205 
206  /**
207  * Randomly returns one element from a given initializer list.
208  * @param randomGenerator The random generator to be used
209  * @param elements The elements from which one elements will be chosen randomly, must contain at least one element
210  * @return The randomly selected element
211  * @tparam T The data type of the element
212  */
213  template <typename T>
214  static T random(RandomGenerator& randomGenerator, const std::initializer_list<T>& elements);
215 
216  /**
217  * Returns a seed value based on the current time.
218  * @return Time-based seed value
219  */
220  static unsigned int timeBasedSeed();
221 
222  protected:
223 
224  /**
225  * Returns the maximal random value of the default random number generator.
226  * @return Maximal random value of the default generator
227  */
228  static constexpr unsigned int randMax();
229 };
230 
231 inline unsigned int RandomI::random(RandomGenerator& randomGenerator, const unsigned int maxValue)
232 {
233  if (maxValue == (unsigned int)(-1))
234  {
235  return random32(randomGenerator);
236  }
237 
238  if (maxValue > randomGenerator.randMax())
239  {
240  return random32(randomGenerator) % (maxValue + 1u);
241  }
242  else
243  {
244  return randomGenerator.rand() % (maxValue + 1u);
245  }
246 }
247 
248 inline int RandomI::random(RandomGenerator& randomGenerator, const int lower, const int upper)
249 {
250  ocean_assert(lower <= upper);
251  ocean_assert(int64_t(upper) - int64_t(lower) <= int64_t(std::numeric_limits<int>::max()));
252 
253  const unsigned int range = (unsigned int)(upper - lower);
254 
255  if (range > randomGenerator.randMax())
256  {
257  return lower + int(random32(randomGenerator) % (range + 1u));
258  }
259  else
260  {
261  return lower + int(randomGenerator.rand() % (range + 1u));
262  }
263 }
264 
265 inline unsigned int RandomI::random(RandomGenerator& randomGenerator, const unsigned int lower, const unsigned int upper)
266 {
267  ocean_assert(lower <= upper);
268 
269  const unsigned int range = upper - lower;
270 
271  if (range == (unsigned int)(-1))
272  {
273  ocean_assert(lower == 0u);
274  ocean_assert(upper == (unsigned int)(-1));
275 
276  return random32(randomGenerator);
277  }
278 
279  if (range > randomGenerator.randMax())
280  {
281  return lower + random32(randomGenerator) % (range + 1u);
282  }
283  else
284  {
285  return lower + randomGenerator.rand() % (range + 1u);
286  }
287 }
288 
289 inline bool RandomI::boolean()
290 {
291  return random(1u) == 0u;
292 }
293 
294 inline bool RandomI::boolean(RandomGenerator& randomGenerator)
295 {
296  return random(randomGenerator, 1u) == 0u;
297 }
298 
299 template <typename T>
300 T RandomI::random(const std::vector<T>& elements)
301 {
302  ocean_assert(!elements.empty());
303 
304  const unsigned int index = RandomI::random((unsigned int)(elements.size()) - 1u);
305 
306  return elements[index];
307 }
308 
309 template <typename T>
310 T RandomI::random(const std::initializer_list<T>& elements)
311 {
312  ocean_assert(elements.size() != 0);
313 
314  const unsigned int index = RandomI::random((unsigned int)(elements.size()) - 1u);
315 
316  return elements.begin()[index];
317 }
318 
319 template <typename T>
320 T RandomI::random(RandomGenerator& randomGenerator, const std::vector<T>& elements)
321 {
322  ocean_assert(!elements.empty());
323 
324  const unsigned int index = RandomI::random(randomGenerator, (unsigned int)(elements.size()) - 1u);
325 
326  return elements[index];
327 }
328 
329 template <typename T>
330 T RandomI::random(RandomGenerator& randomGenerator, const std::initializer_list<T>& elements)
331 {
332  ocean_assert(elements.size() != 0);
333 
334  const unsigned int index = RandomI::random(randomGenerator, (unsigned int)(elements.size()) - 1u);
335 
336  return elements.begin()[index];
337 }
338 
339 constexpr unsigned int RandomI::randMax()
340 {
341  return RAND_MAX;
342 }
343 
344 }
345 
346 #endif // META_OCEAN_BASE_RANDOM_I_H
This class implements a generator for random numbers.
Definition: RandomGenerator.h:42
unsigned int rand()
Returns the next random number.
Definition: RandomGenerator.h:161
static constexpr unsigned int randMax()
Returns the maximal random value of this generator.
Definition: RandomGenerator.h:183
This class provides base random functions and several random functions for integer data types.
Definition: RandomI.h:29
static int random(const int lower, const int upper)
Returns one random integer value within a specific range.
static void random(const unsigned int maxValue, unsigned int &first, unsigned int &second)
Returns two different random integer values with specified maximum value.
static constexpr unsigned int randMax()
Returns the maximal random value of the default random number generator.
Definition: RandomI.h:339
static unsigned int timeBasedSeed()
Returns a seed value based on the current time.
static uint64_t random64(RandomGenerator &randomGenerator)
Returns one random integer number with range [0x00000000 00000000, 0xFFFFFFFF FFFFFFFF] using an expl...
static uint32_t random32(RandomGenerator &randomGenerator)
Returns one random integer number with range [0x00000000, 0xFFFFFFFF] using an explicit random genera...
static uint32_t random32()
Returns one random integer number with range [0x00000000, 0xFFFFFFFF].
static void initialize()
Initializes the standard random generator for this thread with a time-based seed value.
static void random(RandomGenerator &randomGenerator, const unsigned int maxValue, unsigned int &first, unsigned int &second, unsigned int &third)
Returns three different random integer values with specified maximum value using an explicit random g...
static uint64_t random64()
Returns one random integer number with range [0x00000000 00000000, 0xFFFFFFFF FFFFFFFF].
static void initialize(const unsigned int value)
Initializes the standard random generator for this thread with a user-defined seed value.
static unsigned int random(const unsigned int lower, const unsigned int upper)
Returns one random integer value within a specific range.
static unsigned int random(const unsigned int maxValue)
Returns one random integer value with specified maximum value.
static void random(RandomGenerator &randomGenerator, const unsigned int maxValue, unsigned int &first, unsigned int &second)
Returns two different random integer values with specified maximum value using an explicit random gen...
static void random(const unsigned int maxValue, unsigned int &first, unsigned int &second, unsigned int &third)
Returns three different random integer values with specified maximum value.
static bool boolean()
Returns a random bool value.
Definition: RandomI.h:289
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15