concepts.hpp 4.5 KB

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