Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r69995 - in trunk: boost/random boost/random/detail libs/random/test
From: steven_at_[hidden]
Date: 2011-03-14 20:47:28


Author: steven_watanabe
Date: 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
New Revision: 69995
URL: http://svn.boost.org/trac/boost/changeset/69995

Log:
Make sure that the type of the seed argument is consistent with the standard for all generators. Eliminate the odd rand48 seeding rules.
Text files modified:
   trunk/boost/random/detail/seed_impl.hpp | 13 ++++++++
   trunk/boost/random/discard_block.hpp | 6 ++-
   trunk/boost/random/lagged_fibonacci.hpp | 29 +++++++++++------
   trunk/boost/random/linear_congruential.hpp | 65 ++++++++--------------------------------
   trunk/boost/random/subtract_with_carry.hpp | 16 ++++----
   trunk/libs/random/test/test_rand48.cpp | 7 ----
   6 files changed, 56 insertions(+), 80 deletions(-)

Modified: trunk/boost/random/detail/seed_impl.hpp
==============================================================================
--- trunk/boost/random/detail/seed_impl.hpp (original)
+++ trunk/boost/random/detail/seed_impl.hpp 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
@@ -32,6 +32,19 @@
 namespace random {
 namespace detail {
 
+// finds the seed type of an engine, given its
+// result_type. If the result_type is integral
+// the seed type is the same. If the result_type
+// is floating point, the seed type is uint32_t
+template<class T>
+struct seed_type
+{
+ typedef typename boost::mpl::if_<boost::is_integral<T>,
+ T,
+ boost::uint32_t
+ >::type type;
+};
+
 template<class Engine, class Iter>
 void generate_from_real(Engine& eng, Iter begin, Iter end)
 {

Modified: trunk/boost/random/discard_block.hpp
==============================================================================
--- trunk/boost/random/discard_block.hpp (original)
+++ trunk/boost/random/discard_block.hpp 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
@@ -41,6 +41,8 @@
 template<class UniformRandomNumberGenerator, std::size_t p, std::size_t r>
 class discard_block_engine
 {
+ typedef typename detail::seed_type<
+ typename UniformRandomNumberGenerator::result_type>::type seed_type;
 public:
     typedef UniformRandomNumberGenerator base_type;
     typedef typename base_type::result_type result_type;
@@ -69,7 +71,7 @@
      * generator with @c value
      */
     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(discard_block_engine,
- result_type, value)
+ seed_type, value)
     { _rng.seed(value); _n = 0; }
     
     /**
@@ -89,7 +91,7 @@
     /** default seeds the underlying generator. */
     void seed() { _rng.seed(); _n = 0; }
     /** Seeds the underlying generator with s. */
- BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(discard_block_engine, result_type, s)
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(discard_block_engine, seed_type, s)
     { _rng.seed(s); _n = 0; }
     /** Seeds the underlying generator with seq. */
     BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(discard_block_engine, SeedSeq, seq)

Modified: trunk/boost/random/lagged_fibonacci.hpp
==============================================================================
--- trunk/boost/random/lagged_fibonacci.hpp (original)
+++ trunk/boost/random/lagged_fibonacci.hpp 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
@@ -51,6 +51,8 @@
     BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
     BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
 
+ BOOST_STATIC_CONSTANT(UIntType, default_seed = 331u);
+
     /** Returns the smallest value that the generator can produce. */
     static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
     /** Returns the largest value that the generator can produce. */
@@ -62,7 +64,7 @@
 
     /** Creates a new @c lagged_fibonacci_engine and calls @c seed(value). */
     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_engine,
- uint32_t, value)
+ UIntType, value)
     { seed(value); }
 
     /** Creates a new @c lagged_fibonacci_engine and calls @c seed(seq). */
@@ -78,17 +80,17 @@
 
     // compiler-generated copy ctor and assignment operator are fine
     
- /** Calls @c seed(331). */
- void seed() { seed(331u); }
+ /** Calls @c seed(default_seed). */
+ void seed() { seed(default_seed); }
 
     /**
      * Sets the state of the generator to values produced by
      * a \minstd_rand0 generator.
      */
     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_engine,
- uint32_t, value)
+ UIntType, value)
     {
- minstd_rand0 intgen(value);
+ minstd_rand0 intgen(static_cast<boost::uint32_t>(value));
         detail::generator_seed_seq<minstd_rand0> gen(intgen);
         seed(gen);
     }
@@ -187,6 +189,8 @@
 const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::long_lag;
 template<class UIntType, int w, unsigned int p, unsigned int q>
 const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::short_lag;
+template<class UIntType, int w, unsigned int p, unsigned int q>
+const UIntType lagged_fibonacci_engine<UIntType, w, p, q>::default_seed;
 #endif
 
 /// \cond show_private
