]> git.donarmstrong.com Git - rsem.git/blob - boost/random/xor_combine.hpp
RSEM Source Codes
[rsem.git] / boost / random / xor_combine.hpp
1 /* boost random/xor_combine.hpp header file
2  *
3  * Copyright Jens Maurer 2002
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  * See http://www.boost.org for most recent version including documentation.
9  *
10  * $Id: xor_combine.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $
11  *
12  */
13
14 #ifndef BOOST_RANDOM_XOR_COMBINE_HPP
15 #define BOOST_RANDOM_XOR_COMBINE_HPP
16
17 #include <iostream>
18 #include <cassert>
19 #include <algorithm> // for std::min and std::max
20 #include <boost/config.hpp>
21 #include <boost/limits.hpp>
22 #include <boost/static_assert.hpp>
23 #include <boost/cstdint.hpp>     // uint32_t
24 #include <boost/random/detail/config.hpp>
25
26
27 namespace boost {
28 namespace random {
29
30 /// \cond hide_private_members
31 #ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
32   #define BOOST_RANDOM_VAL_TYPE typename URNG1::result_type 
33 #else
34   #define BOOST_RANDOM_VAL_TYPE uint32_t
35 #endif
36 /// \endcond
37
38 /**
39  * Instantiations of @c xor_combine model a \pseudo_random_number_generator.
40  * To produce its output it invokes each of the base generators, shifts
41  * their results and xors them together.
42  */
43 template<class URNG1, int s1, class URNG2, int s2
44 #ifndef BOOST_RANDOM_DOXYGEN
45 , BOOST_RANDOM_VAL_TYPE val = 0
46 #endif
47 >
48 class xor_combine
49 {
50 public:
51   typedef URNG1 base1_type;
52   typedef URNG2 base2_type;
53   typedef typename base1_type::result_type result_type;
54
55   BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
56   BOOST_STATIC_CONSTANT(int, shift1 = s1);
57   BOOST_STATIC_CONSTANT(int, shift2 = s2);
58
59   /**
60    * Constructors a @c xor_combine by default constructing
61    * both base generators.
62    */
63   xor_combine() : _rng1(), _rng2()
64   { }
65   /**
66    * Constructs a @c xor_combine by copying two base generators.
67    */
68   xor_combine(const base1_type & rng1, const base2_type & rng2)
69     : _rng1(rng1), _rng2(rng2) { }
70   /**
71    * Constructs a @c xor_combine, seeding both base generators
72    * with @c v.
73    */
74   xor_combine(const result_type & v)
75     : _rng1(v), _rng2(v) { }
76   /**
77    * Constructs a @c xor_combine, seeding both base generators
78    * with values from the iterator range [first, last) and changes
79    * first to point to the element after the last one used.  If there
80    * are not enough elements in the range to seed both generators,
81    * throws @c std::invalid_argument.
82    */
83   template<class It> xor_combine(It& first, It last)
84     : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
85   /**
86    * Calls @c seed() for both base generators.
87    */
88   void seed() { _rng1.seed(); _rng2.seed(); }
89   /**
90    * @c seeds both base generators with @c v.
91    */
92   void seed(const result_type & v) { _rng1.seed(v); _rng2.seed(v); }
93   /**
94    * seeds both base generators with values from the iterator
95    * range [first, last) and changes first to point to the element
96    * after the last one used.  If there are not enough elements in
97    * the range to seed both generators, throws @c std::invalid_argument.
98    */
99   template<class It> void seed(It& first, It last)
100   {
101     _rng1.seed(first, last);
102     _rng2.seed(first, last);
103   }
104
105   /** Returns the first base generator. */
106   const base1_type& base1() { return _rng1; }
107   /** Returns the second base generator. */
108   const base2_type& base2() { return _rng2; }
109
110   /** Returns the next value of the generator. */
111   result_type operator()()
112   {
113     // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
114 #if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
115     BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::is_integer);
116     BOOST_STATIC_ASSERT(std::numeric_limits<typename base2_type::result_type>::is_integer);
117     BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::digits >= std::numeric_limits<typename base2_type::result_type>::digits);
118 #endif
119     return (_rng1() << s1) ^ (_rng2() << s2);
120   }
121
122   /**
123    * Returns the smallest value that the generator can produce.
124    */
125   result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::min BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.min)()); }
126   /**
127    * Returns the largest value that the generator can produce.
128    */
129   result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::max BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.max)()); }
130   static bool validation(result_type x) { return val == x; }
131
132 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
133
134 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
135   template<class CharT, class Traits>
136   friend std::basic_ostream<CharT,Traits>&
137   operator<<(std::basic_ostream<CharT,Traits>& os, const xor_combine& s)
138   {
139     os << s._rng1 << " " << s._rng2 << " ";
140     return os;
141   }
142
143   template<class CharT, class Traits>
144   friend std::basic_istream<CharT,Traits>&
145   operator>>(std::basic_istream<CharT,Traits>& is, xor_combine& s)
146   {
147     is >> s._rng1 >> std::ws >> s._rng2 >> std::ws;
148     return is;
149   }
150 #endif
151
152   friend bool operator==(const xor_combine& x, const xor_combine& y)
153   { return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
154   friend bool operator!=(const xor_combine& x, const xor_combine& y)
155   { return !(x == y); }
156 #else
157   // Use a member function; Streamable concept not supported.
158   bool operator==(const xor_combine& rhs) const
159   { return _rng1 == rhs._rng1 && _rng2 == rhs._rng2; }
160   bool operator!=(const xor_combine& rhs) const
161   { return !(*this == rhs); }
162 #endif
163
164 private:
165   base1_type _rng1;
166   base2_type _rng2;
167 };
168
169 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
170 //  A definition is required even for integral static constants
171 template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
172 const bool xor_combine<URNG1, s1, URNG2, s2, val>::has_fixed_range;
173 template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
174 const int xor_combine<URNG1, s1, URNG2, s2, val>::shift1;
175 template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
176 const int xor_combine<URNG1, s1, URNG2, s2, val>::shift2;
177 #endif
178
179 #undef BOOST_RANDOM_VAL_TYPE
180
181 } // namespace random
182 } // namespace boost
183
184 #endif // BOOST_RANDOM_XOR_COMBINE_HPP