]> git.sesse.net Git - casparcg/blob - dependencies64/boost/boost/random/xor_combine.hpp
[general] Added cg_producer_registry as dependency in frame_producer_dependencies
[casparcg] / dependencies64 / boost / 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$
11  *
12  */
13
14 #ifndef BOOST_RANDOM_XOR_COMBINE_HPP
15 #define BOOST_RANDOM_XOR_COMBINE_HPP
16
17 #include <istream>
18 #include <iosfwd>
19 #include <cassert>
20 #include <algorithm> // for std::min and std::max
21 #include <boost/config.hpp>
22 #include <boost/limits.hpp>
23 #include <boost/cstdint.hpp>     // uint32_t
24 #include <boost/random/detail/config.hpp>
25 #include <boost/random/detail/seed.hpp>
26 #include <boost/random/detail/seed_impl.hpp>
27 #include <boost/random/detail/operators.hpp>
28
29 namespace boost {
30 namespace random {
31
32 /**
33  * Instantiations of @c xor_combine_engine model a
34  * \pseudo_random_number_generator.  To produce its output it
35  * invokes each of the base generators, shifts their results
36  * and xors them together.
37  */
38 template<class URNG1, int s1, class URNG2, int s2>
39 class xor_combine_engine
40 {
41 public:
42     typedef URNG1 base1_type;
43     typedef URNG2 base2_type;
44     typedef typename base1_type::result_type result_type;
45
46     BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
47     BOOST_STATIC_CONSTANT(int, shift1 = s1);
48     BOOST_STATIC_CONSTANT(int, shift2 = s2);
49
50     /**
51      * Constructors a @c xor_combine_engine by default constructing
52      * both base generators.
53      */
54     xor_combine_engine() : _rng1(), _rng2() { }
55
56     /** Constructs a @c xor_combine by copying two base generators. */
57     xor_combine_engine(const base1_type & rng1, const base2_type & rng2)
58       : _rng1(rng1), _rng2(rng2) { }
59
60     /**
61      * Constructs a @c xor_combine_engine, seeding both base generators
62      * with @c v.
63      *
64      * @xmlwarning
65      * The exact algorithm used by this function may change in the future.
66      * @endxmlwarning
67      */
68     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(xor_combine_engine,
69         result_type, v)
70     { seed(v); }
71
72     /**
73      * Constructs a @c xor_combine_engine, seeding both base generators
74      * with values produced by @c seq.
75      */
76     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(xor_combine_engine,
77         SeedSeq, seq)
78     { seed(seq); }
79
80     /**
81      * Constructs a @c xor_combine_engine, seeding both base generators
82      * with values from the iterator range [first, last) and changes
83      * first to point to the element after the last one used.  If there
84      * are not enough elements in the range to seed both generators,
85      * throws @c std::invalid_argument.
86      */
87     template<class It> xor_combine_engine(It& first, It last)
88       : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
89
90     /** Calls @c seed() for both base generators. */
91     void seed() { _rng1.seed(); _rng2.seed(); }
92
93     /** @c seeds both base generators with @c v. */
94     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(xor_combine_engine, result_type, v)
95     { _rng1.seed(v); _rng2.seed(v); }
96
97     /** @c seeds both base generators with values produced by @c seq. */
98     BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(xor_combine_engine, SeedSeq, seq)
99     { _rng1.seed(seq); _rng2.seed(seq); }
100
101     /**
102      * seeds both base generators with values from the iterator
103      * range [first, last) and changes first to point to the element
104      * after the last one used.  If there are not enough elements in
105      * the range to seed both generators, throws @c std::invalid_argument.
106      */
107     template<class It> void seed(It& first, It last)
108     {
109         _rng1.seed(first, last);
110         _rng2.seed(first, last);
111     }
112
113     /** Returns the first base generator. */
114     const base1_type& base1() const { return _rng1; }
115
116     /** Returns the second base generator. */
117     const base2_type& base2() const { return _rng2; }
118
119     /** Returns the next value of the generator. */
120     result_type operator()()
121     {
122         return (_rng1() << s1) ^ (_rng2() << s2);
123     }
124   
125     /** Fills a range with random values */
126     template<class Iter>
127     void generate(Iter first, Iter last)
128     { detail::generate_from_int(*this, first, last); }
129
130     /** Advances the state of the generator by @c z. */
131     void discard(boost::uintmax_t z)
132     {
133         _rng1.discard(z);
134         _rng2.discard(z);
135     }
136
137     /** Returns the smallest value that the generator can produce. */
138     static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::min)((URNG1::min)(), (URNG2::min)()); }
139     /** Returns the largest value that the generator can produce. */
140     static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::max)((URNG1::min)(), (URNG2::max)()); }
141
142     /**
143      * Writes the textual representation of the generator to a @c std::ostream.
144      */
145     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, xor_combine_engine, s)
146     {
147         os << s._rng1 << ' ' << s._rng2;
148         return os;
149     }
150     
151     /**
152      * Reads the textual representation of the generator from a @c std::istream.
153      */
154     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, xor_combine_engine, s)
155     {
156         is >> s._rng1 >> std::ws >> s._rng2;
157         return is;
158     }
159     
160     /** Returns true if the two generators will produce identical sequences. */
161     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(xor_combine_engine, x, y)
162     { return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
163     
164     /** Returns true if the two generators will produce different sequences. */
165     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(xor_combine_engine)
166
167 private:
168     base1_type _rng1;
169     base2_type _rng2;
170 };
171
172 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
173 //  A definition is required even for integral static constants
174 template<class URNG1, int s1, class URNG2, int s2>
175 const bool xor_combine_engine<URNG1, s1, URNG2, s2>::has_fixed_range;
176 template<class URNG1, int s1, class URNG2, int s2>
177 const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift1;
178 template<class URNG1, int s1, class URNG2, int s2>
179 const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift2;
180 #endif
181
182 /// \cond show_private
183
184 /** Provided for backwards compatibility. */
185 template<class URNG1, int s1, class URNG2, int s2,
186     typename URNG1::result_type v = 0>
187 class xor_combine : public xor_combine_engine<URNG1, s1, URNG2, s2>
188 {
189     typedef xor_combine_engine<URNG1, s1, URNG2, s2> base_type;
190 public:
191     typedef typename base_type::result_type result_type;
192     xor_combine() {}
193     xor_combine(result_type val) : base_type(val) {}
194     template<class It>
195     xor_combine(It& first, It last) : base_type(first, last) {}
196     xor_combine(const URNG1 & rng1, const URNG2 & rng2)
197       : base_type(rng1, rng2) { }
198
199     result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::min)((this->base1().min)(), (this->base2().min)()); }
200     result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::max)((this->base1().min)(), (this->base2().max)()); }
201 };
202
203 /// \endcond
204
205 } // namespace random
206 } // namespace boost
207
208 #endif // BOOST_RANDOM_XOR_COMBINE_HPP