1 | |
2 | // Copyright 2005-2009 Daniel James. |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5 | |
6 | // This uses std::rand to generate random values for tests. |
7 | // Which is not good as different platforms will be running different tests. |
8 | // It would be much better to use Boost.Random, but it doesn't |
9 | // support all the compilers that I want to test on. |
10 | |
11 | #if !defined(BOOST_UNORDERED_TEST_HELPERS_GENERATORS_HEADER) |
12 | #define |
13 | |
14 | #include "./fwd.hpp" |
15 | #include <boost/assert.hpp> |
16 | #include <boost/type_traits/add_const.hpp> |
17 | #include <climits> |
18 | #include <cstdlib> |
19 | #include <stdexcept> |
20 | #include <string> |
21 | #include <utility> |
22 | |
23 | namespace test { |
24 | struct seed_t |
25 | { |
26 | seed_t(unsigned int x) |
27 | { |
28 | using namespace std; |
29 | srand(seed: x); |
30 | } |
31 | }; |
32 | |
33 | std::size_t random_value(std::size_t max) |
34 | { |
35 | using namespace std; |
36 | return static_cast<std::size_t>(rand()) % max; |
37 | } |
38 | |
39 | static int origin = 0; |
40 | |
41 | void reset_sequence() { origin = 0; } |
42 | |
43 | inline int generate(int const*, random_generator g) |
44 | { |
45 | if (g == sequential) { |
46 | BOOST_ASSERT_MSG( |
47 | origin < INT_MAX, "test::reset_sequence() should be invoked" ); |
48 | return origin++; |
49 | } |
50 | |
51 | using namespace std; |
52 | int value = rand(); |
53 | if (g == limited_range) { |
54 | value = value % 100; |
55 | } |
56 | return value; |
57 | } |
58 | |
59 | inline char generate(char const*, random_generator) |
60 | { |
61 | using namespace std; |
62 | return static_cast<char>((rand() >> 1) % (128 - 32) + 32); |
63 | } |
64 | |
65 | inline signed char generate(signed char const*, random_generator) |
66 | { |
67 | using namespace std; |
68 | return static_cast<signed char>(rand()); |
69 | } |
70 | |
71 | inline std::string generate(std::string const*, random_generator g) |
72 | { |
73 | using namespace std; |
74 | |
75 | char* char_ptr = 0; |
76 | |
77 | std::string result; |
78 | |
79 | if (g == limited_range) { |
80 | std::size_t length = test::random_value(max: 2) + 2; |
81 | |
82 | char const* strings[] = {"'vZh(3~ms" , "%m" , "_Y%U" , "N'Y" , "4,J_J" }; |
83 | for (std::size_t i = 0; i < length; ++i) { |
84 | result += strings[random_value(max: sizeof(strings) / sizeof(strings[0]))]; |
85 | } |
86 | } else { |
87 | std::size_t length = test::random_value(max: 10) + 1; |
88 | for (std::size_t i = 0; i < length; ++i) { |
89 | result += generate(char_ptr, g); |
90 | } |
91 | } |
92 | |
93 | return result; |
94 | } |
95 | |
96 | float generate(float const*, random_generator g) |
97 | { |
98 | using namespace std; |
99 | int x = 0; |
100 | int value = generate(&x, g); |
101 | return (float)value / (float)RAND_MAX; |
102 | } |
103 | } |
104 | |
105 | #endif |
106 | |