@@ -215,7 +219,7 @@
     typedef lagged_fibonacci_engine<UIntType, w, p, q> base_type;
 public:
     lagged_fibonacci() {}
- BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci, uint32_t, val)
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci, UIntType, val)
     { this->seed(val); }
     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci, SeedSeq, seq)
     { this->seed(seq); }
@@ -261,6 +265,8 @@
     BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
     BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
 
+ BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 331u);
+
     /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(). */
     lagged_fibonacci_01_engine() { seed(); }
     /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(value). */
@@ -274,8 +280,8 @@
 
     // compiler-generated copy ctor and assignment operator are fine
 
- /** Calls seed(331u). */
- void seed() { seed(331u); }
+ /** Calls seed(default_seed). */
+ void seed() { seed(default_seed); }
 
     /**
      * Constructs a \minstd_rand0 generator with the constructor parameter
@@ -284,7 +290,7 @@
      * seeds will be equivalent to some seed within this range. See
      * \linear_congruential_engine for details.
      */
- BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01_engine, uint32_t, value)
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01_engine, boost::uint32_t, value)
     {
         minstd_rand0 intgen(value);
         detail::generator_seed_seq<minstd_rand0> gen(intgen);
@@ -414,7 +420,8 @@
 const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::short_lag;
 template<class RealType, int w, unsigned int p, unsigned int q>
 const int lagged_fibonacci_01_engine<RealType,w,p,q>::word_size;
-
+template<class RealType, int w, unsigned int p, unsigned int q>
+const boost::uint32_t lagged_fibonacci_01_engine<RealType,w,p,q>::default_seed;
 #endif
 
 /// \cond show_private
@@ -449,7 +456,7 @@
     typedef lagged_fibonacci_01_engine<RealType, w, p, q> base_type;
 public:
     lagged_fibonacci_01() {}
- BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01, uint32_t, val)
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01, boost::uint32_t, val)
     { this->seed(val); }
     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01, SeedSeq, seq)
     { this->seed(seq); }

Modified: trunk/boost/random/linear_congruential.hpp
==============================================================================
--- trunk/boost/random/linear_congruential.hpp (original)
+++ trunk/boost/random/linear_congruential.hpp 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
@@ -347,7 +347,7 @@
 class rand48
 {
 public:
- typedef uint32_t result_type;
+ typedef boost::uint32_t result_type;
 
     BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
     /**
@@ -363,15 +363,15 @@
     /** Seeds the generator with the default seed. */
     rand48() : lcf(cnv(static_cast<uint32_t>(1))) {}
     /**
- * If T is an integral type smaller than int64_t, constructs
- * a \rand48 generator with x(0) := (x0 << 16) | 0x330e. Otherwise
- * constructs a \rand48 generator with x(0) = x0.
+ * Constructs a \rand48 generator with x(0) := (x0 << 16) | 0x330e.
      */
- template<class T> explicit rand48(const T& x0) : lcf(cnv(x0)) { }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(rand48, result_type, x0)
+ { seed(x0); }
     /**
      * Seeds the generator with values produced by @c seq.generate().
      */
- template<class SeedSeq> explicit rand48(SeedSeq& seq) : lcf(cnv(seq)) { }
+ BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(rand48, SeedSeq, seq)
+ { seed(seq); }
     /**
      * Seeds the generator using values from an iterator range,
      * and updates first to point one past the last value consumed.
@@ -383,11 +383,10 @@
     /** Seeds the generator with the default seed. */
     void seed() { seed(static_cast<uint32_t>(1)); }
     /**
- * If T is an integral type smaller than int64_t, changes
- * the current value x(n) of the generator to (x0 << 16) | 0x330e.
- * Otherwise changes the current value x(n) to x0.
+ * Changes the current value x(n) of the generator to (x0 << 16) | 0x330e.
      */
- template<class T> void seed(const T& x0) { lcf.seed(cnv(x0)); }
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(rand48, result_type, x0)
+ { lcf.seed(cnv(x0)); }
     /**
      * Seeds the generator using values from an iterator range,
      * and updates first to point one past the last value consumed.
@@ -396,7 +395,8 @@
     /**
      * Seeds the generator with values produced by @c seq.generate().
      */
- template<class SeedSeq> void seed(SeedSeq& seq) { lcf.seed(cnv(seq)); }
+ BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(rand48, SeedSeq, seq)
+ { lcf.seed(seq); }
 
     /** Returns the next value of the generator. */
     uint32_t operator()() { return static_cast<uint32_t>(lcf() >> 17); }
@@ -447,47 +447,8 @@
         0xB, uint64_t(1)<<48> lcf_t;
     lcf_t lcf;
 
- template<class T>
- struct cnv_impl_arithmetic {
- typedef uint64_t type;
- static type call(T x)
- {
- if(sizeof(T) < sizeof(uint64_t)) {
- return (static_cast<uint64_t>(x) << 16) | 0x330e;
- } else {
- return(static_cast<uint64_t>(x));
- }
- }
- };
-
- template<class T>
- struct cnv_impl_seed_seq
- {
- typedef T& type;
- static type call(T& seq) { return seq; }
- };
-
- template<class T, class CV_T>
- struct cnv_impl :
- mpl::if_<is_arithmetic<T>,
- cnv_impl_arithmetic<T>,
- cnv_impl_seed_seq<CV_T> >::type
- {};
-
- template<class T>
- static typename cnv_impl<T, T>::type cnv(T& x)
- {
- return cnv_impl<T, T>::call(x);
- }
- template<class T>
- static typename cnv_impl<T, const T>::type cnv(const T& x)
- {
- return cnv_impl<T, const T>::call(x);
- }
- static lcf_t& cnv(rand48& x) { return x.lcf; }
- static uint64_t cnv(float x) { return(static_cast<uint64_t>(x)); }
- static uint64_t cnv(double x) { return(static_cast<uint64_t>(x)); }
- static uint64_t cnv(long double x) { return(static_cast<uint64_t>(x)); }
+ static boost::uint64_t cnv(boost::uint32_t x)
+ { return (static_cast<uint64_t>(x) << 16) | 0x330e; }
     /// \endcond
 };
 #endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */

