• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* test_generator.ipp
2 *
3 * Copyright Steven Watanabe 2011
4 * Distributed under the Boost Software License, Version 1.0. (See
5 * accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
7 *
8 * $Id$
9 *
10 */
11
12#include "concepts.hpp"
13#include <boost/random/seed_seq.hpp>
14
15#define BOOST_TEST_MAIN
16#include <boost/test/unit_test.hpp>
17
18using boost::random::test::RandomNumberEngine;
19BOOST_CONCEPT_ASSERT((RandomNumberEngine< BOOST_RANDOM_URNG >));
20
21typedef BOOST_RANDOM_URNG::result_type result_type;
22typedef boost::random::detail::seed_type<result_type>::type seed_type;
23
24#ifdef BOOST_MSVC
25#pragma warning(push)
26#pragma warning(disable:4244)
27#endif
28
29#ifndef BOOST_RANDOM_DISCARD_COUNT1
30#define BOOST_RANDOM_DISCARD_COUNT1 9307
31#endif
32
33template<class Converted, class URNG, class T>
34void test_seed_conversion(URNG & urng, const T & t)
35{
36    Converted c = static_cast<Converted>(t);
37    if(static_cast<T>(c) == t) {
38        URNG urng2(c);
39        std::ostringstream msg;
40        msg << "Testing seed: type " << typeid(Converted).name() << ", value " << c;
41        BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
42        urng2.seed(c);
43        BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
44    }
45}
46
47#ifdef BOOST_MSVC
48#pragma warning(pop)
49#endif
50
51void test_seed(seed_type value)
52{
53    BOOST_RANDOM_URNG urng(value);
54
55    // integral types
56    test_seed_conversion<char>(urng, value);
57    test_seed_conversion<signed char>(urng, value);
58    test_seed_conversion<unsigned char>(urng, value);
59    test_seed_conversion<short>(urng, value);
60    test_seed_conversion<unsigned short>(urng, value);
61    test_seed_conversion<int>(urng, value);
62    test_seed_conversion<unsigned int>(urng, value);
63    test_seed_conversion<long>(urng, value);
64    test_seed_conversion<unsigned long>(urng, value);
65#if !defined(BOOST_NO_INT64_T)
66    test_seed_conversion<boost::int64_t>(urng, value);
67    test_seed_conversion<boost::uint64_t>(urng, value);
68#endif
69
70    // floating point types
71    test_seed_conversion<float>(urng, value);
72    test_seed_conversion<double>(urng, value);
73    test_seed_conversion<long double>(urng, value);
74}
75
76BOOST_AUTO_TEST_CASE(test_default_seed)
77{
78    BOOST_RANDOM_URNG urng;
79    BOOST_RANDOM_URNG urng2;
80    urng2();
81    BOOST_CHECK_NE(urng, urng2);
82    urng2.seed();
83    BOOST_CHECK_EQUAL(urng, urng2);
84}
85
86BOOST_AUTO_TEST_CASE(test_arithmetic_seed)
87{
88    test_seed(static_cast<seed_type>(0));
89    test_seed(static_cast<seed_type>(127));
90    test_seed(static_cast<seed_type>(539157235));
91    test_seed(static_cast<seed_type>(~0u));
92}
93
94BOOST_AUTO_TEST_CASE(test_iterator_seed)
95{
96    const std::vector<int> v((std::max)(std::size_t(9999u), sizeof(BOOST_RANDOM_URNG) / 4), 0x41);
97    std::vector<int>::const_iterator it = v.begin();
98    std::vector<int>::const_iterator it_end = v.end();
99    BOOST_RANDOM_URNG urng(it, it_end);
100    BOOST_CHECK(it != v.begin());
101    std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words = (it - v.begin());
102    BOOST_CHECK_GT(n_words, 0);
103    BOOST_CHECK_EQUAL(n_words, BOOST_RANDOM_SEED_WORDS);
104
105    it = v.begin();
106    BOOST_RANDOM_URNG urng2;
107    urng2.seed(it, it_end);
108    std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words2 = (it - v.begin());
109    BOOST_CHECK_EQUAL(n_words, n_words2);
110    BOOST_CHECK_EQUAL(urng, urng2);
111
112    it = v.end();
113    BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
114    BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
115
116    if(n_words > 1) {
117        it = v.end();
118        --it;
119        BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
120        it = v.end();
121        --it;
122        BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
123    }
124}
125
126BOOST_AUTO_TEST_CASE(test_seed_seq_seed)
127{
128    boost::random::seed_seq q;
129    BOOST_RANDOM_URNG urng(q);
130    BOOST_RANDOM_URNG urng2;
131    BOOST_CHECK_NE(urng, urng2);
132    urng2.seed(q);
133    BOOST_CHECK_EQUAL(urng, urng2);
134}
135
136template<class CharT>
137void do_test_streaming(const BOOST_RANDOM_URNG& urng)
138{
139    BOOST_RANDOM_URNG urng2;
140    std::basic_ostringstream<CharT> output;
141    output << urng;
142    BOOST_CHECK_NE(urng, urng2);
143    // restore old state
144    std::basic_istringstream<CharT> input(output.str());
145    input >> urng2;
146    BOOST_CHECK_EQUAL(urng, urng2);
147}
148
149BOOST_AUTO_TEST_CASE(test_streaming)
150{
151    BOOST_RANDOM_URNG urng;
152    urng.discard(9307);
153    do_test_streaming<char>(urng);
154#if !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_STD_WSTRING)
155    do_test_streaming<wchar_t>(urng);
156#endif
157}
158
159BOOST_AUTO_TEST_CASE(test_discard)
160{
161    BOOST_RANDOM_URNG urng;
162    BOOST_RANDOM_URNG urng2;
163    BOOST_CHECK_EQUAL(urng, urng2);
164    for(int i = 0; i < BOOST_RANDOM_DISCARD_COUNT1; ++i)
165        urng();
166    BOOST_CHECK_NE(urng, urng2);
167    urng2.discard(BOOST_RANDOM_DISCARD_COUNT1);
168    BOOST_CHECK_EQUAL(urng, urng2);
169}
170
171#ifdef BOOST_RANDOM_DISCARD_COUNT2
172BOOST_AUTO_TEST_CASE(test_discard2)
173{
174    BOOST_RANDOM_URNG urng;
175    BOOST_RANDOM_URNG urng2;
176    BOOST_CHECK_EQUAL(urng, urng2);
177    for(int i = 0; i < BOOST_RANDOM_DISCARD_COUNT2; ++i)
178        urng();
179    BOOST_CHECK_NE(urng, urng2);
180    urng2.discard(BOOST_RANDOM_DISCARD_COUNT2);
181    BOOST_CHECK_EQUAL(urng, urng2);
182}
183#endif
184
185#ifdef BOOST_RANDOM_DISCARD_MAX
186BOOST_AUTO_TEST_CASE(test_discard_max)
187{
188    boost::uintmax_t val = (std::numeric_limits<boost::uintmax_t>::max)();
189    boost::uintmax_t half = val / 2;
190    BOOST_RANDOM_URNG urng;
191    BOOST_RANDOM_URNG urng2;
192    urng.discard(half);
193    urng.discard(half);
194    urng.discard(val - 2*half);
195    urng2.discard(val);
196    BOOST_CHECK_EQUAL(urng, urng2);
197}
198#endif
199
200BOOST_AUTO_TEST_CASE(test_copy)
201{
202    BOOST_RANDOM_URNG urng;
203    urng.discard(9307);
204    {
205        BOOST_RANDOM_URNG urng2 = urng;
206        BOOST_CHECK_EQUAL(urng, urng2);
207    }
208    {
209        BOOST_RANDOM_URNG urng2(urng);
210        BOOST_CHECK_EQUAL(urng, urng2);
211    }
212    {
213        BOOST_RANDOM_URNG urng2;
214        urng2 = urng;
215        BOOST_CHECK_EQUAL(urng, urng2);
216    }
217}
218
219BOOST_AUTO_TEST_CASE(test_min_max)
220{
221    BOOST_RANDOM_URNG urng;
222    for(int i = 0; i < 10000; ++i) {
223        result_type value = urng();
224        BOOST_CHECK_GE(value, (BOOST_RANDOM_URNG::min)());
225        BOOST_CHECK_LE(value, (BOOST_RANDOM_URNG::max)());
226    }
227}
228
229BOOST_AUTO_TEST_CASE(test_comparison)
230{
231    BOOST_RANDOM_URNG urng;
232    BOOST_RANDOM_URNG urng2;
233    BOOST_CHECK(urng == urng2);
234    BOOST_CHECK(!(urng != urng2));
235    urng();
236    BOOST_CHECK(urng != urng2);
237    BOOST_CHECK(!(urng == urng2));
238}
239
240BOOST_AUTO_TEST_CASE(validate)
241{
242    BOOST_RANDOM_URNG urng;
243    for(int i = 0; i < 9999; ++i) {
244        urng();
245    }
246    BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_VALIDATION_VALUE);
247}
248
249BOOST_AUTO_TEST_CASE(validate_seed_seq)
250{
251    boost::random::seed_seq seed;
252    BOOST_RANDOM_URNG urng(seed);
253    for(int i = 0; i < 9999; ++i) {
254        urng();
255    }
256    BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE);
257}
258
259BOOST_AUTO_TEST_CASE(validate_iter)
260{
261    const std::vector<int> v((std::max)(std::size_t(9999u), sizeof(BOOST_RANDOM_URNG) / 4), 0x41);
262    std::vector<int>::const_iterator it = v.begin();
263    std::vector<int>::const_iterator it_end = v.end();
264    BOOST_RANDOM_URNG urng(it, it_end);
265    for(int i = 0; i < 9999; ++i) {
266        urng();
267    }
268    BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_ITERATOR_VALIDATION_VALUE);
269}
270
271BOOST_AUTO_TEST_CASE(test_generate)
272{
273    BOOST_RANDOM_URNG urng;
274    boost::uint32_t expected[] = BOOST_RANDOM_GENERATE_VALUES;
275    static const std::size_t N = sizeof(expected)/sizeof(expected[0]);
276    boost::uint32_t actual[N];
277    urng.generate(&actual[0], &actual[0] + N);
278    BOOST_CHECK_EQUAL_COLLECTIONS(actual, actual + N, expected, expected + N);
279}
280