Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / tests / randomize.h
blobbdebd4db5e9659623e169f06bf1486263ef28440
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
51 : public std::unary_function<T &, void>
53 public:
55 randomize_element (T * array, size_t size, unsigned int seed)
56 : array_ (array)
57 , coefficient_ (static_cast<double> (size) / (RAND_MAX + 1.0f))
58 , seed_ (seed)
62 void
63 operator() (T & value) // We need this to be a reference!
65 size_t const index =
66 static_cast<size_t> (
67 this->coefficient_ * ACE_OS::rand_r (&this->seed_));
69 // Swap rather than assign so that we don't lose the original
70 // value.
71 std::swap (value, this->array_[index]);
74 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_;
87 /**
88 * @fn randomize
90 * @brief Randomize the order of elements in an array.
92 * @param array The array whose elements will be reordered
93 * randomly.
94 * @param size The number of elements in the array.
95 * @param seed The random number generator seed value. A default
96 * value is provided so that the generated random
97 number order may be "repeatable" if so desired.
99 * This function template randomizes the order of elements in an
100 * array of any type. It is also reentrant (unless the array itself
101 * is accessed by multiple threads).
102 * @par
103 * Sample usage:
104 * @par
105 * \verbatim
106 static size_t const NUM_TIMES = 100;
107 ACE_Time_Value times[NUM_TIMES] = { ... };
108 randomize (times,
109 NUM_TIMES,
110 static_cast<unsigned int> (ACE_OS::time (0L)));
111 \endverbatim
113 template<typename T>
114 void
115 randomize (T * array, size_t size, unsigned int seed = 0)
117 // Randomize all elements of the array.
118 std::for_each (array,
119 array + size,
120 randomize_element<T> (array, size, seed));
124 #endif /* !ACE_TESTS_RANDOMIZE_H */