1 /* concepts.hpp
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 #ifndef BOOST_RANDOM_TEST_CONCEPTS_HPP
13 #define BOOST_RANDOM_TEST_CONCEPTS_HPP
14
15 #include <boost/config.hpp>
16
17 #ifdef BOOST_MSVC
18 #pragma warning(push)
19 #pragma warning(disable:4100)
20 #endif
21
22 #include <boost/concept_check.hpp>
23
24 #ifdef BOOST_MSVC
25 #pragma warning(pop)
26 #endif
27
28 #include <boost/concept_archetype.hpp>
29 #include <boost/concept/requires.hpp>
30 #include <boost/mpl/assert.hpp>
31 #include <boost/type_traits/is_arithmetic.hpp>
32 #include <boost/type_traits/is_integral.hpp>
33 #include <boost/type_traits/is_same.hpp>
34 #include <boost/cstdint.hpp>
35 #include <boost/static_assert.hpp>
36 #include <istream>
37 #include <ostream>
38
39 #ifdef BOOST_MSVC
40 #pragma warning(push)
41 #pragma warning(disable:4510)
42 #pragma warning(disable:4610)
43 #endif
44
45 namespace boost {
46 namespace random {
47 namespace test {
48
49 template<class Base = null_archetype<> >
50 struct seed_seq_archetype : Base
51 {
52 template<class Iter>
53 BOOST_CONCEPT_REQUIRES(
54 ((Mutable_RandomAccessIterator<Iter>))
55 ((UnsignedInteger<typename Mutable_RandomAccessIterator<Iter>::value_type>)),
56 (void))
generateboost::random::test::seed_seq_archetype57 generate(Iter, Iter) {}
58 };
59
60 template<class R = unsigned, class Base = null_archetype<> >
61 struct uniform_random_number_generator_archetype : Base
62 {
63 typedef R result_type;
BOOST_PREVENT_MACRO_SUBSTITUTIONboost::random::test::uniform_random_number_generator_archetype64 static R min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
BOOST_PREVENT_MACRO_SUBSTITUTIONboost::random::test::uniform_random_number_generator_archetype65 static R max BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
operator ()boost::random::test::uniform_random_number_generator_archetype66 R operator()() { return 0; }
67 };
68
69 template<class SSeq>
70 struct SeedSeq
71 {
72 public:
BOOST_CONCEPT_USAGEboost::random::test::SeedSeq73 BOOST_CONCEPT_USAGE(SeedSeq)
74 {
75 q.generate(rb, re);
76 }
77 private:
78 SSeq q;
79 mutable_random_access_iterator_archetype<boost::uint32_t> rb, re;
80 };
81
82 template<class T>
83 struct Streamable
84 {
85 public:
BOOST_CONCEPT_USAGEboost::random::test::Streamable86 BOOST_CONCEPT_USAGE(Streamable)
87 {
88 os << x;
89 is >> v;
90 wos << x;
91 wis >> v;
92 }
93 private:
94 const T x;
95 T v;
96
97 std::istream is;
98 std::ostream os;
99 std::wistream wis;
100 std::wostream wos;
101 };
102
103 // Type deduction will fail unless the arguments have the same type.
104 template <typename T>
same_type(T const &,T const &)105 void same_type(T const&, T const&) {}
106
107 template <class E>
108 struct RandomNumberEngine :
109 DefaultConstructible<E>,
110 CopyConstructible<E>,
111 Assignable<E>,
112 EqualityComparable<E>,
113 Streamable<E>
114 {
115 public:
116 typedef typename E::result_type result_type;
117
118 // relaxed from the standard
119 BOOST_MPL_ASSERT((boost::is_arithmetic<result_type>));
120
121 // backwards compatibility check
122 BOOST_STATIC_ASSERT(!E::has_fixed_range);
123
124 // a generator can be used to seed another generator (extension)
125 BOOST_CONCEPT_ASSERT((SeedSeq<E>));
126
BOOST_CONCEPT_USAGEboost::random::test::RandomNumberEngine127 BOOST_CONCEPT_USAGE(RandomNumberEngine)
128 {
129 same_type(e(), result_type());
130 same_type((E::min)(), result_type());
131 same_type((E::max)(), result_type());
132
133 (void)E();
134 (void)E(s);
135 (void)E(q);
136
137 e.seed();
138 e.seed(s);
139 e.seed(q);
140
141 e.discard(z);
142
143 // extension
144 (void)E(sb, se);
145 e.seed(sb, se);
146 }
147
148 private:
149 E e;
150 E v;
151 const E x;
152 seed_seq_archetype<> q;
153 typename detail::seed_type<result_type>::type s;
154 uintmax_t z;
155
156 input_iterator_archetype<boost::uint32_t> sb, se;
157 };
158
159 template<class D>
160 struct RandomNumberDistribution :
161 DefaultConstructible<D>,
162 CopyConstructible<D>,
163 Assignable<D>,
164 EqualityComparable<D>,
165 Streamable<D>
166 {
167 public:
168 typedef typename D::result_type result_type;
169 typedef typename D::param_type param_type;
170 // backwards compatibility
171 typedef typename D::input_type input_type;
172
173 typedef param_type P;
174
175 BOOST_CONCEPT_ASSERT((DefaultConstructible<P>));
176 BOOST_CONCEPT_ASSERT((CopyConstructible<P>));
177 BOOST_CONCEPT_ASSERT((Assignable<P>));
178 BOOST_CONCEPT_ASSERT((EqualityComparable<P>));
179 BOOST_CONCEPT_ASSERT((Streamable<P>));
180
181 BOOST_MPL_ASSERT((boost::is_same<typename P::distribution_type, D>));
182
BOOST_CONCEPT_USAGEboost::random::test::RandomNumberDistribution183 BOOST_CONCEPT_USAGE(RandomNumberDistribution)
184 {
185 (void)D(p);
186 d.reset();
187 same_type(x.param(), p);
188 d.param(p);
189 same_type(d(g), result_type());
190 same_type(d(g, p), result_type());
191 same_type((x.min)(), result_type());
192 same_type((x.max)(), result_type());
193 }
194
195 private:
196 D d;
197 const D x;
198 const P p;
199 uniform_random_number_generator_archetype<> g;
200 };
201
202 }
203 }
204 }
205
206 #ifdef BOOST_MSVC
207 #pragma warning(pop)
208 #endif
209
210 #endif
211