Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / randomize.h
blob25d47a543b684a8a43e28f4d21d9f787268e5e7d
1 // -*- C++ -*-
3 // ============================================================================
4 /**
5 * @file randomize.h
7 * Randomize the contents of an array.
9 * @author Ossama Othman
11 * @note Based on code originally found in test_config.h and Test_Output.cpp
13 // ============================================================================
15 #ifndef ACE_TESTS_RANDOMIZE_H
16 #define ACE_TESTS_RANDOMIZE_H
18 #include "ace/OS_NS_stdlib.h"
20 #include <algorithm>
21 #include <functional>
23 namespace
25 /**
26 * @class randomize_index
28 * @brief Functor that randomly swaps the order of two array
29 * elements.
31 * @internal Do not directly use this class. Use the @c randomize()
32 * function template found below instead.
34 * This functor generates random array index using high-order bits (e.g.,
35 * MAX_VAL * rand() / (RAND_MAX + 1.0)) rather than low-order ones
36 * (e.g. rand() % MAX_VAL) to improve randomness. The array element
37 * reference by that index is then swapped with the array element
38 * provided to the functor.
40 * @note The improved randomness may be overkill for this functor's
41 * intended use cases, but it is a good thing to practice/have
42 * nonetheless.
44 * @see Numerical Recipes in C: The Art of Scientific Computing
45 * (William H. Press, Brian P. Flannery, Saul A. Teukolsky,
46 * William T. Vetterling; New York: Cambridge University Press,
47 * 1992 (2nd ed., p. 277).
49 template<typename T>
50 class randomize_element
52 public:
53 typedef T &argument_type;
54 typedef void result_type;
56 randomize_element (T * array, size_t size, unsigned int seed)
57 : array_ (array)
58 , coefficient_ (static_cast<double> (size) / (RAND_MAX + 1.0f))
59 , seed_ (seed)
63 void
64 operator() (T & value) // We need this to be a reference!
66 size_t const index =
67 static_cast<size_t> (
68 this->coefficient_ * ACE_OS::rand_r (&this->seed_));
70 // Swap rather than assign so that we don't lose the original
71 // value.
72 std::swap (value, this->array_[index]);
75 private:
76 // The array.
77 T * const array_;
79 // Factor out the constant coefficient.
80 double const coefficient_;
82 // Random number generator seed value.
83 unsigned int seed_;
86 /**
87 * @fn randomize
89 * @brief Randomize the order of elements in an array.
91 * @param array The array whose elements will be reordered
92 * randomly.
93 * @param size The number of elements in the array.
94 * @param seed The random number generator seed value. A default
95 * value is provided so that the generated random
96 number order may be "repeatable" if so desired.
98 * This function template randomizes the order of elements in an
99 * array of any type. It is also reentrant (unless the array itself
100 * is accessed by multiple threads).
101 * @par
102 * Sample usage:
103 * @par
104 * \verbatim
105 static size_t const NUM_TIMES = 100;
106 ACE_Time_Value times[NUM_TIMES] = { ... };
107 randomize (times,
108 NUM_TIMES,
109 static_cast<unsigned int> (ACE_OS::time (0L)));
110 \endverbatim
112 template<typename T>
113 void
114 randomize (T * array, size_t size, unsigned int seed = 0)
116 // Randomize all elements of the array.
117 std::for_each (array,
118 array + size,
119 randomize_element<T> (array, size, seed));
123 #endif /* !ACE_TESTS_RANDOMIZE_H */