Modified: trunk/boost/random/subtract_with_carry.hpp
==============================================================================
--- trunk/boost/random/subtract_with_carry.hpp (original)
+++ trunk/boost/random/subtract_with_carry.hpp 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
@@ -128,7 +128,7 @@
      * it with @c value.
      */
     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_engine,
- uint32_t, value)
+ IntType, value)
     { seed(value); }
     /**
      * Constructs a new @c subtract_with_carry_engine and seeds
@@ -152,10 +152,10 @@
     /** Seeds the generator with the default seed. */
     void seed() { seed(default_seed); }
     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_engine,
- uint32_t, value)
+ IntType, value)
     {
         typedef linear_congruential_engine<uint32_t,40014,0,2147483563> gen_t;
- gen_t intgen(value);
+ gen_t intgen(static_cast<boost::uint32_t>(value));
         detail::generator_seed_seq<gen_t> gen(intgen);
         seed(gen);
     }
@@ -337,7 +337,7 @@
     BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
     BOOST_STATIC_CONSTANT(std::size_t, long_lag = r);
     BOOST_STATIC_CONSTANT(std::size_t, short_lag = s);
- BOOST_STATIC_CONSTANT(uint32_t, default_seed = 19780503u);
+ BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 19780503u);
 
     BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_integer);
 
@@ -345,7 +345,7 @@
     subtract_with_carry_01_engine() { init_modulus(); seed(); }
     /** Creates a new subtract_with_carry_01_engine and seeds it with value. */
     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_01_engine,
- uint32_t, value)
+ boost::uint32_t, value)
     { init_modulus(); seed(value); }
     /**
      * Creates a new \subtract_with_carry_01_engine and seeds with with values
@@ -383,7 +383,7 @@
 
     /** Seeds the generator with @c value. */
     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_01_engine,
- uint32_t, value)
+ boost::uint32_t, value)
     {
         typedef linear_congruential_engine<uint32_t, 40014, 0, 2147483563> gen_t;
         gen_t intgen(value);
@@ -550,7 +550,7 @@
     BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(subtract_with_carry, Gen, gen)
     { seed(gen); }
     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry,
- uint32_t, val)
+ IntType, val)
     { seed(val); }
     template<class It>
     subtract_with_carry(It& first, It last) : base_type(first, last) {}
@@ -560,7 +560,7 @@
         detail::generator_seed_seq<Gen> seq(gen);
         base_type::seed(seq);
     }
- BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry, uint32_t, val)
+ BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry, IntType, val)
     { base_type::seed(val); }
     template<class It>
     void seed(It& first, It last) { base_type::seed(first, last); }

Modified: trunk/libs/random/test/test_rand48.cpp
==============================================================================
--- trunk/libs/random/test/test_rand48.cpp (original)
+++ trunk/libs/random/test/test_rand48.cpp 2011-03-14 20:47:25 EDT (Mon, 14 Mar 2011)
@@ -23,11 +23,4 @@
 
 #define BOOST_RANDOM_GENERATE_VALUES { 0x55424A4U, 0x3A2CCEF5U, 0x6ADB4A65U, 0x2B019719U }
 
-// rand48 uses non-standard seeding
-template<class Converted, class T>
-void test_seed_conversion(boost::rand48 & urng, const T & t) {
- boost::rand48 urng2(t);
- urng2.seed(t);
-}
-
 #include "test_generator.ipp"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk